VM: change lot of visitation objects to use cool lambda functions instead
parent
fce5d4353a
commit
365b39e0cc
|
@ -108,20 +108,11 @@ code_block* callback_heap::add(cell owner, cell return_rewind) {
|
||||||
return stub;
|
return stub;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct callback_updater {
|
|
||||||
callback_heap* callbacks;
|
|
||||||
|
|
||||||
explicit callback_updater(callback_heap* callbacks)
|
|
||||||
: callbacks(callbacks) {}
|
|
||||||
|
|
||||||
void operator()(code_block* stub, cell size) {
|
|
||||||
callbacks->update(stub);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void callback_heap::update() {
|
void callback_heap::update() {
|
||||||
callback_updater updater(this);
|
auto callback_updater = [&](code_block* stub, cell size) {
|
||||||
allocator->iterate(updater);
|
update(stub);
|
||||||
|
};
|
||||||
|
allocator->iterate(callback_updater);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory (add(), allot_alien())*/
|
/* Allocates memory (add(), allot_alien())*/
|
||||||
|
|
59
vm/image.cpp
59
vm/image.cpp
|
@ -77,21 +77,14 @@ struct startup_fixup {
|
||||||
cell size(code_block* compiled) { return compiled->size(*this); }
|
cell size(code_block* compiled) { return compiled->size(*this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct start_object_updater {
|
void factor_vm::fixup_data(cell data_offset, cell code_offset) {
|
||||||
factor_vm* parent;
|
startup_fixup fixup(data_offset, code_offset);
|
||||||
startup_fixup fixup;
|
slot_visitor<startup_fixup> visitor(this, fixup);
|
||||||
slot_visitor<startup_fixup> visitor;
|
visitor.visit_all_roots();
|
||||||
|
|
||||||
start_object_updater(factor_vm* parent, startup_fixup fixup)
|
|
||||||
: parent(parent),
|
|
||||||
fixup(fixup),
|
|
||||||
visitor(slot_visitor<startup_fixup>(parent, fixup)) { }
|
|
||||||
|
|
||||||
void operator()(object* obj, cell size) {
|
|
||||||
parent->data->tenured->starts.record_object_start_offset(obj);
|
|
||||||
|
|
||||||
|
auto start_object_updater = [&](object *obj, cell size) {
|
||||||
|
data->tenured->starts.record_object_start_offset(obj);
|
||||||
visitor.visit_slots(obj);
|
visitor.visit_slots(obj);
|
||||||
|
|
||||||
switch (obj->type()) {
|
switch (obj->type()) {
|
||||||
case ALIEN_TYPE: {
|
case ALIEN_TYPE: {
|
||||||
|
|
||||||
|
@ -100,11 +93,11 @@ struct start_object_updater {
|
||||||
if (to_boolean(ptr->base))
|
if (to_boolean(ptr->base))
|
||||||
ptr->update_address();
|
ptr->update_address();
|
||||||
else
|
else
|
||||||
ptr->expired = parent->true_object;
|
ptr->expired = true_object;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DLL_TYPE: {
|
case DLL_TYPE: {
|
||||||
parent->ffi_dlopen((dll*)obj);
|
ffi_dlopen((dll*)obj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -112,16 +105,8 @@ struct start_object_updater {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
data->tenured->iterate(start_object_updater, fixup);
|
||||||
|
|
||||||
void factor_vm::fixup_data(cell data_offset, cell code_offset) {
|
|
||||||
startup_fixup fixup(data_offset, code_offset);
|
|
||||||
slot_visitor<startup_fixup> visitor(this, fixup);
|
|
||||||
visitor.visit_all_roots();
|
|
||||||
|
|
||||||
start_object_updater updater(this, fixup);
|
|
||||||
data->tenured->iterate(updater, fixup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct startup_code_block_relocation_visitor {
|
struct startup_code_block_relocation_visitor {
|
||||||
|
@ -169,25 +154,15 @@ struct startup_code_block_relocation_visitor {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct startup_code_block_updater {
|
|
||||||
factor_vm* parent;
|
|
||||||
startup_fixup fixup;
|
|
||||||
|
|
||||||
startup_code_block_updater(factor_vm* parent, startup_fixup fixup)
|
|
||||||
: parent(parent), fixup(fixup) {}
|
|
||||||
|
|
||||||
void operator()(code_block* compiled, cell size) {
|
|
||||||
slot_visitor<startup_fixup> visitor(parent, fixup);
|
|
||||||
visitor.visit_code_block_objects(compiled);
|
|
||||||
|
|
||||||
startup_code_block_relocation_visitor code_visitor(parent, fixup);
|
|
||||||
compiled->each_instruction_operand(code_visitor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void factor_vm::fixup_code(cell data_offset, cell code_offset) {
|
void factor_vm::fixup_code(cell data_offset, cell code_offset) {
|
||||||
startup_fixup fixup(data_offset, code_offset);
|
startup_fixup fixup(data_offset, code_offset);
|
||||||
startup_code_block_updater updater(this, fixup);
|
auto updater = [&](code_block* compiled, cell size) {
|
||||||
|
slot_visitor<startup_fixup> visitor(this, fixup);
|
||||||
|
visitor.visit_code_block_objects(compiled);
|
||||||
|
|
||||||
|
startup_code_block_relocation_visitor code_visitor(this, fixup);
|
||||||
|
compiled->each_instruction_operand(code_visitor);
|
||||||
|
};
|
||||||
code->allocator->iterate(updater, fixup);
|
code->allocator->iterate(updater, fixup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,37 +87,6 @@ struct slot_become_fixup : no_fixup {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct object_become_visitor {
|
|
||||||
slot_visitor<slot_become_fixup>* visitor;
|
|
||||||
|
|
||||||
explicit object_become_visitor(slot_visitor<slot_become_fixup>* visitor)
|
|
||||||
: visitor(visitor) {}
|
|
||||||
|
|
||||||
void operator()(object* obj) { visitor->visit_slots(obj); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct code_block_become_visitor {
|
|
||||||
slot_visitor<slot_become_fixup>* visitor;
|
|
||||||
|
|
||||||
explicit code_block_become_visitor(
|
|
||||||
slot_visitor<slot_become_fixup>* visitor) : visitor(visitor) {}
|
|
||||||
|
|
||||||
void operator()(code_block* compiled, cell size) {
|
|
||||||
visitor->visit_code_block_objects(compiled);
|
|
||||||
visitor->visit_embedded_literals(compiled);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct code_block_write_barrier_visitor {
|
|
||||||
code_heap* code;
|
|
||||||
|
|
||||||
explicit code_block_write_barrier_visitor(code_heap* code) : code(code) {}
|
|
||||||
|
|
||||||
void operator()(code_block* compiled, cell size) {
|
|
||||||
code->write_barrier(compiled);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* classes.tuple uses this to reshape tuples; tools.deploy.shaker uses this
|
/* classes.tuple uses this to reshape tuples; tools.deploy.shaker uses this
|
||||||
to coalesce equal but distinct quotations and wrappers. */
|
to coalesce equal but distinct quotations and wrappers. */
|
||||||
/* Calls gc */
|
/* Calls gc */
|
||||||
|
@ -147,11 +116,16 @@ void factor_vm::primitive_become() {
|
||||||
slot_become_fixup(&become_map));
|
slot_become_fixup(&become_map));
|
||||||
visitor.visit_all_roots();
|
visitor.visit_all_roots();
|
||||||
|
|
||||||
object_become_visitor object_visitor(&visitor);
|
auto object_become_visitor = [&](object* obj) {
|
||||||
each_object(object_visitor);
|
visitor.visit_slots(obj);
|
||||||
|
};
|
||||||
|
each_object(object_become_visitor);
|
||||||
|
|
||||||
code_block_become_visitor code_block_visitor(&visitor);
|
auto code_block_become_visitor = [&](code_block* compiled, cell size) {
|
||||||
each_code_block(code_block_visitor);
|
visitor.visit_code_block_objects(compiled);
|
||||||
|
visitor.visit_embedded_literals(compiled);
|
||||||
|
};
|
||||||
|
each_code_block(code_block_become_visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Since we may have introduced old->new references, need to revisit
|
/* Since we may have introduced old->new references, need to revisit
|
||||||
|
@ -159,7 +133,9 @@ void factor_vm::primitive_become() {
|
||||||
data->mark_all_cards();
|
data->mark_all_cards();
|
||||||
|
|
||||||
{
|
{
|
||||||
code_block_write_barrier_visitor code_block_visitor(code);
|
auto code_block_visitor = [&](code_block* compiled, cell size) {
|
||||||
|
code->write_barrier(compiled);
|
||||||
|
};
|
||||||
each_code_block(code_block_visitor);
|
each_code_block(code_block_visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,19 +188,11 @@ template <typename Fixup> void slot_visitor<Fixup>::visit_data_roots() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup> struct callback_slot_visitor {
|
|
||||||
slot_visitor<Fixup>* visitor;
|
|
||||||
|
|
||||||
callback_slot_visitor(slot_visitor<Fixup>* visitor) : visitor(visitor) {}
|
|
||||||
|
|
||||||
void operator()(code_block* stub, cell size) {
|
|
||||||
visitor->visit_handle(&stub->owner);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Fixup> void slot_visitor<Fixup>::visit_callback_roots() {
|
template <typename Fixup> void slot_visitor<Fixup>::visit_callback_roots() {
|
||||||
callback_slot_visitor<Fixup> callback_visitor(this);
|
auto callback_slot_visitor = [&](code_block* stub, cell size) {
|
||||||
parent->callbacks->allocator->iterate(callback_visitor);
|
visit_handle(&stub->owner);
|
||||||
|
};
|
||||||
|
parent->callbacks->allocator->iterate(callback_slot_visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
|
@ -381,18 +373,6 @@ template <typename Fixup> void slot_visitor<Fixup>::visit_contexts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup> struct literal_references_visitor {
|
|
||||||
slot_visitor<Fixup>* visitor;
|
|
||||||
|
|
||||||
explicit literal_references_visitor(slot_visitor<Fixup>* visitor)
|
|
||||||
: visitor(visitor) {}
|
|
||||||
|
|
||||||
void operator()(instruction_operand op) {
|
|
||||||
if (op.rel_type() == RT_LITERAL)
|
|
||||||
op.store_value(visitor->visit_pointer(op.load_value()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_code_block_objects(code_block* compiled) {
|
void slot_visitor<Fixup>::visit_code_block_objects(code_block* compiled) {
|
||||||
visit_handle(&compiled->owner);
|
visit_handle(&compiled->owner);
|
||||||
|
@ -402,10 +382,14 @@ void slot_visitor<Fixup>::visit_code_block_objects(code_block* compiled) {
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_embedded_literals(code_block* compiled) {
|
void slot_visitor<Fixup>::visit_embedded_literals(code_block* compiled) {
|
||||||
if (!parent->code->uninitialized_p(compiled)) {
|
if (parent->code->uninitialized_p(compiled))
|
||||||
literal_references_visitor<Fixup> visitor(this);
|
return;
|
||||||
compiled->each_instruction_operand(visitor);
|
|
||||||
}
|
auto update_literal_refs = [&](instruction_operand op) {
|
||||||
|
if (op.rel_type() == RT_LITERAL)
|
||||||
|
op.store_value(visit_pointer(op.load_value()));
|
||||||
|
};
|
||||||
|
compiled->each_instruction_operand(update_literal_refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup> struct call_frame_code_block_visitor {
|
template <typename Fixup> struct call_frame_code_block_visitor {
|
||||||
|
@ -465,25 +449,18 @@ void slot_visitor<Fixup>::visit_uninitialized_code_blocks() {
|
||||||
parent->code->uninitialized_blocks = new_uninitialized_blocks;
|
parent->code->uninitialized_blocks = new_uninitialized_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup> struct embedded_code_pointers_visitor {
|
|
||||||
Fixup fixup;
|
|
||||||
|
|
||||||
explicit embedded_code_pointers_visitor(Fixup fixup) : fixup(fixup) {}
|
|
||||||
|
|
||||||
void operator()(instruction_operand op) {
|
|
||||||
relocation_type type = op.rel_type();
|
|
||||||
if (type == RT_ENTRY_POINT || type == RT_ENTRY_POINT_PIC ||
|
|
||||||
type == RT_ENTRY_POINT_PIC_TAIL)
|
|
||||||
op.store_code_block(fixup.fixup_code(op.load_code_block()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_embedded_code_pointers(code_block* compiled) {
|
void slot_visitor<Fixup>::visit_embedded_code_pointers(code_block* compiled) {
|
||||||
if (!parent->code->uninitialized_p(compiled)) {
|
if (parent->code->uninitialized_p(compiled))
|
||||||
embedded_code_pointers_visitor<Fixup> operand_visitor(fixup);
|
return;
|
||||||
compiled->each_instruction_operand(operand_visitor);
|
auto update_code_block_refs = [&](instruction_operand op){
|
||||||
}
|
relocation_type type = op.rel_type();
|
||||||
|
if (type == RT_ENTRY_POINT ||
|
||||||
|
type == RT_ENTRY_POINT_PIC ||
|
||||||
|
type == RT_ENTRY_POINT_PIC_TAIL)
|
||||||
|
op.store_code_block(fixup.fixup_code(op.load_code_block()));
|
||||||
|
};
|
||||||
|
compiled->each_instruction_operand(update_code_block_refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
|
@ -500,7 +477,6 @@ template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_mark_stack(std::vector<cell>* mark_stack) {
|
void slot_visitor<Fixup>::visit_mark_stack(std::vector<cell>* mark_stack) {
|
||||||
while (!mark_stack->empty()) {
|
while (!mark_stack->empty()) {
|
||||||
cell ptr = mark_stack->back();
|
cell ptr = mark_stack->back();
|
||||||
// TJaba
|
|
||||||
mark_stack->pop_back();
|
mark_stack->pop_back();
|
||||||
|
|
||||||
if (ptr & 1) {
|
if (ptr & 1) {
|
||||||
|
|
Loading…
Reference in New Issue