}
void callback_heap::store_callback_operand(code_block* stub, cell index) {
- parent->store_external_address(callback_operand(stub, index));
+ instruction_operand op = callback_operand(stub, index);
+ op.store_value(parent->compute_external_address(op));
}
void callback_heap::store_callback_operand(code_block* stub, cell index,
return ext_addr;
}
-void factor_vm::store_external_address(instruction_operand op) {
- op.store_value(compute_external_address(op));
-}
-
cell factor_vm::compute_here_address(cell arg, cell offset,
code_block* compiled) {
fixnum n = untag_fixnum(arg);
if (n >= 0)
return compiled->entry_point() + offset + n;
- else
- return compiled->entry_point() - n;
+ return compiled->entry_point() - n;
}
struct initial_code_block_visitor {
return array_nth(untag<array>(literals), literal_index++);
}
- void operator()(instruction_operand op) {
+ fixnum compute_operand_value(instruction_operand op) {
switch (op.rel_type()) {
case RT_LITERAL:
- op.store_value(next_literal());
- break;
+ return next_literal();
case RT_ENTRY_POINT:
- op.store_value(parent->compute_entry_point_address(next_literal()));
- break;
+ return parent->compute_entry_point_address(next_literal());
case RT_ENTRY_POINT_PIC:
- op.store_value(parent->compute_entry_point_pic_address(next_literal()));
- break;
+ return parent->compute_entry_point_pic_address(next_literal());
case RT_ENTRY_POINT_PIC_TAIL:
- op.store_value(
- parent->compute_entry_point_pic_tail_address(next_literal()));
- break;
+ return parent->compute_entry_point_pic_tail_address(next_literal());
case RT_HERE:
- op.store_value(parent->compute_here_address(
- next_literal(), op.rel_offset(), op.compiled));
- break;
+ return parent->compute_here_address(
+ next_literal(), op.rel_offset(), op.compiled);
case RT_UNTAGGED:
- op.store_value(untag_fixnum(next_literal()));
- break;
+ return untag_fixnum(next_literal());
default:
- parent->store_external_address(op);
- break;
+ return parent->compute_external_address(op);
}
}
+
+ void operator()(instruction_operand op) {
+ op.store_value(compute_operand_value(op));
+ }
};
/* Perform all fixups on a code block */
};
template <typename Fixup>
-void update_relocation(factor_vm* parent,
- cell old_entry_point,
- Fixup fixup,
- instruction_operand op) {
+fixnum compute_operand_value(factor_vm* parent,
+ cell old_entry_point,
+ Fixup fixup,
+ instruction_operand op) {
cell old_offset = op.rel_offset() + old_entry_point;
-
switch (op.rel_type()) {
case RT_LITERAL: {
cell value = op.load_value(old_offset);
if (immediate_p(value))
- op.store_value(value);
- else
- op.store_value(
- RETAG(fixup.fixup_data(untag<object>(value)), TAG(value)));
- break;
+ return value;
+ return RETAG(fixup.fixup_data(untag<object>(value)), TAG(value));
}
case RT_ENTRY_POINT:
case RT_ENTRY_POINT_PIC:
cell value = op.load_value(old_offset);
cell offset = TAG(value);
code_block* compiled = (code_block*)UNTAG(value);
- op.store_value((cell)fixup.fixup_code(compiled) + offset);
- break;
+ return (cell)fixup.fixup_code(compiled) + offset;
}
case RT_THIS:
case RT_CARDS_OFFSET:
case RT_DECKS_OFFSET:
- parent->store_external_address(op);
- break;
+ return parent->compute_external_address(op);
default:
- op.store_value(op.load_value(old_offset));
- break;
+ return op.load_value(old_offset);
}
}
-template <typename Fixup> struct code_block_compaction_updater {
- factor_vm* parent;
- slot_visitor<Fixup> forwarder;
-
- code_block_compaction_updater(
- factor_vm* parent, slot_visitor<Fixup> forwarder)
- : parent(parent), forwarder(forwarder) { }
-
- void operator()(code_block* old_address, code_block* new_address, cell size) {
- forwarder.visit_code_block_objects(new_address);
-
- cell old_entry_point = old_address->entry_point();
- auto update_func = [&](instruction_operand op) {
- update_relocation(parent, old_entry_point, forwarder.fixup, op);
- };
- new_address->each_instruction_operand(update_func);
- }
-};
-
/* After a compaction, invalidate any code heap roots which are not
marked, and also slide the valid roots up so that call sites can be updated
correctly in case an inline cache compilation triggered compaction. */
/* Slide everything in the code heap up, and update data and code heap
pointers inside code blocks. */
- {
- code_block_compaction_updater<compaction_fixup> code_block_updater(
- this, forwarder);
- code->allocator->compact(code_block_updater, fixup, &code_finger);
- }
+ auto compact_data_func = [&](code_block* old_addr,
+ code_block* new_addr,
+ cell size) {
+ forwarder.visit_code_block_objects(new_addr);
+ cell old_entry_point = old_addr->entry_point();
+ auto update_func = [&](instruction_operand op) {
+ op.store_value(compute_operand_value(this,
+ old_entry_point,
+ forwarder.fixup,
+ op));
+ };
+ new_addr->each_instruction_operand(update_func);
+ };
+ code->allocator->compact(compact_data_func, fixup, &code_finger);
forwarder.visit_all_roots();
forwarder.visit_context_code_blocks();
fixup(fixup),
visitor(slot_visitor<startup_fixup>(parent, fixup)) {}
- void operator()(instruction_operand op) {
+ fixnum compute_operand_value(instruction_operand op) {
code_block* compiled = op.compiled;
cell old_offset =
op.rel_offset() + compiled->entry_point() - fixup.code_offset;
-
switch (op.rel_type()) {
case RT_LITERAL: {
cell value = op.load_value(old_offset);
if (immediate_p(value))
- op.store_value(value);
- else
- op.store_value(
- RETAG(fixup.fixup_data(untag<object>(value)), TAG(value)));
- break;
+ return value;
+ return RETAG(fixup.fixup_data(untag<object>(value)), TAG(value));
}
case RT_ENTRY_POINT:
case RT_ENTRY_POINT_PIC:
cell value = op.load_value(old_offset);
cell offset = TAG(value);
code_block* compiled = (code_block*)UNTAG(value);
- op.store_value((cell)fixup.fixup_code(compiled) + offset);
- break;
+ return (cell)fixup.fixup_code(compiled) + offset;
}
case RT_UNTAGGED:
- break;
+ return op.load_value(old_offset);
default:
- parent->store_external_address(op);
- break;
+ return parent->compute_external_address(op);
}
}
+
+ void operator()(instruction_operand op) {
+ op.store_value(compute_operand_value(op));
+ }
};
void factor_vm::fixup_code(cell data_offset, cell code_offset) {
cell compute_dlsym_toc_address(array* literals, cell index);
#endif
cell compute_vm_address(cell arg);
- void store_external_address(instruction_operand op);
cell lookup_external_address(relocation_type rel_type,
code_block* compiled,
array* parameters,