]> gitweb.factorcode.org Git - factor.git/commitdiff
inlineimpl.hpp is toast
authorPhil Dawes <phil@phildawes.net>
Tue, 29 Sep 2009 18:53:10 +0000 (19:53 +0100)
committerPhil Dawes <phil@phildawes.net>
Tue, 29 Sep 2009 18:53:10 +0000 (19:53 +0100)
12 files changed:
vm/arrays.hpp
vm/booleans.hpp
vm/byte_arrays.hpp
vm/callstack.hpp
vm/code_heap.hpp
vm/data_gc.cpp
vm/generic_arrays.hpp
vm/inlineimpls.hpp [deleted file]
vm/local_roots.hpp
vm/master.hpp
vm/math.hpp
vm/vm.hpp

index 96d6dc137a277974d27771956ae6c20c996189a3..3abd78474e6912a10576d75fb8facb1f3839261b 100755 (executable)
@@ -10,4 +10,25 @@ inline cell array_nth(array *array, cell slot)
        return array->data()[slot];
 }
 
+inline void factor_vm::set_array_nth(array *array, cell slot, cell value)
+{
+#ifdef FACTOR_DEBUG
+       assert(slot < array_capacity(array));
+       assert(array->h.hi_tag() == ARRAY_TYPE);
+       check_tagged_pointer(value);
+#endif
+       array->data()[slot] = value;
+       write_barrier(array);
+}
+
+struct growable_array {
+       cell count;
+       gc_root<array> elements;
+
+       growable_array(factor_vm *myvm, cell capacity = 10) : count(0), elements(myvm->allot_array(capacity,F),myvm) {}
+
+       void add(cell elt);
+       void trim();
+};
+
 }
index 88235122a3dc4e32ff21ea0d2fb32164acb16a0d..498c3f74be565e4bdfe75678e6b2b909dc6917c5 100644 (file)
@@ -4,4 +4,9 @@ namespace factor
 VM_C_API void box_boolean(bool value, factor_vm *vm);
 VM_C_API bool to_boolean(cell value, factor_vm *vm);
 
+inline cell factor_vm::tag_boolean(cell untagged)
+{
+       return (untagged ? T : F);
+}
+
 }
index 412ef35bb4403ee39e5aa0ef975114ad79a07a9b..0d74793dafda79bd1ee5af24af38aff546024321 100755 (executable)
@@ -1,4 +1,16 @@
 namespace factor
 {
 
+struct growable_byte_array {
+       cell count;
+       gc_root<byte_array> elements;
+
+       growable_byte_array(factor_vm *myvm,cell capacity = 40) : count(0), elements(myvm->allot_byte_array(capacity),myvm) { }
+
+       void append_bytes(void *elts, cell len);
+       void append_byte_array(cell elts);
+
+       void trim();
+};
+
 }
index 630332d7b0997e44c9a11e5df6f8899c4b20ee70..1cfe9a763e4d190e5cf2225d2362d70feaac8edc 100755 (executable)
@@ -8,4 +8,49 @@ inline static cell callstack_size(cell size)
 
 VM_ASM_API void save_callstack_bottom(stack_frame *callstack_bottom, factor_vm *vm);
 
+/* This is a little tricky. The iterator may allocate memory, so we
+keep the callstack in a GC root and use relative offsets */
+template<typename TYPE> void factor_vm::iterate_callstack_object(callstack *stack_, TYPE &iterator)
+{
+       gc_root<callstack> stack(stack_,this);
+       fixnum frame_offset = untag_fixnum(stack->length) - sizeof(stack_frame);
+
+       while(frame_offset >= 0)
+       {
+               stack_frame *frame = stack->frame_at(frame_offset);
+               frame_offset -= frame->size;
+               iterator(frame,this);
+       }
+}
+
+template<typename TYPE> void factor_vm::iterate_callstack(cell top, cell bottom, TYPE &iterator)
+{
+       stack_frame *frame = (stack_frame *)bottom - 1;
+
+       while((cell)frame >= top)
+       {
+               iterator(frame,this);
+               frame = frame_successor(frame);
+       }
+}
+
+/* Every object has a regular representation in the runtime, which makes GC
+much simpler. Every slot of the object until binary_payload_start is a pointer
+to some other object. */
+struct factor_vm;
+inline void factor_vm::do_slots(cell obj, void (* iter)(cell *,factor_vm*))
+{
+       cell scan = obj;
+       cell payload_start = binary_payload_start((object *)obj);
+       cell end = obj + payload_start;
+
+       scan += sizeof(cell);
+
+       while(scan < end)
+       {
+               iter((cell *)scan,this);
+               scan += sizeof(cell);
+       }
+}
+
 }
