vm: don't flush instruction cache twice per code block on a major GC on PowerPC

db4
Slava Pestov 2009-10-15 22:31:41 -05:00
parent f212549a5f
commit 70dcecf61a
7 changed files with 56 additions and 18 deletions

View File

@ -38,7 +38,7 @@ void factor_vm::collect_aging()
collector.trace_contexts(); collector.trace_contexts();
collector.trace_code_heap_roots(&code->points_to_aging); collector.trace_code_heap_roots(&code->points_to_aging);
collector.cheneys_algorithm(); 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; nursery.here = nursery.start;
code->points_to_nursery.clear(); code->points_to_nursery.clear();

View File

@ -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) void factor_vm::check_code_address(cell address)
{ {
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG

View File

@ -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; factor_vm *myvm;
full_updater(factor_vm *myvm_) : myvm(myvm_) {} after_growing_heap_updater(factor_vm *myvm_) : myvm(myvm_) {}
void operator()(heap_block *block) 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; 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) void operator()(heap_block *block)
{ {
code_block *compiled = (code_block *)block; myvm->update_code_block_for_full_gc((code_block *)block);
myvm->update_literal_references(compiled);
myvm->update_word_references(compiled);
} }
}; };
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) if(growing_data_heap)
{ {
full_updater updater(this); after_growing_heap_updater updater(this);
code->free_unmarked(updater); code->free_unmarked(updater);
} }
else else
{ {
literal_and_word_reference_updater updater(this); after_full_updater updater(this);
code->free_unmarked(updater); 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; data_heap *old = data;
set_data_heap(data->grow(requested_bytes)); set_data_heap(data->grow(requested_bytes));
collect_full_impl(trace_contexts_p); collect_full_impl(trace_contexts_p);
free_unmarked_code_blocks(true); update_code_heap_for_full_gc(true);
delete old; delete old;
} }
@ -169,7 +171,7 @@ void factor_vm::collect_full(bool trace_contexts_p)
std::swap(data->tenured,data->tenured_semispace); std::swap(data->tenured,data->tenured_semispace);
reset_generation(data->tenured); reset_generation(data->tenured);
collect_full_impl(trace_contexts_p); collect_full_impl(trace_contexts_p);
free_unmarked_code_blocks(false); update_code_heap_for_full_gc(false);
} }
} }

View File

@ -7,7 +7,7 @@ gc_state::gc_state(gc_op op_) : op(op_), start_time(current_micros()) {}
gc_state::~gc_state() {} gc_state::~gc_state() {}
void factor_vm::update_dirty_code_blocks(std::set<code_block *> *remembered_set) void factor_vm::update_code_heap_for_minor_gc(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 */
std::set<code_block *>::const_iterator iter = remembered_set->begin(); std::set<code_block *>::const_iterator iter = remembered_set->begin();

View File

@ -24,7 +24,7 @@ void factor_vm::collect_nursery()
simple_unmarker(card_mark_mask)); simple_unmarker(card_mark_mask));
collector.trace_code_heap_roots(&code->points_to_nursery); collector.trace_code_heap_roots(&code->points_to_nursery);
collector.cheneys_algorithm(); 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; nursery.here = nursery.start;
code->points_to_nursery.clear(); code->points_to_nursery.clear();

View File

@ -21,7 +21,7 @@ void factor_vm::collect_to_tenured()
dummy_unmarker()); dummy_unmarker());
collector.trace_code_heap_roots(&code->points_to_aging); collector.trace_code_heap_roots(&code->points_to_aging);
collector.cheneys_algorithm(); 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; nursery.here = nursery.start;
reset_generation(data->aging); reset_generation(data->aging);

View File

@ -234,11 +234,11 @@ struct factor_vm
} }
// gc // gc
void update_dirty_code_blocks(std::set<code_block *> *remembered_set); void update_code_heap_for_minor_gc(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();
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_full_impl(bool trace_contexts_p);
void collect_growing_heap(cell requested_bytes, bool trace_contexts_p); void collect_growing_heap(cell requested_bytes, bool trace_contexts_p);
void collect_full(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 update_literal_references(code_block *compiled);
void relocate_code_block_step(relocation_entry rel, cell index, 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_word_references(code_block *compiled);
void update_code_block_for_full_gc(code_block *compiled);
void check_code_address(cell address); void check_code_address(cell address);
void relocate_code_block(code_block *compiled); void relocate_code_block(code_block *compiled);
void fixup_labels(array *labels, code_block *compiled); void fixup_labels(array *labels, code_block *compiled);