summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-03-18 11:18:47 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-03-18 11:18:47 +0000
commitbd78c94a3b41f8d2097efc0415fa26e0cd1140ef (patch)
tree72ce0126788012594c474276392ec0071046f318
parent8b18faef8aeaf40150c208272a2fc117611e8ae8 (diff)
downloadhaskell-bd78c94a3b41f8d2097efc0415fa26e0cd1140ef.tar.gz
Fixes to "Retract Hp *before* checking for HpLim==0"
-rw-r--r--compiler/codeGen/CgForeignCall.hs9
-rw-r--r--rts/HeapStackCheck.cmm12
2 files changed, 19 insertions, 2 deletions
diff --git a/compiler/codeGen/CgForeignCall.hs b/compiler/codeGen/CgForeignCall.hs
index cf99f316c3..87c82cb3ba 100644
--- a/compiler/codeGen/CgForeignCall.hs
+++ b/compiler/codeGen/CgForeignCall.hs
@@ -212,7 +212,11 @@ emitLoadThreadState = do
bWord),
-- SpLim = tso->stack + RESERVED_STACK_WORDS;
CmmAssign spLim (cmmOffsetW (cmmOffset (CmmReg (CmmLocal tso)) tso_STACK)
- rESERVED_STACK_WORDS)
+ rESERVED_STACK_WORDS),
+ -- HpAlloc = 0;
+ -- HpAlloc is assumed to be set to non-zero only by a failed
+ -- a heap check, see HeapStackCheck.cmm:GC_GENERIC
+ CmmAssign hpAlloc (CmmLit zeroCLit)
]
emitOpenNursery
-- and load the current cost centre stack from the TSO when profiling:
@@ -267,13 +271,14 @@ stgHp = CmmReg hp
stgCurrentTSO = CmmReg currentTSO
stgCurrentNursery = CmmReg currentNursery
-sp, spLim, hp, hpLim, currentTSO, currentNursery :: CmmReg
+sp, spLim, hp, hpLim, currentTSO, currentNursery, hpAlloc :: CmmReg
sp = CmmGlobal Sp
spLim = CmmGlobal SpLim
hp = CmmGlobal Hp
hpLim = CmmGlobal HpLim
currentTSO = CmmGlobal CurrentTSO
currentNursery = CmmGlobal CurrentNursery
+hpAlloc = CmmGlobal HpAlloc
-- -----------------------------------------------------------------------------
-- For certain types passed to foreign calls, we adjust the actual
diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm
index 1533ae0617..a1b6d65f34 100644
--- a/rts/HeapStackCheck.cmm
+++ b/rts/HeapStackCheck.cmm
@@ -26,6 +26,17 @@ import LeaveCriticalSection;
* - If HpLim==0, indicating that we should context-switch, we yield
* to the scheduler (return ThreadYielding).
*
+ * Note that we must leave no slop in the heap (this is a requirement
+ * for LDV profiling, at least), so if we just had a heap-check
+ * failure, then we must retract Hp by HpAlloc. How do we know
+ * whether there was a heap-check failure? HpLim might be zero, and
+ * yet we got here as a result of a stack-check failure. Hence, we
+ * require that HpAlloc is only non-zero if there was a heap-check
+ * failure, otherwise it is zero, so we can always safely subtract
+ * HpAlloc from Hp.
+ *
+ * Hence, HpAlloc is zeroed in LOAD_THREAD_STATE().
+ *
* - If the context_switch flag is set (the backup plan if setting HpLim
* to 0 didn't trigger a context switch), we yield to the scheduler
* (return ThreadYielding).
@@ -70,6 +81,7 @@ import LeaveCriticalSection;
} \
if (HpAlloc <= BLOCK_SIZE \
&& bdescr_link(CurrentNursery) != NULL) { \
+ HpAlloc = 0; \
CLOSE_NURSERY(); \
CurrentNursery = bdescr_link(CurrentNursery); \
OPEN_NURSERY(); \