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) cell factor_vm::frame_executing_quot(stack_frame *frame)
{ {
tagged<object> executing(frame_executing(frame)); return frame_code(frame)->owner_quot();
code_block *compiled = frame_code(frame);
if(!compiled->optimized_p() && executing->type() == WORD_TYPE)
executing = executing.as<word>()->def;
return executing.value();
} }
stack_frame *factor_vm::frame_successor(stack_frame *frame) stack_frame *factor_vm::frame_successor(stack_frame *frame)
@ -114,13 +110,14 @@ struct stack_frame_accumulator {
factor_vm *parent; factor_vm *parent;
growable_array frames; 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_quot(owner->owner_quot(),parent);
data_root<object> executing(parent->frame_executing(frame),parent); data_root<object> executing(owner->owner,parent);
data_root<object> scan(parent->frame_scan(frame),parent); data_root<object> scan(owner->scan(parent, addr),parent);
frames.add(executing.value()); frames.add(executing.value());
frames.add(executing_quot.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() void factor_vm::primitive_callstack_to_array()
{ {
data_root<callstack> callstack(ctx->pop(),this); data_root<callstack> callstack(ctx->pop(),this);
stack_frame_accumulator accum(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(); accum.frames.trim();
ctx->push(accum.frames.elements.value()); ctx->push(accum.frames.elements.value());
} }
stack_frame *factor_vm::innermost_stack_frame(stack_frame *bottom, stack_frame *top) 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 /* This is a little tricky. The iterator may allocate memory, so we
keep the callstack in a GC root and use relative offsets */ keep the callstack in a GC root and use relative offsets */
template<typename Iterator, typename Fixup> 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) Iterator &iterator, Fixup &fixup)
{ {
data_root<callstack> stack(stack_,this); data_root<callstack> stack(stack_,this);
@ -43,7 +43,14 @@ void factor_vm::iterate_callstack_object_reversed(callstack *stack_,
} }
template<typename Iterator> 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); data_root<callstack> stack(stack_,this);
fixnum frame_offset = factor::untag_fixnum(stack->length) - sizeof(stack_frame); 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> 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) if (ctx->callstack_top == ctx->callstack_bottom)
return; return;
@ -99,32 +106,11 @@ void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator, Fix
} }
template<typename Iterator> 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) no_fixup none;
return; iterate_callstack_reversed(ctx, iterator, none);
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;
}
} }
} }

View File

@ -3,6 +3,14 @@
namespace factor 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 cell code_block::scan(factor_vm *vm, void *addr) const
{ {
switch(type()) switch(type())

View File

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

View File

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