vm: callstack_reversed for callstack_to_array
parent
0af5fff27c
commit
a1958c67bd
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
|
11
vm/vm.hpp
11
vm/vm.hpp
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue