]> gitweb.factorcode.org Git - factor.git/blobdiff - vm/callbacks.hpp
alien.syntax: clarify that we can dispatch off ENUM: members
[factor.git] / vm / callbacks.hpp
index 571c7713c7ec0504d13e7046db3454a1341f7f78..234daa88d1e31670c5a0ef2815331a5dcb0e3f9f 100644 (file)
@@ -1,38 +1,40 @@
-namespace factor
-{
+namespace factor {
 
-struct callback {
-       cell size;
-       code_block *compiled;
-       void *code() { return (void *)(this + 1); }
-};
+// 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;
-       cell here;
-       factor_vm *myvm;
-
-       explicit callback_heap(cell size, factor_vm *myvm);
-       ~callback_heap();
-
-       callback *add(code_block *compiled);
-       void update(callback *stub);
-
-       callback *next(callback *stub)
-       {
-               return (callback *)((cell)stub + stub->size + sizeof(callback));
-       }
-
-       template<typename Iterator> void iterate(Iterator &iter)
-       {
-               callback *scan = (callback *)seg->start;
-               callback *end = (callback *)here;
-               while(scan < end)
-               {
-                       iter(scan);
-                       scan = next(scan);
-               }
-       }
+  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);
 };
 
 }