#undef ARG
}
-template<typename Iterator> void factor_vm::iterate_relocations(code_block *compiled, Iterator &iter)
-{
- if(to_boolean(compiled->relocation))
- {
- byte_array *relocation = untag<byte_array>(compiled->relocation);
-
- cell index = 0;
- cell length = array_capacity(relocation) / sizeof(relocation_entry);
-
- for(cell i = 0; i < length; i++)
- {
- relocation_entry rel = relocation->data<relocation_entry>()[i];
- iter(rel,index,compiled);
- index += rel.number_of_parameters();
- }
- }
-}
-
-struct literal_references_updater {
- factor_vm *parent;
-
- explicit literal_references_updater(factor_vm *parent_) : parent(parent_) {}
-
- void operator()(relocation_entry rel, cell index, code_block *compiled)
- {
- if(rel.rel_type() == RT_IMMEDIATE)
- {
- embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
- array *literals = untag<array>(compiled->literals);
- ptr.store_address(array_nth(literals,index));
- }
- }
-};
-
-/* Update pointers to literals from compiled code. */
-void factor_vm::update_literal_references(code_block *compiled)
-{
- if(!code->needs_fixup_p(compiled))
- {
- literal_references_updater updater(this);
- iterate_relocations(compiled,updater);
- flush_icache_for(compiled);
- }
-}
-
/* Compute an address to store at a relocation */
void factor_vm::relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled)
{
explicit slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
parent(parent_), visitor(visitor_) {}
- cell visit_pointer(cell pointer)
- {
- if(immediate_p(pointer)) return pointer;
+ 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);
+};
- object *untagged = untag<object>(pointer);
- untagged = visitor(untagged);
- return RETAG(untagged,TAG(pointer));
- }
+template<typename Visitor>
+cell slot_visitor<Visitor>::visit_pointer(cell pointer)
+{
+ if(immediate_p(pointer)) return pointer;
- void visit_handle(cell *handle)
- {
- *handle = visit_pointer(*handle);
- }
+ object *untagged = untag<object>(pointer);
+ untagged = visitor(untagged);
+ return RETAG(untagged,TAG(pointer));
+}
- void visit_slots(object *ptr, cell payload_start)
- {
- cell *slot = (cell *)ptr;
- cell *end = (cell *)((cell)ptr + payload_start);
+template<typename Visitor>
+void slot_visitor<Visitor>::visit_handle(cell *handle)
+{
+ *handle = visit_pointer(*handle);
+}
- if(slot != end)
- {
- slot++;
- for(; slot < end; slot++) visit_handle(slot);
- }
- }
+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);
- void visit_slots(object *ptr)
+ if(slot != end)
{
- visit_slots(ptr,ptr->binary_payload_start());
+ slot++;
+ for(; slot < end; slot++) visit_handle(slot);
}
+}
- void visit_stack_elements(segment *region, cell *top)
+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++)
{
- for(cell *ptr = (cell *)region->start; ptr <= top; ptr++)
- visit_handle(ptr);
+ data_root_range r = *iter;
+ for(cell index = 0; index < r.len; index++)
+ visit_handle(r.start + index);
}
+}
+
+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();
- void visit_data_roots()
+ for(; iter < end; iter++)
{
- std::vector<data_root_range>::const_iterator iter = parent->data_roots.begin();
- std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
+ cell *handle = (cell *)(*iter);
- for(; iter < end; iter++)
- {
- data_root_range r = *iter;
- for(cell index = 0; index < r.len; index++)
- visit_handle(r.start + index);
- }
+ if(*handle)
+ *handle = (cell)visitor(*(object **)handle);
}
+}
- void visit_bignum_roots()
- {
- std::vector<cell>::const_iterator iter = parent->bignum_roots.begin();
- std::vector<cell>::const_iterator end = parent->bignum_roots.end();
+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);
- for(; iter < end; iter++)
- {
- cell *handle = (cell *)(*iter);
+ visit_data_roots();
+ visit_bignum_roots();
- if(*handle)
- *handle = (cell)visitor(*(object **)handle);
- }
- }
+ 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;
- void visit_roots()
+ while(ctx)
{
- visit_handle(&parent->true_object);
- visit_handle(&parent->bignum_zero);
- visit_handle(&parent->bignum_pos_one);
- visit_handle(&parent->bignum_neg_one);
+ visit_stack_elements(ctx->datastack_region,(cell *)ctx->datastack);
+ visit_stack_elements(ctx->retainstack_region,(cell *)ctx->retainstack);
- visit_data_roots();
- visit_bignum_roots();
+ visit_handle(&ctx->catchstack_save);
+ visit_handle(&ctx->current_callback_save);
- for(cell i = 0; i < special_object_count; i++)
- visit_handle(&parent->special_objects[i]);
+ ctx = ctx->next;
}
+}
- void visit_contexts()
- {
- context *ctx = parent->ctx;
-
- while(ctx)
- {
- visit_stack_elements(ctx->datastack_region,(cell *)ctx->datastack);
- visit_stack_elements(ctx->retainstack_region,(cell *)ctx->retainstack);
-
- visit_handle(&ctx->catchstack_save);
- visit_handle(&ctx->current_callback_save);
+template<typename Visitor>
+struct literal_references_visitor {
+ factor_vm *parent;
+ slot_visitor<Visitor> *visitor;
- ctx = ctx->next;
- }
- }
+ explicit literal_references_visitor(factor_vm *parent_, slot_visitor<Visitor> *visitor_)
+ : parent(parent_), visitor(visitor_) {}
- void visit_literal_references(code_block *compiled)
+ void operator()(relocation_entry rel, cell index, code_block *compiled)
{
- visit_handle(&compiled->owner);
- visit_handle(&compiled->literals);
- visit_handle(&compiled->relocation);
+ 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);
+ }
}
};
+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);
+}
+
}