diff --git a/basis/cpu/x86/32/bootstrap.factor b/basis/cpu/x86/32/bootstrap.factor index 5e0561bfca..2eaa1f387b 100755 --- a/basis/cpu/x86/32/bootstrap.factor +++ b/basis/cpu/x86/32/bootstrap.factor @@ -4,7 +4,7 @@ USING: bootstrap.image.private kernel kernel.private namespaces system cpu.x86.assembler cpu.x86.assembler.operands layouts vocabs parser compiler.constants compiler.codegen.relocation sequences math math.private generic.single.private -threads.private ; +threads.private locals ; IN: bootstrap.x86 4 \ cell set @@ -23,6 +23,7 @@ IN: bootstrap.x86 : vm-reg ( -- reg ) EBX ; : ctx-reg ( -- reg ) EBP ; : nv-regs ( -- seq ) { ESI EDI EBX } ; +: volatile-regs ( -- seq ) { EAX ECX EDX } ; : nv-reg ( -- reg ) ESI ; : ds-reg ( -- reg ) ESI ; : rs-reg ( -- reg ) EDI ; @@ -34,12 +35,12 @@ IN: bootstrap.x86 0 CALL f rc-relative rel-dlsym ; [ - ! store entry point - ESP bootstrap-cell 2 * neg [+] 0 MOV rc-absolute-cell rel-this - ! store stack frame size - ESP bootstrap-cell neg [+] stack-frame-size MOV ! alignment ESP stack-frame-size bootstrap-cell - SUB + ! store entry point + ESP stack-frame-size 3 bootstrap-cells - [+] 0 MOV rc-absolute-cell rel-this + ! store stack frame size + ESP stack-frame-size 2 bootstrap-cells - [+] stack-frame-size MOV ] jit-prolog jit-define [ @@ -96,6 +97,36 @@ IN: bootstrap.x86 "end_callback" jit-call ] \ c-to-factor define-sub-primitive +! The signal-handler and leaf-signal-handler subprimitives are special-cased +! in vm/quotations.cpp not to trigger generation of a stack frame, so they can +! peform their own prolog/epilog preserving registers. + +:: jit-signal-handler-prolog ( -- frame-size ) + stack-frame-size 8 bootstrap-cells + :> frame-size + ESP frame-size bootstrap-cell - SUB ! minus a cell for return address + ESP [] EAX MOV + ESP 1 bootstrap-cells [+] ECX MOV + ESP 2 bootstrap-cells [+] EDX MOV + ESP 3 bootstrap-cells [+] EBX MOV + ESP 4 bootstrap-cells [+] EBP MOV + ESP 5 bootstrap-cells [+] ESI MOV + ESP 6 bootstrap-cells [+] EDI MOV + ESP frame-size 3 bootstrap-cells - [+] 0 MOV rc-absolute-cell rel-this + ESP frame-size 2 bootstrap-cells - [+] frame-size MOV + ! subprimitive definition assumes vm's been loaded + jit-load-vm + frame-size ; + +:: jit-signal-handler-epilog ( frame-size -- ) + EAX ESP [] MOV + ECX ESP 1 bootstrap-cells [+] MOV + EDX ESP 2 bootstrap-cells [+] MOV + EBX ESP 3 bootstrap-cells [+] MOV + EBP ESP 4 bootstrap-cells [+] MOV + ESI ESP 5 bootstrap-cells [+] MOV + EDI ESP 6 bootstrap-cells [+] MOV + ESP frame-size bootstrap-cell - ADD ; + [ EAX ds-reg [] MOV ds-reg bootstrap-cell SUB diff --git a/basis/cpu/x86/64/bootstrap.factor b/basis/cpu/x86/64/bootstrap.factor index efb6fa9408..0c132411fb 100755 --- a/basis/cpu/x86/64/bootstrap.factor +++ b/basis/cpu/x86/64/bootstrap.factor @@ -4,7 +4,7 @@ USING: bootstrap.image.private kernel kernel.private namespaces system layouts vocabs parser compiler.constants compiler.codegen.relocation math math.private cpu.x86.assembler cpu.x86.assembler.operands sequences generic.single.private -threads.private ; +threads.private locals ; IN: bootstrap.x86 8 \ cell set @@ -91,9 +91,7 @@ IN: bootstrap.x86 "end_callback" jit-call ] \ c-to-factor define-sub-primitive -USE: locals - -:: jit-save-volatile-regs ( -- frame-size ) +:: jit-signal-handler-prolog ( -- frame-size ) ! do we also need to save XMM? volatile-regs length bootstrap-cells 16 align stack-frame-size + :> frame-size RSP frame-size bootstrap-cell - SUB ! minus a cell for return address @@ -105,43 +103,11 @@ USE: locals RSP frame-size 2 bootstrap-cells - [+] frame-size MOV frame-size ; -:: jit-restore-volatile-regs ( frame-size -- ) +:: jit-signal-handler-epilog ( frame-size -- ) volatile-regs [| r i | r RSP i bootstrap-cells [+] MOV ] each-index RSP frame-size bootstrap-cell - ADD ; -! The signal-handler and leaf-signal-handler subprimitives are special-cased -! in vm/quotations.cpp not to trigger generation of a stack frame, so they can -! peform their own prolog/epilog preserving registers. - -[| | - jit-save-volatile-regs :> frame-size - jit-save-context - RAX vm-reg vm-signal-handler-addr-offset [+] MOV - RAX CALL - frame-size jit-restore-volatile-regs -] \ signal-handler define-sub-primitive - -[| | - jit-save-volatile-regs :> frame-size - jit-save-context - RAX vm-reg vm-signal-handler-addr-offset [+] MOV - RAX CALL - ! Stack at this point has a fake stack frame set up to represent the - ! leaf procedure we interrupted. We must tear down that frame in - ! addition to our own before resuming. - ! Grab our frame's return address and place it just underneath the leaf proc's - ! return address, since we can't touch any registers once they've been - ! restored. If we got this far there should be no faults here and we - ! can get away with corrupting the stack frame. - RAX RSP frame-size bootstrap-cell - [+] MOV - RSP frame-size 2 bootstrap-cells + [+] RAX MOV - - ! Popping 3 extra cells here leaves the resume address at the top of the stack - ! when we RET. - frame-size 3 bootstrap-cells + jit-restore-volatile-regs -] \ leaf-signal-handler define-sub-primitive - [ arg1 ds-reg [] MOV ds-reg bootstrap-cell SUB diff --git a/basis/cpu/x86/bootstrap.factor b/basis/cpu/x86/bootstrap.factor index ba5f2f8594..480b0efa90 100644 --- a/basis/cpu/x86/bootstrap.factor +++ b/basis/cpu/x86/bootstrap.factor @@ -3,7 +3,7 @@ USING: bootstrap.image.private compiler.constants compiler.codegen.relocation compiler.units cpu.x86.assembler cpu.x86.assembler.operands kernel kernel.private layouts -locals.backend make math math.private namespaces sequences +locals locals.backend make math math.private namespaces sequences slots.private strings.private vocabs ; IN: bootstrap.x86 @@ -102,6 +102,38 @@ big-endian off 0 CALL f rc-relative rel-word-pic ] jit-word-call jit-define +! The signal-handler and leaf-signal-handler subprimitives are special-cased +! in vm/quotations.cpp not to trigger generation of a stack frame, so they can +! peform their own prolog/epilog preserving registers. + +[| | + jit-signal-handler-prolog :> frame-size + jit-save-context + temp0 vm-reg vm-signal-handler-addr-offset [+] MOV + temp0 CALL + frame-size jit-signal-handler-epilog +] \ signal-handler define-sub-primitive + +[| | + jit-signal-handler-prolog :> frame-size + jit-save-context + temp0 vm-reg vm-signal-handler-addr-offset [+] MOV + temp0 CALL + ! Stack at this point has a fake stack frame set up to represent the + ! leaf procedure we interrupted. We must tear down that frame in + ! addition to our own before resuming. + ! Grab our frame's return address and place it just underneath the leaf proc's + ! return address, since we can't touch any registers once they've been + ! restored. If we got this far there should be no faults here and we + ! can get away with corrupting the stack frame. + temp0 stack-reg frame-size bootstrap-cell - [+] MOV + stack-reg frame-size stack-frame-size + 2 bootstrap-cells - [+] temp0 MOV + + ! Pop enough of the fake frame to leave the resume address at the top of the + ! stack when we RET. + frame-size stack-frame-size + bootstrap-cell - jit-signal-handler-epilog +] \ leaf-signal-handler define-sub-primitive + [ ! load boolean temp0 ds-reg [] MOV diff --git a/vm/callstack.cpp b/vm/callstack.cpp index 770fc9e1f2..79cee091f6 100755 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -102,10 +102,11 @@ void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler) // Make a fake frame for the leaf procedure cell leaf_word = find_word_for_address(this, *pc); - cell newsp = *sp - 4 * sizeof(cell); - *(cell*)(newsp + 3*sizeof(cell)) = 4*sizeof(cell); - *(cell*)(newsp + 2*sizeof(cell)) = leaf_word; - *(cell*) newsp = *pc; + // XXX get platform-appropriate stack frame size + cell newsp = *sp - 32; + *(cell*)(newsp + 32 - sizeof(cell)) = 32; + *(cell*)(newsp + 32 - 2*sizeof(cell)) = leaf_word; + *(cell*) newsp = *pc; *sp = newsp; handler_word = tagged(special_objects[LEAF_SIGNAL_HANDLER_WORD]); }