]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: split off parts of data_gc into sub-files and clean up logic
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 8 Oct 2009 07:10:28 +0000 (02:10 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 8 Oct 2009 07:10:28 +0000 (02:10 -0500)
vm/aging_collector.cpp
vm/aging_collector.hpp
vm/data_gc.cpp
vm/data_gc.hpp
vm/full_collector.cpp
vm/full_collector.hpp
vm/nursery_collector.cpp
vm/nursery_collector.hpp
vm/to_tenured_collector.cpp
vm/vm.hpp

index 918d5e322de159085eb520aa166f95163b001e09..287e5c306cc007ef533075d670612a70b149684b 100644 (file)
@@ -7,13 +7,21 @@ aging_collector::aging_collector(factor_vm *myvm_) :
        copying_collector<aging_space,aging_policy>
        (myvm_,myvm_->data->aging,aging_policy(myvm_)) {}
 
-void aging_collector::go()
+void factor_vm::collect_aging()
 {
-       trace_roots();
-       trace_contexts();
-       trace_cards(data->tenured);
-       trace_code_heap_roots();
-       cheneys_algorithm();
+       std::swap(data->aging,data->aging_semispace);
+       reset_generation(data->aging);
+
+       aging_collector collector(this);
+
+       collector.trace_roots();
+       collector.trace_contexts();
+       collector.trace_cards(data->tenured);
+       collector.trace_code_heap_roots();
+       collector.cheneys_algorithm();
+       update_dirty_code_blocks();
+
+       nursery.here = nursery.start;
 }
 
 }
index 71b8938710f6a46932af2d5e1c894eaa039be168..21917970201c972ace4a1b959d6f619b1f8ffd75 100644 (file)
@@ -18,7 +18,6 @@ struct aging_policy {
 
 struct aging_collector : copying_collector<aging_space,aging_policy> {
        aging_collector(factor_vm *myvm_);
-       void go();
 };
 
 }
index 7e3aa95e112582e1c28634a768299392f3cf28af..be31636eb7588f300923702bebc28f89bc600619 100755 (executable)
@@ -12,345 +12,6 @@ gc_state::gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_ge
 
 gc_state::~gc_state() { }
 
-template<typename Strategy> object *factor_vm::resolve_forwarding(object *untagged, Strategy &strategy)
-{
-       check_data_pointer(untagged);
-
-       /* is there another forwarding pointer? */
-       while(untagged->h.forwarding_pointer_p())
-               untagged = untagged->h.forwarding_pointer();
-
-       /* we've found the destination */
-       untagged->h.check_header();
-       return untagged;
-}
-
-template<typename Strategy> void factor_vm::trace_handle(cell *handle, Strategy &strategy)
-{
-       cell pointer = *handle;
-
-       if(!immediate_p(pointer))
-       {
-               object *untagged = untag<object>(pointer);
-               if(strategy.should_copy_p(untagged))
-               {
-                       object *forwarding = resolve_forwarding(untagged,strategy);
-
-                       if(forwarding == untagged)
-                               untagged = strategy.copy_object(untagged);
-                       else if(strategy.should_copy_p(forwarding))
-                               untagged = strategy.copy_object(forwarding);
-                       else
-                               untagged = forwarding;
-
-                       *handle = RETAG(untagged,TAG(pointer));
-               }
-       }
-}
-
-template<typename Strategy> void factor_vm::trace_slots(object *ptr, Strategy &strategy)
-{
-       cell *slot = (cell *)ptr;
-       cell *end = (cell *)((cell)ptr + binary_payload_start(ptr));
-
-       if(slot != end)
-       {
-               slot++;
-               for(; slot < end; slot++) trace_handle(slot,strategy);
-       }
-}
-
-template<typename Strategy> object *factor_vm::promote_object(object *untagged, Strategy &strategy)
-{
-       cell size = untagged_object_size(untagged);
-       object *newpointer = strategy.allot(size);
-       if(!newpointer) longjmp(current_gc->gc_unwind,1);
-
-       generation_statistics *s = &gc_stats.generations[current_gc->collecting_gen];
-       s->object_count++;
-       s->bytes_copied += size;
-
-       memcpy(newpointer,untagged,size);
-       untagged->h.forward_to(newpointer);
-
-       return newpointer;
-}
-
-template<typename Strategy> void factor_vm::trace_card(card *ptr, old_space *gen, Strategy &strategy)
-{
-       cell card_start = card_to_addr(ptr);
-       cell card_scan = card_start + gen->card_offset(card_start);
-       cell card_end = card_to_addr(ptr + 1);
-
-       if(gen->here < card_end) card_end = gen->here;
-
-       strategy.copy_reachable_objects(card_scan,&card_end);
-
-       gc_stats.cards_scanned++;
-}
-
-template<typename Strategy> void factor_vm::trace_card_deck(card_deck *deck, old_space *gen, card mask, card unmask, Strategy &strategy)
-{
-       card *first_card = deck_to_card(deck);
-       card *last_card = deck_to_card(deck + 1);
-
-       u32 *quad_ptr;
-       u32 quad_mask = mask | (mask << 8) | (mask << 16) | (mask << 24);
-
-       for(quad_ptr = (u32 *)first_card; quad_ptr < (u32 *)last_card; quad_ptr++)
-       {
-               if(*quad_ptr & quad_mask)
-               {
-                       card *ptr = (card *)quad_ptr;
-
-                       int card;
-                       for(card = 0; card < 4; card++)
-                       {
-                               if(ptr[card] & mask)
-                               {
-                                       trace_card(&ptr[card],gen,strategy);
-                                       ptr[card] &= ~unmask;
-                               }
-                       }
-               }
-       }
-
-       gc_stats.decks_scanned++;
-}
-
-/* Trace all objects referenced from marked cards */
-template<typename Strategy> void factor_vm::trace_cards(cell gen, old_space *z, Strategy &strategy)
-{
-       u64 start_time = current_micros();
-
-       card_deck *first_deck = addr_to_deck(z->start);
-       card_deck *last_deck = addr_to_deck(z->end);
-
-       card mask, unmask;
-
-       /* if we are collecting the nursery, we care about old->nursery pointers
-       but not old->aging pointers */
-       if(current_gc->collecting_nursery_p())
-       {
-               mask = card_points_to_nursery;
-
-               /* after the collection, no old->nursery pointers remain
-               anywhere, but old->aging pointers might remain in tenured
-               space */
-               if(gen == tenured_gen)
-                       unmask = card_points_to_nursery;
-               /* after the collection, all cards in aging space can be
-               cleared */
-               else if(gen == aging_gen)
-                       unmask = card_mark_mask;
-               else
-               {
-                       critical_error("bug in trace_generation_cards",gen);
-                       return;
-               }
-       }
-       /* if we are collecting aging space into tenured space, we care about
-       all old->nursery and old->aging pointers. no old->aging pointers can
-       remain */
-       else if(current_gc->collecting_aging_p())
-       {
-               if(current_gc->collecting_aging_again)
-               {
-                       mask = card_points_to_aging;
-                       unmask = card_mark_mask;
-               }
-               /* after we collect aging space into the aging semispace, no
-               old->nursery pointers remain but tenured space might still have
-               pointers to aging space. */
-               else
-               {
-                       mask = card_points_to_aging;
-                       unmask = card_points_to_nursery;
-               }
-       }
-       else
-       {
-               critical_error("bug in trace_generation_cards",gen);
-               return;
-       }
-
-       card_deck *ptr;
-
-       for(ptr = first_deck; ptr < last_deck; ptr++)
-       {
-               if(*ptr & mask)
-               {
-                       trace_card_deck(ptr,z,mask,unmask,strategy);
-                       *ptr &= ~unmask;
-               }
-       }
-
-       gc_stats.card_scan_time += (current_micros() - start_time);
-}
-
-/* Copy all tagged pointers in a range of memory */
-template<typename Strategy> void factor_vm::trace_stack_elements(segment *region, cell top, Strategy &strategy)
-{
-       cell ptr = region->start;
-
-       for(; ptr <= top; ptr += sizeof(cell))
-               trace_handle((cell*)ptr,strategy);
-}
-
-template<typename Strategy> void factor_vm::trace_registered_locals(Strategy &strategy)
-{
-       std::vector<cell>::const_iterator iter = gc_locals.begin();
-       std::vector<cell>::const_iterator end = gc_locals.end();
-
-       for(; iter < end; iter++)
-               trace_handle((cell *)(*iter),strategy);
-}
-
-template<typename Strategy> void factor_vm::trace_registered_bignums(Strategy &strategy)
-{
-       std::vector<cell>::const_iterator iter = gc_bignums.begin();
-       std::vector<cell>::const_iterator end = gc_bignums.end();
-
-       for(; iter < end; iter++)
-       {
-               cell *handle = (cell *)(*iter);
-
-               if(*handle)
-               {
-                       *handle |= BIGNUM_TYPE;
-                       trace_handle(handle,strategy);
-                       *handle &= ~BIGNUM_TYPE;
-               }
-       }
-}
-
-/* Copy roots over at the start of GC, namely various constants, stacks,
-the user environment and extra roots registered by local_roots.hpp */
-template<typename Strategy> void factor_vm::trace_roots(Strategy &strategy)
-{
-       trace_handle(&T,strategy);
-       trace_handle(&bignum_zero,strategy);
-       trace_handle(&bignum_pos_one,strategy);
-       trace_handle(&bignum_neg_one,strategy);
-
-       trace_registered_locals(strategy);
-       trace_registered_bignums(strategy);
-
-       int i;
-       for(i = 0; i < USER_ENV; i++)
-               trace_handle(&userenv[i],strategy);
-}
-
-template<typename Strategy> struct stack_frame_marker {
-       factor_vm *myvm;
-       Strategy &strategy;
-
-       explicit stack_frame_marker(factor_vm *myvm_, Strategy &strategy_) :
-               myvm(myvm_), strategy(strategy_) {}
-       void operator()(stack_frame *frame)
-       {
-               myvm->mark_code_block(myvm->frame_code(frame),strategy);
-       }
-};
-
-/* Mark code blocks executing in currently active stack frames. */
-template<typename Strategy> void factor_vm::mark_active_blocks(context *stacks, Strategy &strategy)
-{
-       if(current_gc->collecting_tenured_p())
-       {
-               cell top = (cell)stacks->callstack_top;
-               cell bottom = (cell)stacks->callstack_bottom;
-
-               stack_frame_marker<Strategy> marker(this,strategy);
-               iterate_callstack(top,bottom,marker);
-       }
-}
-
-template<typename Strategy> void factor_vm::mark_object_code_block(object *object, Strategy &strategy)
-{
-       switch(object->h.hi_tag())
-       {
-       case WORD_TYPE:
-               {
-                       word *w = (word *)object;
-                       if(w->code)
-                               mark_code_block(w->code,strategy);
-                       if(w->profiling)
-                               mark_code_block(w->profiling,strategy);
-                       break;
-               }
-       case QUOTATION_TYPE:
-               {
-                       quotation *q = (quotation *)object;
-                       if(q->code)
-                               mark_code_block(q->code,strategy);
-                       break;
-               }
-       case CALLSTACK_TYPE:
-               {
-                       callstack *stack = (callstack *)object;
-                       stack_frame_marker<Strategy> marker(this,strategy);
-                       iterate_callstack_object(stack,marker);
-                       break;
-               }
-       }
-}
-
-template<typename Strategy> void factor_vm::trace_contexts(Strategy &strategy)
-{
-       save_stacks();
-       context *stacks = stack_chain;
-
-       while(stacks)
-       {
-               trace_stack_elements(stacks->datastack_region,stacks->datastack,strategy);
-               trace_stack_elements(stacks->retainstack_region,stacks->retainstack,strategy);
-
-               trace_handle(&stacks->catchstack_save,strategy);
-               trace_handle(&stacks->current_callback_save,strategy);
-
-               mark_active_blocks(stacks,strategy);
-
-               stacks = stacks->next;
-       }
-}
-
-/* Trace all literals referenced from a code block. Only for aging and nursery collections */
-template<typename Strategy> void factor_vm::trace_literal_references(code_block *compiled, Strategy &strategy)
-{
-       trace_handle(&compiled->owner,strategy);
-       trace_handle(&compiled->literals,strategy);
-       trace_handle(&compiled->relocation,strategy);
-}
-
-/* Trace literals referenced from all code blocks. Only for aging and nursery collections */
-template<typename Strategy> void factor_vm::trace_code_heap_roots(Strategy &strategy)
-{
-       if(current_gc->collecting_gen >= code->youngest_referenced_generation)
-       {
-               unordered_map<code_block *,cell>::const_iterator iter = code->remembered_set.begin();
-               unordered_map<code_block *,cell>::const_iterator end = code->remembered_set.end();
-
-               for(; iter != end; iter++)
-               {
-                       if(current_gc->collecting_gen >= iter->second)
-                               trace_literal_references(iter->first,strategy);
-               }
-
-               gc_stats.code_heap_scans++;
-       }
-}
-
-/* Mark all literals referenced from a word XT. Only for tenured
-collections */
-template<typename Strategy> void factor_vm::mark_code_block(code_block *compiled, Strategy &strategy)
-{
-       check_code_address((cell)compiled);
-
-       code->mark_block(compiled);
-       trace_literal_references(compiled,strategy);
-}
-
 struct literal_and_word_reference_updater {
        factor_vm *myvm;
 
@@ -398,193 +59,6 @@ void factor_vm::update_dirty_code_blocks()
        code->youngest_referenced_generation = gen;
 }
 
