factor/vm/collector.hpp

84 lines
2.2 KiB
C++

namespace factor {
struct must_start_gc_again {
};
template <typename TargetGeneration, typename Policy>
struct gc_workhorse : no_fixup {
static const bool translated_code_block_map = false;
factor_vm* parent;
TargetGeneration* target;
Policy policy;
code_heap* code;
gc_workhorse(factor_vm* parent, TargetGeneration* target, Policy policy)
: parent(parent), target(target), policy(policy), code(parent->code) {}
object* fixup_data(object* obj) {
FACTOR_ASSERT((parent->current_gc &&
parent->current_gc->op == collect_growing_heap_op) ||
parent->data->seg->in_segment_p((cell)obj));
if (!policy.should_copy_p(obj)) {
policy.visited_object(obj);
return obj;
}
/* is there another forwarding pointer? */
while (obj->forwarding_pointer_p()) {
object* dest = obj->forwarding_pointer();
obj = dest;
}
if (!policy.should_copy_p(obj)) {
policy.visited_object(obj);
return obj;
}
cell size = obj->size();
object* newpointer = target->allot(size);
if (!newpointer)
throw must_start_gc_again();
memcpy(newpointer, obj, size);
obj->forward_to(newpointer);
policy.promoted_object(newpointer);
return newpointer;
}
code_block* fixup_code(code_block* compiled) {
if (!code->allocator->state.marked_p((cell)compiled)) {
code->allocator->state.set_marked_p((cell)compiled, compiled->size());
parent->mark_stack.push_back((cell)compiled + 1);
}
return compiled;
}
};
template <typename TargetGeneration, typename Policy> struct collector {
data_heap* data;
TargetGeneration* target;
slot_visitor<gc_workhorse<TargetGeneration, Policy> > visitor;
cell scan;
collector(factor_vm* parent, TargetGeneration* target, Policy policy)
: data(parent->data),
target(target),
visitor(parent, gc_workhorse<TargetGeneration, Policy>(parent, target, policy)) {
scan = target->start + target->occupied_space();
}
void cheneys_algorithm() {
while (scan && scan < this->target->here) {
this->visitor.visit_object((object*)scan);
scan = this->target->next_object_after(scan);
}
}
};
}