vm: more efficient code heap remembered set
parent
c5979615b7
commit
21f55ab1a3
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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_) {}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
vm/gc.cpp
29
vm/gc.cpp
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue