cpu.x86.32: update for resumable signal handlers

db4
Joe Groff 2011-10-25 23:25:19 -07:00
parent d6eae2f42d
commit ff2d480d98
4 changed files with 77 additions and 47 deletions

View File

@ -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

View File

@ -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

View 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

View File

@ -102,9 +102,10 @@ 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;
// 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]);