cpu.x86.32: update for resumable signal handlers
parent
d6eae2f42d
commit
ff2d480d98
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
|
Loading…
Reference in New Issue