VM: fix jit-signal-handler-prolog/epilog to account for the home space
Windows 64bit abi requires callers to reserve 32 bytes of home space in the stack frame which the callee is free to clobber. Previous versions of VS didn't compile code to take advantage of the home space so it worked fined. VS2015 however, is using the home space which causes registers and flags that were supposed to be saved to be overwritten. The fix is to put a little extra empty space at the bottom of the stack frame.db4
parent
316b16f377
commit
663e5e2a09
|
@ -8,7 +8,6 @@ IN: bootstrap.x86
|
|||
|
||||
4 \ cell set
|
||||
|
||||
: signal-handler-stack-frame-size ( -- n ) 12 bootstrap-cells ;
|
||||
: stack-frame-size ( -- n ) 8 bootstrap-cells ;
|
||||
: shift-arg ( -- reg ) ECX ;
|
||||
: div-arg ( -- reg ) EAX ;
|
||||
|
|
|
@ -4,7 +4,6 @@ USING: cpu.x86.assembler.operands kernel layouts parser
|
|||
sequences ;
|
||||
IN: bootstrap.x86
|
||||
|
||||
: signal-handler-stack-frame-size ( -- n ) 20 bootstrap-cells ;
|
||||
: stack-frame-size ( -- n ) 4 bootstrap-cells ;
|
||||
: nv-regs ( -- seq ) { RBX R12 R13 R14 R15 } ;
|
||||
: volatile-regs ( -- seq ) { RAX RCX RDX RSI RDI R8 R9 R10 R11 } ;
|
||||
|
|
|
@ -6,7 +6,6 @@ IN: bootstrap.x86
|
|||
|
||||
DEFER: stack-reg
|
||||
|
||||
: signal-handler-stack-frame-size ( -- n ) 24 bootstrap-cells ;
|
||||
: stack-frame-size ( -- n ) 8 bootstrap-cells ;
|
||||
: nv-regs ( -- seq ) { RBX RSI RDI R12 R13 R14 R15 } ;
|
||||
: volatile-regs ( -- seq ) { RAX RCX RDX R8 R9 R10 R11 } ;
|
||||
|
|
|
@ -92,28 +92,30 @@ big-endian off
|
|||
! The *-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.
|
||||
|
||||
!
|
||||
! It is important that the total is 192/64 and that it matches the
|
||||
! constants in vm/cpu-x86.*.hpp
|
||||
: jit-signal-handler-prolog ( -- )
|
||||
! minus a cell each for flags, return address
|
||||
! use LEA so we don't dirty flags
|
||||
stack-reg stack-reg signal-handler-stack-frame-size
|
||||
2 bootstrap-cells - neg [+] LEA
|
||||
! Return address already on stack -> 8/4 bytes.
|
||||
|
||||
signal-handler-save-regs
|
||||
[| r i | stack-reg i bootstrap-cells [+] r MOV ] each-index
|
||||
! Push all registers. 15 regs/120 bytes on 64bit, 7 regs/28 bytes
|
||||
! on 32bit -> 128/32 bytes.
|
||||
signal-handler-save-regs [ PUSH ] each
|
||||
|
||||
! Push flags -> 136/36 bytes
|
||||
PUSHF
|
||||
|
||||
! Register parameter area 32 bytes, unused on platforms other than
|
||||
! windows 64 bit, but including it doesn't hurt. Plus
|
||||
! alignment. LEA used so we don't dirty flags -> 192/64 bytes.
|
||||
stack-reg stack-reg 7 bootstrap-cells neg [+] LEA
|
||||
|
||||
jit-load-vm ;
|
||||
|
||||
: jit-signal-handler-epilog ( -- )
|
||||
stack-reg stack-reg 7 bootstrap-cells [+] LEA
|
||||
POPF
|
||||
|
||||
signal-handler-save-regs
|
||||
[| r i | r stack-reg i bootstrap-cells [+] MOV ] each-index
|
||||
|
||||
stack-reg stack-reg signal-handler-stack-frame-size
|
||||
2 bootstrap-cells - [+] LEA ;
|
||||
signal-handler-save-regs reverse [ POP ] each ;
|
||||
|
||||
[| |
|
||||
jit-signal-handler-prolog
|
||||
|
|
|
@ -2,9 +2,9 @@ namespace factor {
|
|||
|
||||
#define FACTOR_CPU_STRING "x86.32"
|
||||
|
||||
/* Must match the signal-handler-stack-frame-size and stack-frame-size
|
||||
constants in bootstrap/assembler/x86.32.factor */
|
||||
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 48;
|
||||
/* Must match the calculation in word jit-signal-handler-prolog in
|
||||
basis/bootstrap/assembler/x86.factor */
|
||||
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 64;
|
||||
static const unsigned JIT_FRAME_SIZE = 32;
|
||||
|
||||
}
|
||||
|
|
|
@ -2,4 +2,8 @@ namespace factor {
|
|||
|
||||
#define FACTOR_CPU_STRING "x86.64"
|
||||
|
||||
/* Must match the calculation in word jit-signal-handler-prolog in
|
||||
basis/bootstrap/assembler/x86.factor */
|
||||
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 192;
|
||||
|
||||
}
|
||||
|
|
|
@ -25,9 +25,8 @@ inline static void uap_clear_fpu_status(void* uap) {
|
|||
#define FUNCTION_CODE_POINTER(ptr) ptr
|
||||
#define FUNCTION_TOC_POINTER(ptr) ptr
|
||||
|
||||
/* Must match the signal-handler-stack-frame-size and stack-frame-size
|
||||
constants in bootstrap/assembler/x86.64.unix.factor */
|
||||
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 160;
|
||||
/* Must match the stack-frame-size constant in
|
||||
bootstrap/assembler/x86.64.unix.factor */
|
||||
static const unsigned JIT_FRAME_SIZE = 32;
|
||||
|
||||
}
|
||||
|
|
|
@ -67,9 +67,8 @@ inline static void uap_clear_fpu_status(void* uap) {
|
|||
mach_clear_fpu_status(UAP_FS(uap));
|
||||
}
|
||||
|
||||
/* Must match the signal-handler-stack-frame-size and stack-frame-size
|
||||
constants in basis/bootstrap/assembler/x86.64.unix.factor */
|
||||
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 160;
|
||||
/* Must match the stack-frame-size constant in
|
||||
basis/bootstrap/assembler/x86.64.unix.factor */
|
||||
static const unsigned JIT_FRAME_SIZE = 32;
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,7 @@ namespace factor {
|
|||
|
||||
#define MXCSR(ctx) (ctx)->MxCsr
|
||||
|
||||
/* Must match the signal-handler-stack-frame-size and stack-frame-size
|
||||
constants in basis/bootstap/assembler/x86.64.windows.factor */
|
||||
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 192;
|
||||
/* Must match the stack-frame-size constant in
|
||||
basis/bootstap/assembler/x86.64.windows.factor */
|
||||
static const unsigned JIT_FRAME_SIZE = 64;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue