VM: Refactor slot_visitor.hpp to Factor style
parent
b1ccfa2194
commit
6d5197923c
|
@ -1,14 +1,11 @@
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
/* Size of the object pointed to by an untagged pointer */
|
/* Size of the object pointed to by an untagged pointer */
|
||||||
template<typename Fixup>
|
template <typename Fixup> cell object::size(Fixup fixup) const {
|
||||||
cell object::size(Fixup fixup) const
|
if (free_p())
|
||||||
{
|
return ((free_heap_block*)this)->size();
|
||||||
if(free_p()) return ((free_heap_block *)this)->size();
|
|
||||||
|
|
||||||
switch(type())
|
switch (type()) {
|
||||||
{
|
|
||||||
case ARRAY_TYPE:
|
case ARRAY_TYPE:
|
||||||
return align(array_size((array*)this), data_alignment);
|
return align(array_size((array*)this), data_alignment);
|
||||||
case BIGNUM_TYPE:
|
case BIGNUM_TYPE:
|
||||||
|
@ -17,9 +14,9 @@ cell object::size(Fixup fixup) const
|
||||||
return align(array_size((byte_array*)this), data_alignment);
|
return align(array_size((byte_array*)this), data_alignment);
|
||||||
case STRING_TYPE:
|
case STRING_TYPE:
|
||||||
return align(string_size(string_capacity((string*)this)), data_alignment);
|
return align(string_size(string_capacity((string*)this)), data_alignment);
|
||||||
case TUPLE_TYPE:
|
case TUPLE_TYPE: {
|
||||||
{
|
tuple_layout* layout = (tuple_layout*)fixup.translate_data(
|
||||||
tuple_layout *layout = (tuple_layout *)fixup.translate_data(untag<object>(((tuple *)this)->layout));
|
untag<object>(((tuple*)this)->layout));
|
||||||
return align(tuple_size(layout), data_alignment);
|
return align(tuple_size(layout), data_alignment);
|
||||||
}
|
}
|
||||||
case QUOTATION_TYPE:
|
case QUOTATION_TYPE:
|
||||||
|
@ -35,28 +32,25 @@ cell object::size(Fixup fixup) const
|
||||||
case WRAPPER_TYPE:
|
case WRAPPER_TYPE:
|
||||||
return align(sizeof(wrapper), data_alignment);
|
return align(sizeof(wrapper), data_alignment);
|
||||||
case CALLSTACK_TYPE:
|
case CALLSTACK_TYPE:
|
||||||
return align(callstack_object_size(untag_fixnum(((callstack *)this)->length)),data_alignment);
|
return align(
|
||||||
|
callstack_object_size(untag_fixnum(((callstack*)this)->length)),
|
||||||
|
data_alignment);
|
||||||
default:
|
default:
|
||||||
critical_error("Invalid header in size", (cell) this);
|
critical_error("Invalid header in size", (cell) this);
|
||||||
return 0; /* can't happen */
|
return 0; /* can't happen */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline cell object::size() const
|
inline cell object::size() const { return size(no_fixup()); }
|
||||||
{
|
|
||||||
return size(no_fixup());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The number of cells from the start of the object which should be scanned by
|
/* The number of cells from the start of the object which should be scanned by
|
||||||
the GC. Some types have a binary payload at the end (string, word, DLL) which
|
the GC. Some types have a binary payload at the end (string, word, DLL) which
|
||||||
we ignore. */
|
we ignore. */
|
||||||
template<typename Fixup>
|
template <typename Fixup> cell object::binary_payload_start(Fixup fixup) const {
|
||||||
cell object::binary_payload_start(Fixup fixup) const
|
if (free_p())
|
||||||
{
|
return 0;
|
||||||
if(free_p()) return 0;
|
|
||||||
|
|
||||||
switch(type())
|
switch (type()) {
|
||||||
{
|
|
||||||
/* these objects do not refer to other objects at all */
|
/* these objects do not refer to other objects at all */
|
||||||
case FLOAT_TYPE:
|
case FLOAT_TYPE:
|
||||||
case BYTE_ARRAY_TYPE:
|
case BYTE_ARRAY_TYPE:
|
||||||
|
@ -77,9 +71,9 @@ cell object::binary_payload_start(Fixup fixup) const
|
||||||
/* everything else consists entirely of pointers */
|
/* everything else consists entirely of pointers */
|
||||||
case ARRAY_TYPE:
|
case ARRAY_TYPE:
|
||||||
return array_size<array>(array_capacity((array*)this));
|
return array_size<array>(array_capacity((array*)this));
|
||||||
case TUPLE_TYPE:
|
case TUPLE_TYPE: {
|
||||||
{
|
tuple_layout* layout = (tuple_layout*)fixup.translate_data(
|
||||||
tuple_layout *layout = (tuple_layout *)fixup.translate_data(untag<object>(((tuple *)this)->layout));
|
untag<object>(((tuple*)this)->layout));
|
||||||
return tuple_size(layout);
|
return tuple_size(layout);
|
||||||
}
|
}
|
||||||
case WRAPPER_TYPE:
|
case WRAPPER_TYPE:
|
||||||
|
@ -90,14 +84,14 @@ cell object::binary_payload_start(Fixup fixup) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline cell object::binary_payload_start() const
|
inline cell object::binary_payload_start() const {
|
||||||
{
|
|
||||||
return binary_payload_start(no_fixup());
|
return binary_payload_start(no_fixup());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Slot visitors iterate over the slots of an object, applying a functor to
|
/* Slot visitors iterate over the slots of an object, applying a functor to
|
||||||
each one that is a non-immediate slot. The pointer is untagged first. The
|
each one that is a non-immediate slot. The pointer is untagged first. The
|
||||||
functor returns a new untagged object pointer. The return value may or may not equal the old one,
|
functor returns a new untagged object pointer. The return value may or may not
|
||||||
|
equal the old one,
|
||||||
however the new pointer receives the same tag before being stored back to the
|
however the new pointer receives the same tag before being stored back to the
|
||||||
original location.
|
original location.
|
||||||
|
|
||||||
|
@ -115,8 +109,8 @@ template<typename Fixup> struct slot_visitor {
|
||||||
factor_vm* parent;
|
factor_vm* parent;
|
||||||
Fixup fixup;
|
Fixup fixup;
|
||||||
|
|
||||||
explicit slot_visitor<Fixup>(factor_vm *parent_, Fixup fixup_) :
|
explicit slot_visitor<Fixup>(factor_vm* parent_, Fixup fixup_)
|
||||||
parent(parent_), fixup(fixup_) {}
|
: parent(parent_), fixup(fixup_) {}
|
||||||
|
|
||||||
cell visit_pointer(cell pointer);
|
cell visit_pointer(cell pointer);
|
||||||
void visit_handle(cell* handle);
|
void visit_handle(cell* handle);
|
||||||
|
@ -139,42 +133,36 @@ template<typename Fixup> struct slot_visitor {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
cell slot_visitor<Fixup>::visit_pointer(cell pointer)
|
cell slot_visitor<Fixup>::visit_pointer(cell pointer) {
|
||||||
{
|
if (immediate_p(pointer))
|
||||||
if(immediate_p(pointer)) return pointer;
|
return pointer;
|
||||||
|
|
||||||
object* untagged = fixup.fixup_data(untag<object>(pointer));
|
object* untagged = fixup.fixup_data(untag<object>(pointer));
|
||||||
return RETAG(untagged, TAG(pointer));
|
return RETAG(untagged, TAG(pointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_handle(cell* handle) {
|
||||||
void slot_visitor<Fixup>::visit_handle(cell *handle)
|
|
||||||
{
|
|
||||||
*handle = visit_pointer(*handle);
|
*handle = visit_pointer(*handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_object_array(cell *start, cell *end)
|
void slot_visitor<Fixup>::visit_object_array(cell* start, cell* end) {
|
||||||
{
|
while (start < end)
|
||||||
while(start < end) visit_handle(start++);
|
visit_handle(start++);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_slots(object *ptr, cell payload_start)
|
void slot_visitor<Fixup>::visit_slots(object* ptr, cell payload_start) {
|
||||||
{
|
|
||||||
cell* slot = (cell*)ptr;
|
cell* slot = (cell*)ptr;
|
||||||
cell* end = (cell*)((cell) ptr + payload_start);
|
cell* end = (cell*)((cell) ptr + payload_start);
|
||||||
|
|
||||||
if(slot != end)
|
if (slot != end) {
|
||||||
{
|
|
||||||
slot++;
|
slot++;
|
||||||
visit_object_array(slot, end);
|
visit_object_array(slot, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_slots(object* obj) {
|
||||||
void slot_visitor<Fixup>::visit_slots(object *obj)
|
|
||||||
{
|
|
||||||
if (obj->type() == CALLSTACK_TYPE)
|
if (obj->type() == CALLSTACK_TYPE)
|
||||||
visit_callstack_object((callstack*)obj);
|
visit_callstack_object((callstack*)obj);
|
||||||
else
|
else
|
||||||
|
@ -182,29 +170,24 @@ void slot_visitor<Fixup>::visit_slots(object *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_stack_elements(segment *region, cell *top)
|
void slot_visitor<Fixup>::visit_stack_elements(segment* region, cell* top) {
|
||||||
{
|
|
||||||
visit_object_array((cell*)region->start, top + 1);
|
visit_object_array((cell*)region->start, top + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_data_roots() {
|
||||||
void slot_visitor<Fixup>::visit_data_roots()
|
std::vector<data_root_range>::const_iterator iter =
|
||||||
{
|
parent->data_roots.begin();
|
||||||
std::vector<data_root_range>::const_iterator iter = parent->data_roots.begin();
|
|
||||||
std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
|
std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
|
||||||
|
|
||||||
for (; iter < end; iter++)
|
for (; iter < end; iter++)
|
||||||
visit_object_array(iter->start, iter->start + iter->len);
|
visit_object_array(iter->start, iter->start + iter->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_bignum_roots() {
|
||||||
void slot_visitor<Fixup>::visit_bignum_roots()
|
|
||||||
{
|
|
||||||
std::vector<cell>::const_iterator iter = parent->bignum_roots.begin();
|
std::vector<cell>::const_iterator iter = parent->bignum_roots.begin();
|
||||||
std::vector<cell>::const_iterator end = parent->bignum_roots.end();
|
std::vector<cell>::const_iterator end = parent->bignum_roots.end();
|
||||||
|
|
||||||
for(; iter < end; iter++)
|
for (; iter < end; iter++) {
|
||||||
{
|
|
||||||
cell* handle = (cell*)(*iter);
|
cell* handle = (cell*)(*iter);
|
||||||
|
|
||||||
if (*handle)
|
if (*handle)
|
||||||
|
@ -212,70 +195,54 @@ void slot_visitor<Fixup>::visit_bignum_roots()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> struct callback_slot_visitor {
|
||||||
struct callback_slot_visitor {
|
|
||||||
callback_heap* callbacks;
|
callback_heap* callbacks;
|
||||||
slot_visitor<Fixup>* visitor;
|
slot_visitor<Fixup>* visitor;
|
||||||
|
|
||||||
explicit callback_slot_visitor(callback_heap *callbacks_, slot_visitor<Fixup> *visitor_) :
|
explicit callback_slot_visitor(callback_heap* callbacks_,
|
||||||
callbacks(callbacks_), visitor(visitor_) {}
|
slot_visitor<Fixup>* visitor_)
|
||||||
|
: callbacks(callbacks_), visitor(visitor_) {}
|
||||||
|
|
||||||
void operator()(code_block *stub)
|
void operator()(code_block* stub) { visitor->visit_handle(&stub->owner); }
|
||||||
{
|
|
||||||
visitor->visit_handle(&stub->owner);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_callback_roots() {
|
||||||
void slot_visitor<Fixup>::visit_callback_roots()
|
|
||||||
{
|
|
||||||
callback_slot_visitor<Fixup> callback_visitor(parent->callbacks, this);
|
callback_slot_visitor<Fixup> callback_visitor(parent->callbacks, this);
|
||||||
parent->callbacks->each_callback(callback_visitor);
|
parent->callbacks->each_callback(callback_visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_literal_table_roots()
|
void slot_visitor<Fixup>::visit_literal_table_roots() {
|
||||||
{
|
std::map<code_block*, cell>* uninitialized_blocks =
|
||||||
std::map<code_block *, cell> *uninitialized_blocks = &parent->code->uninitialized_blocks;
|
&parent->code->uninitialized_blocks;
|
||||||
std::map<code_block *, cell>::const_iterator iter = uninitialized_blocks->begin();
|
std::map<code_block*, cell>::const_iterator iter =
|
||||||
|
uninitialized_blocks->begin();
|
||||||
std::map<code_block*, cell>::const_iterator end = uninitialized_blocks->end();
|
std::map<code_block*, cell>::const_iterator end = uninitialized_blocks->end();
|
||||||
|
|
||||||
std::map<code_block*, cell> new_uninitialized_blocks;
|
std::map<code_block*, cell> new_uninitialized_blocks;
|
||||||
for(; iter != end; iter++)
|
for (; iter != end; iter++) {
|
||||||
{
|
new_uninitialized_blocks.insert(
|
||||||
new_uninitialized_blocks.insert(std::make_pair(
|
std::make_pair(iter->first, visit_pointer(iter->second)));
|
||||||
iter->first,
|
|
||||||
visit_pointer(iter->second)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parent->code->uninitialized_blocks = new_uninitialized_blocks;
|
parent->code->uninitialized_blocks = new_uninitialized_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_sample_callstacks() {
|
||||||
void slot_visitor<Fixup>::visit_sample_callstacks()
|
|
||||||
{
|
|
||||||
for (std::vector<cell>::iterator iter = parent->sample_callstacks.begin();
|
for (std::vector<cell>::iterator iter = parent->sample_callstacks.begin();
|
||||||
iter != parent->sample_callstacks.end();
|
iter != parent->sample_callstacks.end(); ++iter) {
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
visit_handle(&*iter);
|
visit_handle(&*iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_sample_threads() {
|
||||||
void slot_visitor<Fixup>::visit_sample_threads()
|
|
||||||
{
|
|
||||||
for (std::vector<profiling_sample>::iterator iter = parent->samples.begin();
|
for (std::vector<profiling_sample>::iterator iter = parent->samples.begin();
|
||||||
iter != parent->samples.end();
|
iter != parent->samples.end(); ++iter) {
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
visit_handle(&iter->thread);
|
visit_handle(&iter->thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_roots() {
|
||||||
void slot_visitor<Fixup>::visit_roots()
|
|
||||||
{
|
|
||||||
visit_handle(&parent->true_object);
|
visit_handle(&parent->true_object);
|
||||||
visit_handle(&parent->bignum_zero);
|
visit_handle(&parent->bignum_zero);
|
||||||
visit_handle(&parent->bignum_pos_one);
|
visit_handle(&parent->bignum_pos_one);
|
||||||
|
@ -288,16 +255,17 @@ void slot_visitor<Fixup>::visit_roots()
|
||||||
visit_sample_callstacks();
|
visit_sample_callstacks();
|
||||||
visit_sample_threads();
|
visit_sample_threads();
|
||||||
|
|
||||||
visit_object_array(parent->special_objects,parent->special_objects + special_object_count);
|
visit_object_array(parent->special_objects,
|
||||||
|
parent->special_objects + special_object_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> struct call_frame_slot_visitor {
|
||||||
struct call_frame_slot_visitor {
|
|
||||||
factor_vm* parent;
|
factor_vm* parent;
|
||||||
slot_visitor<Fixup>* visitor;
|
slot_visitor<Fixup>* visitor;
|
||||||
|
|
||||||
explicit call_frame_slot_visitor(factor_vm *parent_, slot_visitor<Fixup> *visitor_) :
|
explicit call_frame_slot_visitor(factor_vm* parent_,
|
||||||
parent(parent_), visitor(visitor_) {}
|
slot_visitor<Fixup>* visitor_)
|
||||||
|
: parent(parent_), visitor(visitor_) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
frame top -> [return address]
|
frame top -> [return address]
|
||||||
|
@ -306,12 +274,12 @@ struct call_frame_slot_visitor {
|
||||||
[entry_point]
|
[entry_point]
|
||||||
[size]
|
[size]
|
||||||
*/
|
*/
|
||||||
void operator()(void *frame_top, cell frame_size, code_block *owner, void *addr)
|
void operator()(void* frame_top, cell frame_size, code_block* owner,
|
||||||
{
|
void* addr) {
|
||||||
cell return_address = owner->offset(addr);
|
cell return_address = owner->offset(addr);
|
||||||
|
|
||||||
code_block *compiled = Fixup::translated_code_block_map
|
code_block* compiled =
|
||||||
? owner
|
Fixup::translated_code_block_map ? owner
|
||||||
: visitor->fixup.translate_code(owner);
|
: visitor->fixup.translate_code(owner);
|
||||||
gc_info* info = compiled->block_gc_info();
|
gc_info* info = compiled->block_gc_info();
|
||||||
|
|
||||||
|
@ -321,21 +289,20 @@ struct call_frame_slot_visitor {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef DEBUG_GC_MAPS
|
#ifdef DEBUG_GC_MAPS
|
||||||
std::cout << "call frame code block " << compiled << " with offset " << return_address << std::endl;
|
std::cout << "call frame code block " << compiled << " with offset "
|
||||||
|
<< return_address << std::endl;
|
||||||
#endif
|
#endif
|
||||||
cell* stack_pointer = (cell*)frame_top;
|
cell* stack_pointer = (cell*)frame_top;
|
||||||
u8* bitmap = info->gc_info_bitmap();
|
u8* bitmap = info->gc_info_bitmap();
|
||||||
|
|
||||||
/* Subtract old value of base pointer from every derived pointer. */
|
/* Subtract old value of base pointer from every derived pointer. */
|
||||||
for(cell spill_slot = 0; spill_slot < info->derived_root_count; spill_slot++)
|
for (cell spill_slot = 0; spill_slot < info->derived_root_count;
|
||||||
{
|
spill_slot++) {
|
||||||
u32 base_pointer = info->lookup_base_pointer(callsite, spill_slot);
|
u32 base_pointer = info->lookup_base_pointer(callsite, spill_slot);
|
||||||
if(base_pointer != (u32)-1)
|
if (base_pointer != (u32) - 1) {
|
||||||
{
|
|
||||||
#ifdef DEBUG_GC_MAPS
|
#ifdef DEBUG_GC_MAPS
|
||||||
std::cout << "visiting derived root " << spill_slot
|
std::cout << "visiting derived root " << spill_slot
|
||||||
<< " with base pointer " << base_pointer
|
<< " with base pointer " << base_pointer << std::endl;
|
||||||
<< std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
stack_pointer[spill_slot] -= stack_pointer[base_pointer];
|
stack_pointer[spill_slot] -= stack_pointer[base_pointer];
|
||||||
}
|
}
|
||||||
|
@ -344,10 +311,8 @@ struct call_frame_slot_visitor {
|
||||||
/* Update all GC roots, including base pointers. */
|
/* Update all GC roots, including base pointers. */
|
||||||
cell callsite_gc_roots = info->callsite_gc_roots(callsite);
|
cell callsite_gc_roots = info->callsite_gc_roots(callsite);
|
||||||
|
|
||||||
for(cell spill_slot = 0; spill_slot < info->gc_root_count; spill_slot++)
|
for (cell spill_slot = 0; spill_slot < info->gc_root_count; spill_slot++) {
|
||||||
{
|
if (bitmap_p(bitmap, callsite_gc_roots + spill_slot)) {
|
||||||
if(bitmap_p(bitmap,callsite_gc_roots + spill_slot))
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_GC_MAPS
|
#ifdef DEBUG_GC_MAPS
|
||||||
std::cout << "visiting GC root " << spill_slot << std::endl;
|
std::cout << "visiting GC root " << spill_slot << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
@ -356,8 +321,8 @@ struct call_frame_slot_visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the base pointers to obtain new derived pointer values. */
|
/* Add the base pointers to obtain new derived pointer values. */
|
||||||
for(cell spill_slot = 0; spill_slot < info->derived_root_count; spill_slot++)
|
for (cell spill_slot = 0; spill_slot < info->derived_root_count;
|
||||||
{
|
spill_slot++) {
|
||||||
u32 base_pointer = info->lookup_base_pointer(callsite, spill_slot);
|
u32 base_pointer = info->lookup_base_pointer(callsite, spill_slot);
|
||||||
if (base_pointer != (u32) - 1)
|
if (base_pointer != (u32) - 1)
|
||||||
stack_pointer[spill_slot] += stack_pointer[base_pointer];
|
stack_pointer[spill_slot] += stack_pointer[base_pointer];
|
||||||
|
@ -366,62 +331,54 @@ struct call_frame_slot_visitor {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_callstack_object(callstack *stack)
|
void slot_visitor<Fixup>::visit_callstack_object(callstack* stack) {
|
||||||
{
|
|
||||||
call_frame_slot_visitor<Fixup> call_frame_visitor(parent, this);
|
call_frame_slot_visitor<Fixup> call_frame_visitor(parent, this);
|
||||||
parent->iterate_callstack_object(stack, call_frame_visitor, fixup);
|
parent->iterate_callstack_object(stack, call_frame_visitor, fixup);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_callstack(context *ctx)
|
void slot_visitor<Fixup>::visit_callstack(context* ctx) {
|
||||||
{
|
|
||||||
call_frame_slot_visitor<Fixup> call_frame_visitor(parent, this);
|
call_frame_slot_visitor<Fixup> call_frame_visitor(parent, this);
|
||||||
parent->iterate_callstack(ctx, call_frame_visitor, fixup);
|
parent->iterate_callstack(ctx, call_frame_visitor, fixup);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> void slot_visitor<Fixup>::visit_contexts() {
|
||||||
void slot_visitor<Fixup>::visit_contexts()
|
|
||||||
{
|
|
||||||
std::set<context*>::const_iterator begin = parent->active_contexts.begin();
|
std::set<context*>::const_iterator begin = parent->active_contexts.begin();
|
||||||
std::set<context*>::const_iterator end = parent->active_contexts.end();
|
std::set<context*>::const_iterator end = parent->active_contexts.end();
|
||||||
while(begin != end)
|
while (begin != end) {
|
||||||
{
|
|
||||||
context* ctx = *begin;
|
context* ctx = *begin;
|
||||||
|
|
||||||
visit_stack_elements(ctx->datastack_seg, (cell*)ctx->datastack);
|
visit_stack_elements(ctx->datastack_seg, (cell*)ctx->datastack);
|
||||||
visit_stack_elements(ctx->retainstack_seg, (cell*)ctx->retainstack);
|
visit_stack_elements(ctx->retainstack_seg, (cell*)ctx->retainstack);
|
||||||
visit_object_array(ctx->context_objects,ctx->context_objects + context_object_count);
|
visit_object_array(ctx->context_objects,
|
||||||
|
ctx->context_objects + context_object_count);
|
||||||
visit_callstack(ctx);
|
visit_callstack(ctx);
|
||||||
begin++;
|
begin++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fixup>
|
template <typename Fixup> struct literal_references_visitor {
|
||||||
struct literal_references_visitor {
|
|
||||||
slot_visitor<Fixup>* visitor;
|
slot_visitor<Fixup>* visitor;
|
||||||
|
|
||||||
explicit literal_references_visitor(slot_visitor<Fixup> *visitor_) : visitor(visitor_) {}
|
explicit literal_references_visitor(slot_visitor<Fixup>* visitor_)
|
||||||
|
: visitor(visitor_) {}
|
||||||
|
|
||||||
void operator()(instruction_operand op)
|
void operator()(instruction_operand op) {
|
||||||
{
|
|
||||||
if (op.rel_type() == RT_LITERAL)
|
if (op.rel_type() == RT_LITERAL)
|
||||||
op.store_value(visitor->visit_pointer(op.load_value()));
|
op.store_value(visitor->visit_pointer(op.load_value()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_code_block_objects(code_block *compiled)
|
void slot_visitor<Fixup>::visit_code_block_objects(code_block* compiled) {
|
||||||
{
|
|
||||||
visit_handle(&compiled->owner);
|
visit_handle(&compiled->owner);
|
||||||
visit_handle(&compiled->parameters);
|
visit_handle(&compiled->parameters);
|
||||||
visit_handle(&compiled->relocation);
|
visit_handle(&compiled->relocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
void slot_visitor<Fixup>::visit_embedded_literals(code_block *compiled)
|
void slot_visitor<Fixup>::visit_embedded_literals(code_block* compiled) {
|
||||||
{
|
if (!parent->code->uninitialized_p(compiled)) {
|
||||||
if(!parent->code->uninitialized_p(compiled))
|
|
||||||
{
|
|
||||||
literal_references_visitor<Fixup> visitor(this);
|
literal_references_visitor<Fixup> visitor(this);
|
||||||
compiled->each_instruction_operand(visitor);
|
compiled->each_instruction_operand(visitor);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue