X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FHeapStackCheck.cmm;h=a1b6d65f34f6e611b67bb1cbd05dcba0683e041a;hb=de75026f5a48d3d052135a973ab4dff76c5b20f5;hp=10baca23c6789552545ab54fed485ff1c4e2579c;hpb=304e7fb703e7afddc1ef9be6aab6505e36b63b06;p=ghc-hetmet.git diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm index 10baca2..a1b6d65 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). @@ -63,13 +74,14 @@ import LeaveCriticalSection; #define GC_GENERIC \ DEBUG_ONLY(foreign "C" heapCheckFail()); \ if (Hp > HpLim) { \ + Hp = Hp - HpAlloc/*in bytes*/; \ if (HpLim == 0) { \ R1 = ThreadYielding; \ goto sched; \ } \ - Hp = Hp - HpAlloc/*in bytes*/; \ if (HpAlloc <= BLOCK_SIZE \ && bdescr_link(CurrentNursery) != NULL) { \ + HpAlloc = 0; \ CLOSE_NURSERY(); \ CurrentNursery = bdescr_link(CurrentNursery); \ OPEN_NURSERY(); \