]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: context switching needs to scrub the return address
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 12 Jun 2010 23:52:28 +0000 (19:52 -0400)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 12 Jun 2010 23:54:31 +0000 (19:54 -0400)
basis/cpu/x86/32/bootstrap.factor
basis/cpu/x86/64/bootstrap.factor
vm/callstack.cpp
vm/gc.cpp
vm/gc_info.cpp
vm/gc_info.hpp
vm/slot_visitor.hpp
vm/vm.hpp

index a52a3390acd150f9f999855e6b819004abafd2f1..38c98913be9f70928895d370d09cc74b779b97b7 100644 (file)
@@ -252,6 +252,10 @@ IN: bootstrap.x86
 
 ! Contexts
 : jit-switch-context ( reg -- )
+    ! Dummy return address -- it never gets returned to but it
+    ! must point to inside the current code block
+    ESP -4 [+] HEX: ffffffff MOV rc-absolute-cell rt-this jit-rel
+
     ! Save ds, rs registers
     jit-load-vm
     jit-save-context
index 393d1c9b8bf1e5afe74e530ce63643eeabb149a5..7269e3240f5fe9caf93b226082e78998e71628a5 100644 (file)
@@ -228,6 +228,11 @@ IN: bootstrap.x86
 
 ! Contexts
 : jit-switch-context ( reg -- )
+    ! Dummy return address -- it never gets returned to but it
+    ! must point to inside the current code block
+    R11 0 [RIP+] LEA
+    RSP -8 [+] R11 MOV
+
     ! Save ds, rs registers
     jit-save-context
 
index e7892405ad1b7726eb36dc8bc03326fa88b7c501..dd7671424517d4ed581c2cbca93ce64359477432 100755 (executable)
@@ -138,6 +138,11 @@ cell factor_vm::frame_scan(stack_frame *frame)
        }
 }
 
+cell factor_vm::frame_offset(stack_frame *frame)
+{
+       return (cell)FRAME_RETURN_ADDRESS(frame,this) - (cell)frame_code(frame)->entry_point();
+}
+
 struct stack_frame_accumulator {
        factor_vm *parent;
        growable_array frames;
index 224da82a9861c6dab43452c3d6fde1f5e07bb263..24f773b2261dcd68df6b9689272c9e850d5f0173 100755 (executable)
--- a/vm/gc.cpp
+++ b/vm/gc.cpp
@@ -210,7 +210,8 @@ struct call_frame_scrubber {
                const code_block *compiled = parent->frame_code(frame);
                gc_info *info = compiled->block_gc_info();
 
-               u32 return_address = (cell)FRAME_RETURN_ADDRESS(frame,parent) - (cell)compiled->entry_point();
+               cell return_address = parent->frame_offset(frame);
+               assert(return_address < compiled->size());
                int index = info->return_address_index(return_address);
 
                if(index != -1)
index 6ffe138f9427e5cd4bf91075e0ed780c02fb26c7..b937d0a6effdd6d1579fd3546a8017a8410ea730 100644 (file)
@@ -3,7 +3,7 @@
 namespace factor
 {
 
-int gc_info::return_address_index(u32 return_address)
+int gc_info::return_address_index(cell return_address)
 {
        u32 *return_address_array = return_addresses();
 
index 0e641de0eb0b2f143f592f5493ebfcb8f3b0266c..d5229a19a5584414dba78a89b5de02cba555229b 100644 (file)
@@ -45,7 +45,7 @@ struct gc_info {
                        + index * gc_root_count;
        }
 
-       int return_address_index(u32 return_address);
+       int return_address_index(cell return_address);
 };
 
 }
index 148c05df1f457fc5d0c9fe6f7f1897e2e94d6a65..8d1c27a55c5d3d33b072a02a1b1208df01ef4b2a 100644 (file)
@@ -286,8 +286,8 @@ struct call_frame_slot_visitor {
        {
                const code_block *compiled = visitor->fixup.translate_code(parent->frame_code(frame));
                gc_info *info = compiled->block_gc_info();
-
-               u32 return_address = (cell)FRAME_RETURN_ADDRESS(frame,parent) - (cell)compiled->entry_point();
+               cell return_address = parent->frame_offset(frame);
+               assert(return_address < compiled->size());
                int index = info->return_address_index(return_address);
 
                if(index != -1)
index 14a00e9d2a4ba02cdc1e8762895cc730cbbb01a3..5c2b0697f78edb6a293feb6d2e5e47978ab79697 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -596,6 +596,7 @@ struct factor_vm
        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 primitive_callstack_to_array();
        stack_frame *innermost_stack_frame(callstack *stack);
        void primitive_innermost_stack_frame_executing();