diff options
-rw-r--r-- | compiler/ghci/ByteCodeGen.lhs | 14 | ||||
-rw-r--r-- | compiler/main/Constants.lhs | 7 | ||||
-rw-r--r-- | includes/Constants.h | 7 | ||||
-rw-r--r-- | rts/Apply.cmm | 4 |
4 files changed, 25 insertions, 7 deletions
diff --git a/compiler/ghci/ByteCodeGen.lhs b/compiler/ghci/ByteCodeGen.lhs index f46eb9460b..846737e0a6 100644 --- a/compiler/ghci/ByteCodeGen.lhs +++ b/compiler/ghci/ByteCodeGen.lhs @@ -178,17 +178,19 @@ mkProtoBCO nm instrs_ordlist origin arity bitmap_size bitmap is_ret mallocd_bloc -- (hopefully rare) cases when the (overestimated) stack use -- exceeds iNTERP_STACK_CHECK_THRESH. maybe_with_stack_check - | is_ret = peep_d - -- don't do stack checks at return points; + | is_ret && stack_usage < aP_STACK_SPLIM = peep_d + -- don't do stack checks at return points, -- everything is aggregated up to the top BCO - -- (which must be a function) - | stack_overest >= iNTERP_STACK_CHECK_THRESH - = STKCHECK stack_overest : peep_d + -- (which must be a function). + -- That is, unless the stack usage is >= AP_STACK_SPLIM, + -- see bug #1466. + | stack_usage >= iNTERP_STACK_CHECK_THRESH + = STKCHECK stack_usage : peep_d | otherwise = peep_d -- the supposedly common case -- We assume that this sum doesn't wrap - stack_overest = sum (map bciStackUse peep_d) + stack_usage = sum (map bciStackUse peep_d) -- Merge local pushes peep_d = peep (fromOL instrs_ordlist) diff --git a/compiler/main/Constants.lhs b/compiler/main/Constants.lhs index 0437217cf6..8dc94d19db 100644 --- a/compiler/main/Constants.lhs +++ b/compiler/main/Constants.lhs @@ -110,6 +110,13 @@ returning to the scheduler. rESERVED_STACK_WORDS = (RESERVED_STACK_WORDS :: Int) \end{code} +Continuations that need more than this amount of stack should do their +own stack check (see bug #1466). + +\begin{code} +aP_STACK_SPLIM = (AP_STACK_SPLIM :: Int) +\end{code} + Size of a word, in bytes \begin{code} diff --git a/includes/Constants.h b/includes/Constants.h index 012acd197c..e0949cbd1f 100644 --- a/includes/Constants.h +++ b/includes/Constants.h @@ -118,6 +118,13 @@ #define RESERVED_STACK_WORDS 21 /* ----------------------------------------------------------------------------- + The limit on the size of the stack check performed when we enter an + AP_STACK, in words. See raiseAsync() and bug #1466. + -------------------------------------------------------------------------- */ + +#define AP_STACK_SPLIM 1024 + +/* ----------------------------------------------------------------------------- Storage manager constants -------------------------------------------------------------------------- */ diff --git a/rts/Apply.cmm b/rts/Apply.cmm index c9c7daa9ac..0498f009b8 100644 --- a/rts/Apply.cmm +++ b/rts/Apply.cmm @@ -249,7 +249,9 @@ INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK") * closure, in which case we must enter the blackhole on return rather * than continuing to evaluate the now-defunct closure. */ - STK_CHK_NP(WDS(Words) + SIZEOF_StgUpdateFrame); + STK_CHK_NP(WDS(Words) + SIZEOF_StgUpdateFrame + WDS(AP_STACK_SPLIM)); + /* ensure there is at least AP_STACK_SPLIM words of headroom available + * after unpacking the AP_STACK. See bug #1466 */ PUSH_UPD_FRAME(Sp - SIZEOF_StgUpdateFrame, R1); Sp = Sp - SIZEOF_StgUpdateFrame - WDS(Words); |