allocator = NULL;
delete seg;
seg = NULL;
-
}
void factor_vm::init_callbacks(cell size) {
}
void callback_heap::update(code_block* stub) {
- store_callback_operand(stub, 1, callback_entry_point(stub));
+ word* w = (word*)UNTAG(stub->owner);
+ store_callback_operand(stub, 1, w->entry_point);
stub->flush_icache();
}
code_block* callback_heap::add(cell owner, cell return_rewind) {
-
/* code_template is a 2-tuple where the first element contains the
relocations and the second a byte array of compiled assembly
code. The code assumes that there are four relocations on x86 and
false_object,
false_object);
}
-
stub->header = bump & ~7;
stub->owner = owner;
stub->parameters = false_object;
memcpy((void*)stub->entry_point(), insns->data<void>(), size);
- /* Store VM pointer */
+ /* Store VM pointer in two relocations. */
store_callback_operand(stub, 0, (cell)parent);
-
- /* Store VM pointer */
- store_callback_operand(stub, 2, (cell) parent);
+ store_callback_operand(stub, 2, (cell)parent);
/* On x86, the RET instruction takes an argument which depends on
the callback's calling convention */
store_callback_operand(stub, 3, return_rewind);
update(stub);
-
return stub;
}
-void callback_heap::update() {
- auto callback_updater = [&](code_block* stub, cell size) {
- update(stub);
- };
- allocator->iterate(callback_updater);
-}
-
/* Allocates memory (add(), allot_alien())*/
void factor_vm::primitive_callback() {
cell return_rewind = to_cell(ctx->pop());
callback_heap(cell size, factor_vm* parent);
~callback_heap();
- cell callback_entry_point(code_block* stub) {
- word* w = (word*)UNTAG(stub->owner);
- return w->entry_point;
- }
-
bool return_takes_param_p();
instruction_operand callback_operand(code_block* stub, cell index);
void store_callback_operand(code_block* stub, cell index, cell value);
void update(code_block* stub);
code_block* add(cell owner, cell return_rewind);
- void update();
};
}
}
update_code_roots_for_compaction();
- callbacks->update();
+
+ /* Each callback has a relocation with a pointer to a code block in
+ the code heap. Since the code heap has now been compacted, those
+ pointers are invalid and we need to update them. */
+ auto callback_updater = [&](code_block* stub, cell size) {
+ callbacks->update(stub);
+ };
+ callbacks->allocator->iterate(callback_updater);
code->initialize_all_blocks_set();