[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