vm: more efficient code heap remembered set

db4
Slava Pestov 2009-10-08 23:10:32 -05:00
parent c5979615b7
commit 21f55ab1a3
10 changed files with 36 additions and 63 deletions

View File

@ -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();
}
}

View File

@ -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)

View File

@ -4,14 +4,12 @@ namespace factor
struct code_heap : heap {
/* Set of blocks which need full relocation. */
unordered_set<code_block *> 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<code_block *, cell> remembered_set;
/* Minimum value in the above map. */
cell youngest_referenced_generation;
/* Code blocks which may reference objects in the nursery */
std::set<code_block *> points_to_nursery;
/* Code blocks which may reference objects in aging space or the nursery */
std::set<code_block *> points_to_aging;
explicit code_heap(bool secure_gc, cell size);
void write_barrier(code_block *compiled);

View File

@ -4,6 +4,7 @@ namespace factor
template<typename TargetGeneration, typename Policy> struct collector {
factor_vm *myvm;
data_heap *data;
code_heap *code;
gc_state *current_gc;
TargetGeneration *target;
Policy policy;
@ -11,6 +12,7 @@ template<typename TargetGeneration, typename Policy> 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_) {}

View File

@ -130,24 +130,13 @@ struct copying_collector : collector<TargetGeneration,Policy> {
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<code_block *> *remembered_set)
{
if(this->current_gc->collecting_gen >= this->myvm->code->youngest_referenced_generation)
{
unordered_map<code_block *,cell> &remembered_set = this->myvm->code->remembered_set;
unordered_map<code_block *,cell>::const_iterator iter = remembered_set.begin();
unordered_map<code_block *,cell>::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<code_block *>::const_iterator iter = remembered_set->begin();
std::set<code_block *>::const_iterator end = remembered_set->end();
for(; iter != end; iter++) trace_literal_references(*iter);
}
void cheneys_algorithm()

View File

@ -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);
}

View File

@ -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<code_block *> *remembered_set)
{
/* The youngest generation that any code block can now reference */
cell gen;
std::set<code_block *>::iterator iter = remembered_set->begin();
std::set<code_block *>::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<code_block *,cell>::iterator iter = code->remembered_set.begin();
unordered_map<code_block *,cell>::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()

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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<code_block *> *remembered_set);
void collect_nursery();
void collect_aging();
void collect_to_tenured();