factor/vm/callbacks.hpp

41 lines
1.8 KiB
C++

namespace factor {
// The callback heap is used to store the machine code that alien-callbacks
// actually jump to when C code invokes them.
// The callback heap has entries that look like code_blocks from the code heap, but
// callback heap entries are allocated contiguously, never deallocated, and all
// fields but the owner are set to false_object. The owner points to the callback
// bottom word, whose entry point is the callback body itself, generated by the
// optimizing compiler. The machine code that follows a callback stub consists of a
// single CALLBACK_STUB machine code template, which performs a jump to a "far"
// address (on PowerPC and x86-64, its loaded into a register first).
// GC updates the CALLBACK_STUB code if the code block of the callback bottom word
// is ever moved. The callback stub itself won't move, though, and is never
// deallocated. This means that the callback stub itself is a stable function
// pointer that C code can hold on to until the associated Factor VM exits.
// Since callback stubs are GC roots, and are never deallocated, the associated
// callback code in the code heap is also never deallocated.
// The callback heap is not saved in the image. Running GC in a new session after
// saving the image will deallocate any code heap entries that were only reachable
// from the callback heap in the previous session when the image was saved.
struct callback_heap {
segment* seg;
free_list_allocator<code_block>* allocator;
factor_vm* parent;
callback_heap(cell size, factor_vm* parent);
~callback_heap();
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);
};
}