cell factor_vm::frame_offset(stack_frame *frame)
{
- char *entry_point = (char *)frame_code(frame)->entry_point();
char *return_address = (char *)FRAME_RETURN_ADDRESS(frame,this);
FACTOR_ASSERT(return_address != 0);
- return return_address - entry_point;
+ return frame_code(frame)->offset(return_address);
}
void factor_vm::set_frame_offset(stack_frame *frame, cell offset)
/* This is a little tricky. The iterator may allocate memory, so we
keep the callstack in a GC root and use relative offsets */
-template<typename Iterator>
-void factor_vm::iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator)
+template<typename Iterator, typename Fixup>
+void factor_vm::iterate_callstack_object_reversed(callstack *stack_,
+ Iterator &iterator, Fixup &fixup)
{
data_root<callstack> stack(stack_,this);
fixnum frame_length = factor::untag_fixnum(stack->length);
void *frame_top = stack->frame_top_at(frame_offset);
void *addr = frame_return_address(frame_top);
- code_block *owner = code->code_block_for_address(addr);
- cell frame_size = owner->stack_frame_size_for_address(addr);
+ void *fixed_addr = (void*)fixup.translate_code((code_block*)addr);
+ code_block *owner = code->code_block_for_address((cell)fixed_addr);
+ cell frame_size = owner->stack_frame_size_for_address((cell)fixed_addr);
#ifdef FACTOR_DEBUG
// check our derived owner and frame size against the ones stored in the frame
// by the function prolog
stack_frame *frame = (stack_frame*)((char*)frame_top + frame_size) - 1;
- FACTOR_ASSERT(owner->entry_point() == frame->entry_point);
+ void *fixed_entry_point =
+ (void*)fixup.translate_code((code_block*)frame->entry_point);
+ FACTOR_ASSERT(owner->entry_point() == fixed_entry_point);
FACTOR_ASSERT(frame_size == frame->size);
#endif
- iterator(owner, addr);
+ iterator(frame_top, owner, fixed_addr);
frame_offset += frame_size;
}
}
FACTOR_ASSERT(frame_size == frame->size);
#endif
+ iterator(frame_top, owner, addr);
frame_top += frame_size;
- iterator(owner, addr);
}
}
return (char*)addr - (char*)entry_point();
}
+ void *address_for_offset(cell offset) const
+ {
+ return (void*)((char*)entry_point() + offset);
+ }
+
cell scan(factor_vm *vm, void *addr) const;
};
code_block_compaction_updater<compaction_fixup> code_block_updater(this,fixup,data_forwarder,code_forwarder);
code->allocator->compact(code_block_updater,fixup,&code_finger);
+ code->update_all_blocks_set(code_forwarding_map);
+
data_forwarder.visit_roots();
if(trace_contexts_p)
{
factor_vm *parent;
explicit stack_frame_printer(factor_vm *parent_) : parent(parent_) {}
- void operator()(code_block *owner, void *addr)
+ void operator()(void *frame_top, code_block *owner, void *addr)
{
std::cout << std::endl;
+ std::cout << "frame: " << frame_top << std::endl;
std::cout << "executing: ";
parent->print_obj(owner->owner);
std::cout << std::endl;
}
code->allocator->initial_free_list(h->code_size);
+ code->initialize_all_blocks_set();
}
struct startup_fixup {
fixup_data(data_offset,code_offset);
fixup_code(data_offset,code_offset);
- code->initialize_all_blocks_set();
-
/* Store image path name */
special_objects[OBJ_IMAGE] = allot_alien(false_object,(cell)p->image_path);
}
Block *forward_block(const Block *original)
{
#ifdef FACTOR_DEBUG
- FACTOR_ASSERT(marked_p(original));
+ // XXX this condition seems to be harmless--ask slava
+ //FACTOR_ASSERT(marked_p(original));
#endif
std::pair<cell,cell> position = bitmap_deref(original);
parent(parent_), visitor(visitor_) {}
/*
- next -> [entry_point]
- [size]
- [return address] -- x86 only, backend adds 1 to each spill location
- [spill area]
- ...
- frame -> [entry_point]
- [size]
+ frame top -> [return address]
+ [spill area]
+ ...
+ [entry_point]
+ [size]
*/
- void operator()(stack_frame *frame)
+ void operator()(void *frame_top, code_block *owner, void *addr)
{
- cell return_address = parent->frame_offset(frame);
- if(return_address == (cell)-1)
- return;
+ cell return_address = owner->offset(addr);
- code_block *compiled = visitor->fixup.translate_code(parent->frame_code(frame));
- gc_info *info = compiled->block_gc_info();
+ gc_info *info = owner->block_gc_info();
- FACTOR_ASSERT(return_address < compiled->size());
+ FACTOR_ASSERT(return_address < owner->size());
cell callsite = info->return_address_index(return_address);
if(callsite == (cell)-1)
return;
#ifdef DEBUG_GC_MAPS
- std::cout << "call frame code block " << compiled << " with offset " << return_address << std::endl;
+ std::cout << "call frame code block " << owner << " with offset " << return_address << std::endl;
#endif
- cell *stack_pointer = (cell *)(parent->frame_successor(frame) + 1);
+ cell *stack_pointer = (cell *)frame_top;
u8 *bitmap = info->gc_info_bitmap();
/* Subtract old value of base pointer from every derived pointer. */
void slot_visitor<Fixup>::visit_callstack_object(callstack *stack)
{
call_frame_slot_visitor<Fixup> call_frame_visitor(parent,this);
- parent->iterate_callstack_object(stack,call_frame_visitor);
+ parent->iterate_callstack_object_reversed(stack,call_frame_visitor,fixup);
}
template<typename Fixup>
void slot_visitor<Fixup>::visit_callstack(context *ctx)
{
call_frame_slot_visitor<Fixup> call_frame_visitor(parent,this);
- parent->iterate_callstack(ctx,call_frame_visitor);
+ parent->iterate_callstack_reversed(ctx,call_frame_visitor);
}
template<typename Fixup>
bool embedded_image_p();
// callstack
- template<typename Iterator> void iterate_callstack_object(callstack *stack_, Iterator &iterator);
- template<typename Iterator> void iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator);
+ template<typename Iterator>
+ void iterate_callstack_object(callstack *stack_, Iterator &iterator);
+
+ template<typename Iterator, typename Fixup>
+ void iterate_callstack_object_reversed(callstack *stack_,
+ Iterator &iterator, Fixup &fixup);
+
void check_frame(stack_frame *frame);
callstack *allot_callstack(cell size);
stack_frame *second_from_top_stack_frame(context *ctx);