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_roots();
collector.trace_contexts(); collector.trace_contexts();
collector.trace_cards(data->tenured); collector.trace_cards(data->tenured);
collector.trace_code_heap_roots(); collector.trace_code_heap_roots(&code->points_to_aging);
collector.cheneys_algorithm(); collector.cheneys_algorithm();
update_dirty_code_blocks(); update_dirty_code_blocks(&code->points_to_aging);
nursery.here = nursery.start; 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) void code_heap::write_barrier(code_block *compiled)
{ {
remembered_set[compiled] = nursery_gen; points_to_nursery.insert(compiled);
youngest_referenced_generation = nursery_gen; points_to_aging.insert(compiled);
} }
bool code_heap::needs_fixup_p(code_block *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) 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); needs_fixup.erase(compiled);
heap_free(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) void factor_vm::init_code_heap(cell size)
{ {
code = new code_heap(secure_gc,size); code = new code_heap(secure_gc,size);
code->youngest_referenced_generation = nursery_gen;
} }
bool factor_vm::in_code_heap_p(cell ptr) bool factor_vm::in_code_heap_p(cell ptr)

View File

@ -5,13 +5,11 @@ struct code_heap : heap {
/* Set of blocks which need full relocation. */ /* Set of blocks which need full relocation. */
unordered_set<code_block *> needs_fixup; unordered_set<code_block *> needs_fixup;
/* Maps code blocks to the youngest generation containing /* Code blocks which may reference objects in the nursery */
one of their literals. If this is tenured (0), the code block std::set<code_block *> points_to_nursery;
is not part of the remembered set. */
unordered_map<code_block *, cell> remembered_set;
/* Minimum value in the above map. */ /* Code blocks which may reference objects in aging space or the nursery */
cell youngest_referenced_generation; std::set<code_block *> points_to_aging;
explicit code_heap(bool secure_gc, cell size); explicit code_heap(bool secure_gc, cell size);
void write_barrier(code_block *compiled); void write_barrier(code_block *compiled);

View File

@ -4,6 +4,7 @@ namespace factor
template<typename TargetGeneration, typename Policy> struct collector { template<typename TargetGeneration, typename Policy> struct collector {
factor_vm *myvm; factor_vm *myvm;
data_heap *data; data_heap *data;
code_heap *code;
gc_state *current_gc; gc_state *current_gc;
TargetGeneration *target; TargetGeneration *target;
Policy policy; Policy policy;
@ -11,6 +12,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
explicit collector(factor_vm *myvm_, TargetGeneration *target_, Policy policy_) : explicit collector(factor_vm *myvm_, TargetGeneration *target_, Policy policy_) :
myvm(myvm_), myvm(myvm_),
data(myvm_->data), data(myvm_->data),
code(myvm_->code),
current_gc(myvm_->current_gc), current_gc(myvm_->current_gc),
target(target_), target(target_),
policy(policy_) {} policy(policy_) {}

View File

@ -131,23 +131,12 @@ struct copying_collector : collector<TargetGeneration,Policy> {
this->trace_handle(&compiled->relocation); this->trace_handle(&compiled->relocation);
} }
/* Trace literals referenced from all code blocks. Only for aging and nursery collections */ void trace_code_heap_roots(std::set<code_block *> *remembered_set)
void trace_code_heap_roots()
{ {
if(this->current_gc->collecting_gen >= this->myvm->code->youngest_referenced_generation) std::set<code_block *>::const_iterator iter = remembered_set->begin();
{ std::set<code_block *>::const_iterator end = remembered_set->end();
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++) for(; iter != end; iter++) trace_literal_references(*iter);
{
if(this->current_gc->collecting_gen >= iter->second)
trace_literal_references(iter->first);
}
this->myvm->gc_stats.code_heap_scans++;
}
} }
void cheneys_algorithm() void cheneys_algorithm()

View File

@ -78,9 +78,7 @@ void full_collector::trace_literal_references(code_block *compiled)
collections */ collections */
void full_collector::mark_code_block(code_block *compiled) void full_collector::mark_code_block(code_block *compiled)
{ {
myvm->check_code_address((cell)compiled); this->code->mark_block(compiled);
this->myvm->code->mark_block(compiled);
trace_literal_references(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); literal_and_word_reference_updater updater(this);
code->free_unmarked(updater); code->free_unmarked(updater);
code->remembered_set.clear(); code->points_to_nursery.clear();
code->youngest_referenced_generation = tenured_gen; 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 */ /* 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()) for(; iter != end; iter++) update_literal_references(*iter);
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;
} }
void factor_vm::record_gc_stats() void factor_vm::record_gc_stats()

View File

@ -15,12 +15,12 @@ void factor_vm::collect_nursery()
collector.trace_contexts(); collector.trace_contexts();
collector.trace_cards(data->tenured); collector.trace_cards(data->tenured);
collector.trace_cards(data->aging); collector.trace_cards(data->aging);
collector.trace_code_heap_roots(); collector.trace_code_heap_roots(&code->points_to_nursery);
collector.cheneys_algorithm(); collector.cheneys_algorithm();
update_dirty_code_blocks(&code->points_to_nursery);
update_dirty_code_blocks();
nursery.here = nursery.start; 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_roots();
collector.trace_contexts(); collector.trace_contexts();
collector.trace_cards(data->tenured); collector.trace_cards(data->tenured);
collector.trace_code_heap_roots(); collector.trace_code_heap_roots(&code->points_to_aging);
collector.cheneys_algorithm(); collector.cheneys_algorithm();
update_dirty_code_blocks(); update_dirty_code_blocks(&code->points_to_aging);
reset_generation(data->aging);
nursery.here = nursery.start; 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 // gc
void free_unmarked_code_blocks(); 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_nursery();
void collect_aging(); void collect_aging();
void collect_to_tenured(); void collect_to_tenured();