VM: use a free_list_allocator for the callbacks, that way they can

individually be freed
db4
Björn Lindqvist 2014-09-09 17:56:56 +02:00 committed by John Benediktsson
parent 4015565cf6
commit 85dade6914
3 changed files with 14 additions and 17 deletions

View File

@ -6,7 +6,7 @@ callback_heap::callback_heap(cell size, factor_vm* parent) {
seg = new segment(size, true); seg = new segment(size, true);
if (!seg) if (!seg)
fatal_error("Out of memory in callback_heap constructor", size); fatal_error("Out of memory in callback_heap constructor", size);
allocator = new bump_allocator<code_block>(size, seg->start); allocator = new free_list_allocator<code_block>(size, seg->start);
this->parent = parent; this->parent = parent;
} }
@ -65,19 +65,20 @@ void callback_heap::update(code_block* stub) {
} }
code_block* callback_heap::add(cell owner, cell return_rewind) { code_block* callback_heap::add(cell owner, cell return_rewind) {
std::cout << "callback_heap::add" << std::endl;
tagged<array> code_template(parent->special_objects[CALLBACK_STUB]); tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
tagged<byte_array> insns(array_nth(code_template.untagged(), 1)); tagged<byte_array> insns(array_nth(code_template.untagged(), 1));
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) { code_block* stub = allocator->allot(bump);
if (!stub) {
parent->general_error(ERROR_CALLBACK_SPACE_OVERFLOW, parent->general_error(ERROR_CALLBACK_SPACE_OVERFLOW,
false_object, false_object,
false_object); false_object);
} }
code_block* stub = allocator->allot(bump); stub->header = bump & ~7;
stub->header = bump | 1;
stub->owner = owner; stub->owner = owner;
stub->parameters = false_object; stub->parameters = false_object;
stub->relocation = false_object; stub->relocation = false_object;
@ -114,14 +115,14 @@ struct callback_updater {
explicit callback_updater(callback_heap* callbacks) explicit callback_updater(callback_heap* callbacks)
: callbacks(callbacks) {} : callbacks(callbacks) {}
void operator()(object* stub) { void operator()(code_block* stub, cell size) {
callbacks->update((code_block*)stub); callbacks->update(stub);
} }
}; };
void callback_heap::update() { void callback_heap::update() {
callback_updater updater(this); callback_updater updater(this);
parent->each_object(allocator, updater); allocator->iterate(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;
bump_allocator<code_block>* allocator; free_list_allocator<code_block>* allocator;
factor_vm* parent; factor_vm* parent;
callback_heap(cell size, factor_vm* parent); callback_heap(cell size, factor_vm* parent);

View File

@ -199,22 +199,18 @@ template <typename Fixup> void slot_visitor<Fixup>::visit_bignum_roots() {
} }
template <typename Fixup> struct callback_slot_visitor { template <typename Fixup> struct callback_slot_visitor {
callback_heap* callbacks;
slot_visitor<Fixup>* visitor; slot_visitor<Fixup>* visitor;
callback_slot_visitor(callback_heap* callbacks, callback_slot_visitor(slot_visitor<Fixup>* visitor) : visitor(visitor) {}
slot_visitor<Fixup>* visitor)
: callbacks(callbacks), visitor(visitor) {}
void operator()(object* stub) { void operator()(code_block* stub, cell size) {
code_block *block = (code_block*)stub; visitor->visit_handle(&stub->owner);
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(this);
parent->each_object(parent->callbacks->allocator, callback_visitor); parent->callbacks->allocator->iterate(callback_visitor);
} }
template <typename Fixup> template <typename Fixup>