diff options
author | Tamar Christina <tamar@zhox.com> | 2018-01-26 13:10:10 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-01-26 14:37:29 -0500 |
commit | a55d581f8f2923560c3444253050b13fdf2dec10 (patch) | |
tree | a93dfe88e55530b362bf1cd15bc7dd928121749a /rts | |
parent | 9a57cfebd2e65109884712a27a0f29d1a71f57b7 (diff) | |
download | haskell-a55d581f8f2923560c3444253050b13fdf2dec10.tar.gz |
Fix Windows stack allocations.
On Windows we use the function `win32AllocStack` to do stack
allocations in 4k blocks and insert a stack check afterwards
to ensure the allocation returned a valid block.
The problem is this function does something that by C semantics
is pointless. The stack allocated value can never escape the
function, and the stack isn't used so the compiler just optimizes
away the entire function body.
After considering a bunch of other possibilities I think the simplest
fix is to just disable optimizations for the function.
Alternatively inline assembly is an option but the stack check function
doesn't have a very portable name as it relies on e.g. `libgcc`.
Thanks to Sergey Vinokurov for helping diagnose and test.
Test Plan: ./validate
Reviewers: bgamari, erikd, simonmar
Reviewed By: bgamari
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #14669
Differential Revision: https://phabricator.haskell.org/D4343
Diffstat (limited to 'rts')
-rw-r--r-- | rts/StgCRun.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/rts/StgCRun.c b/rts/StgCRun.c index 176e64ca98..5460598ced 100644 --- a/rts/StgCRun.c +++ b/rts/StgCRun.c @@ -99,11 +99,17 @@ StgFunPtr StgReturn(void) #endif #if defined(mingw32_HOST_OS) -// On windows the stack has to be allocated 4k at a time, otherwise -// we get a segfault. The C compiler knows how to do this (it calls -// _alloca()), so we make sure that we can allocate as much stack as -// we need: -StgWord8 *win32AllocStack(void) +/* + * Note [Windows Stack allocations] + * + * On windows the stack has to be allocated 4k at a time, otherwise + * we get a segfault. The C compiler knows how to do this (it calls + * _alloca()), so we make sure that we can allocate as much stack as + * we need. However since we are doing a local stack allocation and the value + * isn't valid outside the frame, compilers are free to optimize this allocation + * and the corresponding stack check away. So to prevent that we request that + * this function never be optimized (See #14669). */ +STG_NO_OPTIMIZE StgWord8 *win32AllocStack(void) { StgWord8 stack[RESERVED_C_STACK_BYTES + 16 + 12]; return stack; |