index 412ef35bb4403ee39e5aa0ef975114ad79a07a9b..df5f14a4824167bd59256a7ee4f9d456fa09326c 100755 (executable)
@@ -1,4 +1,11 @@
 namespace factor
 {
 
+inline void factor_vm::check_code_pointer(cell ptr)
+{
+#ifdef FACTOR_DEBUG
+       assert(in_code_heap_p(ptr));
+#endif
+}
+
 }
index 58c2b914f2e5670b37858982157fe6dc64561c3a..d23caa798f8d36e2332f929eb0a1054dad797b8f 100755 (executable)
@@ -667,4 +667,68 @@ VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *myvm
        VM_PTR->inline_gc(gc_roots_base,gc_roots_size);
 }
 
+inline object *factor_vm::allot_zone(zone *z, cell a)
+{
+       cell h = z->here;
+       z->here = h + align8(a);
+       object *obj = (object *)h;
+       allot_barrier(obj);
+       return obj;
+}
+
+/*
+ * It is up to the caller to fill in the object's fields in a meaningful
+ * fashion!
+ */
+object *factor_vm::allot_object(header header, cell size)
+{
+#ifdef GC_DEBUG
+       if(!gc_off)
+               gc();
+#endif
+
+       object *obj;
+
+       if(nursery.size - allot_buffer_zone > size)
+       {
+               /* If there is insufficient room, collect the nursery */
+               if(nursery.here + allot_buffer_zone + size > nursery.end)
+                       garbage_collection(data->nursery(),false,0);
+
+               cell h = nursery.here;
+               nursery.here = h + align8(size);
+               obj = (object *)h;
+       }
+       /* If the object is bigger than the nursery, allocate it in
+       tenured space */
+       else
+       {
+               zone *tenured = &data->generations[data->tenured()];
+
+               /* If tenured space does not have enough room, collect */
+               if(tenured->here + size > tenured->end)
+               {
+                       gc();
+                       tenured = &data->generations[data->tenured()];
+               }
+
+               /* If it still won't fit, grow the heap */
+               if(tenured->here + size > tenured->end)
+               {
+                       garbage_collection(data->tenured(),true,size);
+                       tenured = &data->generations[data->tenured()];
+               }
+
+               obj = allot_zone(tenured,size);
+
+               /* Allows initialization code to store old->new pointers
+               without hitting the write barrier in the common case of
+               a nursery allocation */
+               write_barrier(obj);
+       }
+
+       obj->h = header;
+       return obj;
+}
+
 }
index 0125cb76519c2a2798adbd9d61969059305faedf..8e499a928f78e3c9775c2121c40fb294ebab51c8 100644 (file)
@@ -19,4 +19,41 @@ template <typename T> cell array_size(T *array)
        return array_size<T>(array_capacity(array));
 }
 
+template <typename TYPE> TYPE *factor_vm::allot_array_internal(cell capacity)
+{
+       TYPE *array = allot<TYPE>(array_size<TYPE>(capacity));
+       array->capacity = tag_fixnum(capacity);
+       return array;
+}
+
+template <typename TYPE> bool factor_vm::reallot_array_in_place_p(TYPE *array, cell capacity)
+{
+       return in_zone(&nursery,array) && capacity <= array_capacity(array);
+}
+
+template <typename TYPE> TYPE *factor_vm::reallot_array(TYPE *array_, cell capacity)
+{
+       gc_root<TYPE> array(array_,this);
+
+       if(reallot_array_in_place_p(array.untagged(),capacity))
+       {
+               array->capacity = tag_fixnum(capacity);
+               return array.untagged();
+       }
+       else
+       {
+               cell to_copy = array_capacity(array.untagged());
+               if(capacity < to_copy)
+                       to_copy = capacity;
+                       
+               TYPE *new_array = allot_array_internal<TYPE>(capacity);
+               
+               memcpy(new_array + 1,array.untagged() + 1,to_copy * TYPE::element_size);
+               memset((char *)(new_array + 1) + to_copy * TYPE::element_size,
+                      0,(capacity - to_copy) * TYPE::element_size);
+               
+               return new_array;
+       }
+}
+
 }
diff --git a/vm/inlineimpls.hpp b/vm/inlineimpls.hpp
deleted file mode 100644 (file)
index 74620dc..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-namespace factor
-{
-
-// I've had to copy inline implementations here to make dependencies work. Am hoping to move this code back into include files
-// once the rest of the reentrant changes are done. -PD
-
-//data_gc.hpp
-inline bool factor_vm::collecting_accumulation_gen_p()
-{
-       return ((data->have_aging_p()
-               && collecting_gen == data->aging()
-               && !collecting_aging_again)
-               || collecting_gen == data->tenured());
-}
-
-inline object *factor_vm::allot_zone(zone *z, cell a)
-{
-       cell h = z->here;
-       z->here = h + align8(a);
-       object *obj = (object *)h;
-       allot_barrier(obj);
-       return obj;
-}
-
-/*
- * It is up to the caller to fill in the object's fields in a meaningful
- * fashion!
- */
-inline object *factor_vm::allot_object(header header, cell size)
-{
-#ifdef GC_DEBUG
-       if(!gc_off)
-               gc();
-#endif
-
-       object *obj;
-
-       if(nursery.size - allot_buffer_zone > size)
-       {
-               /* If there is insufficient room, collect the nursery */
-               if(nursery.here + allot_buffer_zone + size > nursery.end)
-                       garbage_collection(data->nursery(),false,0);
-
-               cell h = nursery.here;
-               nursery.here = h + align8(size);
-               obj = (object *)h;
-       }
-       /* If the object is bigger than the nursery, allocate it in
-       tenured space */
-       else
-       {
-               zone *tenured = &data->generations[data->tenured()];
-
-               /* If tenured space does not have enough room, collect */
-               if(tenured->here + size > tenured->end)
-               {
-                       gc();
-                       tenured = &data->generations[data->tenured()];
-               }
-
-               /* If it still won't fit, grow the heap */
-               if(tenured->here + size > tenured->end)
-               {
-                       garbage_collection(data->tenured(),true,size);
-                       tenured = &data->generations[data->tenured()];
-               }
-
-               obj = allot_zone(tenured,size);
-
-               /* Allows initialization code to store old->new pointers
-               without hitting the write barrier in the common case of
-               a nursery allocation */
-               write_barrier(obj);
-       }
-
-       obj->h = header;
-       return obj;
-}
-
-template<typename TYPE> TYPE *factor_vm::allot(cell size)
-{
-       return (TYPE *)allot_object(header(TYPE::type_number),size);
-}
-
-inline void factor_vm::check_data_pointer(object *pointer)
-{
-#ifdef FACTOR_DEBUG
-       if(!growing_data_heap)
-       {
-               assert((cell)pointer >= data->seg->start
-                      && (cell)pointer < data->seg->end);
-       }
-#endif
-}
-
-inline void factor_vm::check_tagged_pointer(cell tagged)
-{
-#ifdef FACTOR_DEBUG
-       if(!immediate_p(tagged))
-       {
-               object *obj = untag<object>(tagged);
-               check_data_pointer(obj);
-               obj->h.hi_tag();
-       }
-#endif
-}
-
-//generic_arrays.hpp
-template <typename TYPE> TYPE *factor_vm::allot_array_internal(cell capacity)
-{
-       TYPE *array = allot<TYPE>(array_size<TYPE>(capacity));
-       array->capacity = tag_fixnum(capacity);
-       return array;
-}
-
-template <typename TYPE> bool factor_vm::reallot_array_in_place_p(TYPE *array, cell capacity)
-{
-       return in_zone(&nursery,array) && capacity <= array_capacity(array);
-}
-
-template <typename TYPE> TYPE *factor_vm::reallot_array(TYPE *array_, cell capacity)
-{
-       gc_root<TYPE> array(array_,this);
-
-       if(reallot_array_in_place_p(array.untagged(),capacity))
-       {
-               array->capacity = tag_fixnum(capacity);
-               return array.untagged();
-       }
-       else
-       {
-               cell to_copy = array_capacity(array.untagged());
-               if(capacity < to_copy)
-                       to_copy = capacity;
-
-               TYPE *new_array = allot_array_internal<TYPE>(capacity);
-       
-               memcpy(new_array + 1,array.untagged() + 1,to_copy * TYPE::element_size);
-               memset((char *)(new_array + 1) + to_copy * TYPE::element_size,
-                       0,(capacity - to_copy) * TYPE::element_size);
-
-               return new_array;
-       }
-}
-
-//arrays.hpp
-inline void factor_vm::set_array_nth(array *array, cell slot, cell value)
-{
-#ifdef FACTOR_DEBUG
-       assert(slot < array_capacity(array));
-       assert(array->h.hi_tag() == ARRAY_TYPE);
-       check_tagged_pointer(value);
-#endif
-       array->data()[slot] = value;
-       write_barrier(array);
-}
-
-struct growable_array {
-       cell count;
-       gc_root<array> elements;
-
-       growable_array(factor_vm *myvm, cell capacity = 10) : count(0), elements(myvm->allot_array(capacity,F),myvm) {}
-
-       void add(cell elt);
-       void trim();
-};
-
-//byte_arrays.hpp
-struct growable_byte_array {
-       cell count;
-       gc_root<byte_array> elements;
-
-       growable_byte_array(factor_vm *myvm,cell capacity = 40) : count(0), elements(myvm->allot_byte_array(capacity),myvm) { }
-
-       void append_bytes(void *elts, cell len);
-       void append_byte_array(cell elts);
-
-       void trim();
-};
-
-//math.hpp
-inline cell factor_vm::allot_integer(fixnum x)
-{
-       if(x < fixnum_min || x > fixnum_max)
-               return tag<bignum>(fixnum_to_bignum(x));
-       else
-               return tag_fixnum(x);
-}
-
-inline cell factor_vm::allot_cell(cell x)
-{
-       if(x > (cell)fixnum_max)
-               return tag<bignum>(cell_to_bignum(x));
-       else
-               return tag_fixnum(x);
-}
-
-inline cell factor_vm::allot_float(double n)
-{
-       boxed_float *flo = allot<boxed_float>(sizeof(boxed_float));
-       flo->n = n;
-       return tag(flo);
-}
-
-inline bignum *factor_vm::float_to_bignum(cell tagged)
-{
-       return double_to_bignum(untag_float(tagged));
-}
-
-inline double factor_vm::bignum_to_float(cell tagged)
-{
-       return bignum_to_double(untag<bignum>(tagged));
-}
-
-inline double factor_vm::untag_float(cell tagged)
-{
-       return untag<boxed_float>(tagged)->n;
-}
-
-inline double factor_vm::untag_float_check(cell tagged)
-{
-       return untag_check<boxed_float>(tagged)->n;
-}
-
-inline fixnum factor_vm::float_to_fixnum(cell tagged)
-{
-       return (fixnum)untag_float(tagged);
-}
-
-inline double factor_vm::fixnum_to_float(cell tagged)
-{
-       return (double)untag_fixnum(tagged);
-}
-
-//callstack.hpp
-/* This is a little tricky. The iterator may allocate memory, so we
-keep the callstack in a GC root and use relative offsets */
-template<typename TYPE> void factor_vm::iterate_callstack_object(callstack *stack_, TYPE &iterator)
-{
-       gc_root<callstack> stack(stack_,this);
-       fixnum frame_offset = untag_fixnum(stack->length) - sizeof(stack_frame);
-
-       while(frame_offset >= 0)
-       {
-               stack_frame *frame = stack->frame_at(frame_offset);
-               frame_offset -= frame->size;
-               iterator(frame,this);
-       }
-}
-
-//booleans.hpp
-inline cell factor_vm::tag_boolean(cell untagged)
-{
-       return (untagged ? T : F);
-}
-
-// callstack.hpp
-template<typename TYPE> void factor_vm::iterate_callstack(cell top, cell bottom, TYPE &iterator)
-{
-       stack_frame *frame = (stack_frame *)bottom - 1;
-
-       while((cell)frame >= top)
-       {
-               iterator(frame,this);
-               frame = frame_successor(frame);
-       }
-}
-
-// data_heap.hpp
-/* Every object has a regular representation in the runtime, which makes GC
-much simpler. Every slot of the object until binary_payload_start is a pointer
-to some other object. */
-struct factor_vm;
-inline void factor_vm::do_slots(cell obj, void (* iter)(cell *,factor_vm*))
-{
-       cell scan = obj;
-       cell payload_start = binary_payload_start((object *)obj);
-       cell end = obj + payload_start;
-
-       scan += sizeof(cell);
-
-       while(scan < end)
-       {
-               iter((cell *)scan,this);
-               scan += sizeof(cell);
-       }
-}
-
-// code_heap.hpp
-
-inline void factor_vm::check_code_pointer(cell ptr)
-{
-#ifdef FACTOR_DEBUG
-       assert(in_code_heap_p(ptr));
-#endif
-}
-
-}
index a827c08f9c867fe92518214a2a63ef90191773b7..300a971f16c4658e0e8be9ca50ca33e4681b5c75 100644 (file)
@@ -1,7 +1,6 @@
 namespace factor
 {
 
-//local_roots.hpp
 template <typename TYPE>
 struct gc_root : public tagged<TYPE>
 {
index d970f1aaeab444849805e8e002dd03760e4ff3fd..d761419ff2478b692b942123f379929b5f4fd015 100755 (executable)
 #include "data_heap.hpp"
 #include "write_barrier.hpp"
 #include "data_gc.hpp"
-#include "generic_arrays.hpp"
 #include "debug.hpp"
-#include "arrays.hpp"
 #include "strings.hpp"
-#include "booleans.hpp"
-#include "byte_arrays.hpp"
 #include "tuples.hpp"
 #include "words.hpp"
-#include "math.hpp"
 #include "float_bits.hpp"
 #include "io.hpp"
 #include "heap.hpp"
-#include "code_heap.hpp"
 #include "image.hpp"
-#include "callstack.hpp"
 #include "alien.hpp"
 #include "vm.hpp"
 #include "tagged.hpp"
 #include "local_roots.hpp"
-#include "inlineimpls.hpp"
+#include "callstack.hpp"
+#include "generic_arrays.hpp"
+#include "arrays.hpp"
+#include "math.hpp"
+#include "booleans.hpp"
+#include "code_heap.hpp"
+#include "byte_arrays.hpp"
 #include "jit.hpp"
 #include "quotations.hpp"
 #include "dispatch.hpp"
index 891cc8d93154684cc051616645954206e0a23419..1f7eda26fa6d84e2a529319b1f06506cc921d8d8 100644 (file)
@@ -5,11 +5,60 @@ static const fixnum fixnum_max = (((fixnum)1 << (WORD_SIZE - TAG_BITS - 1)) - 1)
 static const fixnum fixnum_min = (-((fixnum)1 << (WORD_SIZE - TAG_BITS - 1)));
 static const fixnum array_size_max = ((cell)1 << (WORD_SIZE - TAG_BITS - 2));
 
-// defined in assembler
+inline cell factor_vm::allot_integer(fixnum x)
+{
+       if(x < fixnum_min || x > fixnum_max)
+               return tag<bignum>(fixnum_to_bignum(x));
+       else
+               return tag_fixnum(x);
+}
 
+inline cell factor_vm::allot_cell(cell x)
+{
+       if(x > (cell)fixnum_max)
+               return tag<bignum>(cell_to_bignum(x));
+       else
+               return tag_fixnum(x);
+}
 
+inline cell factor_vm::allot_float(double n)
+{
+       boxed_float *flo = allot<boxed_float>(sizeof(boxed_float));
+       flo->n = n;
+       return tag(flo);
+}
 
+inline bignum *factor_vm::float_to_bignum(cell tagged)
+{
+       return double_to_bignum(untag_float(tagged));
+}
+
+inline double factor_vm::bignum_to_float(cell tagged)
+{
+       return bignum_to_double(untag<bignum>(tagged));
+}
 
+inline double factor_vm::untag_float(cell tagged)
+{
+       return untag<boxed_float>(tagged)->n;
+}
+
+inline double factor_vm::untag_float_check(cell tagged)
+{
+       return untag_check<boxed_float>(tagged)->n;
+}
+
+inline fixnum factor_vm::float_to_fixnum(cell tagged)
+{
+       return (fixnum)untag_float(tagged);
+}
+
+inline double factor_vm::fixnum_to_float(cell tagged)
+{
+       return (double)untag_fixnum(tagged);
+}
+
+// defined in assembler
 
 VM_C_API void box_float(float flo, factor_vm *vm);
 VM_C_API float to_float(cell value, factor_vm *vm);
index a6a8c9689932ca2cc723b19d70c59e486bcb9e93..0f8e76e480e9603fa32eb6c292260a4ba2ae13a3 100644 (file)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -101,20 +101,20 @@ struct factor_vm
        void bignum_destructive_add(bignum * bignum, bignum_digit_type n);
        void bignum_destructive_scale_up(bignum * bignum, bignum_digit_type factor);
        void bignum_divide_unsigned_large_denominator(bignum * numerator, bignum * denominator, 
-                                                                                                 bignum * * quotient, bignum * * remainder, int q_negative_p, int r_negative_p);
+                                                     bignum * * quotient, bignum * * remainder, int q_negative_p, int r_negative_p);
        void bignum_divide_unsigned_normalized(bignum * u, bignum * v, bignum * q);
        bignum_digit_type bignum_divide_subtract(bignum_digit_type * v_start, bignum_digit_type * v_end, 
-                                                                                        bignum_digit_type guess, bignum_digit_type * u_start);
+                                                bignum_digit_type guess, bignum_digit_type * u_start);
        void bignum_divide_unsigned_medium_denominator(bignum * numerator,bignum_digit_type denominator, 
-                                                                                                  bignum * * quotient, bignum * * remainder,int q_negative_p, int r_negative_p);
+                                                      bignum * * quotient, bignum * * remainder,int q_negative_p, int r_negative_p);
        void bignum_destructive_normalization(bignum * source, bignum * target, int shift_left);
        void bignum_destructive_unnormalization(bignum * bignum, int shift_right);
        bignum_digit_type bignum_digit_divide(bignum_digit_type uh, bignum_digit_type ul, 
-                                                                                 bignum_digit_type v, bignum_digit_type * q) /* return value */;
+                                             bignum_digit_type v, bignum_digit_type * q) /* return value */;
        bignum_digit_type bignum_digit_divide_subtract(bignum_digit_type v1, bignum_digit_type v2, 
-                                                                                                  bignum_digit_type guess, bignum_digit_type * u);
+                                                      bignum_digit_type guess, bignum_digit_type * u);
        void bignum_divide_unsigned_small_denominator(bignum * numerator, bignum_digit_type denominator, 
-                                                                                                 bignum * * quotient, bignum * * remainder,int q_negative_p, int r_negative_p);
+                                                     bignum * * quotient, bignum * * remainder,int q_negative_p, int r_negative_p);
        bignum_digit_type bignum_destructive_scale_down(bignum * bignum, bignum_digit_type denominator);
        bignum * bignum_remainder_unsigned_small_denominator(bignum * n, bignum_digit_type d, int negative_p);
        bignum *bignum_digit_to_bignum(bignum_digit_type digit, int negative_p);
@@ -171,7 +171,6 @@ struct factor_vm
        template<typename T> void each_object(T &functor);
        cell find_all_words();
        cell object_size(cell tagged);
-
        
        //write barrier
        cell allot_markers_offset;
@@ -282,14 +281,46 @@ struct factor_vm
        void clear_gc_stats();
        void primitive_become();
        void inline_gc(cell *gc_roots_base, cell gc_roots_size);
-       inline bool collecting_accumulation_gen_p();
        inline object *allot_zone(zone *z, cell a);
-       inline object *allot_object(header header, cell size);
-       template <typename TYPE> TYPE *allot(cell size);
-       inline void check_data_pointer(object *pointer);
-       inline void check_tagged_pointer(cell tagged);
+       object *allot_object(header header, cell size);
        void primitive_clear_gc_stats();
 
+       template<typename TYPE> TYPE *allot(cell size)
+       {
+               return (TYPE *)allot_object(header(TYPE::type_number),size);
+       }
+
+       inline bool collecting_accumulation_gen_p()
+       {
+               return ((data->have_aging_p()
+                        && collecting_gen == data->aging()
+                        && !collecting_aging_again)
+                       || collecting_gen == data->tenured());
+       }
+
+       inline void check_data_pointer(object *pointer)
+       {
+       #ifdef FACTOR_DEBUG
+               if(!growing_data_heap)
+               {
+                       assert((cell)pointer >= data->seg->start
+                              && (cell)pointer < data->seg->end);
+               }
+       #endif
+       }
+
+       inline void check_tagged_pointer(cell tagged)
+       {
+       #ifdef FACTOR_DEBUG
+               if(!immediate_p(tagged))
+               {
+                       object *obj = untag<object>(tagged);
+                       check_data_pointer(obj);
+                       obj->h.hi_tag();
+               }
+       #endif
+       }
+
        // local roots
        /* If a runtime function needs to call another function which potentially
           allocates memory, it must wrap any local variable references to Factor