]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: replace remaining stack_frame-based logic
authorJoe Groff <arcata@gmail.com>
Wed, 7 Dec 2011 01:53:52 +0000 (17:53 -0800)
committerJoe Groff <arcata@gmail.com>
Wed, 14 Dec 2011 17:56:49 +0000 (09:56 -0800)
13 files changed:
vm/callstack.cpp
vm/callstack.hpp
vm/code_block_visitor.hpp
vm/code_blocks.cpp
vm/contexts.hpp
vm/cpu-ppc.hpp
vm/cpu-x86.cpp
vm/cpu-x86.hpp
vm/entry_points.cpp
vm/entry_points.hpp
vm/layouts.hpp
vm/sampling_profiler.cpp
vm/vm.hpp

index 70378da1d5758e0912799812bdc96e83e46a9f17..830ef6b35ce3bbfb1ccb77ad23695ee63fb44a61 100755 (executable)
@@ -3,14 +3,6 @@
 namespace factor
 {
 
-void factor_vm::check_frame(stack_frame *frame)
-{
-#ifdef FACTOR_DEBUG
-       check_code_pointer((cell)frame->entry_point);
-       FACTOR_ASSERT(frame->size != 0);
-#endif
-}
-
 callstack *factor_vm::allot_callstack(cell size)
 {
        callstack *stack = allot<callstack>(callstack_object_size(size));
@@ -26,22 +18,23 @@ This means that if 'callstack' is called in tail position, we
 will have popped a necessary frame... however this word is only
 called by continuation implementation, and user code shouldn't
 be calling it at all, so we leave it as it is for now. */
-stack_frame *factor_vm::second_from_top_stack_frame(context *ctx)
+void *factor_vm::second_from_top_stack_frame(context *ctx)
 {
-       stack_frame *frame = ctx->bottom_frame();
-       while(frame >= ctx->callstack_top
-               && frame_successor(frame) >= ctx->callstack_top
-               && frame_successor(frame_successor(frame)) >= ctx->callstack_top)
+       void *frame_top = ctx->callstack_top;
+       for (unsigned i = 0; i < 2; ++i)
        {
-               frame = frame_successor(frame);
+               void *pred = frame_predecessor(frame_top);
+               if (pred >= ctx->callstack_bottom)
+                       return frame_top;
+               frame_top = pred;
        }
-       return frame + 1;
+       return frame_top;
 }
 
 cell factor_vm::capture_callstack(context *ctx)
 {
-       stack_frame *top = second_from_top_stack_frame(ctx);
-       stack_frame *bottom = ctx->callstack_bottom;
+       void *top = second_from_top_stack_frame(ctx);
+       void *bottom = ctx->callstack_bottom;
 
        fixnum size = std::max((fixnum)0,(fixnum)bottom - (fixnum)top);
 
@@ -61,49 +54,13 @@ void factor_vm::primitive_callstack_for()
        ctx->push(capture_callstack(other_ctx));
 }
 
-code_block *factor_vm::frame_code(stack_frame *frame)
-{
-       check_frame(frame);
-       return (code_block *)frame->entry_point - 1;
-}
-
-code_block_type factor_vm::frame_type(stack_frame *frame)
-{
-       return frame_code(frame)->type();
-}
-
-cell factor_vm::frame_executing(stack_frame *frame)
-{
-       return frame_code(frame)->owner;
-}
-
-cell factor_vm::frame_executing_quot(stack_frame *frame)
-{
-       return frame_code(frame)->owner_quot();
-}
-
-stack_frame *factor_vm::frame_successor(stack_frame *frame)
-{
-       check_frame(frame);
-       return (stack_frame *)((cell)frame - frame->size);
-}
-
-cell factor_vm::frame_offset(stack_frame *frame)
-{
-       char *return_address = (char *)FRAME_RETURN_ADDRESS(frame,this);
-       FACTOR_ASSERT(return_address != 0);
-       return frame_code(frame)->offset(return_address);
-}
-
-void factor_vm::set_frame_offset(stack_frame *frame, cell offset)
+void *factor_vm::frame_predecessor(void *frame_top)
 {
-       char *entry_point = (char *)frame_code(frame)->entry_point();
-       FRAME_RETURN_ADDRESS(frame,this) = entry_point + offset;
-}
-
-cell factor_vm::frame_scan(stack_frame *frame)
-{
-       return frame_code(frame)->scan(this, FRAME_RETURN_ADDRESS(frame,this));
+       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);
+       return (void*)((char*)frame_top + frame_size);
 }
 
 struct stack_frame_accumulator {
@@ -145,14 +102,18 @@ void factor_vm::primitive_callstack_to_array()
 
 }
 
-stack_frame *factor_vm::innermost_stack_frame(stack_frame *bottom, stack_frame *top)
+void *factor_vm::innermost_stack_frame(void *bottom, void *top)
 {
-       stack_frame *frame = bottom - 1;
-
-       while(frame >= top && frame_successor(frame) >= top)
-               frame = frame_successor(frame);
-
-       return frame;
+       /* if (top < bottom)
+       {
+               void *pred = frame_predecessor(top);
+               if (pred < bottom)
+                       return pred;
+               else
+                       return top;
+       }
+       else */
+               return top;
 }
 
 /* Some primitives implementing a limited form of callstack mutation.
@@ -160,15 +121,17 @@ Used by the single stepper. */
 void factor_vm::primitive_innermost_stack_frame_executing()
 {
        callstack *stack = untag_check<callstack>(ctx->pop());
-       stack_frame *frame = innermost_stack_frame(stack->bottom(), stack->top());
-       ctx->push(frame_executing_quot(frame));
+       void *frame = innermost_stack_frame(stack->bottom(), stack->top());
+       void *addr = frame_return_address(frame);
+       ctx->push(code->code_block_for_address((cell)addr)->owner_quot());
 }
 
 void factor_vm::primitive_innermost_stack_frame_scan()
 {
        callstack *stack = untag_check<callstack>(ctx->pop());
-       stack_frame *frame = innermost_stack_frame(stack->bottom(), stack->top());
-       ctx->push(frame_scan(frame));
+       void *frame = innermost_stack_frame(stack->bottom(), stack->top());
+       void *addr = frame_return_address(frame);
+       ctx->push(code->code_block_for_address((cell)addr)->scan(this,addr));
 }
 
 void factor_vm::primitive_set_innermost_stack_frame_quot()
@@ -181,10 +144,11 @@ void factor_vm::primitive_set_innermost_stack_frame_quot()
 
        jit_compile_quot(quot.value(),true);
 
-       stack_frame *inner = innermost_stack_frame(stack->bottom(), stack->top());
-       cell offset = frame_offset(inner);
-       inner->entry_point = quot->entry_point;
-       set_frame_offset(inner,offset);
+       void *inner = innermost_stack_frame(stack->bottom(), stack->top());
+       void *addr = frame_return_address(inner);
+       code_block *block = code->code_block_for_address((cell)addr);
+       cell offset = block->offset(addr);
+       set_frame_return_address(inner, (char*)quot->entry_point + offset);
 }
 
 void factor_vm::primitive_callstack_bounds()
