VM: more changes of structs to lambda functions
parent
4dfac78fc1
commit
4bc0720e51
|
@ -57,27 +57,6 @@ cell factor_vm::frame_predecessor(cell frame_top) {
|
|||
return frame_top + frame_size;
|
||||
}
|
||||
|
||||
struct stack_frame_accumulator {
|
||||
factor_vm* parent;
|
||||
growable_array frames;
|
||||
|
||||
/* Allocates memory (frames is a growable_array, constructor allocates) */
|
||||
explicit stack_frame_accumulator(factor_vm* parent)
|
||||
: parent(parent), frames(parent) {}
|
||||
|
||||
|
||||
/* Allocates memory (frames.add()) */
|
||||
void operator()(cell frame_top, cell size, code_block* owner, cell addr) {
|
||||
data_root<object> executing_quot(owner->owner_quot(), parent);
|
||||
data_root<object> executing(owner->owner, parent);
|
||||
data_root<object> scan(owner->scan(parent, addr), parent);
|
||||
|
||||
frames.add(executing.value());
|
||||
frames.add(executing_quot.value());
|
||||
frames.add(scan.value());
|
||||
}
|
||||
};
|
||||
|
||||
struct stack_frame_in_array {
|
||||
cell cells[3];
|
||||
};
|
||||
|
@ -85,19 +64,30 @@ struct stack_frame_in_array {
|
|||
/* Allocates memory (frames.trim()), iterate_callstack_object() */
|
||||
void factor_vm::primitive_callstack_to_array() {
|
||||
data_root<callstack> callstack(ctx->peek(), this);
|
||||
/* Allocates memory here. */
|
||||
growable_array frames(this);
|
||||
|
||||
stack_frame_accumulator accum(this);
|
||||
iterate_callstack_object(callstack.untagged(), accum);
|
||||
auto stack_frame_accumulator = [&](cell frame_top,
|
||||
cell size,
|
||||
code_block* owner,
|
||||
cell addr) {
|
||||
data_root<object> executing_quot(owner->owner_quot(), this);
|
||||
data_root<object> executing(owner->owner, this);
|
||||
data_root<object> scan(owner->scan(this, addr), this);
|
||||
|
||||
frames.add(executing.value());
|
||||
frames.add(executing_quot.value());
|
||||
frames.add(scan.value());
|
||||
};
|
||||
iterate_callstack_object(callstack.untagged(), stack_frame_accumulator);
|
||||
|
||||
/* The callstack iterator visits frames in reverse order (top to bottom) */
|
||||
std::reverse((stack_frame_in_array*)accum.frames.elements->data(),
|
||||
(stack_frame_in_array*)(accum.frames.elements->data() +
|
||||
accum.frames.count));
|
||||
|
||||
accum.frames.trim();
|
||||
|
||||
ctx->replace(accum.frames.elements.value());
|
||||
std::reverse((stack_frame_in_array*)frames.elements->data(),
|
||||
(stack_frame_in_array*)(frames.elements->data() +
|
||||
frames.count));
|
||||
frames.trim();
|
||||
|
||||
ctx->replace(frames.elements.value());
|
||||
}
|
||||
|
||||
/* Some primitives implementing a limited form of callstack mutation.
|
||||
|
|
|
@ -90,16 +90,15 @@ struct update_word_references_relocation_visitor {
|
|||
: parent(parent), reset_inline_caches(reset_inline_caches) {}
|
||||
|
||||
void operator()(instruction_operand op) {
|
||||
code_block* compiled = op.load_code_block();
|
||||
switch (op.rel_type()) {
|
||||
case RT_ENTRY_POINT: {
|
||||
code_block* compiled = op.load_code_block();
|
||||
cell owner = compiled->owner;
|
||||
if (to_boolean(owner))
|
||||
op.store_value(parent->compute_entry_point_address(owner));
|
||||
break;
|
||||
}
|
||||
case RT_ENTRY_POINT_PIC: {
|
||||
code_block* compiled = op.load_code_block();
|
||||
if (reset_inline_caches || !compiled->pic_p()) {
|
||||
cell owner = parent->code_block_owner(compiled);
|
||||
if (to_boolean(owner))
|
||||
|
@ -108,7 +107,6 @@ struct update_word_references_relocation_visitor {
|
|||
break;
|
||||
}
|
||||
case RT_ENTRY_POINT_PIC_TAIL: {
|
||||
code_block* compiled = op.load_code_block();
|
||||
if (reset_inline_caches || !compiled->pic_p()) {
|
||||
cell owner = parent->code_block_owner(compiled);
|
||||
if (to_boolean(owner))
|
||||
|
@ -460,42 +458,32 @@ code_block* factor_vm::add_code_block(code_block_type type, cell code_,
|
|||
return compiled;
|
||||
}
|
||||
|
||||
/* Find the RT_DLSYM relocation nearest to the given return address. */
|
||||
struct find_symbol_at_address_visitor {
|
||||
factor_vm* parent;
|
||||
cell return_address;
|
||||
cell symbol;
|
||||
cell library;
|
||||
|
||||
find_symbol_at_address_visitor(factor_vm* parent, cell return_address)
|
||||
: parent(parent),
|
||||
return_address(return_address),
|
||||
symbol(false_object),
|
||||
library(false_object) {}
|
||||
|
||||
void operator()(instruction_operand op) {
|
||||
if (op.rel_type() == RT_DLSYM && op.pointer <= return_address) {
|
||||
code_block* compiled = op.compiled;
|
||||
array* parameters = untag<array>(compiled->parameters);
|
||||
cell index = op.index;
|
||||
symbol = array_nth(parameters, index);
|
||||
library = array_nth(parameters, index + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* References to undefined symbols are patched up to call this function on
|
||||
image load. It finds the symbol and library, and throws an error. */
|
||||
void factor_vm::undefined_symbol() {
|
||||
cell frame = ctx->callstack_top;
|
||||
cell return_address = *(cell*)frame;
|
||||
code_block* compiled = code->code_block_for_address(return_address);
|
||||
find_symbol_at_address_visitor visitor(this, return_address);
|
||||
compiled->each_instruction_operand(visitor);
|
||||
if (!to_boolean(visitor.symbol))
|
||||
|
||||
/* Find the RT_DLSYM relocation nearest to the given return
|
||||
address. */
|
||||
cell symbol = false_object;
|
||||
cell library = false_object;
|
||||
|
||||
auto find_symbol_at_address_visitor = [&](instruction_operand op) {
|
||||
if (op.rel_type() == RT_DLSYM && op.pointer <= return_address) {
|
||||
array* parameters = untag<array>(compiled->parameters);
|
||||
cell index = op.index;
|
||||
symbol = array_nth(parameters, index);
|
||||
library = array_nth(parameters, index + 1);
|
||||
}
|
||||
};
|
||||
compiled->each_instruction_operand(find_symbol_at_address_visitor);
|
||||
|
||||
if (!to_boolean(symbol))
|
||||
critical_error("Can't find RT_DLSYM at return address", return_address);
|
||||
else
|
||||
general_error(ERROR_UNDEFINED_SYMBOL, visitor.symbol, visitor.library);
|
||||
general_error(ERROR_UNDEFINED_SYMBOL, symbol, library);
|
||||
}
|
||||
|
||||
void undefined_symbol() { return current_vm()->undefined_symbol(); }
|
||||
|
|
|
@ -257,16 +257,6 @@ struct code_compaction_fixup {
|
|||
}
|
||||
};
|
||||
|
||||
struct object_grow_heap_updater {
|
||||
slot_visitor<code_compaction_fixup> forwarder;
|
||||
|
||||
explicit object_grow_heap_updater(
|
||||
slot_visitor<code_compaction_fixup> forwarder)
|
||||
: forwarder(forwarder) {}
|
||||
|
||||
void operator()(object* obj) { forwarder.visit_object_code_block(obj); }
|
||||
};
|
||||
|
||||
/* Compact just the code heap, after growing the data heap */
|
||||
void factor_vm::collect_compact_code_impl() {
|
||||
/* Figure out where blocks are going to go */
|
||||
|
@ -282,8 +272,10 @@ void factor_vm::collect_compact_code_impl() {
|
|||
forwarder.visit_context_code_blocks();
|
||||
|
||||
/* Update code heap references in data heap */
|
||||
object_grow_heap_updater object_updater(forwarder);
|
||||
each_object(object_updater);
|
||||
auto object_grow_heap_updater = [&](object* obj) {
|
||||
forwarder.visit_object_code_block(obj);
|
||||
};
|
||||
each_object(object_grow_heap_updater);
|
||||
|
||||
/* Slide everything in the code heap up, and update code heap
|
||||
pointers inside code blocks. */
|
||||
|
|
Loading…
Reference in New Issue