]> gitweb.factorcode.org Git - factor.git/commitdiff
Various VM cleanups, new approach for bignum GC root registration
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 3 May 2009 10:48:03 +0000 (05:48 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 3 May 2009 10:48:03 +0000 (05:48 -0500)
Makefile
vm/bignum.cpp
vm/callstack.cpp
vm/data_gc.cpp
vm/data_gc.h [deleted file]
vm/data_gc.hpp
vm/data_heap.cpp
vm/errors.cpp
vm/local_roots.cpp
vm/local_roots.hpp
vm/math.cpp

index a21711b9162098e3b93bc169cde7dbec909ab7b3..8c07a656b8177a6023a4bb946394c333bd285064 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -179,6 +179,9 @@ clean:
        rm -f vm/*.o
        rm -f factor*.dll libfactor.{a,so,dylib} libfactor-ffi-test.{a,so,dylib} Factor.app/Contents/Frameworks/libfactor.dylib
 
+tags:
+       etags vm/*.{cpp,hpp,mm,S,c}
+
 vm/resources.o:
        $(WINDRES) vm/factor.rs vm/resources.o
 
@@ -197,6 +200,6 @@ vm/ffi_test.o: vm/ffi_test.c
 .mm.o:
        $(CPP) -c $(CFLAGS) -o $@ $<
 
-.PHONY: factor
+.PHONY: factor tags clean
 
 .SUFFIXES: .mm
index 3a665f22d3db20430cabfd0e6b2e58c616e39669..72356ff5569324cbf880e9e83d3bae0bbb8b0646 100755 (executable)
@@ -505,6 +505,8 @@ bignum_compare_unsigned(F_BIGNUM * x, F_BIGNUM * y)
 F_BIGNUM *
 bignum_add_unsigned(F_BIGNUM * x, F_BIGNUM * y, int negative_p)
 {
+  GC_BIGNUM(x); GC_BIGNUM(y);
+
   if ((BIGNUM_LENGTH (y)) > (BIGNUM_LENGTH (x)))
     {
       F_BIGNUM * z = x;
@@ -514,11 +516,7 @@ bignum_add_unsigned(F_BIGNUM * x, F_BIGNUM * y, int negative_p)
   {
     bignum_length_type x_length = (BIGNUM_LENGTH (x));
     
-    REGISTER_BIGNUM(x);
-    REGISTER_BIGNUM(y);
     F_BIGNUM * r = (allot_bignum ((x_length + 1), negative_p));
-    UNREGISTER_BIGNUM(y);
-    UNREGISTER_BIGNUM(x);
 
     bignum_digit_type sum;
     bignum_digit_type carry = 0;
@@ -575,6 +573,8 @@ bignum_add_unsigned(F_BIGNUM * x, F_BIGNUM * y, int negative_p)
 F_BIGNUM *
 bignum_subtract_unsigned(F_BIGNUM * x, F_BIGNUM * y)
 {
+  GC_BIGNUM(x); GC_BIGNUM(y);
+  
   int negative_p = 0;
   switch (bignum_compare_unsigned (x, y))
     {
@@ -595,11 +595,7 @@ bignum_subtract_unsigned(F_BIGNUM * x, F_BIGNUM * y)
   {
     bignum_length_type x_length = (BIGNUM_LENGTH (x));
     
-    REGISTER_BIGNUM(x);
-    REGISTER_BIGNUM(y);
     F_BIGNUM * r = (allot_bignum (x_length, negative_p));
-    UNREGISTER_BIGNUM(y);
-    UNREGISTER_BIGNUM(x);
 
     bignum_digit_type difference;
     bignum_digit_type borrow = 0;
@@ -656,6 +652,8 @@ bignum_subtract_unsigned(F_BIGNUM * x, F_BIGNUM * y)
 F_BIGNUM *
 bignum_multiply_unsigned(F_BIGNUM * x, F_BIGNUM * y, int negative_p)
 {
+  GC_BIGNUM(x); GC_BIGNUM(y);
+
   if ((BIGNUM_LENGTH (y)) > (BIGNUM_LENGTH (x)))
     {
       F_BIGNUM * z = x;
@@ -674,12 +672,8 @@ bignum_multiply_unsigned(F_BIGNUM * x, F_BIGNUM * y, int negative_p)
     bignum_length_type x_length = (BIGNUM_LENGTH (x));
     bignum_length_type y_length = (BIGNUM_LENGTH (y));
 
-    REGISTER_BIGNUM(x);
-    REGISTER_BIGNUM(y);
     F_BIGNUM * r =
       (allot_bignum_zeroed ((x_length + y_length), negative_p));
-    UNREGISTER_BIGNUM(y);
-    UNREGISTER_BIGNUM(x);
 
     bignum_digit_type * scan_x = (BIGNUM_START_PTR (x));
     bignum_digit_type * end_x = (scan_x + x_length);
@@ -731,11 +725,11 @@ F_BIGNUM *
 bignum_multiply_unsigned_small_factor(F_BIGNUM * x, bignum_digit_type y,
                                       int negative_p)
 {
+  GC_BIGNUM(x);
+  
   bignum_length_type length_x = (BIGNUM_LENGTH (x));
 
-  REGISTER_BIGNUM(x);
   F_BIGNUM * p = (allot_bignum ((length_x + 1), negative_p));
-  UNREGISTER_BIGNUM(x);
 
   bignum_destructive_copy (x, p);
   (BIGNUM_REF (p, length_x)) = 0;
@@ -813,24 +807,20 @@ bignum_divide_unsigned_large_denominator(F_BIGNUM * numerator,
                                          int q_negative_p,
                                          int r_negative_p)
 {
+  GC_BIGNUM(numerator); GC_BIGNUM(denominator);
+  
   bignum_length_type length_n = ((BIGNUM_LENGTH (numerator)) + 1);
   bignum_length_type length_d = (BIGNUM_LENGTH (denominator));
 
-  REGISTER_BIGNUM(numerator);
-  REGISTER_BIGNUM(denominator);
-
   F_BIGNUM * q =
     ((quotient != ((F_BIGNUM * *) 0))
      ? (allot_bignum ((length_n - length_d), q_negative_p))
      : BIGNUM_OUT_OF_BAND);
-
-  REGISTER_BIGNUM(q);
+  GC_BIGNUM(q);
+  
   F_BIGNUM * u = (allot_bignum (length_n, r_negative_p));
-  UNREGISTER_BIGNUM(q);
-
-  UNREGISTER_BIGNUM(denominator);
-  UNREGISTER_BIGNUM(numerator);
-
+  GC_BIGNUM(u);
+  
   int shift = 0;
   BIGNUM_ASSERT (length_d > 1);
   {
@@ -849,15 +839,7 @@ bignum_divide_unsigned_large_denominator(F_BIGNUM * numerator,
     }
   else
     {
-      REGISTER_BIGNUM(numerator);
-      REGISTER_BIGNUM(denominator);
-      REGISTER_BIGNUM(u);
-      REGISTER_BIGNUM(q);
       F_BIGNUM * v = (allot_bignum (length_d, 0));
-      UNREGISTER_BIGNUM(q);
-      UNREGISTER_BIGNUM(u);
-      UNREGISTER_BIGNUM(denominator);
-      UNREGISTER_BIGNUM(numerator);
 
       bignum_destructive_normalization (numerator, u, shift);
       bignum_destructive_normalization (denominator, v, shift);
@@ -866,14 +848,10 @@ bignum_divide_unsigned_large_denominator(F_BIGNUM * numerator,
         bignum_destructive_unnormalization (u, shift);
     }
 
-  REGISTER_BIGNUM(u);
   if(q)
     q = bignum_trim (q);
-  UNREGISTER_BIGNUM(u);
 
-  REGISTER_BIGNUM(q);
   u = bignum_trim (u);
-  UNREGISTER_BIGNUM(q);
 
   if (quotient != ((F_BIGNUM * *) 0))
     (*quotient) = q;
@@ -1047,9 +1025,13 @@ bignum_divide_unsigned_medium_denominator(F_BIGNUM * numerator,
                                           int q_negative_p,
                                           int r_negative_p)
 {
+  GC_BIGNUM(numerator);
+  
   bignum_length_type length_n = (BIGNUM_LENGTH (numerator));
   bignum_length_type length_q;
-  F_BIGNUM * q;
+  F_BIGNUM * q = NULL;
+  GC_BIGNUM(q);
+  
   int shift = 0;
   /* Because `bignum_digit_divide' requires a normalized denominator. */
   while (denominator < (BIGNUM_RADIX / 2))
@@ -1061,20 +1043,14 @@ bignum_divide_unsigned_medium_denominator(F_BIGNUM * numerator,
     {
       length_q = length_n;
 
-      REGISTER_BIGNUM(numerator);
       q = (allot_bignum (length_q, q_negative_p));
-      UNREGISTER_BIGNUM(numerator);
-
       bignum_destructive_copy (numerator, q);
     }
   else
     {
       length_q = (length_n + 1);
 
-      REGISTER_BIGNUM(numerator);
       q = (allot_bignum (length_q, q_negative_p));
-      UNREGISTER_BIGNUM(numerator);
-
       bignum_destructive_normalization (numerator, q, shift);
     }
   {
@@ -1096,9 +1072,7 @@ bignum_divide_unsigned_medium_denominator(F_BIGNUM * numerator,
         if (shift != 0)
           r >>= shift;
 
-        REGISTER_BIGNUM(q);
         (*remainder) = (bignum_digit_to_bignum (r, r_negative_p));
-        UNREGISTER_BIGNUM(q);
       }
 
     if (quotient != ((F_BIGNUM * *) 0))
@@ -1295,20 +1269,17 @@ bignum_divide_unsigned_small_denominator(F_BIGNUM * numerator,
                                          int q_negative_p,
                                          int r_negative_p)
 {
-  REGISTER_BIGNUM(numerator);
+  GC_BIGNUM(numerator);
+  
   F_BIGNUM * q = (bignum_new_sign (numerator, q_negative_p));
-  UNREGISTER_BIGNUM(numerator);
+  GC_BIGNUM(q);
 
   bignum_digit_type r = (bignum_destructive_scale_down (q, denominator));
 
   q = (bignum_trim (q));
 
   if (remainder != ((F_BIGNUM * *) 0))
-  {
-    REGISTER_BIGNUM(q);
     (*remainder) = (bignum_digit_to_bignum (r, r_negative_p));
-    UNREGISTER_BIGNUM(q);
-  }
 
   (*quotient) = q;
 
@@ -1381,6 +1352,7 @@ bignum_digit_to_bignum(bignum_digit_type digit, int negative_p)
 F_BIGNUM *
 allot_bignum(bignum_length_type length, int negative_p)
 {
+       gc();
   BIGNUM_ASSERT ((length >= 0) || (length < BIGNUM_RADIX));
   F_BIGNUM * result = allot_array_internal<F_BIGNUM>(length + 1);
   BIGNUM_SET_NEGATIVE_P (result, negative_p);
@@ -1441,10 +1413,8 @@ bignum_trim(F_BIGNUM * bignum)
 F_BIGNUM *
 bignum_new_sign(F_BIGNUM * bignum, int negative_p)
 {
-  REGISTER_BIGNUM(bignum);
-  F_BIGNUM * result =
-    (allot_bignum ((BIGNUM_LENGTH (bignum)), negative_p));
-  UNREGISTER_BIGNUM(bignum);
+  GC_BIGNUM(bignum);
+  F_BIGNUM * result = (allot_bignum ((BIGNUM_LENGTH (bignum)), negative_p));
 
   bignum_destructive_copy (bignum, result);
   return (result);
@@ -1553,6 +1523,8 @@ bignum_bitwise_xor(F_BIGNUM * arg1, F_BIGNUM * arg2)
 F_BIGNUM *
 bignum_magnitude_ash(F_BIGNUM * arg1, F_FIXNUM n)
 {
+  GC_BIGNUM(arg1);
+  
   F_BIGNUM * result = NULL;
   bignum_digit_type *scan1;
   bignum_digit_type *scanr;
@@ -1566,10 +1538,8 @@ bignum_magnitude_ash(F_BIGNUM * arg1, F_FIXNUM n)
     digit_offset = n / BIGNUM_DIGIT_LENGTH;
     bit_offset =   n % BIGNUM_DIGIT_LENGTH;
 
-    REGISTER_BIGNUM(arg1);
     result = allot_bignum_zeroed (BIGNUM_LENGTH (arg1) + digit_offset + 1,
-                                     BIGNUM_NEGATIVE_P(arg1));
-    UNREGISTER_BIGNUM(arg1);
+                                  BIGNUM_NEGATIVE_P(arg1));
 
     scanr = BIGNUM_START_PTR (result) + digit_offset;
     scan1 = BIGNUM_START_PTR (arg1);
@@ -1591,10 +1561,8 @@ bignum_magnitude_ash(F_BIGNUM * arg1, F_FIXNUM n)
     digit_offset = -n / BIGNUM_DIGIT_LENGTH;
     bit_offset =   -n % BIGNUM_DIGIT_LENGTH;
     
-    REGISTER_BIGNUM(arg1);
     result = allot_bignum_zeroed (BIGNUM_LENGTH (arg1) - digit_offset,
-                                     BIGNUM_NEGATIVE_P(arg1));
-    UNREGISTER_BIGNUM(arg1);
+                                  BIGNUM_NEGATIVE_P(arg1));
     
     scanr = BIGNUM_START_PTR (result);
     scan1 = BIGNUM_START_PTR (arg1) + digit_offset;
@@ -1617,6 +1585,8 @@ bignum_magnitude_ash(F_BIGNUM * arg1, F_FIXNUM n)
 F_BIGNUM *
 bignum_pospos_bitwise_op(int op, F_BIGNUM * arg1, F_BIGNUM * arg2)
 {
+  GC_BIGNUM(arg1); GC_BIGNUM(arg2);
+  
   F_BIGNUM * result;
   bignum_length_type max_length;
 
@@ -1627,11 +1597,7 @@ bignum_pospos_bitwise_op(int op, F_BIGNUM * arg1, F_BIGNUM * arg2)
   max_length =  (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2))
                ? BIGNUM_LENGTH(arg1) : BIGNUM_LENGTH(arg2);
 
-  REGISTER_BIGNUM(arg1);
-  REGISTER_BIGNUM(arg2);
   result = allot_bignum(max_length, 0);
-  UNREGISTER_BIGNUM(arg2);
-  UNREGISTER_BIGNUM(arg1);
 
   scanr = BIGNUM_START_PTR(result);
   scan1 = BIGNUM_START_PTR(arg1);
@@ -1654,6 +1620,8 @@ bignum_pospos_bitwise_op(int op, F_BIGNUM * arg1, F_BIGNUM * arg2)
 F_BIGNUM *
 bignum_posneg_bitwise_op(int op, F_BIGNUM * arg1, F_BIGNUM * arg2)
 {
+  GC_BIGNUM(arg1); GC_BIGNUM(arg2);
+  
   F_BIGNUM * result;
   bignum_length_type max_length;
 
@@ -1666,11 +1634,7 @@ bignum_posneg_bitwise_op(int op, F_BIGNUM * arg1, F_BIGNUM * arg2)
   max_length =  (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2) + 1)
                ? BIGNUM_LENGTH(arg1) : BIGNUM_LENGTH(arg2) + 1;
 
-  REGISTER_BIGNUM(arg1);
-  REGISTER_BIGNUM(arg2);
   result = allot_bignum(max_length, neg_p);
-  UNREGISTER_BIGNUM(arg2);
-  UNREGISTER_BIGNUM(arg1);
 
   scanr = BIGNUM_START_PTR(result);
   scan1 = BIGNUM_START_PTR(arg1);
@@ -1709,6 +1673,8 @@ bignum_posneg_bitwise_op(int op, F_BIGNUM * arg1, F_BIGNUM * arg2)
 F_BIGNUM *
 bignum_negneg_bitwise_op(int op, F_BIGNUM * arg1, F_BIGNUM * arg2)
 {
+  GC_BIGNUM(arg1); GC_BIGNUM(arg2);
+  
   F_BIGNUM * result;
   bignum_length_type max_length;
 
@@ -1721,11 +1687,7 @@ bignum_negneg_bitwise_op(int op, F_BIGNUM * arg1, F_BIGNUM * arg2)
   max_length =  (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2))
                ? BIGNUM_LENGTH(arg1) + 1 : BIGNUM_LENGTH(arg2) + 1;
 
-  REGISTER_BIGNUM(arg1);
-  REGISTER_BIGNUM(arg2);
   result = allot_bignum(max_length, neg_p);
-  UNREGISTER_BIGNUM(arg2);
-  UNREGISTER_BIGNUM(arg1);
 
   scanr = BIGNUM_START_PTR(result);
   scan1 = BIGNUM_START_PTR(arg1);
@@ -1800,12 +1762,12 @@ bignum_negate_magnitude(F_BIGNUM * arg)
 F_BIGNUM *
 bignum_integer_length(F_BIGNUM * bignum)
 {
+  GC_BIGNUM(bignum);
+  
   bignum_length_type index = ((BIGNUM_LENGTH (bignum)) - 1);
   bignum_digit_type digit = (BIGNUM_REF (bignum, index));
   
-  REGISTER_BIGNUM(bignum);
   F_BIGNUM * result = (allot_bignum (2, 0));
-  UNREGISTER_BIGNUM(bignum);
   
   (BIGNUM_REF (result, 0)) = index;
   (BIGNUM_REF (result, 1)) = 0;
index bb995ab20fda7251360556ada16ff4b8999be831..f7c56d378cf9b16bb4cbb1f3df2eca0f9dbaf2b6 100755 (executable)
@@ -3,7 +3,7 @@
 static void check_frame(F_STACK_FRAME *frame)
 {
 #ifdef FACTOR_DEBUG
-       check_code_pointer(frame->xt);
+       check_code_pointer((CELL)frame->xt);
        assert(frame->size != 0);
 #endif
 }
@@ -20,9 +20,8 @@ void iterate_callstack(CELL top, CELL bottom, CALLSTACK_ITER iterator)
 
        while((CELL)frame >= top)
        {
-               F_STACK_FRAME *next = frame_successor(frame);
                iterator(frame);
-               frame = next;
+               frame = frame_successor(frame);
        }
 }
 
index 634d44ab2c4aeef405bf3c91c1927e32c21da82c..b6c24ba4f901aec7b5ae099d0463146e29f93c1c 100755 (executable)
@@ -37,8 +37,109 @@ void init_data_gc(void)
        collecting_aging_again = false;
 }
 
+/* Given a pointer to oldspace, copy it to newspace */
+static void *copy_untagged_object(void *pointer, CELL size)
+{
+       if(newspace->here + size >= newspace->end)
+               longjmp(gc_jmp,1);
+       allot_barrier(newspace->here);
+       void *newpointer = allot_zone(newspace,size);
+
+       F_GC_STATS *s = &gc_stats[collecting_gen];
+       s->object_count++;
+       s->bytes_copied += size;
+
+       memcpy(newpointer,pointer,size);
+       return newpointer;
+}
+
+static void forward_object(CELL untagged, CELL newpointer)
+{
+       put(untagged,RETAG(newpointer,GC_COLLECTED));
+}
+
+static CELL copy_object_impl(CELL untagged)
+{
+       CELL newpointer = (CELL)copy_untagged_object(
+               (void*)untagged,
+               untagged_object_size(untagged));
+       forward_object(untagged,newpointer);
+       return newpointer;
+}
+
+static bool should_copy_p(CELL untagged)
+{
+       if(in_zone(newspace,untagged))
+               return false;
+       if(collecting_gen == TENURED)
+               return true;
+       else if(HAVE_AGING_P && collecting_gen == AGING)
+               return !in_zone(&data_heap->generations[TENURED],untagged);
+       else if(collecting_gen == NURSERY)
+               return in_zone(&nursery,untagged);
+       else
+       {
+               critical_error("Bug in should_copy_p",untagged);
+               return false;
+       }
+}
+
+/* Follow a chain of forwarding pointers */
+static CELL resolve_forwarding(CELL untagged, CELL tag)
+{
+       check_data_pointer(untagged);
+
+       CELL header = get(untagged);
+       /* another forwarding pointer */
+       if(TAG(header) == GC_COLLECTED)
+               return resolve_forwarding(UNTAG(header),tag);
+       /* we've found the destination */
+       else
+       {
+               check_header(header);
+               CELL pointer = RETAG(untagged,tag);
+               if(should_copy_p(untagged))
+                       pointer = RETAG(copy_object_impl(untagged),tag);
+               return pointer;
+       }
+}
+
+/* Given a pointer to a tagged pointer to oldspace, copy it to newspace.
+If the object has already been copied, return the forwarding
+pointer address without copying anything; otherwise, install
+a new forwarding pointer. While this preserves the tag, it does
+not dispatch on it in any way. */
+static CELL copy_object(CELL pointer)
+{
+       check_data_pointer(pointer);
+
+       CELL tag = TAG(pointer);
+       CELL untagged = UNTAG(pointer);
+       CELL header = get(untagged);
+
+       if(TAG(header) == GC_COLLECTED)
+               return resolve_forwarding(UNTAG(header),tag);
+       else
+       {
+               check_header(header);
+               return RETAG(copy_object_impl(untagged),tag);
+       }
+}
+
+void copy_handle(CELL *handle)
+{
+       CELL pointer = *handle;
+
+       if(!immediate_p(pointer))
+       {
+               check_data_pointer(pointer);
+               if(should_copy_p(pointer))
+                       *handle = copy_object(pointer);
+       }
+}
+
 /* Scan all the objects in the card */
-void copy_card(F_CARD *ptr, CELL gen, CELL here)
+static void copy_card(F_CARD *ptr, CELL gen, CELL here)
 {
        CELL card_scan = (CELL)CARD_TO_ADDR(ptr) + CARD_OFFSET(ptr);
        CELL card_end = (CELL)CARD_TO_ADDR(ptr + 1);
@@ -51,7 +152,7 @@ void copy_card(F_CARD *ptr, CELL gen, CELL here)
        cards_scanned++;
 }
 
-void copy_card_deck(F_DECK *deck, CELL gen, F_CARD mask, F_CARD unmask)
+static void copy_card_deck(F_DECK *deck, CELL gen, F_CARD mask, F_CARD unmask)
 {
        F_CARD *first_card = DECK_TO_CARD(deck);
        F_CARD *last_card = DECK_TO_CARD(deck + 1);
@@ -83,7 +184,7 @@ void copy_card_deck(F_DECK *deck, CELL gen, F_CARD mask, F_CARD unmask)
 }
 
 /* Copy all newspace objects referenced from marked cards to the destination */
-void copy_gen_cards(CELL gen)
+static void copy_gen_cards(CELL gen)
 {
        F_DECK *first_deck = ADDR_TO_DECK(data_heap->generations[gen].start);
        F_DECK *last_deck = ADDR_TO_DECK(data_heap->generations[gen].end);
@@ -150,7 +251,7 @@ void copy_gen_cards(CELL gen)
 
 /* Scan cards in all generations older than the one being collected, copying
 old->new references */
-void copy_cards(void)
+static void copy_cards(void)
 {
        u64 start = current_micros();
 
@@ -162,7 +263,7 @@ void copy_cards(void)
 }
 
 /* Copy all tagged pointers in a range of memory */
-void copy_stack_elements(F_SEGMENT *region, CELL top)
+static void copy_stack_elements(F_SEGMENT *region, CELL top)
 {
        CELL ptr = region->start;
 
@@ -170,17 +271,38 @@ void copy_stack_elements(F_SEGMENT *region, CELL top)
                copy_handle((CELL*)ptr);
 }
 
-void copy_registered_locals(void)
+static void copy_registered_locals(void)
+{
+       CELL scan = gc_locals_region->start;
+
+       for(; scan <= gc_locals; scan += CELLS)
+               copy_handle(*(CELL **)scan);
+}
+
+static void copy_registered_bignums(void)
 {
-       CELL ptr = gc_locals_region->start;
+       CELL scan = gc_bignums_region->start;
 
-       for(; ptr <= gc_locals; ptr += CELLS)
-               copy_handle(*(CELL **)ptr);
+       for(; scan <= gc_bignums; scan += CELLS)
+       {
+               CELL *handle = *(CELL **)scan;
+               CELL pointer = *handle;
+
+               if(pointer)
+               {
+                       check_data_pointer(pointer);
+                       if(should_copy_p(pointer))
+                               *handle = copy_object(pointer);
+#ifdef FACTOR_DEBUG
+                       assert(hi_tag(*handle) == BIGNUM_TYPE);
+#endif
+               }
+       }
 }
 
 /* Copy roots over at the start of GC, namely various constants, stacks,
 the user environment and extra roots registered by local_roots.hpp */
-void copy_roots(void)
+static void copy_roots(void)
 {
        copy_handle(&T);
        copy_handle(&bignum_zero);
@@ -188,7 +310,7 @@ void copy_roots(void)
        copy_handle(&bignum_neg_one);
 
        copy_registered_locals();
-       copy_stack_elements(extra_roots_region,extra_roots);
+       copy_registered_bignums();
 
        if(!performing_compaction)
        {
@@ -214,107 +336,7 @@ void copy_roots(void)
                copy_handle(&userenv[i]);
 }
 
-/* Given a pointer to oldspace, copy it to newspace */
-INLINE void *copy_untagged_object(void *pointer, CELL size)
-{
-       if(newspace->here + size >= newspace->end)
-               longjmp(gc_jmp,1);
-       allot_barrier(newspace->here);
-       void *newpointer = allot_zone(newspace,size);
-
-       F_GC_STATS *s = &gc_stats[collecting_gen];
-       s->object_count++;
-       s->bytes_copied += size;
-
-       memcpy(newpointer,pointer,size);
-       return newpointer;
-}
-
-INLINE void forward_object(CELL pointer, CELL newpointer)
-{
-       if(pointer != newpointer)
-               put(UNTAG(pointer),RETAG(newpointer,GC_COLLECTED));
-}
-
-INLINE CELL copy_object_impl(CELL pointer)
-{
-       CELL newpointer = (CELL)copy_untagged_object(
-               (void*)UNTAG(pointer),
-               object_size(pointer));
-       forward_object(pointer,newpointer);
-       return newpointer;
-}
-
-bool should_copy_p(CELL untagged)
-{
-       if(in_zone(newspace,untagged))
-               return false;
-       if(collecting_gen == TENURED)
-               return true;
-       else if(HAVE_AGING_P && collecting_gen == AGING)
-               return !in_zone(&data_heap->generations[TENURED],untagged);
-       else if(collecting_gen == NURSERY)
-               return in_zone(&nursery,untagged);
-       else
-       {
-               critical_error("Bug in should_copy_p",untagged);
-               return false;
-       }
-}
-
-/* Follow a chain of forwarding pointers */
-CELL resolve_forwarding(CELL untagged, CELL tag)
-{
-       check_data_pointer(untagged);
-
-       CELL header = get(untagged);
-       /* another forwarding pointer */
-       if(TAG(header) == GC_COLLECTED)
-               return resolve_forwarding(UNTAG(header),tag);
-       /* we've found the destination */
-       else
-       {
-               check_header(header);
-               CELL pointer = RETAG(untagged,tag);
-               if(should_copy_p(untagged))
-                       pointer = RETAG(copy_object_impl(pointer),tag);
-               return pointer;
-       }
-}
-
-/* Given a pointer to a tagged pointer to oldspace, copy it to newspace.
-If the object has already been copied, return the forwarding
-pointer address without copying anything; otherwise, install
-a new forwarding pointer. */
-INLINE CELL copy_object(CELL pointer)
-{
-       check_data_pointer(pointer);
-
-       CELL tag = TAG(pointer);
-       CELL header = get(UNTAG(pointer));
-
-       if(TAG(header) == GC_COLLECTED)
-               return resolve_forwarding(UNTAG(header),tag);
-       else
-       {
-               check_header(header);
-               return RETAG(copy_object_impl(pointer),tag);
-       }
-}
-
-void copy_handle(CELL *handle)
-{
-       CELL pointer = *handle;
-
-       if(!immediate_p(pointer))
-       {
-               check_data_pointer(pointer);
-               if(should_copy_p(pointer))
-                       *handle = copy_object(pointer);
-       }
-}
-
-CELL copy_next_from_nursery(CELL scan)
+static CELL copy_next_from_nursery(CELL scan)
 {
        CELL *obj = (CELL *)scan;
        CELL *end = (CELL *)(scan + binary_payload_start(scan));
@@ -342,7 +364,7 @@ CELL copy_next_from_nursery(CELL scan)
        return scan + untagged_object_size(scan);
 }
 
-CELL copy_next_from_aging(CELL scan)
+static CELL copy_next_from_aging(CELL scan)
 {
        CELL *obj = (CELL *)scan;
        CELL *end = (CELL *)(scan + binary_payload_start(scan));
@@ -374,7 +396,7 @@ CELL copy_next_from_aging(CELL scan)
        return scan + untagged_object_size(scan);
 }
 
-CELL copy_next_from_tenured(CELL scan)
+static CELL copy_next_from_tenured(CELL scan)
 {
        CELL *obj = (CELL *)scan;
        CELL *end = (CELL *)(scan + binary_payload_start(scan));
@@ -424,7 +446,7 @@ void copy_reachable_objects(CELL scan, CELL *end)
 }
 
 /* Prepare to start copying reachable objects into an unused zone */
-void begin_gc(CELL requested_bytes)
+static void begin_gc(CELL requested_bytes)
 {
        if(growing_data_heap)
        {
@@ -457,7 +479,7 @@ void begin_gc(CELL requested_bytes)
        }
 }
 
-void end_gc(CELL gc_elapsed)
+static void end_gc(CELL gc_elapsed)
 {
        F_GC_STATS *s = &gc_stats[collecting_gen];
 
@@ -604,19 +626,19 @@ void primitive_gc_stats(void)
        {
                F_GC_STATS *s = &gc_stats[i];
                stats.add(allot_cell(s->collections));
-               stats.add(tag_bignum(long_long_to_bignum(s->gc_time)));
-               stats.add(tag_bignum(long_long_to_bignum(s->max_gc_time)));
+               stats.add(tag<F_BIGNUM>(long_long_to_bignum(s->gc_time)));
+               stats.add(tag<F_BIGNUM>(long_long_to_bignum(s->max_gc_time)));
                stats.add(allot_cell(s->collections == 0 ? 0 : s->gc_time / s->collections));
                stats.add(allot_cell(s->object_count));
-               stats.add(tag_bignum(long_long_to_bignum(s->bytes_copied)));
+               stats.add(tag<F_BIGNUM>(long_long_to_bignum(s->bytes_copied)));
 
                total_gc_time += s->gc_time;
        }
 
-       stats.add(tag_bignum(ulong_long_to_bignum(total_gc_time)));
-       stats.add(tag_bignum(ulong_long_to_bignum(cards_scanned)));
-       stats.add(tag_bignum(ulong_long_to_bignum(decks_scanned)));
-       stats.add(tag_bignum(ulong_long_to_bignum(card_scan_time)));
+       stats.add(tag<F_BIGNUM>(ulong_long_to_bignum(total_gc_time)));
+       stats.add(tag<F_BIGNUM>(ulong_long_to_bignum(cards_scanned)));
+       stats.add(tag<F_BIGNUM>(ulong_long_to_bignum(decks_scanned)));
+       stats.add(tag<F_BIGNUM>(ulong_long_to_bignum(card_scan_time)));
        stats.add(allot_cell(code_heap_scans));
 
        stats.trim();
@@ -644,8 +666,8 @@ void primitive_clear_gc_stats(void)
    to coalesce equal but distinct quotations and wrappers. */
 void primitive_become(void)
 {
-       F_ARRAY *new_objects = untag_array(dpop());
-       F_ARRAY *old_objects = untag_array(dpop());
+       F_ARRAY *new_objects = untag_check<F_ARRAY>(dpop());
+       F_ARRAY *old_objects = untag_check<F_ARRAY>(dpop());
 
        CELL capacity = array_capacity(new_objects);
        if(capacity != array_capacity(old_objects))
@@ -658,7 +680,8 @@ void primitive_become(void)
                CELL old_obj = array_nth(old_objects,i);
                CELL new_obj = array_nth(new_objects,i);
 
-               forward_object(old_obj,new_obj);
+               if(old_obj != new_obj)
+                       forward_object(UNTAG(old_obj),new_obj);
        }
 
        gc();
diff --git a/vm/data_gc.h b/vm/data_gc.h
deleted file mode 100644 (file)
index 1def24a..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-void gc(void);
-DLLEXPORT void minor_gc(void);
-
-/* used during garbage collection only */
-
-F_ZONE *newspace;
-bool performing_gc;
-bool performing_compaction;
-CELL collecting_gen;
-
-/* if true, we collecting AGING space for the second time, so if it is still
-full, we go on to collect TENURED */
-bool collecting_aging_again;
-
-/* in case a generation fills up in the middle of a gc, we jump back
-up to try collecting the next generation. */
-jmp_buf gc_jmp;
-
-/* statistics */
-typedef struct {
-       CELL collections;
-       u64 gc_time;
-       u64 max_gc_time;
-       CELL object_count;
-       u64 bytes_copied;
-} F_GC_STATS;
-
-F_GC_STATS gc_stats[MAX_GEN_COUNT];
-u64 cards_scanned;
-u64 decks_scanned;
-u64 card_scan_time;
-CELL code_heap_scans;
-
-/* What generation was being collected when copy_code_heap_roots() was last
-called? Until the next call to add_code_block(), future
-collections of younger generations don't have to touch the code
-heap. */
-CELL last_code_heap_scan;
-
-/* sometimes we grow the heap */
-bool growing_data_heap;
-F_DATA_HEAP *old_data_heap;
-
-INLINE bool collecting_accumulation_gen_p(void)
-{
-       return ((HAVE_AGING_P
-               && collecting_gen == AGING
-               && !collecting_aging_again)
-               || collecting_gen == TENURED);
-}
-
-/* test if the pointer is in generation being collected, or a younger one. */
-INLINE bool should_copy(CELL untagged)
-{
-       if(in_zone(newspace,untagged))
-               return false;
-       if(collecting_gen == TENURED)
-               return true;
-       else if(HAVE_AGING_P && collecting_gen == AGING)
-               return !in_zone(&data_heap->generations[TENURED],untagged);
-       else if(collecting_gen == NURSERY)
-               return in_zone(&nursery,untagged);
-       else
-       {
-               critical_error("Bug in should_copy",untagged);
-               return false;
-       }
-}
-
-void copy_handle(CELL *handle);
-
-void garbage_collection(volatile CELL gen,
-       bool growing_data_heap_,
-       CELL requested_bytes);
-
-/* We leave this many bytes free at the top of the nursery so that inline
-allocation (which does not call GC because of possible roots in volatile
-registers) does not run out of memory */
-#define ALLOT_BUFFER_ZONE 1024
-
-/* If this is defined, we GC every allocation. This catches missing local roots */
-
-/*
- * It is up to the caller to fill in the object's fields in a meaningful
- * fashion!
- */
-
-INLINE void *allot_object(CELL type, CELL a)
-{
-#ifdef GC_DEBUG
-       if(!gc_off)
-               gc();
-#endif
-
-       CELL *object;
-
-       if(nursery.size - ALLOT_BUFFER_ZONE > a)
-       {
-               /* If there is insufficient room, collect the nursery */
-               if(nursery.here + ALLOT_BUFFER_ZONE + a > nursery.end)
-                       garbage_collection(NURSERY,false,0);
-
-               CELL h = nursery.here;
-               nursery.here = h + align8(a);
-               object = (CELL*)h;
-       }
-       /* If the object is bigger than the nursery, allocate it in
-       tenured space */
-       else
-       {
-               F_ZONE *tenured = &data_heap->generations[TENURED];
-
-               /* If tenured space does not have enough room, collect */
-               if(tenured->here + a > tenured->end)
-               {
-                       gc();
-                       tenured = &data_heap->generations[TENURED];
-               }
-
-               /* If it still won't fit, grow the heap */
-               if(tenured->here + a > tenured->end)
-               {
-                       garbage_collection(TENURED,true,a);
-                       tenured = &data_heap->generations[TENURED];
-               }
-
-               object = (CELL *)allot_zone(tenured,a);
-
-               /* We have to do this */
-               allot_barrier((CELL)object);
-
-               /* Allows initialization code to store old->new pointers
-               without hitting the write barrier in the common case of
-               a nursery allocation */
-               write_barrier((CELL)object);
-       }
-
-       *object = tag_header(type);
-       return object;
-}
-
-void copy_reachable_objects(CELL scan, CELL *end);
-
-void primitive_gc(void);
-void primitive_gc_stats(void);
-void clear_gc_stats(void);
-void primitive_clear_gc_stats(void);
-void primitive_become(void);
-
-INLINE void check_data_pointer(CELL pointer)
-{
-#ifdef FACTOR_DEBUG
-       if(!growing_data_heap)
-       {
-               assert(pointer >= data_heap->segment->start
-                      && pointer < data_heap->segment->end);
-       }
-#endif
-}
index 2e508c93a5f27c65d6df8b424481a3f232db39c5..f84f9f069901b5570c6ca2608ad44cb6b11ece40 100755 (executable)
@@ -28,9 +28,6 @@ INLINE bool collecting_accumulation_gen_p(void)
 
 extern CELL last_code_heap_scan;
 
-/* test if the pointer is in generation being collected, or a younger one. */
-bool should_copy_p(CELL untagged);
-
 void copy_handle(CELL *handle);
 
 void garbage_collection(volatile CELL gen,
index 4abc37db23712cdee1497148e441b784d76810ef..ea206c6b3f81de9a005ea0664663fe759dd7efa7 100644 (file)
@@ -224,7 +224,7 @@ CELL unaligned_object_size(CELL pointer)
        case STRING_TYPE:
                return string_size(string_capacity((F_STRING*)pointer));
        case TUPLE_TYPE:
-               tuple = untag<F_TUPLE>(pointer);
+               tuple = (F_TUPLE *)pointer;
                layout = untag<F_TUPLE_LAYOUT>(tuple->layout);
                return tuple_size(layout);
        case QUOTATION_TYPE:
@@ -284,7 +284,7 @@ CELL binary_payload_start(CELL pointer)
        case ARRAY_TYPE:
                return array_size<F_ARRAY>(array_capacity((F_ARRAY*)pointer));
        case TUPLE_TYPE:
-               tuple = untag<F_TUPLE>(pointer);
+               tuple = (F_TUPLE *)pointer;
                layout = untag<F_TUPLE_LAYOUT>(tuple->layout);
                return tuple_size(layout);
        case WRAPPER_TYPE:
index 81a0b0cc036b128575b5c065d42307ce570b4bfd..04040228022a78dd3510b8822efb92e896f17b58 100755 (executable)
@@ -113,7 +113,6 @@ void memory_protection_error(CELL addr, F_STACK_FRAME *native_stack)
                general_error(ERROR_RS_OVERFLOW,F,F,native_stack);
        else if(in_page(addr, nursery.end, 0, 0))
                critical_error("allot_object() missed GC check",0);
-       else if(in_page(addr, gc_locals_region->start, 0, -1))
        else
                general_error(ERROR_MEMORY,allot_cell(addr),F,native_stack);
 }
index 14822f82ee44130e32e2d9a338f1233b2e082c4f..05d5602f0ef135fcb1b172ebfc0edb223f21c2c2 100644 (file)
@@ -3,5 +3,5 @@
 F_SEGMENT *gc_locals_region;
 CELL gc_locals;
 
-F_SEGMENT *extra_roots_region;
-CELL extra_roots;
+F_SEGMENT *gc_bignums_region;
+CELL gc_bignums;
index 34b51222f3fc810031001340be5e41f0e84a752c..3f57afcdaf33722192fc1ccab84004a1475007fc 100644 (file)
@@ -20,12 +20,18 @@ struct gc_root : public tagged<T>
        ~gc_root() { CELL old = gc_local_pop(); assert(old == (CELL)this); }
 };
 
-/* Extra roots: stores pointers to objects in the heap. Requires extra work
-(you have to unregister before accessing the object) but more flexible. */
-extern F_SEGMENT *extra_roots_region;
-extern CELL extra_roots;
+/* A similar hack for the bignum implementation */
+extern F_SEGMENT *gc_bignums_region;
+extern CELL gc_bignums;
 
-DEFPUSHPOP(root_,extra_roots)
+DEFPUSHPOP(gc_bignum_,gc_bignums)
 
-#define REGISTER_BIGNUM(obj) if(obj) root_push(tag_bignum(obj))
-#define UNREGISTER_BIGNUM(obj) if(obj) obj = (untag_bignum_fast(root_pop()))
+struct gc_bignum
+{
+       F_BIGNUM **addr;
+
+       gc_bignum(F_BIGNUM **addr_) : addr(addr_) { if(*addr_) check_data_pointer((CELL)*addr_); gc_bignum_push((CELL)addr); }
+       ~gc_bignum() { assert((CELL)addr == gc_bignum_pop()); }
+};
+
+#define GC_BIGNUM(x) gc_bignum x##__gc_root(&x)
index 5bb8df8198867fee42b2eed74eba6533d218eaac..e3f9354b092630dbf7c69d784dfd1622a59f9607 100644 (file)
@@ -51,9 +51,9 @@ F_FASTCALL void overflow_fixnum_subtract(F_FIXNUM x, F_FIXNUM y)
 F_FASTCALL void overflow_fixnum_multiply(F_FIXNUM x, F_FIXNUM y)
 {
        F_BIGNUM *bx = fixnum_to_bignum(x);
-       REGISTER_BIGNUM(bx);
+       GC_BIGNUM(bx);
        F_BIGNUM *by = fixnum_to_bignum(y);
-       UNREGISTER_BIGNUM(bx);
+       GC_BIGNUM(by);
        drepl(tag<F_BIGNUM>(bignum_multiply(bx,by)));
 }