[commit: ghc] ghc-8.4: Fix Windows stack allocations. (d4d6e44)
git at git.haskell.org
git at git.haskell.org
Mon Jan 29 22:34:11 UTC 2018
Repository : ssh://git@git.haskell.org/ghc
On branch : ghc-8.4
Link : http://ghc.haskell.org/trac/ghc/changeset/d4d6e448d1700dbc074058540724fab54e5f0f33/ghc
>---------------------------------------------------------------
commit d4d6e448d1700dbc074058540724fab54e5f0f33
Author: Tamar Christina <tamar at zhox.com>
Date: Fri Jan 26 13:10:10 2018 -0500
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
(cherry picked from commit a55d581f8f2923560c3444253050b13fdf2dec10)
>---------------------------------------------------------------
d4d6e448d1700dbc074058540724fab54e5f0f33
includes/Stg.h | 10 ++++++++++
rts/StgCRun.c | 16 +++++++++++-----
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/includes/Stg.h b/includes/Stg.h
index f377e50..2e02347 100644
--- a/includes/Stg.h
+++ b/includes/Stg.h
@@ -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
-------------------------------------------------------------------------- */
diff --git a/rts/StgCRun.c b/rts/StgCRun.c
index 2166249..4ce0c44 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;
More information about the ghc-commits
mailing list