vm: callstack_reversed for callstack_to_array

db4
Joe Groff 2011-12-06 14:51:41 -08:00
parent 0af5fff27c
commit a1958c67bd
5 changed files with 46 additions and 44 deletions

View File

@ -79,11 +79,7 @@ cell factor_vm::frame_executing(stack_frame *frame)
cell factor_vm::frame_executing_quot(stack_frame *frame)
{
tagged<object> executing(frame_executing(frame));
code_block *compiled = frame_code(frame);
if(!compiled->optimized_p() && executing->type() == WORD_TYPE)
executing = executing.as<word>()->def;
return executing.value();
return frame_code(frame)->owner_quot();
}
stack_frame *factor_vm::frame_successor(stack_frame *frame)
@ -114,13 +110,14 @@ struct stack_frame_accumulator {
factor_vm *parent;
growable_array frames;
explicit stack_frame_accumulator(factor_vm *parent_) : parent(parent_), frames(parent_) {}
explicit stack_frame_accumulator(factor_vm *parent_)
: parent(parent_), frames(parent_) {}
void operator()(stack_frame *frame)
void operator()(void *frame_top, cell frame_size, code_block *owner, void *addr)
{
data_root<object> executing_quot(parent->frame_executing_quot(frame),parent);
data_root<object> executing(parent->frame_executing(frame),parent);
data_root<object> scan(parent->frame_scan(frame),parent);
data_root<object> executing_quot(owner->owner_quot(),parent);
data_root<object> executing(owner->owner,parent);
data_root<object> scan(owner->scan(parent, addr),parent);
frames.add(executing.value());
frames.add(executing_quot.value());
@ -128,15 +125,24 @@ struct stack_frame_accumulator {
}
};
struct stack_frame_in_array { cell cells[3]; };
void factor_vm::primitive_callstack_to_array()
{
data_root<callstack> callstack(ctx->pop(),this);
stack_frame_accumulator accum(this);
iterate_callstack_object(callstack.untagged(),accum);
iterate_callstack_object_reversed(callstack.untagged(),accum);
/* The callstack iterator visits frames in reverse order (top to bottom) */
std::reverse(
(stack_frame_in_array*)accum.frames.elements->data(),
(stack_frame_in_array*)(accum.frames.elements->data() + accum.frames.count));
accum.frames.trim();
ctx->push(accum.frames.elements.value());
}
stack_frame *factor_vm::innermost_stack_frame(stack_frame *bottom, stack_frame *top)

View File

@ -9,7 +9,7 @@ inline static cell callstack_object_size(cell size)
/* 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, typename Fixup>
void factor_vm::iterate_callstack_object_reversed(callstack *stack_,
inline void factor_vm::iterate_callstack_object_reversed(callstack *stack_,
Iterator &iterator, Fixup &fixup)
{
data_root<callstack> stack(stack_,this);
@ -43,7 +43,14 @@ void factor_vm::iterate_callstack_object_reversed(callstack *stack_,
}
template<typename Iterator>
void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator)
inline void factor_vm::iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator)
{
no_fixup none;
iterate_callstack_object_reversed(stack_, iterator, none);
}
template<typename Iterator>
inline 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);
@ -57,7 +64,7 @@ void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator)
}
template<typename Iterator, typename Fixup>
void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup)
inline void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup)
{
if (ctx->callstack_top == ctx->callstack_bottom)
return;
@ -99,32 +106,11 @@ void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator, Fix
}
template<typename Iterator>
void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator)
inline void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator)
{
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);
code_block *owner = code->code_block_for_address((cell)addr);
cell frame_size = owner->stack_frame_size_for_address((cell)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;
FACTOR_ASSERT(owner->entry_point() == frame->entry_point);
FACTOR_ASSERT(frame_size == frame->size);
#endif
iterator(frame_top, frame_size, owner, addr);
frame_top += frame_size;
}
no_fixup none;
iterate_callstack_reversed(ctx, iterator, none);
}
}

View File

@ -3,6 +3,14 @@
namespace factor
{
cell code_block::owner_quot() const
{
tagged<object> executing(owner);
if (!optimized_p() && executing->type() == WORD_TYPE)
executing = executing.as<word>()->def;
return executing.value();
}
cell code_block::scan(factor_vm *vm, void *addr) const
{
switch(type())

View File

@ -133,6 +133,7 @@ struct code_block
}
cell scan(factor_vm *vm, void *addr) const;
cell owner_quot() const;
};
VM_C_API void undefined_symbol(void);

View File

@ -626,8 +626,10 @@ struct factor_vm
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 iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator,
Fixup &fixup);
template<typename Iterator>
void iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator);
void check_frame(stack_frame *frame);
callstack *allot_callstack(cell size);
@ -650,11 +652,10 @@ struct factor_vm
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, typename Fixup>
void iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup);
template<typename Iterator>
void iterate_callstack_reversed(context *ctx, Iterator &iterator);
// cpu-*
void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);