-template<typename Strategy>
-cheney_collector<Strategy>::cheney_collector(factor_vm *myvm_, old_space *target_)
-: myvm(myvm_), current_gc(myvm_->current_gc), target(target_)
-{
-       scan = target->here;
-}
-
-template<typename Strategy> Strategy &cheney_collector<Strategy>::strategy()
-{
-       return static_cast<Strategy &>(*this);
-}
-
-template<typename Strategy> object *cheney_collector<Strategy>::allot(cell size)
-{
-       return target->allot(size);
-}
-
-template<typename Strategy> object *cheney_collector<Strategy>::copy_object(object *untagged)
-{
-       return myvm->promote_object(untagged,strategy());
-}
-
-template<typename Strategy> bool cheney_collector<Strategy>::should_copy_p(object *pointer)
-{
-       return strategy().should_copy_p(pointer);
-}
-
-template<typename Strategy> cell cheney_collector<Strategy>::trace_next(cell scan)
-{
-       object *obj = (object *)scan;
-       myvm->trace_slots(obj,strategy());
-       return scan + myvm->untagged_object_size(obj);
-}
-
-template<typename Strategy> void cheney_collector<Strategy>::go()
-{
-       strategy().copy_reachable_objects(scan,&target->here);
-}
-
-struct nursery_strategy : cheney_collector<nursery_strategy>
-{
-       explicit nursery_strategy(factor_vm *myvm_, old_space *target_) :
-               cheney_collector<nursery_strategy>(myvm_,target_) {}
-
-       bool should_copy_p(object *untagged)
-       {
-               return myvm->nursery.contains_p(untagged);
-       }
-
-       void copy_reachable_objects(cell scan, cell *end)
-       {
-               while(scan < *end) scan = trace_next(scan);
-       }
-};
-
-struct aging_strategy : cheney_collector<aging_strategy>
-{
-       zone *tenured;
-
-       explicit aging_strategy(factor_vm *myvm_, old_space *target_) :
-               cheney_collector<aging_strategy>(myvm_,target_),
-               tenured(myvm->data->tenured) {}
-
-       bool should_copy_p(object *untagged)
-       {
-               if(target->contains_p(untagged))
-                       return false;
-               else
-                       return !tenured->contains_p(untagged);
-       }
-       
-       void copy_reachable_objects(cell scan, cell *end)
-       {
-               while(scan < *end) scan = trace_next(scan);
-       }
-};
-
-struct aging_agian_strategy : cheney_collector<aging_agian_strategy>
-{
-       explicit aging_agian_strategy(factor_vm *myvm_, old_space *target_) :
-               cheney_collector<aging_agian_strategy>(myvm_,target_) {}
-
-       bool should_copy_p(object *untagged)
-       {
-               return !target->contains_p(untagged);
-       }
-       
-       void copy_reachable_objects(cell scan, cell *end)
-       {
-               while(scan < *end) scan = trace_next(scan);
-       }
-};
-
-struct tenured_strategy : cheney_collector<tenured_strategy>
-{
-       explicit tenured_strategy(factor_vm *myvm_, old_space *target_) :
-               cheney_collector<tenured_strategy>(myvm_,target_) {}
-       
-       bool should_copy_p(object *untagged)
-       {
-               return !target->contains_p(untagged);
-       }
-       
-       void copy_reachable_objects(cell scan, cell *end)
-       {
-               while(scan < *end)
-               {
-                       myvm->mark_object_code_block(myvm->untag<object>(scan),*this);
-                       scan = trace_next(scan);
-               }
-       }
-};
-
-void factor_vm::collect_nursery()
-{
-       nursery_strategy collector(this,data->aging);
-
-       trace_roots(collector);
-       trace_contexts(collector);
-       trace_cards(tenured_gen,data->tenured,collector);
-       trace_cards(aging_gen,data->aging,collector);
-       trace_code_heap_roots(collector);
-       collector.go();
-       update_dirty_code_blocks();
-
-       nursery.here = nursery.start;
-}
-
-void factor_vm::collect_aging()
-{
-       std::swap(data->aging,data->aging_semispace);
-       reset_generation(data->aging);
-
-       aging_strategy collector(this,data->aging);
-
-       trace_roots(collector);
-       trace_contexts(collector);
-       trace_cards(tenured_gen,data->tenured,collector);
-       trace_code_heap_roots(collector);
-       collector.go();
-       update_dirty_code_blocks();
-
-       nursery.here = nursery.start;
-}
-
-void factor_vm::collect_aging_again()
-{
-       aging_agian_strategy collector(this,data->tenured);
-
-       trace_roots(collector);
-       trace_contexts(collector);
-       trace_cards(tenured_gen,data->tenured,collector);
-       trace_code_heap_roots(collector);
-       collector.go();
-       update_dirty_code_blocks();
-
-       reset_generation(data->aging);
-       nursery.here = nursery.start;
-}
-
-void factor_vm::collect_tenured(cell requested_bytes, bool trace_contexts_)
-{
-       if(current_gc->growing_data_heap)
-       {
-               current_gc->old_data_heap = data;
-               set_data_heap(grow_data_heap(current_gc->old_data_heap,requested_bytes));
-       }
-       else
-       {
-               std::swap(data->tenured,data->tenured_semispace);
-               reset_generation(data->tenured);
-       }
-
-       tenured_strategy collector(this,data->tenured);
-
-        trace_roots(collector);
-        if(trace_contexts_) trace_contexts(collector);
-        collector.go();
-        free_unmarked_code_blocks();
-
-       reset_generation(data->aging);
-       nursery.here = nursery.start;
-
-       if(current_gc->growing_data_heap)
-               delete current_gc->old_data_heap;
-}
-
 void factor_vm::record_gc_stats()
 {
        generation_statistics *s = &gc_stats.generations[current_gc->collecting_gen];
@@ -599,11 +73,13 @@ void factor_vm::record_gc_stats()
 /* Collect gen and all younger generations.
 If growing_data_heap_ is true, we must grow the data heap to such a size that
 an allocation of requested_bytes won't fail */
-void factor_vm::garbage_collection(cell collecting_gen_, bool growing_data_heap_, bool trace_contexts_, cell requested_bytes)
+void factor_vm::garbage_collection(cell collecting_gen_, bool growing_data_heap_, bool trace_contexts_p, cell requested_bytes)
 {
        assert(!gc_off);
        assert(!current_gc);
 
+       save_stacks();
+
        current_gc = new gc_state(data,growing_data_heap_,collecting_gen_);
 
        /* Keep trying to GC higher and higher generations until we don't run out
@@ -640,12 +116,12 @@ void factor_vm::garbage_collection(cell collecting_gen_, bool growing_data_heap_
         else if(current_gc->collecting_aging_p())
        {
                if(current_gc->collecting_aging_again)
-                       collect_aging_again();
+                       collect_to_tenured();
                else
                        collect_aging();
        }
         else if(current_gc->collecting_tenured_p())
-               collect_tenured(requested_bytes,trace_contexts_);
+               collect_full(requested_bytes,trace_contexts_p);
 
        record_gc_stats();
 
index d9bed8e78576f2e8fadd205422f3ef6a47af6e9f..9304a3ad03064a6d827f45972cb6d5bb2cda92c4 100755 (executable)
@@ -63,21 +63,6 @@ struct gc_state {
        }
 };
 
-template<typename Strategy> struct cheney_collector {
-       factor_vm *myvm;
-       gc_state *current_gc;
-       old_space *target;
-       cell scan;
-
-       explicit cheney_collector(factor_vm *myvm_, old_space *target);
-       Strategy &strategy();
-       object *allot(cell size);
-       cell trace_next(cell scan);
-       object *copy_object(object *untagged);
-       bool should_copy_p(object *untagged);
-       void go();
-};
-
 VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *myvm);
 
 }
index bead2f733829689760eddbd49cfa28466c0b2b14..c54dd6b72e1cc3660abecb401ac3a5431a2013d8 100644 (file)
@@ -3,9 +3,8 @@
 namespace factor
 {
 
-full_collector::full_collector(factor_vm *myvm_, bool trace_contexts_p_) :
-       copying_collector<tenured_space,full_policy>(myvm_,myvm_->data->tenured,full_policy(myvm_)),
-       trace_contexts_p(trace_contexts_p_) {}
+full_collector::full_collector(factor_vm *myvm_) :
+       copying_collector<tenured_space,full_policy>(myvm_,myvm_->data->tenured,full_policy(myvm_)) {}
 
 struct stack_frame_marker {
        factor_vm *myvm;
@@ -21,22 +20,29 @@ struct stack_frame_marker {
 };
 
 /* Mark code blocks executing in currently active stack frames. */
-void full_collector::mark_active_blocks(context *stacks)
+void full_collector::mark_active_blocks()
 {
-       cell top = (cell)stacks->callstack_top;
-       cell bottom = (cell)stacks->callstack_bottom;
+       context *stacks = this->myvm->stack_chain;
 
-       stack_frame_marker marker(this);
-       myvm->iterate_callstack(top,bottom,marker);
+       while(stacks)
+       {
+               cell top = (cell)stacks->callstack_top;
+               cell bottom = (cell)stacks->callstack_bottom;
+
+               stack_frame_marker marker(this);
+               myvm->iterate_callstack(top,bottom,marker);
+
+               stacks = stacks->next;
+       }
 }
 
-void full_collector::mark_object_code_block(object *object)
+void full_collector::mark_object_code_block(object *obj)
 {
-       switch(object->h.hi_tag())
+       switch(obj->h.hi_tag())
        {
        case WORD_TYPE:
                {
-                       word *w = (word *)object;
+                       word *w = (word *)obj;
                        if(w->code)
                                mark_code_block(w->code);
                        if(w->profiling)
@@ -45,14 +51,14 @@ void full_collector::mark_object_code_block(object *object)
                }
        case QUOTATION_TYPE:
                {
-                       quotation *q = (quotation *)object;
+                       quotation *q = (quotation *)obj;
                        if(q->code)
                                mark_code_block(q->code);
                        break;
                }
        case CALLSTACK_TYPE:
                {
-                       callstack *stack = (callstack *)object;
+                       callstack *stack = (callstack *)obj;
                        stack_frame_marker marker(this);
                        myvm->iterate_callstack_object(stack,marker);
                        break;
@@ -78,11 +84,47 @@ void full_collector::mark_code_block(code_block *compiled)
        trace_literal_references(compiled);
 }
 
-void full_collector::go()
+void full_collector::cheneys_algorithm()
+{
+       while(scan && scan < target->here)
+       {
+               object *obj = (object *)scan;
+               this->trace_slots(obj);
+               this->mark_object_code_block(obj);
+               scan = target->next_object_after(this->myvm,scan);
+       }
+}
+
+void factor_vm::collect_full(cell requested_bytes, bool trace_contexts_p)
 {
-       trace_roots();
-        if(trace_contexts_p) trace_contexts();
-        cheneys_algorithm();
+       if(current_gc->growing_data_heap)
+       {
+               current_gc->old_data_heap = data;
+               set_data_heap(grow_data_heap(current_gc->old_data_heap,requested_bytes));
+       }
+       else
+       {
+               std::swap(data->tenured,data->tenured_semispace);
+               reset_generation(data->tenured);
+       }
+
+       full_collector collector(this);
+
+       collector.trace_roots();
+        if(trace_contexts_p)
+       {
+               collector.trace_contexts();
+               collector.mark_active_blocks();
+       }
+
+       collector.cheneys_algorithm();
+       free_unmarked_code_blocks();
+
+       reset_generation(data->aging);
+       nursery.here = nursery.start;
+
+       if(current_gc->growing_data_heap)
+               delete current_gc->old_data_heap;
 }
 
 }
index d5c47416fa950e3f2ae91444b210c542970c0391..d39358e0e2e3c064c9eec2ed9861dbff1aed5b34 100644 (file)
@@ -16,12 +16,12 @@ struct full_policy {
 struct full_collector : copying_collector<tenured_space,full_policy> {
        bool trace_contexts_p;
 
-       full_collector(factor_vm *myvm_, bool trace_contexts_p_);
-       void mark_active_blocks(context *stacks);
+       full_collector(factor_vm *myvm_);
+       void mark_active_blocks();
        void mark_object_code_block(object *object);
        void trace_literal_references(code_block *compiled);
        void mark_code_block(code_block *compiled);
-       void go();
+       void cheneys_algorithm();
 };
 
 }
index 302f9585626fbe1b32d1aa05b371660fd6cf790a..f5dc38605373762aef701c66c42786d094073b0f 100644 (file)
@@ -7,14 +7,20 @@ nursery_collector::nursery_collector(factor_vm *myvm_) :
        copying_collector<aging_space,nursery_policy>
        (myvm_,myvm_->data->aging,nursery_policy(myvm_)) {}
 
-void nursery_collector::go()
+void factor_vm::collect_nursery()
 {
-       trace_roots();
-       trace_contexts();
-       trace_cards(data->tenured);
-       trace_cards(data->aging);
-       trace_code_heap_roots();
-       cheneys_algorithm();
+       nursery_collector collector(this);
+
+       collector.trace_roots();
+       collector.trace_contexts();
+       collector.trace_cards(data->tenured);
+       collector.trace_cards(data->aging);
+       collector.trace_code_heap_roots();
+       collector.cheneys_algorithm();
+
+       update_dirty_code_blocks();
+
+       nursery.here = nursery.start;
 }
 
 }
index 1cfe063187033ef3a3992cb8e611aeb146137b66..cff988cf9dc9999ccd4deaef9f960f76fb230e3b 100644 (file)
@@ -14,7 +14,6 @@ struct nursery_policy {
 
 struct nursery_collector : copying_collector<aging_space,nursery_policy> {
        nursery_collector(factor_vm *myvm_);
-       void go();
 };
 
 }
index 2693e35a2fe870022142a84b3480d0bf54817d3f..a0341ec93d845d522b3addab6fbf37ad8ed6c152 100644 (file)
@@ -7,13 +7,19 @@ to_tenured_collector::to_tenured_collector(factor_vm *myvm_) :
        copying_collector<tenured_space,to_tenured_policy>
        (myvm_,myvm_->data->tenured,to_tenured_policy(myvm_)) {}
 
-void to_tenured_collector::go()
+void factor_vm::collect_to_tenured()
 {
-       trace_roots();
-       trace_contexts();
-       trace_cards(data->tenured);
-       trace_code_heap_roots();
-       cheneys_algorithm();
+       to_tenured_collector collector(this);
+
+       collector.trace_roots();
+       collector.trace_contexts();
+       collector.trace_cards(data->tenured);
+       collector.trace_code_heap_roots();
+       collector.cheneys_algorithm();
+       update_dirty_code_blocks();
+
+       reset_generation(data->aging);
+       nursery.here = nursery.start;
 }
 
 }
index 02ab128969297a82e782d390b71fb9f6d7ca8a11..80dd67c76dc00cbd2e25e0fef28ab2e34ff2d353 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -205,7 +205,7 @@ struct factor_vm
        int bignum_unsigned_logbitp(int shift, bignum * bignum);
        bignum *digit_stream_to_bignum(unsigned int n_digits, unsigned int (*producer)(unsigned int, factor_vm *), unsigned int radix, int negative_p);
 
-       //data_heap
+       //data heap
        void init_card_decks();
        data_heap *grow_data_heap(data_heap *data, cell requested_bytes);
        void clear_cards(old_space *gen);
@@ -262,32 +262,15 @@ struct factor_vm
                *addr_to_deck((cell)obj) = card_mark_mask;
        }
 
