diff --git a/vm/aging_collector.cpp b/vm/aging_collector.cpp index 9a856374f6..7437273649 100644 --- a/vm/aging_collector.cpp +++ b/vm/aging_collector.cpp @@ -38,7 +38,7 @@ void factor_vm::collect_aging() collector.trace_contexts(); collector.trace_code_heap_roots(&code->points_to_aging); collector.cheneys_algorithm(); - update_dirty_code_blocks(&code->points_to_aging); + update_code_heap_for_minor_gc(&code->points_to_aging); nursery.here = nursery.start; code->points_to_nursery.clear(); diff --git a/vm/code_block.cpp b/vm/code_block.cpp index 7214aa235e..bb05fe8933 100755 --- a/vm/code_block.cpp +++ b/vm/code_block.cpp @@ -356,6 +356,41 @@ void factor_vm::update_word_references(code_block *compiled) } } +/* This runs after a full collection */ +struct literal_and_word_references_updater { + factor_vm *myvm; + + explicit literal_and_word_references_updater(factor_vm *myvm_) : myvm(myvm_) {} + + void operator()(relocation_entry rel, cell index, code_block *compiled) + { + relocation_type type = myvm->relocation_type_of(rel); + switch(type) + { + case RT_IMMEDIATE: + case RT_XT: + case RT_XT_PIC: + case RT_XT_PIC_TAIL: + myvm->relocate_code_block_step(rel,index,compiled); + break; + default: + break; + } + } +}; + +void factor_vm::update_code_block_for_full_gc(code_block *compiled) +{ + if(code->needs_fixup_p(compiled)) + relocate_code_block(compiled); + else + { + literal_and_word_references_updater updater(this); + iterate_relocations(compiled,updater); + flush_icache_for(compiled); + } +} + void factor_vm::check_code_address(cell address) { #ifdef FACTOR_DEBUG diff --git a/vm/full_collector.cpp b/vm/full_collector.cpp index db3d1dcc53..64d83df3f5 100644 --- a/vm/full_collector.cpp +++ b/vm/full_collector.cpp @@ -97,10 +97,12 @@ void full_collector::cheneys_algorithm() } } -struct full_updater { +/* After growing the heap, we have to perform a full relocation to update +references to card and deck arrays. */ +struct after_growing_heap_updater { factor_vm *myvm; - full_updater(factor_vm *myvm_) : myvm(myvm_) {} + after_growing_heap_updater(factor_vm *myvm_) : myvm(myvm_) {} void operator()(heap_block *block) { @@ -108,29 +110,29 @@ struct full_updater { } }; -struct literal_and_word_reference_updater { +/* After a full GC that did not grow the heap, we have to update references +to literals and other words. */ +struct after_full_updater { factor_vm *myvm; - literal_and_word_reference_updater(factor_vm *myvm_) : myvm(myvm_) {} + after_full_updater(factor_vm *myvm_) : myvm(myvm_) {} void operator()(heap_block *block) { - code_block *compiled = (code_block *)block; - myvm->update_literal_references(compiled); - myvm->update_word_references(compiled); + myvm->update_code_block_for_full_gc((code_block *)block); } }; -void factor_vm::free_unmarked_code_blocks(bool growing_data_heap) +void factor_vm::update_code_heap_for_full_gc(bool growing_data_heap) { if(growing_data_heap) { - full_updater updater(this); + after_growing_heap_updater updater(this); code->free_unmarked(updater); } else { - literal_and_word_reference_updater updater(this); + after_full_updater updater(this); code->free_unmarked(updater); } @@ -160,7 +162,7 @@ void factor_vm::collect_growing_heap(cell requested_bytes, bool trace_contexts_p data_heap *old = data; set_data_heap(data->grow(requested_bytes)); collect_full_impl(trace_contexts_p); - free_unmarked_code_blocks(true); + update_code_heap_for_full_gc(true); delete old; } @@ -169,7 +171,7 @@ void factor_vm::collect_full(bool trace_contexts_p) std::swap(data->tenured,data->tenured_semispace); reset_generation(data->tenured); collect_full_impl(trace_contexts_p); - free_unmarked_code_blocks(false); + update_code_heap_for_full_gc(false); } } diff --git a/vm/gc.cpp b/vm/gc.cpp index c4e8d25e20..a087a49b1c 100755 --- a/vm/gc.cpp +++ b/vm/gc.cpp @@ -7,7 +7,7 @@ gc_state::gc_state(gc_op op_) : op(op_), start_time(current_micros()) {} gc_state::~gc_state() {} -void factor_vm::update_dirty_code_blocks(std::set *remembered_set) +void factor_vm::update_code_heap_for_minor_gc(std::set *remembered_set) { /* The youngest generation that any code block can now reference */ std::set::const_iterator iter = remembered_set->begin(); diff --git a/vm/nursery_collector.cpp b/vm/nursery_collector.cpp index 85f04dbb2d..0cb231417e 100644 --- a/vm/nursery_collector.cpp +++ b/vm/nursery_collector.cpp @@ -24,7 +24,7 @@ void factor_vm::collect_nursery() simple_unmarker(card_mark_mask)); collector.trace_code_heap_roots(&code->points_to_nursery); collector.cheneys_algorithm(); - update_dirty_code_blocks(&code->points_to_nursery); + update_code_heap_for_minor_gc(&code->points_to_nursery); nursery.here = nursery.start; code->points_to_nursery.clear(); diff --git a/vm/to_tenured_collector.cpp b/vm/to_tenured_collector.cpp index 6689411684..68038703c5 100644 --- a/vm/to_tenured_collector.cpp +++ b/vm/to_tenured_collector.cpp @@ -21,7 +21,7 @@ void factor_vm::collect_to_tenured() dummy_unmarker()); collector.trace_code_heap_roots(&code->points_to_aging); collector.cheneys_algorithm(); - update_dirty_code_blocks(&code->points_to_aging); + update_code_heap_for_minor_gc(&code->points_to_aging); nursery.here = nursery.start; reset_generation(data->aging); diff --git a/vm/vm.hpp b/vm/vm.hpp index ce2acfab45..e2fc589cd2 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -234,11 +234,11 @@ struct factor_vm } // gc - void update_dirty_code_blocks(std::set *remembered_set); + void update_code_heap_for_minor_gc(std::set *remembered_set); void collect_nursery(); void collect_aging(); void collect_to_tenured(); - void free_unmarked_code_blocks(bool growing_data_heap); + void update_code_heap_for_full_gc(bool growing_data_heap); void collect_full_impl(bool trace_contexts_p); void collect_growing_heap(cell requested_bytes, bool trace_contexts_p); void collect_full(bool trace_contexts_p); @@ -479,6 +479,7 @@ struct factor_vm void update_literal_references(code_block *compiled); void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled); void update_word_references(code_block *compiled); + void update_code_block_for_full_gc(code_block *compiled); void check_code_address(cell address); void relocate_code_block(code_block *compiled); void fixup_labels(array *labels, code_block *compiled);