VM: "formalize" the callback_heaps object allocation using a

bump_allocator<code_block>

The advantage of doing it this way is that you can reuse the existing
each_object method to iterate all callbacks
db4
Björn Lindqvist 2014-09-09 14:45:01 +02:00 committed by John Benediktsson
parent 4867e7bc96
commit 4015565cf6
3 changed files with 24 additions and 27 deletions

View File

@ -2,12 +2,21 @@
namespace factor { namespace factor {
callback_heap::callback_heap(cell size, factor_vm* parent) callback_heap::callback_heap(cell size, factor_vm* parent) {
: seg(new segment(size, true)), here(seg->start), parent(parent) {} seg = new segment(size, true);
if (!seg)
fatal_error("Out of memory in callback_heap constructor", size);
allocator = new bump_allocator<code_block>(size, seg->start);
this->parent = parent;
}
callback_heap::~callback_heap() { callback_heap::~callback_heap() {
delete allocator;
allocator = NULL;
delete seg; delete seg;
seg = NULL; seg = NULL;
} }
void factor_vm::init_callbacks(cell size) { 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 size = array_capacity(insns.untagged());
cell bump = align(size + sizeof(code_block), data_alignment); cell bump = align(size + sizeof(code_block), data_alignment);
if (allocator->here + bump > allocator->end) {
if (here + bump > seg->end) {
parent->general_error(ERROR_CALLBACK_SPACE_OVERFLOW, parent->general_error(ERROR_CALLBACK_SPACE_OVERFLOW,
false_object, false_object,
false_object); false_object);
} }
free_heap_block* free_block = (free_heap_block*)here; code_block* stub = allocator->allot(bump);
free_block->make_free(bump); stub->header = bump | 1;
here += bump;
code_block* stub = (code_block*)free_block;
stub->owner = owner; stub->owner = owner;
stub->parameters = false_object; stub->parameters = false_object;
stub->relocation = false_object; stub->relocation = false_object;
@ -109,12 +114,14 @@ struct callback_updater {
explicit callback_updater(callback_heap* callbacks) explicit callback_updater(callback_heap* callbacks)
: callbacks(callbacks) {} : callbacks(callbacks) {}
void operator()(code_block* stub) { callbacks->update(stub); } void operator()(object* stub) {
callbacks->update((code_block*)stub);
}
}; };
void callback_heap::update() { void callback_heap::update() {
callback_updater updater(this); callback_updater updater(this);
each_callback(updater); parent->each_object(allocator, updater);
} }
/* Allocates memory */ /* Allocates memory */

View File

@ -25,7 +25,7 @@ from the callback heap in the previous session when the image was saved. */
struct callback_heap { struct callback_heap {
segment* seg; segment* seg;
cell here; bump_allocator<code_block>* allocator;
factor_vm* parent; factor_vm* parent;
callback_heap(cell size, 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); code_block* add(cell owner, cell return_rewind);
void update(); void update();
code_block* next(code_block* stub) {
return (code_block*)((cell)stub + stub->size());
}
template <typename Iterator> 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);
}
}
}; };
} }

View File

@ -206,12 +206,15 @@ template <typename Fixup> struct callback_slot_visitor {
slot_visitor<Fixup>* visitor) slot_visitor<Fixup>* visitor)
: callbacks(callbacks), 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 <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(parent->callbacks, this); callback_slot_visitor<Fixup> callback_visitor(parent->callbacks, this);
parent->callbacks->each_callback(callback_visitor); parent->each_object(parent->callbacks->allocator, callback_visitor);
} }
template <typename Fixup> template <typename Fixup>