diff --git a/basis/cpu/x86/32/bootstrap.factor b/basis/cpu/x86/32/bootstrap.factor index a52a3390ac..38c98913be 100644 --- a/basis/cpu/x86/32/bootstrap.factor +++ b/basis/cpu/x86/32/bootstrap.factor @@ -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 diff --git a/basis/cpu/x86/64/bootstrap.factor b/basis/cpu/x86/64/bootstrap.factor index 393d1c9b8b..7269e3240f 100644 --- a/basis/cpu/x86/64/bootstrap.factor +++ b/basis/cpu/x86/64/bootstrap.factor @@ -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 diff --git a/vm/callstack.cpp b/vm/callstack.cpp index e7892405ad..dd76714245 100755 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -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; diff --git a/vm/gc.cpp b/vm/gc.cpp index 224da82a98..24f773b226 100755 --- 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) diff --git a/vm/gc_info.cpp b/vm/gc_info.cpp index 6ffe138f94..b937d0a6ef 100644 --- a/vm/gc_info.cpp +++ b/vm/gc_info.cpp @@ -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(); diff --git a/vm/gc_info.hpp b/vm/gc_info.hpp index 0e641de0eb..d5229a19a5 100644 --- a/vm/gc_info.hpp +++ b/vm/gc_info.hpp @@ -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); }; } diff --git a/vm/slot_visitor.hpp b/vm/slot_visitor.hpp index 148c05df1f..8d1c27a55c 100644 --- a/vm/slot_visitor.hpp +++ b/vm/slot_visitor.hpp @@ -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) diff --git a/vm/vm.hpp b/vm/vm.hpp index 14a00e9d2a..5c2b0697f7 100755 --- 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();