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<code_block>(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) {
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;
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 */
struct callback_heap {
segment* seg;
- cell here;
+ bump_allocator<code_block>* allocator;
factor_vm* parent;
callback_heap(cell size, factor_vm* parent);
code_block* add(cell owner, cell return_rewind);
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);
- }
- }
};
}
slot_visitor<Fixup>* 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() {
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>