-       // data_gc
-       template<typename Strategy> object *resolve_forwarding(object *untagged, Strategy &strategy);
-       template<typename Strategy> void trace_handle(cell *handle, Strategy &strategy);
-       template<typename Strategy> object *promote_object(object *pointer, Strategy &strategy);
-       template<typename Strategy> void trace_slots(object *ptr, Strategy &strategy);
-       template<typename Strategy> void trace_card(card *ptr, old_space *gen, Strategy &strategy);
-       template<typename Strategy> void trace_card_deck(card_deck *deck, old_space *gen, card mask, card unmask, Strategy &strategy);
-       template<typename Strategy> void trace_cards(cell gen, old_space *z, Strategy &strategy);
-       template<typename Strategy> void trace_stack_elements(segment *region, cell top, Strategy &strategy);
-       template<typename Strategy> void trace_registered_locals(Strategy &strategy);
-       template<typename Strategy> void trace_registered_bignums(Strategy &strategy);
-       template<typename Strategy> void trace_roots(Strategy &strategy);
-       template<typename Strategy> void mark_active_blocks(context *stacks, Strategy &strategy);
-       template<typename Strategy> void trace_contexts(Strategy &strategy);
-       template<typename Strategy> void trace_literal_references(code_block *compiled, Strategy &strategy);
-       template<typename Strategy> void trace_code_heap_roots(Strategy &strategy);
-       template<typename Strategy> void mark_code_block(code_block *compiled, Strategy &strategy);
-       template<typename Strategy> void mark_object_code_block(object *object, Strategy &strategy);
+       // gc
        void free_unmarked_code_blocks();
        void update_dirty_code_blocks();
        void collect_nursery();
        void collect_aging();
-       void collect_aging_again();
-       void collect_tenured(cell requested_bytes, bool trace_contexts_);
+       void collect_to_tenured();
+       void collect_full(cell requested_bytes, bool trace_contexts_p);
        void record_gc_stats();
-       void garbage_collection(cell gen, bool growing_data_heap, bool trace_contexts, cell requested_bytes);
+       void garbage_collection(cell gen, bool growing_data_heap, bool trace_contexts_p, cell requested_bytes);
        void gc();
        void primitive_gc();
        void primitive_gc_stats();
@@ -528,7 +511,7 @@ struct factor_vm
        code_block *allot_code_block(cell size, cell type);
        code_block *add_code_block(cell type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_);
 
-       //code_heap
+       //code heap
        inline void check_code_pointer(cell ptr)
        {
        #ifdef FACTOR_DEBUG