]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: callstack_reversed for callstack_to_array
authorJoe Groff <arcata@gmail.com>
Tue, 6 Dec 2011 22:51:41 +0000 (14:51 -0800)
committerJoe Groff <arcata@gmail.com>
Wed, 14 Dec 2011 17:56:48 +0000 (09:56 -0800)
vm/callstack.cpp
vm/callstack.hpp
vm/code_blocks.cpp
vm/code_blocks.hpp
vm/vm.hpp

index fcf517fde5f16abf34bc558d0390742f03edf7be..f18dc04392a2abbfe7724c15d75671cb6ff3aa19 100755 (executable)
@@ -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)
index dd80608d48eae1ca70eed7fdaa1e3c0e5692ffd3..e17f36895af39d2683f92eb3c79509d9ca018e7e 100755 (executable)
@@ -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);
 }
 
+
 }
index c2f572bdbad0534833d00806c52cf8c994e78aac..3781453c76145b82a9914240e4a69f5ca762d9be 100755 (executable)
@@ -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())
index d7e2858684d962135b3d6a94567afc145c71576d..4f67a199267335241d7275b183504349b5ebb6c8 100644 (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);
index 2cf45384049bb6eee0c2e47c95ecc2b64edd82c3..07ebcc1f1a73a1305e21cf97acb89390b9525e69 100755 (executable)
--- a/vm/vm.hpp
+++ b/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);