factor/vm/slot_visitor.hpp

158 lines
3.8 KiB
C++
Raw Normal View History

namespace factor
{
template<typename Visitor> struct slot_visitor {
factor_vm *parent;
Visitor visitor;
explicit slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
parent(parent_), visitor(visitor_) {}
2009-11-22 14:37:39 -05:00
cell visit_pointer(cell pointer);
void visit_handle(cell *handle);
void visit_slots(object *ptr, cell payload_start);
void visit_slots(object *ptr);
void visit_stack_elements(segment *region, cell *top);
void visit_data_roots();
void visit_bignum_roots();
void visit_roots();
void visit_contexts();
void visit_literal_references(code_block *compiled);
};
2009-11-06 02:22:53 -05:00
2009-11-22 14:37:39 -05:00
template<typename Visitor>
cell slot_visitor<Visitor>::visit_pointer(cell pointer)
{
if(immediate_p(pointer)) return pointer;
2009-11-22 14:37:39 -05:00
object *untagged = untag<object>(pointer);
untagged = visitor(untagged);
return RETAG(untagged,TAG(pointer));
}
2009-11-22 14:37:39 -05:00
template<typename Visitor>
void slot_visitor<Visitor>::visit_handle(cell *handle)
{
*handle = visit_pointer(*handle);
}
2009-11-22 14:37:39 -05:00
template<typename Visitor>
void slot_visitor<Visitor>::visit_slots(object *ptr, cell payload_start)
{
cell *slot = (cell *)ptr;
cell *end = (cell *)((cell)ptr + payload_start);
2009-11-22 14:37:39 -05:00
if(slot != end)
2009-10-25 00:51:14 -04:00
{
2009-11-22 14:37:39 -05:00
slot++;
for(; slot < end; slot++) visit_handle(slot);
2009-10-25 00:51:14 -04:00
}
2009-11-22 14:37:39 -05:00
}
2009-10-25 00:51:14 -04:00
2009-11-22 14:37:39 -05:00
template<typename Visitor>
void slot_visitor<Visitor>::visit_slots(object *ptr)
{
visit_slots(ptr,ptr->binary_payload_start());
}
template<typename Visitor>
void slot_visitor<Visitor>::visit_stack_elements(segment *region, cell *top)
{
for(cell *ptr = (cell *)region->start; ptr <= top; ptr++)
visit_handle(ptr);
}
template<typename Visitor>
void slot_visitor<Visitor>::visit_data_roots()
{
std::vector<data_root_range>::const_iterator iter = parent->data_roots.begin();
std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
for(; iter < end; iter++)
{
2009-11-22 14:37:39 -05:00
data_root_range r = *iter;
for(cell index = 0; index < r.len; index++)
visit_handle(r.start + index);
}
2009-11-22 14:37:39 -05:00
}
template<typename Visitor>
void slot_visitor<Visitor>::visit_bignum_roots()
{
std::vector<cell>::const_iterator iter = parent->bignum_roots.begin();
std::vector<cell>::const_iterator end = parent->bignum_roots.end();
2009-11-22 14:37:39 -05:00
for(; iter < end; iter++)
{
2009-11-22 14:37:39 -05:00
cell *handle = (cell *)(*iter);
2009-11-22 14:37:39 -05:00
if(*handle)
*handle = (cell)visitor(*(object **)handle);
}
2009-11-22 14:37:39 -05:00
}
2009-11-22 14:37:39 -05:00
template<typename Visitor>
void slot_visitor<Visitor>::visit_roots()
{
visit_handle(&parent->true_object);
visit_handle(&parent->bignum_zero);
visit_handle(&parent->bignum_pos_one);
visit_handle(&parent->bignum_neg_one);
2009-11-22 14:37:39 -05:00
visit_data_roots();
visit_bignum_roots();
2009-11-22 14:37:39 -05:00
for(cell i = 0; i < special_object_count; i++)
visit_handle(&parent->special_objects[i]);
}
template<typename Visitor>
void slot_visitor<Visitor>::visit_contexts()
{
context *ctx = parent->ctx;
2009-11-22 14:37:39 -05:00
while(ctx)
{
2009-11-22 14:37:39 -05:00
visit_stack_elements(ctx->datastack_region,(cell *)ctx->datastack);
visit_stack_elements(ctx->retainstack_region,(cell *)ctx->retainstack);
2009-11-22 14:37:39 -05:00
visit_handle(&ctx->catchstack_save);
visit_handle(&ctx->current_callback_save);
2009-11-22 14:37:39 -05:00
ctx = ctx->next;
}
2009-11-22 14:37:39 -05:00
}
2009-11-22 14:37:39 -05:00
template<typename Visitor>
struct literal_references_visitor {
factor_vm *parent;
slot_visitor<Visitor> *visitor;
2009-11-22 14:37:39 -05:00
explicit literal_references_visitor(factor_vm *parent_, slot_visitor<Visitor> *visitor_)
: parent(parent_), visitor(visitor_) {}
2009-11-22 14:37:39 -05:00
void operator()(relocation_entry rel, cell index, code_block *compiled)
{
2009-11-22 14:37:39 -05:00
if(rel.rel_type() == RT_IMMEDIATE)
{
embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
cell literal = ptr.load_address();
literal = visitor->visit_pointer(literal);
ptr.store_address(literal);
}
}
};
2009-11-22 14:37:39 -05:00
template<typename Visitor>
void slot_visitor<Visitor>::visit_literal_references(code_block *compiled)
{
visit_handle(&compiled->owner);
visit_handle(&compiled->literals);
visit_handle(&compiled->relocation);
literal_references_visitor<Visitor> visitor(parent,this);
parent->iterate_relocations(compiled,visitor);
}
}