vm: growing heap no longer uses relocate_code_block()

db4
Slava Pestov 2009-11-28 19:48:26 -06:00
parent 9a79a6253c
commit 260cc9e2ff
5 changed files with 138 additions and 104 deletions

View File

@ -8,12 +8,19 @@ template<typename Visitor> struct code_block_visitor {
explicit code_block_visitor(factor_vm *parent_, Visitor visitor_) :
parent(parent_), visitor(visitor_) {}
code_block *visit_code_block(code_block *compiled);
void visit_object_code_block(object *obj);
void visit_embedded_code_pointers(code_block *compiled);
void visit_context_code_blocks();
void visit_callback_code_blocks();
};
template<typename Visitor>
code_block *code_block_visitor<Visitor>::visit_code_block(code_block *compiled)
{
return visitor(compiled);
}
template<typename Visitor>
struct call_frame_code_block_visitor {
factor_vm *parent;

View File

@ -145,10 +145,10 @@ cell factor_vm::code_block_owner(code_block *compiled)
}
}
struct word_references_updater {
struct update_word_references_relocation_visitor {
factor_vm *parent;
word_references_updater(factor_vm *parent_) : parent(parent_) {}
explicit update_word_references_relocation_visitor(factor_vm *parent_) : parent(parent_) {}
void operator()(relocation_entry rel, cell index, code_block *compiled)
{
@ -200,57 +200,12 @@ void factor_vm::update_word_references(code_block *compiled)
code->code_heap_free(compiled);
else
{
word_references_updater updater(this);
iterate_relocations(compiled,updater);
update_word_references_relocation_visitor visitor(this);
iterate_relocations(compiled,visitor);
compiled->flush_icache();
}
}
cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block *compiled)
{
array *literals = (to_boolean(compiled->literals)
? untag<array>(compiled->literals) : NULL);
#define ARG array_nth(literals,index)
switch(rel.rel_type())
{
case RT_PRIMITIVE:
return compute_primitive_relocation(ARG);
case RT_DLSYM:
return compute_dlsym_relocation(literals,index);
case RT_IMMEDIATE:
return ARG;
case RT_XT:
return compute_xt_relocation(ARG);
case RT_XT_PIC:
return compute_xt_pic_relocation(ARG);
case RT_XT_PIC_TAIL:
return compute_xt_pic_tail_relocation(ARG);
case RT_HERE:
return compute_here_relocation(ARG,rel.rel_offset(),compiled);
case RT_THIS:
return (cell)compiled->xt();
case RT_CONTEXT:
return compute_context_relocation();
case RT_UNTAGGED:
return untag_fixnum(ARG);
case RT_MEGAMORPHIC_CACHE_HITS:
return (cell)&dispatch_stats.megamorphic_cache_hits;
case RT_VM:
return compute_vm_relocation(ARG);
case RT_CARDS_OFFSET:
return cards_offset;
case RT_DECKS_OFFSET:
return decks_offset;
default:
critical_error("Bad rel type",rel.rel_type());
return 0; /* Can't happen */
}
#undef ARG
}
void factor_vm::check_code_address(cell address)
{
#ifdef FACTOR_DEBUG
@ -258,15 +213,65 @@ void factor_vm::check_code_address(cell address)
#endif
}
struct code_block_relocator {
struct relocate_code_block_relocation_visitor {
factor_vm *parent;
explicit code_block_relocator(factor_vm *parent_) : parent(parent_) {}
explicit relocate_code_block_relocation_visitor(factor_vm *parent_) : parent(parent_) {}
void operator()(relocation_entry rel, cell index, code_block *compiled)
{
instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
op.store_value(parent->compute_relocation(rel,index,compiled));
array *literals = (parent->to_boolean(compiled->literals)
? untag<array>(compiled->literals) : NULL);
switch(rel.rel_type())
{
case RT_PRIMITIVE:
op.store_value(parent->compute_primitive_relocation(array_nth(literals,index)));
break;
case RT_DLSYM:
op.store_value(parent->compute_dlsym_relocation(literals,index));
break;
case RT_IMMEDIATE:
op.store_value(array_nth(literals,index));
break;
case RT_XT:
op.store_value(parent->compute_xt_relocation(array_nth(literals,index)));
break;
case RT_XT_PIC:
op.store_value(parent->compute_xt_pic_relocation(array_nth(literals,index)));
break;
case RT_XT_PIC_TAIL:
op.store_value(parent->compute_xt_pic_tail_relocation(array_nth(literals,index)));
break;
case RT_HERE:
op.store_value(parent->compute_here_relocation(array_nth(literals,index),rel.rel_offset(),compiled));
break;
case RT_THIS:
op.store_value((cell)compiled->xt());
break;
case RT_CONTEXT:
op.store_value(parent->compute_context_relocation());
break;
case RT_UNTAGGED:
op.store_value(untag_fixnum(array_nth(literals,index)));
break;
case RT_MEGAMORPHIC_CACHE_HITS:
op.store_value((cell)&parent->dispatch_stats.megamorphic_cache_hits);
break;
case RT_VM:
op.store_value(parent->compute_vm_relocation(array_nth(literals,index)));
break;
case RT_CARDS_OFFSET:
op.store_value(parent->cards_offset);
break;
case RT_DECKS_OFFSET:
op.store_value(parent->decks_offset);
break;
default:
critical_error("Bad rel type",rel.rel_type());
break;
}
}
};
@ -274,8 +279,8 @@ struct code_block_relocator {
void factor_vm::relocate_code_block(code_block *compiled)
{
code->needs_fixup.erase(compiled);
code_block_relocator relocator(this);
iterate_relocations(compiled,relocator);
relocate_code_block_relocation_visitor visitor(this);
iterate_relocations(compiled,visitor);
compiled->flush_icache();
}

View File

@ -9,10 +9,7 @@ void factor_vm::update_fixup_set_for_compaction(mark_bits<code_block> *forwardin
std::set<code_block *> new_needs_fixup;
for(; iter != end; iter++)
{
printf("a block needs fixup\n");
new_needs_fixup.insert(forwarding_map->forward_block(*iter));
}
code->needs_fixup = new_needs_fixup;
}
@ -69,18 +66,15 @@ struct compaction_sizer {
struct object_compaction_updater {
factor_vm *parent;
slot_visitor<forwarder<object> > slot_forwarder;
code_block_visitor<forwarder<code_block> > code_forwarder;
mark_bits<code_block> *code_forwarding_map;
mark_bits<object> *data_forwarding_map;
object_start_map *starts;
explicit object_compaction_updater(factor_vm *parent_,
slot_visitor<forwarder<object> > slot_forwarder_,
code_block_visitor<forwarder<code_block> > code_forwarder_,
mark_bits<object> *data_forwarding_map_) :
mark_bits<object> *data_forwarding_map_,
mark_bits<code_block> *code_forwarding_map_) :
parent(parent_),
slot_forwarder(slot_forwarder_),
code_forwarder(code_forwarder_),
code_forwarding_map(code_forwarding_map_),
data_forwarding_map(data_forwarding_map_),
starts(&parent->data->tenured->starts) {}
@ -94,44 +88,83 @@ struct object_compaction_updater {
memmove(new_address,old_address,size);
slot_visitor<forwarder<object> > slot_forwarder(parent,forwarder<object>(data_forwarding_map));
slot_forwarder.visit_slots(new_address,payload_start);
code_block_visitor<forwarder<code_block> > code_forwarder(parent,forwarder<code_block>(code_forwarding_map));
code_forwarder.visit_object_code_block(new_address);
starts->record_object_start_offset(new_address);
}
};
struct relative_address_updater {
template<typename SlotForwarder>
struct code_block_compaction_relocation_visitor {
factor_vm *parent;
code_block *old_address;
slot_visitor<SlotForwarder> slot_forwarder;
code_block_visitor<forwarder<code_block> > code_forwarder;
explicit relative_address_updater(factor_vm *parent_, code_block *old_address_) :
parent(parent_), old_address(old_address_) {}
explicit code_block_compaction_relocation_visitor(factor_vm *parent_,
code_block *old_address_,
slot_visitor<SlotForwarder> slot_forwarder_,
code_block_visitor<forwarder<code_block> > code_forwarder_) :
parent(parent_),
old_address(old_address_),
slot_forwarder(slot_forwarder_),
code_forwarder(code_forwarder_) {}
void operator()(relocation_entry rel, cell index, code_block *compiled)
{
relocation_type type = rel.rel_type();
instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
relocation_type type = rel.rel_type();
cell value;
if(type == RT_HERE || type == RT_THIS)
value = parent->compute_relocation(rel,index,compiled);
else
value = op.load_value(rel.rel_offset() + (cell)old_address->xt());
array *literals = (parent->to_boolean(compiled->literals)
? untag<array>(compiled->literals) : NULL);
op.store_value(value);
cell old_offset = rel.rel_offset() + (cell)old_address->xt();
switch(type)
{
case RT_IMMEDIATE:
op.store_value(slot_forwarder.visit_pointer(op.load_value(old_offset)));
break;
case RT_XT:
case RT_XT_PIC:
case RT_XT_PIC_TAIL:
op.store_code_block(code_forwarder.visit_code_block(op.load_code_block(old_offset)));
break;
case RT_HERE:
op.store_value(parent->compute_here_relocation(array_nth(literals,index),rel.rel_offset(),compiled));
break;
case RT_THIS:
op.store_value((cell)compiled->xt());
break;
case RT_CARDS_OFFSET:
op.store_value(parent->cards_offset);
break;
case RT_DECKS_OFFSET:
op.store_value(parent->decks_offset);
break;
default:
op.store_value(op.load_value(old_offset));
break;
}
}
};
template<typename SlotForwarder, typename CodeBlockForwarder>
template<typename SlotForwarder>
struct code_block_compaction_updater {
factor_vm *parent;
slot_visitor<forwarder<object> > slot_forwarder;
slot_visitor<SlotForwarder> slot_forwarder;
code_block_visitor<forwarder<code_block> > code_forwarder;
explicit code_block_compaction_updater(factor_vm *parent_,
slot_visitor<forwarder<object> > slot_forwarder_,
slot_visitor<SlotForwarder> slot_forwarder_,
code_block_visitor<forwarder<code_block> > code_forwarder_) :
parent(parent_), slot_forwarder(slot_forwarder_), code_forwarder(code_forwarder_) {}
parent(parent_),
slot_forwarder(slot_forwarder_),
code_forwarder(code_forwarder_) {}
void operator()(code_block *old_address, code_block *new_address, cell size)
{
@ -139,11 +172,8 @@ struct code_block_compaction_updater {
slot_forwarder.visit_code_block_objects(new_address);
relative_address_updater updater(parent,old_address);
parent->iterate_relocations(new_address,updater);
slot_forwarder.visit_embedded_literals(new_address);
code_forwarder.visit_embedded_code_pointers(new_address);
code_block_compaction_relocation_visitor<SlotForwarder> visitor(parent,old_address,slot_forwarder,code_forwarder);
parent->iterate_relocations(new_address,visitor);
}
};
@ -170,13 +200,13 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p)
/* Slide everything in tenured space up, and update data and code heap
pointers inside objects. */
object_compaction_updater object_updater(this,slot_forwarder,code_forwarder,data_forwarding_map);
object_compaction_updater object_updater(this,data_forwarding_map,code_forwarding_map);
compaction_sizer object_sizer(data_forwarding_map);
tenured->compact(object_updater,object_sizer);
/* Slide everything in the code heap up, and update data and code heap
pointers inside code blocks. */
code_block_compaction_updater<slot_visitor<forwarder<object> >, code_block_visitor<forwarder<code_block> > > code_block_updater(this,slot_forwarder,code_forwarder);
code_block_compaction_updater<forwarder<object> > code_block_updater(this,slot_forwarder,code_forwarder);
standard_sizer<code_block> code_block_sizer;
code->allocator->compact(code_block_updater,code_block_sizer);
@ -193,10 +223,10 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p)
current_gc->event->ended_compaction();
}
struct object_code_block_updater {
struct object_grow_heap_updater {
code_block_visitor<forwarder<code_block> > code_forwarder;
explicit object_code_block_updater(code_block_visitor<forwarder<code_block> > code_forwarder_) :
explicit object_grow_heap_updater(code_block_visitor<forwarder<code_block> > code_forwarder_) :
code_forwarder(code_forwarder_) {}
void operator()(object *obj)
@ -205,16 +235,8 @@ struct object_code_block_updater {
}
};
struct code_block_grow_heap_updater {
factor_vm *parent;
explicit code_block_grow_heap_updater(factor_vm *parent_) : parent(parent_) {}
void operator()(code_block *old_address, code_block *new_address, cell size)
{
memmove(new_address,old_address,size);
parent->relocate_code_block(new_address);
}
struct dummy_slot_forwarder {
object *operator()(object *obj) { return obj; }
};
/* Compact just the code heap, after growing the data heap */
@ -226,6 +248,7 @@ void factor_vm::collect_compact_code_impl(bool trace_contexts_p)
update_fixup_set_for_compaction(code_forwarding_map);
slot_visitor<dummy_slot_forwarder> slot_forwarder(this,dummy_slot_forwarder());
code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(code_forwarding_map));
if(trace_contexts_p)
@ -235,12 +258,12 @@ void factor_vm::collect_compact_code_impl(bool trace_contexts_p)
}
/* Update code heap references in data heap */
object_code_block_updater updater(code_forwarder);
object_grow_heap_updater updater(code_forwarder);
each_object(updater);
/* Slide everything in the code heap up, and update code heap
pointers inside code blocks. */
code_block_grow_heap_updater code_block_updater(this);
code_block_compaction_updater<dummy_slot_forwarder> code_block_updater(this,slot_forwarder,code_forwarder);
standard_sizer<code_block> code_block_sizer;
code->allocator->compact(code_block_updater,code_block_sizer);

View File

@ -163,13 +163,13 @@ void factor_vm::fixup_data(cell data_offset, cell code_offset)
data->tenured->iterate(fixupper,sizer);
}
struct code_block_updater {
struct code_block_fixup_relocation_visitor {
factor_vm *parent;
cell code_offset;
slot_visitor<data_fixupper> data_visitor;
code_fixupper code_visitor;
code_block_updater(factor_vm *parent_, cell data_offset_, cell code_offset_) :
code_block_fixup_relocation_visitor(factor_vm *parent_, cell data_offset_, cell code_offset_) :
parent(parent_),
code_offset(code_offset_),
data_visitor(slot_visitor<data_fixupper>(parent_,data_fixupper(data_offset_))),
@ -247,8 +247,8 @@ struct code_block_fixupper {
slot_visitor<data_fixupper> data_visitor(parent,data_fixupper(data_offset));
data_visitor.visit_code_block_objects(compiled);
code_block_updater updater(parent,data_offset,code_offset);
parent->iterate_relocations(compiled,updater);
code_block_fixup_relocation_visitor code_visitor(parent,data_offset,code_offset);
parent->iterate_relocations(compiled,code_visitor);
}
};

View File

@ -531,7 +531,6 @@ struct factor_vm
}
void update_word_references(code_block *compiled);
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
void check_code_address(cell address);
void relocate_code_block(code_block *compiled);
void fixup_labels(array *labels, code_block *compiled);