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 4 \ cell set
: signal-handler-stack-frame-size ( -- n ) 12 bootstrap-cells ;
: stack-frame-size ( -- n ) 8 bootstrap-cells ; : stack-frame-size ( -- n ) 8 bootstrap-cells ;
: shift-arg ( -- reg ) ECX ; : shift-arg ( -- reg ) ECX ;
: div-arg ( -- reg ) EAX ; : div-arg ( -- reg ) EAX ;

View File

@ -4,7 +4,6 @@ USING: cpu.x86.assembler.operands kernel layouts parser
sequences ; sequences ;
IN: bootstrap.x86 IN: bootstrap.x86
: signal-handler-stack-frame-size ( -- n ) 20 bootstrap-cells ;
: stack-frame-size ( -- n ) 4 bootstrap-cells ; : stack-frame-size ( -- n ) 4 bootstrap-cells ;
: nv-regs ( -- seq ) { RBX R12 R13 R14 R15 } ; : nv-regs ( -- seq ) { RBX R12 R13 R14 R15 } ;
: volatile-regs ( -- seq ) { RAX RCX RDX RSI RDI R8 R9 R10 R11 } ; : volatile-regs ( -- seq ) { RAX RCX RDX RSI RDI R8 R9 R10 R11 } ;

View File

@ -6,7 +6,6 @@ IN: bootstrap.x86
DEFER: stack-reg DEFER: stack-reg
: signal-handler-stack-frame-size ( -- n ) 24 bootstrap-cells ;
: stack-frame-size ( -- n ) 8 bootstrap-cells ; : stack-frame-size ( -- n ) 8 bootstrap-cells ;
: nv-regs ( -- seq ) { RBX RSI RDI R12 R13 R14 R15 } ; : nv-regs ( -- seq ) { RBX RSI RDI R12 R13 R14 R15 } ;
: volatile-regs ( -- seq ) { RAX RCX RDX R8 R9 R10 R11 } ; : 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 ! The *-signal-handler subprimitives are special-cased in vm/quotations.cpp
! not to trigger generation of a stack frame, so they can ! not to trigger generation of a stack frame, so they can
! peform their own prolog/epilog preserving registers. ! 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 ( -- ) : jit-signal-handler-prolog ( -- )
! minus a cell each for flags, return address ! Return address already on stack -> 8/4 bytes.
! use LEA so we don't dirty flags
stack-reg stack-reg signal-handler-stack-frame-size
2 bootstrap-cells - neg [+] LEA
signal-handler-save-regs ! Push all registers. 15 regs/120 bytes on 64bit, 7 regs/28 bytes
[| r i | stack-reg i bootstrap-cells [+] r MOV ] each-index ! on 32bit -> 128/32 bytes.
signal-handler-save-regs [ PUSH ] each
! Push flags -> 136/36 bytes
PUSHF 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-load-vm ;
: jit-signal-handler-epilog ( -- ) : jit-signal-handler-epilog ( -- )
stack-reg stack-reg 7 bootstrap-cells [+] LEA
POPF POPF
signal-handler-save-regs reverse [ POP ] each ;
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 ;
[| | [| |
jit-signal-handler-prolog jit-signal-handler-prolog

View File

@ -2,9 +2,9 @@ namespace factor {
#define FACTOR_CPU_STRING "x86.32" #define FACTOR_CPU_STRING "x86.32"
/* Must match the signal-handler-stack-frame-size and stack-frame-size /* Must match the calculation in word jit-signal-handler-prolog in
constants in bootstrap/assembler/x86.32.factor */ basis/bootstrap/assembler/x86.factor */
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 48; static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 64;
static const unsigned JIT_FRAME_SIZE = 32; static const unsigned JIT_FRAME_SIZE = 32;
} }

View File

@ -2,4 +2,8 @@ namespace factor {
#define FACTOR_CPU_STRING "x86.64" #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_CODE_POINTER(ptr) ptr
#define FUNCTION_TOC_POINTER(ptr) ptr #define FUNCTION_TOC_POINTER(ptr) ptr
/* Must match the signal-handler-stack-frame-size and stack-frame-size /* Must match the stack-frame-size constant in
constants in bootstrap/assembler/x86.64.unix.factor */ bootstrap/assembler/x86.64.unix.factor */
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 160;
static const unsigned JIT_FRAME_SIZE = 32; 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)); mach_clear_fpu_status(UAP_FS(uap));
} }
/* Must match the signal-handler-stack-frame-size and stack-frame-size /* Must match the stack-frame-size constant in
constants in basis/bootstrap/assembler/x86.64.unix.factor */ basis/bootstrap/assembler/x86.64.unix.factor */
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 160;
static const unsigned JIT_FRAME_SIZE = 32; static const unsigned JIT_FRAME_SIZE = 32;
} }

View File

@ -7,8 +7,7 @@ namespace factor {
#define MXCSR(ctx) (ctx)->MxCsr #define MXCSR(ctx) (ctx)->MxCsr
/* Must match the signal-handler-stack-frame-size and stack-frame-size /* Must match the stack-frame-size constant in
constants in basis/bootstap/assembler/x86.64.windows.factor */ basis/bootstap/assembler/x86.64.windows.factor */
static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 192;
static const unsigned JIT_FRAME_SIZE = 64; static const unsigned JIT_FRAME_SIZE = 64;
} }