diff --git a/vm/callbacks.cpp b/vm/callbacks.cpp index 0f7bdfb940..784352b722 100644 --- a/vm/callbacks.cpp +++ b/vm/callbacks.cpp @@ -2,12 +2,21 @@ namespace factor { -callback_heap::callback_heap(cell size, factor_vm* parent) - : seg(new segment(size, true)), here(seg->start), parent(parent) {} +callback_heap::callback_heap(cell size, factor_vm* parent) { + seg = new segment(size, true); + if (!seg) + fatal_error("Out of memory in callback_heap constructor", size); + allocator = new bump_allocator(size, seg->start); + this->parent = parent; + +} callback_heap::~callback_heap() { + delete allocator; + allocator = NULL; delete seg; seg = NULL; + } void factor_vm::init_callbacks(cell size) { @@ -61,18 +70,14 @@ code_block* callback_heap::add(cell owner, cell return_rewind) { cell size = array_capacity(insns.untagged()); cell bump = align(size + sizeof(code_block), data_alignment); - - if (here + bump > seg->end) { + if (allocator->here + bump > allocator->end) { parent->general_error(ERROR_CALLBACK_SPACE_OVERFLOW, false_object, false_object); } - free_heap_block* free_block = (free_heap_block*)here; - free_block->make_free(bump); - here += bump; - - code_block* stub = (code_block*)free_block; + code_block* stub = allocator->allot(bump); + stub->header = bump | 1; stub->owner = owner; stub->parameters = false_object; stub->relocation = false_object; @@ -109,12 +114,14 @@ struct callback_updater { explicit callback_updater(callback_heap* callbacks) : callbacks(callbacks) {} - void operator()(code_block* stub) { callbacks->update(stub); } + void operator()(object* stub) { + callbacks->update((code_block*)stub); + } }; void callback_heap::update() { callback_updater updater(this); - each_callback(updater); + parent->each_object(allocator, updater); } /* Allocates memory */ diff --git a/vm/callbacks.hpp b/vm/callbacks.hpp index 385fb680cd..3bb0f6cc82 100644 --- a/vm/callbacks.hpp +++ b/vm/callbacks.hpp @@ -25,7 +25,7 @@ from the callback heap in the previous session when the image was saved. */ struct callback_heap { segment* seg; - cell here; + bump_allocator* allocator; factor_vm* parent; callback_heap(cell size, factor_vm* parent); @@ -47,19 +47,6 @@ struct callback_heap { code_block* add(cell owner, cell return_rewind); void update(); - - code_block* next(code_block* stub) { - return (code_block*)((cell)stub + stub->size()); - } - - template void each_callback(Iterator& iter) { - code_block* scan = (code_block*)seg->start; - code_block* end = (code_block*)here; - while (scan < end) { - iter(scan); - scan = next(scan); - } - } }; } diff --git a/vm/slot_visitor.hpp b/vm/slot_visitor.hpp index 6096c8fb03..1726ac7921 100644 --- a/vm/slot_visitor.hpp +++ b/vm/slot_visitor.hpp @@ -206,12 +206,15 @@ template struct callback_slot_visitor { slot_visitor* visitor) : callbacks(callbacks), visitor(visitor) {} - void operator()(code_block* stub) { visitor->visit_handle(&stub->owner); } + void operator()(object* stub) { + code_block *block = (code_block*)stub; + visitor->visit_handle(&block->owner); + } }; template void slot_visitor::visit_callback_roots() { callback_slot_visitor callback_visitor(parent->callbacks, this); - parent->callbacks->each_callback(callback_visitor); + parent->each_object(parent->callbacks->allocator, callback_visitor); } template