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 callbacksdb4
parent
4867e7bc96
commit
4015565cf6
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue