]> gitweb.factorcode.org Git - factor.git/commitdiff
cpu.x86.32: update for resumable signal handlers
authorJoe Groff <arcata@gmail.com>
Wed, 26 Oct 2011 06:25:19 +0000 (23:25 -0700)
committerJoe Groff <arcata@gmail.com>
Fri, 28 Oct 2011 04:18:19 +0000 (21:18 -0700)
basis/cpu/x86/32/bootstrap.factor
basis/cpu/x86/64/bootstrap.factor
basis/cpu/x86/bootstrap.factor
vm/callstack.cpp

index 5e0561bfca475115cda55c8cbbf37775d3367ea5..2eaa1f387b00a2373bca63b33e990ca66c4d137a 100755 (executable)
@@ -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
index efb6fa940861032556d9a3c034f6307a604e5519..0c132411fbf2248de40b584f567d19b852ccdc82 100755 (executable)
@@ -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
index ba5f2f8594e51526c8e85a4cef535d3cc577e98a..480b0efa90aa020373109bc1348b5e7ea24229d6 100644 (file)
@@ -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
index 770fc9e1f2e64d4c99f0452e65d8c9187de06dc0..79cee091f6945cdd91ae74f1b989870a40ecf709 100755 (executable)
@@ -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<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]);
                }