From 9ccec333213338c9c720b4a2571fb9d221d6fd1a Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 6 Oct 2009 00:13:54 -0500 Subject: [PATCH] vm: more GC refactoring --- vm/data_gc.cpp | 272 +++++++++++++++++++++----------------------- vm/data_gc.hpp | 16 +++ vm/inline_cache.cpp | 4 + vm/vm.cpp | 9 +- vm/vm.hpp | 9 -- 5 files changed, 155 insertions(+), 155 deletions(-) diff --git a/vm/data_gc.cpp b/vm/data_gc.cpp index dad6b9c9eb..35a5ba07de 100755 --- a/vm/data_gc.cpp +++ b/vm/data_gc.cpp @@ -17,68 +17,6 @@ gc_state::gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_ge gc_state::~gc_state() { } -/* Given a pointer to oldspace, copy it to newspace */ -object *factor_vm::copy_untagged_object_impl(object *pointer, cell size) -{ - if(current_gc->newspace->here + size >= current_gc->newspace->end) - longjmp(current_gc->gc_unwind,1); - - object *newpointer = allot_zone(current_gc->newspace,size); - - gc_stats *s = &stats[current_gc->collecting_gen]; - s->object_count++; - s->bytes_copied += size; - - memcpy(newpointer,pointer,size); - return newpointer; -} - -object *factor_vm::copy_object_impl(object *untagged) -{ - object *newpointer = copy_untagged_object_impl(untagged,untagged_object_size(untagged)); - untagged->h.forward_to(newpointer); - return newpointer; -} - -/* Follow a chain of forwarding pointers */ -template object *factor_vm::resolve_forwarding(object *untagged, Strategy &strategy) -{ - check_data_pointer(untagged); - - /* is there another forwarding pointer? */ - if(untagged->h.forwarding_pointer_p()) - return resolve_forwarding(untagged->h.forwarding_pointer(),strategy); - /* we've found the destination */ - else - { - untagged->h.check_header(); - if(strategy.should_copy_p(untagged)) - return copy_object_impl(untagged); - else - return untagged; - } -} - -template Type *factor_vm::copy_untagged_object(Type *untagged, Strategy &strategy) -{ - check_data_pointer(untagged); - - if(untagged->h.forwarding_pointer_p()) - untagged = (Type *)resolve_forwarding(untagged->h.forwarding_pointer(),strategy); - else - { - untagged->h.check_header(); - untagged = (Type *)copy_object_impl(untagged); - } - - return untagged; -} - -template cell factor_vm::copy_object(cell pointer, Strategy &strategy) -{ - return RETAG(copy_untagged_object(untag(pointer),strategy),TAG(pointer)); -} - template void factor_vm::trace_handle(cell *handle, Strategy &strategy) { cell pointer = *handle; @@ -88,7 +26,7 @@ template void factor_vm::trace_handle(cell *handle, Strategy object *obj = untag(pointer); check_data_pointer(obj); if(strategy.should_copy_p(obj)) - *handle = copy_object(pointer,strategy); + *handle = strategy.copy_object(pointer); } } @@ -247,7 +185,7 @@ template void factor_vm::trace_registered_bignums(Strategy &s { check_data_pointer(pointer); if(strategy.should_copy_p(pointer)) - *handle = copy_untagged_object(pointer,strategy); + *handle = untag(strategy.copy_object(tag(pointer))); #ifdef FACTOR_DEBUG assert((*handle)->h.hi_tag() == BIGNUM_TYPE); #endif @@ -383,15 +321,18 @@ template struct literal_reference_tracer { aging and nursery collections */ template void factor_vm::trace_code_heap_roots(Strategy &strategy) { - literal_reference_tracer tracer(this,strategy); - iterate_code_heap(tracer); + if(current_gc->collecting_gen >= last_code_heap_scan) + { + literal_reference_tracer tracer(this,strategy); + iterate_code_heap(tracer); - if(current_gc->collecting_accumulation_gen_p()) - last_code_heap_scan = current_gc->collecting_gen; - else - last_code_heap_scan = current_gc->collecting_gen + 1; - - code_heap_scans++; + if(current_gc->collecting_accumulation_gen_p()) + last_code_heap_scan = current_gc->collecting_gen; + else + last_code_heap_scan = current_gc->collecting_gen + 1; + + code_heap_scans++; + } } /* Mark all literals referenced from a word XT. Only for tenured @@ -406,37 +347,6 @@ template void factor_vm::mark_code_block(code_block *compiled trace_handle(&compiled->relocation,strategy); } -template cell factor_vm::copy_next(cell scan, Strategy &strategy) -{ - cell *obj = (cell *)scan; - cell *end = (cell *)(scan + binary_payload_start((object *)scan)); - - if(obj != end) - { - obj++; - - for(; obj < end; obj++) - trace_handle(obj,strategy); - } - - return scan + untagged_object_size((object *)scan); -} - -template void factor_vm::update_code_heap_roots(Strategy &strategy) -{ - if(current_gc->collecting_gen >= last_code_heap_scan) - { - code_heap_scans++; - - trace_code_heap_roots(strategy); - - if(current_gc->collecting_accumulation_gen_p()) - last_code_heap_scan = current_gc->collecting_gen; - else - last_code_heap_scan = current_gc->collecting_gen + 1; - } -} - struct literal_and_word_reference_updater { factor_vm *myvm; @@ -502,12 +412,107 @@ void factor_vm::begin_gc(cell requested_bytes) } } -struct nursery_collector +template +copying_collector::copying_collector(factor_vm *myvm_) +: myvm(myvm_), current_gc(myvm_->current_gc) { - factor_vm *myvm; + scan = current_gc->newspace->here; +} + +template Strategy ©ing_collector::strategy() +{ + return static_cast(*this); +} + +/* Given a pointer to oldspace, copy it to newspace */ +template object *copying_collector::copy_untagged_object_impl(object *pointer, cell size) +{ + if(current_gc->newspace->here + size >= current_gc->newspace->end) + longjmp(current_gc->gc_unwind,1); + + object *newpointer = myvm->allot_zone(current_gc->newspace,size); + + gc_stats *s = &myvm->stats[current_gc->collecting_gen]; + s->object_count++; + s->bytes_copied += size; + + memcpy(newpointer,pointer,size); + return newpointer; +} + +template object *copying_collector::copy_object_impl(object *untagged) +{ + object *newpointer = copy_untagged_object_impl(untagged,myvm->untagged_object_size(untagged)); + untagged->h.forward_to(newpointer); + return newpointer; +} + +/* Follow a chain of forwarding pointers */ +template object *copying_collector::resolve_forwarding(object *untagged) +{ + myvm->check_data_pointer(untagged); + + /* is there another forwarding pointer? */ + if(untagged->h.forwarding_pointer_p()) + return resolve_forwarding(untagged->h.forwarding_pointer()); + /* we've found the destination */ + else + { + untagged->h.check_header(); + if(should_copy_p(untagged)) + return copy_object_impl(untagged); + else + return untagged; + } +} + +template cell copying_collector::copy_object(cell pointer) +{ + object *untagged = myvm->untag(pointer); + + myvm->check_data_pointer(untagged); + + if(untagged->h.forwarding_pointer_p()) + untagged = resolve_forwarding(untagged->h.forwarding_pointer()); + else + { + untagged->h.check_header(); + untagged = copy_object_impl(untagged); + } + + return RETAG(untagged,TAG(pointer)); +} + +template bool copying_collector::should_copy_p(object *pointer) +{ + return strategy().should_copy_p(pointer); +} + +template cell copying_collector::copy_next(cell scan) +{ + cell *obj = (cell *)scan; + cell *end = (cell *)(scan + myvm->binary_payload_start((object *)scan)); + + if(obj != end) + { + obj++; + + for(; obj < end; obj++) + myvm->trace_handle(obj,strategy()); + } + + return scan + myvm->untagged_object_size((object *)scan); +} + +template void copying_collector::go() +{ + strategy().copy_reachable_objects(scan,¤t_gc->newspace->here); +} + +struct nursery_collector : copying_collector +{ + explicit nursery_collector(factor_vm *myvm_) : copying_collector(myvm_) {} - explicit nursery_collector(factor_vm *myvm_) : myvm(myvm_) {} - bool should_copy_p(object *untagged) { if(myvm->current_gc->newspace->contains_p(untagged)) @@ -515,11 +520,10 @@ struct nursery_collector else return myvm->nursery.contains_p(untagged); } - + void copy_reachable_objects(cell scan, cell *end) { - while(scan < myvm->current_gc->newspace->here) - scan = myvm->copy_next(scan,*this); + while(scan < *end) scan = copy_next(scan); } }; @@ -527,26 +531,18 @@ void factor_vm::collect_nursery() { nursery_collector collector(this); - cell scan = current_gc->newspace->here; - trace_roots(collector); trace_contexts(collector); trace_cards(collector); - - if(current_gc->collecting_gen >= last_code_heap_scan) - update_code_heap_roots(collector); - - collector.copy_reachable_objects(scan,¤t_gc->newspace->here); - + trace_code_heap_roots(collector); + collector.go(); update_dirty_code_blocks(); } -struct aging_collector +struct aging_collector : copying_collector { - factor_vm *myvm; + explicit aging_collector(factor_vm *myvm_) : copying_collector(myvm_) {} - explicit aging_collector(factor_vm *myvm_) : myvm(myvm_) {} - bool should_copy_p(object *untagged) { if(myvm->current_gc->newspace->contains_p(untagged)) @@ -557,8 +553,7 @@ struct aging_collector void copy_reachable_objects(cell scan, cell *end) { - while(scan < myvm->current_gc->newspace->here) - scan = myvm->copy_next(scan,*this); + while(scan < *end) scan = copy_next(scan); } }; @@ -566,25 +561,17 @@ void factor_vm::collect_aging() { aging_collector collector(this); - cell scan = current_gc->newspace->here; - trace_roots(collector); trace_contexts(collector); trace_cards(collector); - - if(current_gc->collecting_gen >= last_code_heap_scan) - update_code_heap_roots(collector); - - collector.copy_reachable_objects(scan,¤t_gc->newspace->here); - + trace_code_heap_roots(collector); + collector.go(); update_dirty_code_blocks(); } -struct tenured_collector +struct tenured_collector : copying_collector { - factor_vm *myvm; - - explicit tenured_collector(factor_vm *myvm_) : myvm(myvm_) {} + explicit tenured_collector(factor_vm *myvm_) : copying_collector(myvm_) {} bool should_copy_p(object *untagged) { @@ -593,10 +580,10 @@ struct tenured_collector void copy_reachable_objects(cell scan, cell *end) { - while(scan < myvm->current_gc->newspace->here) + while(scan < *end) { myvm->mark_object_code_block(myvm->untag(scan),*this); - scan = myvm->copy_next(scan,*this); + scan = copy_next(scan); } } }; @@ -605,14 +592,9 @@ void factor_vm::collect_tenured(bool trace_contexts_) { tenured_collector collector(this); - cell scan = current_gc->newspace->here; - trace_roots(collector); - if(trace_contexts_) - trace_contexts(collector); - - collector.copy_reachable_objects(scan,¤t_gc->newspace->here); - + if(trace_contexts_) trace_contexts(collector); + collector.go(); free_unmarked_code_blocks(); } diff --git a/vm/data_gc.hpp b/vm/data_gc.hpp index 14825c054f..95c7249823 100755 --- a/vm/data_gc.hpp +++ b/vm/data_gc.hpp @@ -63,6 +63,22 @@ struct gc_state { } }; +template struct copying_collector { + factor_vm *myvm; + gc_state *current_gc; + cell scan; + + explicit copying_collector(factor_vm *myvm_); + Strategy &strategy(); + object *copy_untagged_object_impl(object *pointer, cell size); + cell copy_next(cell scan); + object *copy_object_impl(object *untagged); + object *resolve_forwarding(object *untagged); + cell copy_object(cell pointer); + bool should_copy_p(object *pointer); + void go(); +}; + VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *myvm); } diff --git a/vm/inline_cache.cpp b/vm/inline_cache.cpp index e278c0d461..1626af1965 100755 --- a/vm/inline_cache.cpp +++ b/vm/inline_cache.cpp @@ -6,6 +6,10 @@ namespace factor void factor_vm::init_inline_caching(int max_size) { max_pic_size = max_size; + cold_call_to_ic_transitions = 0; + ic_to_pic_transitions = 0; + pic_to_mega_transitions = 0; + for(int i = 0; i < 4; i++) pic_counts[i] = 0; } void factor_vm::deallocate_inline_cache(cell return_address) diff --git a/vm/vm.cpp b/vm/vm.cpp index 45cf05075c..15df6cc18a 100755 --- a/vm/vm.cpp +++ b/vm/vm.cpp @@ -3,6 +3,13 @@ namespace factor { -factor_vm::factor_vm() { } +factor_vm::factor_vm() : + profiling_p(false), + secure_gc(false), + gc_off(false), + current_gc(NULL), + fep_disabled(false), + full_output(false) + { } } diff --git a/vm/vm.hpp b/vm/vm.hpp index c7176dd6ed..ad0931112e 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -243,13 +243,6 @@ struct factor_vm cell last_code_heap_scan; void init_data_gc(); - object *copy_untagged_object_impl(object *pointer, cell size); - object *copy_object_impl(object *untagged); - object *resolve_forwarding(object *untagged); - template Type *copy_untagged_object(Type *untagged); - template object *resolve_forwarding(object *untagged, Strategy &strategy); - template Type *copy_untagged_object(Type *untagged, Strategy &strategy); - template cell copy_object(cell pointer, Strategy &strategy); template void trace_handle(cell *handle, Strategy &strategy); template void trace_card(card *ptr, cell gen, cell here, Strategy &strategy); template void trace_card_deck(card_deck *deck, cell gen, card mask, card unmask, Strategy &strategy); @@ -265,8 +258,6 @@ struct factor_vm template void trace_code_heap_roots(Strategy &strategy); template void mark_code_block(code_block *compiled, Strategy &strategy); template void mark_object_code_block(object *object, Strategy &strategy); - template cell copy_next(cell scan, Strategy &strategy); - template void update_code_heap_roots(Strategy &strategy); void free_unmarked_code_blocks(); void update_dirty_code_blocks(); void begin_gc(cell requested_bytes);