}
}
-template<typename Iterator> void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator)
+template<typename Iterator> void factor_vm::iterate_callstack_object(callstack *stack_,
+ Iterator &iterator)
{
data_root<callstack> stack(stack_,this);
fixnum frame_offset = factor::untag_fixnum(stack->length) - sizeof(stack_frame);
}
}
+template<typename Iterator, typename Fixup>
+void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup)
+{
+ if (ctx->callstack_top == ctx->callstack_bottom)
+ return;
+
+ char *frame_top = (char*)ctx->callstack_top;
+
+ while (frame_top < (char*)ctx->callstack_bottom)
+ {
+ void *addr = frame_return_address((void*)frame_top);
+ FACTOR_ASSERT(addr != 0);
+
+ 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*)(frame_top + frame_size) - 1;
+ 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(frame_top, owner, fixed_addr);
+ frame_top += frame_size;
+ }
+}
+
template<typename Iterator>
void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator)
{
explicit call_frame_code_block_visitor(factor_vm *parent_, Fixup fixup_) :
parent(parent_), fixup(fixup_) {}
- void operator()(stack_frame *frame)
+ void operator()(void *frame_top, code_block *owner, void *addr)
{
- cell offset = parent->frame_offset(frame);
- code_block *compiled = fixup.fixup_code(parent->frame_code(frame));
- frame->entry_point = compiled->entry_point();
- parent->set_frame_offset(frame,offset);
+ set_frame_return_address(frame_top, addr);
+ // XXX remove this when prolog data is removed
+ cell frame_size = owner->stack_frame_size_for_address((cell)addr);
+ stack_frame *frame = (stack_frame*)((char*)frame_top + frame_size) - 1;
+ frame->entry_point = owner->entry_point();
}
};
{
callstack *stack = (callstack *)obj;
call_frame_code_block_visitor<Fixup> call_frame_visitor(parent,fixup);
- parent->iterate_callstack_object(stack,call_frame_visitor);
+ parent->iterate_callstack_object_reversed(stack,call_frame_visitor,fixup);
break;
}
}
void code_block_visitor<Fixup>::visit_context_code_blocks()
{
call_frame_code_block_visitor<Fixup> call_frame_visitor(parent,fixup);
- parent->iterate_active_callstacks(call_frame_visitor);
+ parent->iterate_active_callstacks_reversed(call_frame_visitor,fixup);
}
template<typename Fixup>
return *(void**)frame_top;
}
-inline static void set_frame_return_address(void *frame_top, cell return_address)
+inline static void set_frame_return_address(void *frame_top, void *return_address)
{
- *(cell*)frame_top = return_address;
+ *(void**)frame_top = return_address;
}
#define CALLSTACK_BOTTOM(ctx) (stack_frame *)(ctx->callstack_seg->end - sizeof(cell) * 5)
}
else if(strcmp(cmd,"code") == 0)
dump_code_heap();
+ else if(strcmp(cmd,"compact-gc") == 0)
+ primitive_compact_gc();
else if(strcmp(cmd,"gc") == 0)
primitive_full_gc();
else if(strcmp(cmd,"compact-gc") == 0)
//FACTOR_ASSERT(marked_p(original));
#endif
std::pair<cell,cell> position = bitmap_deref(original);
+ cell offset = (cell)original & (data_alignment - 1);
cell approx_popcount = forwarding[position.first];
cell mask = ((cell)1 << position.second) - 1;
cell new_line_number = approx_popcount + popcount(marked[position.first] & mask);
- Block *new_block = line_block(new_line_number);
+ Block *new_block = (Block*)((char*)line_block(new_line_number) + offset);
#ifdef FACTOR_DEBUG
FACTOR_ASSERT(new_block <= original);
#endif
void slot_visitor<Fixup>::visit_callstack(context *ctx)
{
call_frame_slot_visitor<Fixup> call_frame_visitor(parent,this);
- parent->iterate_callstack_reversed(ctx,call_frame_visitor);
+ parent->iterate_callstack_reversed(ctx,call_frame_visitor,fixup);
}
template<typename Fixup>
void primitive_check_datastack();
void primitive_load_locals();
- template<typename Iterator> void iterate_active_callstacks(Iterator &iter)
+ template<typename Iterator>
+ void iterate_active_callstacks(Iterator &iter)
{
std::set<context *>::const_iterator begin = active_contexts.begin();
std::set<context *>::const_iterator end = active_contexts.end();
}
}
+ template<typename Iterator, typename Fixup>
+ void iterate_active_callstacks_reversed(Iterator &iter, Fixup &fixup)
+ {
+ std::set<context *>::const_iterator begin = active_contexts.begin();
+ std::set<context *>::const_iterator end = active_contexts.end();
+ while(begin != end)
+ {
+ iterate_callstack_reversed(*begin++,iter,fixup);
+ }
+ }
+
// run
void primitive_exit();
void primitive_nano_count();
void primitive_innermost_stack_frame_scan();
void primitive_set_innermost_stack_frame_quot();
void primitive_callstack_bounds();
- template<typename Iterator> void iterate_callstack_reversed(context *ctx, Iterator &iterator);
- template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
+
+ template<typename Iterator>
+ void iterate_callstack_reversed(context *ctx, Iterator &iterator);
+
+ template<typename Iterator, typename Fixup>
+ void iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup);
+
+ template<typename Iterator>
+ void iterate_callstack(context *ctx, Iterator &iterator);
// cpu-*
void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);