From a1958c67bd6116dfb4f0c363fdc8fcb79cd036e1 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Tue, 6 Dec 2011 14:51:41 -0800 Subject: [PATCH] vm: callstack_reversed for callstack_to_array --- vm/callstack.cpp | 28 +++++++++++++++++----------- vm/callstack.hpp | 42 ++++++++++++++---------------------------- vm/code_blocks.cpp | 8 ++++++++ vm/code_blocks.hpp | 1 + vm/vm.hpp | 11 ++++++----- 5 files changed, 46 insertions(+), 44 deletions(-) diff --git a/vm/callstack.cpp b/vm/callstack.cpp index fcf517fde5..f18dc04392 100755 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -79,11 +79,7 @@ cell factor_vm::frame_executing(stack_frame *frame) cell factor_vm::frame_executing_quot(stack_frame *frame) { - tagged executing(frame_executing(frame)); - code_block *compiled = frame_code(frame); - if(!compiled->optimized_p() && executing->type() == WORD_TYPE) - executing = executing.as()->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 executing_quot(parent->frame_executing_quot(frame),parent); - data_root executing(parent->frame_executing(frame),parent); - data_root scan(parent->frame_scan(frame),parent); + data_root executing_quot(owner->owner_quot(),parent); + data_root executing(owner->owner,parent); + data_root 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(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) diff --git a/vm/callstack.hpp b/vm/callstack.hpp index dd80608d48..e17f36895a 100755 --- a/vm/callstack.hpp +++ b/vm/callstack.hpp @@ -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 -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 stack(stack_,this); @@ -43,7 +43,14 @@ void factor_vm::iterate_callstack_object_reversed(callstack *stack_, } template -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 +inline void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator) { data_root 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 -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 -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); } + } diff --git a/vm/code_blocks.cpp b/vm/code_blocks.cpp index c2f572bdba..3781453c76 100755 --- a/vm/code_blocks.cpp +++ b/vm/code_blocks.cpp @@ -3,6 +3,14 @@ namespace factor { +cell code_block::owner_quot() const +{ + tagged executing(owner); + if (!optimized_p() && executing->type() == WORD_TYPE) + executing = executing.as()->def; + return executing.value(); +} + cell code_block::scan(factor_vm *vm, void *addr) const { switch(type()) diff --git a/vm/code_blocks.hpp b/vm/code_blocks.hpp index d7e2858684..4f67a19926 100644 --- a/vm/code_blocks.hpp +++ b/vm/code_blocks.hpp @@ -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); diff --git a/vm/vm.hpp b/vm/vm.hpp index 2cf4538404..07ebcc1f1a 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -626,8 +626,10 @@ struct factor_vm void iterate_callstack_object(callstack *stack_, Iterator &iterator); template - void iterate_callstack_object_reversed(callstack *stack_, - Iterator &iterator, Fixup &fixup); + void iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator, + Fixup &fixup); + template + 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 - void iterate_callstack_reversed(context *ctx, Iterator &iterator); - template void iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup); + template + void iterate_callstack_reversed(context *ctx, Iterator &iterator); // cpu-* void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);