}
}
-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)
{
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
#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;
+ }
}
};
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();
}
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;
}
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) {}
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)
{
- 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());
+ instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
- op.store_value(value);
+ array *literals = (parent->to_boolean(compiled->literals)
+ ? untag<array>(compiled->literals) : NULL);
+
+ 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)
{
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);
}
};
/* 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);
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)
}
};
-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 */
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)
}
/* 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);