index 0872afe331aa81532b8b6509d6d56e622b849c41..f4fbac2d91d4769f767d37f5946eff124517ca2c 100755 (executable)
@@ -27,16 +27,6 @@ inline void factor_vm::iterate_callstack_object(callstack *stack_,
                code_block *owner = code->code_block_for_address((cell)fixed_addr);
                cell frame_size = owner->stack_frame_size_for_address((cell)fixed_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*)((char*)frame_top + frame_size) - 1;
-               void *fixed_entry_point =
-                       (void*)fixup.translate_code((code_block*)frame->entry_point);
-               FACTOR_ASSERT(owner->entry_point() == fixed_entry_point);
-               FACTOR_ASSERT(frame_size == frame->size);
-#endif
-
                iterator(frame_top, frame_size, owner, fixed_addr);
                frame_offset += frame_size;
        }
@@ -72,16 +62,6 @@ inline void factor_vm::iterate_callstack(context *ctx, Iterator &iterator, Fixup
 
                cell frame_size = fixed_owner->stack_frame_size_for_address((cell)fixed_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;
-               void *fixed_entry_point = Fixup::translated_code_block_map
-                       ? (void*)fixup.translate_code((code_block*)frame->entry_point)
-                       : frame->entry_point;
-               FACTOR_ASSERT(owner->entry_point() == fixed_entry_point);
-               FACTOR_ASSERT(frame_size == frame->size);
-#endif
                void *fixed_addr_for_iter = Fixup::translated_code_block_map
                        ? fixed_addr
                        : addr;
index 4bd6092052f54f6480ac3046b716ce314aa61ee7..2baa6d1aa7650e24f6b4325edde085a9872db997 100644 (file)
@@ -49,9 +49,6 @@ struct call_frame_code_block_visitor {
                        : fixup.fixup_code(owner);
                void *fixed_addr = compiled->address_for_offset(owner->offset(addr));
                set_frame_return_address(frame_top, fixed_addr);
-               // XXX remove this when prolog data is removed
-               stack_frame *frame = (stack_frame*)((char*)frame_top + frame_size) - 1;
-               frame->entry_point = compiled->entry_point();
        }
 };
 
index 3781453c76145b82a9914240e4a69f5ca762d9be..0d17225128887228459458ccffbb5ae63291f72b 100755 (executable)
@@ -508,14 +508,13 @@ struct find_symbol_at_address_visitor {
 image load. It finds the symbol and library, and throws an error. */
 void factor_vm::undefined_symbol()
 {
-       stack_frame *frame = innermost_stack_frame(ctx->callstack_bottom,
-               ctx->callstack_top);
-       code_block *compiled = frame_code(frame);
-       cell return_address = (cell)FRAME_RETURN_ADDRESS(frame, this);
-       find_symbol_at_address_visitor visitor(this, return_address);
+       void *frame = innermost_stack_frame(ctx->callstack_bottom, ctx->callstack_top);
+       void *return_address = frame_return_address(frame);
+       code_block *compiled = code->code_block_for_address((cell)return_address);
+       find_symbol_at_address_visitor visitor(this, (cell)return_address);
        compiled->each_instruction_operand(visitor);
        if (!to_boolean(visitor.symbol))
-               critical_error("Can't find RT_DLSYM at return address", return_address);
+               critical_error("Can't find RT_DLSYM at return address", (cell)return_address);
        else
                general_error(ERROR_UNDEFINED_SYMBOL,visitor.symbol,visitor.library);
 }
index 30ed74ecd963fe7eb74bc2b1f6320e1787a54bb7..79b4c9fd307e7d2ccb4a76a9600f1b2c1a8c62b5 100644 (file)
@@ -20,8 +20,8 @@ struct context {
        // First 4 fields accessed directly by compiler. See basis/vm/vm.factor
 
        /* Factor callstack pointers */
-       stack_frame *callstack_top;
-       stack_frame *callstack_bottom;
+       void *callstack_top;
+       void *callstack_bottom;
 
        /* current datastack top pointer */
        cell datastack;
@@ -73,11 +73,6 @@ struct context {
                datastack += sizeof(cell);
                replace(tagged);
        }
-
-       stack_frame *bottom_frame()
-       {
-               return callstack_bottom - 1;
-       }
 };
 
 VM_C_API context *new_context(factor_vm *parent);
index abaa965065cdc2bc494ce36633c05d0156dbacbf..101f8a43dbd822d23f4dfd76188c19cc874c9d0a 100644 (file)
@@ -7,7 +7,7 @@ namespace factor
 #define FACTOR_CPU_STRING "ppc.32"
 #endif
 
-#define CALLSTACK_BOTTOM(ctx) (stack_frame *)(ctx->callstack_seg->end - 32)
+#define CALLSTACK_BOTTOM(ctx) (void *)(ctx->callstack_seg->end - 32)
 
 /* In the instruction sequence:
 
index 1687becedb6ff1cd191204e2b32b2bb7a9e2d88a..bb52f406af734c1853ccb745eba9daff8a9b771a 100644 (file)
@@ -13,18 +13,16 @@ void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler)
                the signal handler to do its thing, and launch the handler without going
                through the resumable subprimitive. */
                signal_resumable = false;
-               stack_frame *frame = ctx->bottom_frame();
+               void *frame_top = (void*)ctx->callstack_top;
 
-               while((cell)frame >= *sp
-                       && frame >= ctx->callstack_top
-                       && (cell)frame >= ctx->callstack_seg->start + stack_reserved)
+               while(frame_top < ctx->callstack_bottom
+                       && (cell)frame_top < ctx->callstack_seg->start + stack_reserved)
                {
-                       frame = frame_successor(frame);
+                       frame_top = frame_predecessor(frame_top);
                }
 
-               cell newsp = (cell)(frame+1);
-               *sp = newsp;
-               ctx->callstack_top = (stack_frame*)newsp;
+               *sp = (cell)frame_top;
+               ctx->callstack_top = frame_top;
                *pc = handler;
        } else {
                signal_resumable = true;
index 45731976b9166d398b1701077e01c8701d54c5e1..8eba75b9fc514db02cdaa19a9187aad0682ddfa9 100755 (executable)
@@ -1,8 +1,6 @@
 namespace factor
 {
 
-#define FRAME_RETURN_ADDRESS(frame,vm) *(void **)(vm->frame_successor(frame) + 1)
-
 inline static void* frame_return_address(void *frame_top)
 {
        return *(void**)frame_top;
@@ -13,7 +11,7 @@ inline static void set_frame_return_address(void *frame_top, void *return_addres
        *(void**)frame_top = return_address;
 }
 
-#define CALLSTACK_BOTTOM(ctx) (stack_frame *)(ctx->callstack_seg->end - sizeof(cell) * 5)
+#define CALLSTACK_BOTTOM(ctx) (void *)(ctx->callstack_seg->end - sizeof(cell) * 5)
 
 inline static void flush_icache(cell start, cell len) {}
 
index f3a834eb17ab657da37d19b6ba86f7b88611f27b..a3cbcd13178849eaca90b79b759dae2990b23d63 100755 (executable)
@@ -26,7 +26,7 @@ template<typename Func> Func factor_vm::get_entry_point(cell n)
        return (Func)entry_point_word->entry_point;
 }
 
-void factor_vm::unwind_native_frames(cell quot, stack_frame *to)
+void factor_vm::unwind_native_frames(cell quot, void *to)
 {
        tagged<word> entry_point_word(special_objects[UNWIND_NATIVE_FRAMES_WORD]);
        void *func = entry_point_word->entry_point;
index 7c7a1b9394f7f68378dedcfa287b0776848e0a31..fc3ae2e400403341cd3b36441d72a905d2503bf7 100755 (executable)
@@ -2,7 +2,7 @@ namespace factor
 {
 
 typedef void (* c_to_factor_func_type)(cell quot);
-typedef void (* unwind_native_frames_func_type)(cell quot, stack_frame *to);
+typedef void (* unwind_native_frames_func_type)(cell quot, void *to);
 typedef cell (* get_fpu_state_func_type)();
 typedef void (* set_fpu_state_func_type)(cell state);
 
index d6c11a611d931e59b518ce8cccbabcdb41bd16f4..1972fe622b5d9a7d9a732d181c3492b6adc8bd22 100644 (file)
@@ -349,30 +349,18 @@ struct dll : public object {
        void *handle;
 };
 
-struct stack_frame {
-       /* Updated by procedure prologue with procedure start address */
-       void *entry_point;
-       /* Frame size in bytes */
-       cell size;
-};
-
 struct callstack : public object {
        static const cell type_number = CALLSTACK_TYPE;
        /* tagged */
        cell length;
        
-       stack_frame *frame_at(cell offset) const
-       {
-               return (stack_frame *)((char *)(this + 1) + offset);
-       }
-
        void *frame_top_at(cell offset) const
        {
                return (void *)((char *)(this + 1) + offset);
        }
 
-       stack_frame *top() const { return (stack_frame *)(this + 1); }
-       stack_frame *bottom() const { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
+       void *top() const { return (void *)(this + 1); }
+       void *bottom() const { return (void *)((cell)(this + 1) + untag_fixnum(length)); }
 };
 
 struct tuple : public object {
index c1c720634bfc4e08e96f571a44fcdd3994914e82..aa3f6a7dbe87575d869a590ddffb6febd07cb2e0 100644 (file)
@@ -49,31 +49,32 @@ void factor_vm::record_sample(bool prolog_p)
                        counts, special_objects[OBJ_CURRENT_THREAD]));
 }
 
+struct record_callstack_sample_iterator {
+       std::vector<cell> *sample_callstacks;
+       bool skip_p;
+
+       record_callstack_sample_iterator(std::vector<cell> *sample_callstacks, bool prolog_p)
+               : sample_callstacks(sample_callstacks), skip_p(prolog_p) {}
+
+       void operator()(void *frame_top, cell frame_size, code_block *owner, void *addr)
+       {
+               if (skip_p)
+                       skip_p = false;
+               else
+                       sample_callstacks->push_back(owner->owner);
+       }
+};
+
 void factor_vm::record_callstack_sample(cell *begin, cell *end, bool prolog_p)
 {
        *begin = sample_callstacks.size();
-       stack_frame *frame = ctx->bottom_frame();
-       if (prolog_p)
-       {
-               FACTOR_ASSERT(frame >= ctx->callstack_top);
-               stack_frame *next_frame = frame_successor(frame);
-               while (next_frame >= ctx->callstack_top)
-               {
-                       sample_callstacks.push_back(frame_code(frame)->owner);
-                       frame = next_frame;
-                       next_frame = frame_successor(next_frame);
-               }
-       }
-       else
-       {
-               while (frame >= ctx->callstack_top)
-               {
-                       sample_callstacks.push_back(frame_code(frame)->owner);
-                       frame = frame_successor(frame);
-               }
-       }
+
+       record_callstack_sample_iterator recorder(&sample_callstacks, prolog_p);
+       iterate_callstack(ctx, recorder);
 
        *end = sample_callstacks.size();
+
+       std::reverse(sample_callstacks.begin() + *begin, sample_callstacks.end());
 }
 
 void factor_vm::set_sampling_profiler(fixnum rate)
index 7a30f0184c821bdd4eebe408b80d94d7fc6b4ee5..bac366d2e856004e6df05d745f741d936dd3885c 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -627,22 +627,14 @@ struct factor_vm
        template<typename Iterator>
        void iterate_callstack_object(callstack *stack_, Iterator &iterator);
 
-       void check_frame(stack_frame *frame);
        callstack *allot_callstack(cell size);
-       stack_frame *second_from_top_stack_frame(context *ctx);
+       void *second_from_top_stack_frame(context *ctx);
        cell capture_callstack(context *ctx);
        void primitive_callstack();
        void primitive_callstack_for();
-       code_block *frame_code(stack_frame *frame);
-       code_block_type frame_type(stack_frame *frame);
-       cell frame_executing(stack_frame *frame);
-       cell frame_executing_quot(stack_frame *frame);
-       stack_frame *frame_successor(stack_frame *frame);
-       cell frame_scan(stack_frame *frame);
-       cell frame_offset(stack_frame *frame);
-       void set_frame_offset(stack_frame *frame, cell offset);
+       void *frame_predecessor(void *frame);
        void primitive_callstack_to_array();
-       stack_frame *innermost_stack_frame(stack_frame *bottom, stack_frame *top);
+       void *innermost_stack_frame(void *bottom, void *top);
        void primitive_innermost_stack_frame_executing();
        void primitive_innermost_stack_frame_scan();
        void primitive_set_innermost_stack_frame_quot();
@@ -714,7 +706,7 @@ struct factor_vm
        // entry points
        void c_to_factor(cell quot);
        template<typename Func> Func get_entry_point(cell n);
-       void unwind_native_frames(cell quot, stack_frame *to);
+       void unwind_native_frames(cell quot, void *to);
        cell get_fpu_state();
        void set_fpu_state(cell state);