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
Björn Lindqvist 2015-08-26 18:17:33 +02:00
parent 316b16f377
commit 663e5e2a09
9 changed files with 28 additions and 28 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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