From 21f55ab1a3beb35232d7623d6084b67f31fb087a Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 8 Oct 2009 23:10:32 -0500 Subject: [PATCH] vm: more efficient code heap remembered set --- vm/aging_collector.cpp | 5 +++-- vm/code_heap.cpp | 8 ++++---- vm/code_heap.hpp | 12 +++++------- vm/collector.hpp | 2 ++ vm/copying_collector.hpp | 23 ++++++----------------- vm/full_collector.cpp | 4 +--- vm/gc.cpp | 29 ++++++----------------------- vm/nursery_collector.cpp | 6 +++--- vm/to_tenured_collector.cpp | 8 +++++--- vm/vm.hpp | 2 +- 10 files changed, 36 insertions(+), 63 deletions(-) diff --git a/vm/aging_collector.cpp b/vm/aging_collector.cpp index 287e5c306c..9b69cd2977 100644 --- a/vm/aging_collector.cpp +++ b/vm/aging_collector.cpp @@ -17,11 +17,12 @@ void factor_vm::collect_aging() collector.trace_roots(); collector.trace_contexts(); collector.trace_cards(data->tenured); - collector.trace_code_heap_roots(); + collector.trace_code_heap_roots(&code->points_to_aging); collector.cheneys_algorithm(); - update_dirty_code_blocks(); + update_dirty_code_blocks(&code->points_to_aging); nursery.here = nursery.start; + code->points_to_nursery.clear(); } } diff --git a/vm/code_heap.cpp b/vm/code_heap.cpp index 6a5391a589..0cb2cae50f 100755 --- a/vm/code_heap.cpp +++ b/vm/code_heap.cpp @@ -7,8 +7,8 @@ code_heap::code_heap(bool secure_gc, cell size) : heap(secure_gc,size) {} void code_heap::write_barrier(code_block *compiled) { - remembered_set[compiled] = nursery_gen; - youngest_referenced_generation = nursery_gen; + points_to_nursery.insert(compiled); + points_to_aging.insert(compiled); } bool code_heap::needs_fixup_p(code_block *compiled) @@ -18,7 +18,8 @@ bool code_heap::needs_fixup_p(code_block *compiled) void code_heap::code_heap_free(code_block *compiled) { - remembered_set.erase(compiled); + points_to_nursery.erase(compiled); + points_to_aging.erase(compiled); needs_fixup.erase(compiled); heap_free(compiled); } @@ -27,7 +28,6 @@ void code_heap::code_heap_free(code_block *compiled) void factor_vm::init_code_heap(cell size) { code = new code_heap(secure_gc,size); - code->youngest_referenced_generation = nursery_gen; } bool factor_vm::in_code_heap_p(cell ptr) diff --git a/vm/code_heap.hpp b/vm/code_heap.hpp index feea7da307..589336fad5 100755 --- a/vm/code_heap.hpp +++ b/vm/code_heap.hpp @@ -4,14 +4,12 @@ namespace factor struct code_heap : heap { /* Set of blocks which need full relocation. */ unordered_set needs_fixup; - - /* Maps code blocks to the youngest generation containing - one of their literals. If this is tenured (0), the code block - is not part of the remembered set. */ - unordered_map remembered_set; - /* Minimum value in the above map. */ - cell youngest_referenced_generation; + /* Code blocks which may reference objects in the nursery */ + std::set points_to_nursery; + + /* Code blocks which may reference objects in aging space or the nursery */ + std::set points_to_aging; explicit code_heap(bool secure_gc, cell size); void write_barrier(code_block *compiled); diff --git a/vm/collector.hpp b/vm/collector.hpp index 06134dd9b7..bfe113c706 100644 --- a/vm/collector.hpp +++ b/vm/collector.hpp @@ -4,6 +4,7 @@ namespace factor template struct collector { factor_vm *myvm; data_heap *data; + code_heap *code; gc_state *current_gc; TargetGeneration *target; Policy policy; @@ -11,6 +12,7 @@ template struct collector { explicit collector(factor_vm *myvm_, TargetGeneration *target_, Policy policy_) : myvm(myvm_), data(myvm_->data), + code(myvm_->code), current_gc(myvm_->current_gc), target(target_), policy(policy_) {} diff --git a/vm/copying_collector.hpp b/vm/copying_collector.hpp index bb17f2e70d..11465a0de7 100644 --- a/vm/copying_collector.hpp +++ b/vm/copying_collector.hpp @@ -130,24 +130,13 @@ struct copying_collector : collector { this->trace_handle(&compiled->literals); this->trace_handle(&compiled->relocation); } - - /* Trace literals referenced from all code blocks. Only for aging and nursery collections */ - void trace_code_heap_roots() + + void trace_code_heap_roots(std::set *remembered_set) { - if(this->current_gc->collecting_gen >= this->myvm->code->youngest_referenced_generation) - { - unordered_map &remembered_set = this->myvm->code->remembered_set; - unordered_map::const_iterator iter = remembered_set.begin(); - unordered_map::const_iterator end = remembered_set.end(); - - for(; iter != end; iter++) - { - if(this->current_gc->collecting_gen >= iter->second) - trace_literal_references(iter->first); - } - - this->myvm->gc_stats.code_heap_scans++; - } + std::set::const_iterator iter = remembered_set->begin(); + std::set::const_iterator end = remembered_set->end(); + + for(; iter != end; iter++) trace_literal_references(*iter); } void cheneys_algorithm() diff --git a/vm/full_collector.cpp b/vm/full_collector.cpp index c54dd6b72e..15a76590f1 100644 --- a/vm/full_collector.cpp +++ b/vm/full_collector.cpp @@ -78,9 +78,7 @@ void full_collector::trace_literal_references(code_block *compiled) collections */ void full_collector::mark_code_block(code_block *compiled) { - myvm->check_code_address((cell)compiled); - - this->myvm->code->mark_block(compiled); + this->code->mark_block(compiled); trace_literal_references(compiled); } diff --git a/vm/gc.cpp b/vm/gc.cpp index be31636eb7..795b75f149 100755 --- a/vm/gc.cpp +++ b/vm/gc.cpp @@ -29,34 +29,17 @@ void factor_vm::free_unmarked_code_blocks() { literal_and_word_reference_updater updater(this); code->free_unmarked(updater); - code->remembered_set.clear(); - code->youngest_referenced_generation = tenured_gen; + code->points_to_nursery.clear(); + code->points_to_aging.clear(); } -void factor_vm::update_dirty_code_blocks() +void factor_vm::update_dirty_code_blocks(std::set *remembered_set) { /* The youngest generation that any code block can now reference */ - cell gen; + std::set::iterator iter = remembered_set->begin(); + std::set::iterator end = remembered_set->end(); - if(current_gc->collecting_accumulation_gen_p()) - gen = current_gc->collecting_gen; - else - gen = current_gc->collecting_gen + 1; - - unordered_map::iterator iter = code->remembered_set.begin(); - unordered_map::iterator end = code->remembered_set.end(); - - for(; iter != end; iter++) - { - if(current_gc->collecting_gen >= iter->second) - { - check_code_address((cell)iter->first); - update_literal_references(iter->first); - iter->second = gen; - } - } - - code->youngest_referenced_generation = gen; + for(; iter != end; iter++) update_literal_references(*iter); } void factor_vm::record_gc_stats() diff --git a/vm/nursery_collector.cpp b/vm/nursery_collector.cpp index f5dc386053..cff753e687 100644 --- a/vm/nursery_collector.cpp +++ b/vm/nursery_collector.cpp @@ -15,12 +15,12 @@ void factor_vm::collect_nursery() collector.trace_contexts(); collector.trace_cards(data->tenured); collector.trace_cards(data->aging); - collector.trace_code_heap_roots(); + collector.trace_code_heap_roots(&code->points_to_nursery); collector.cheneys_algorithm(); - - update_dirty_code_blocks(); + update_dirty_code_blocks(&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 a0341ec93d..1242acd897 100644 --- a/vm/to_tenured_collector.cpp +++ b/vm/to_tenured_collector.cpp @@ -14,12 +14,14 @@ void factor_vm::collect_to_tenured() collector.trace_roots(); collector.trace_contexts(); collector.trace_cards(data->tenured); - collector.trace_code_heap_roots(); + collector.trace_code_heap_roots(&code->points_to_aging); collector.cheneys_algorithm(); - update_dirty_code_blocks(); + update_dirty_code_blocks(&code->points_to_aging); - reset_generation(data->aging); nursery.here = nursery.start; + reset_generation(data->aging); + code->points_to_nursery.clear(); + code->points_to_aging.clear(); } } diff --git a/vm/vm.hpp b/vm/vm.hpp index 80dd67c76d..2957714d42 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -264,7 +264,7 @@ struct factor_vm // gc void free_unmarked_code_blocks(); - void update_dirty_code_blocks(); + void update_dirty_code_blocks(std::set *remembered_set); void collect_nursery(); void collect_aging(); void collect_to_tenured();