Skip to content
Snippets Groups Projects
Commit a55d581f authored by Tamar Christina's avatar Tamar Christina Committed by Ben Gamari
Browse files

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
parent 9a57cfeb
No related merge requests found
......@@ -204,6 +204,16 @@
#define STG_UNUSED GNUC3_ATTRIBUTE(__unused__)
/* Prevent functions from being optimized.
See Note [Windows Stack allocations] */
#if defined(__clang__)
#define STG_NO_OPTIMIZE __attribute__((optnone))
#elif defined(__GNUC__) || defined(__GNUG__)
#define STG_NO_OPTIMIZE __attribute__((optimize("O0")))
#else
#define STG_NO_OPTIMIZE /* nothing */
#endif
/* -----------------------------------------------------------------------------
Global type definitions
-------------------------------------------------------------------------- */
......
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment