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)
|
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)
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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);
|
||||||
|
|
11
vm/vm.hpp
11
vm/vm.hpp
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue