diff --git a/vm/callstack.cpp b/vm/callstack.cpp index d9766aea2c..7ead848d79 100644 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -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 executing_quot(owner->owner_quot(), parent); - data_root executing(owner->owner, parent); - data_root 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(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 executing_quot(owner->owner_quot(), this); + data_root executing(owner->owner, this); + data_root 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. diff --git a/vm/code_blocks.cpp b/vm/code_blocks.cpp index 8fdc447ea3..f5f8b3be2d 100644 --- a/vm/code_blocks.cpp +++ b/vm/code_blocks.cpp @@ -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(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(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(); } diff --git a/vm/compaction.cpp b/vm/compaction.cpp index 0992830996..f0b56ef356 100644 --- a/vm/compaction.cpp +++ b/vm/compaction.cpp @@ -257,16 +257,6 @@ struct code_compaction_fixup { } }; -struct object_grow_heap_updater { - slot_visitor forwarder; - - explicit object_grow_heap_updater( - slot_visitor 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. */