summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGHC GitLab CI <ghc-ci@gitlab-haskell.org>2020-11-25 23:03:58 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-11-29 15:33:54 -0500
commite992ea84248e2ac9f9d439cd9b25745e8c41e32d (patch)
tree478d276ef3f3f3e3bbcd3d03c971dc02f171d527
parent1bc104b029b4f043cac42253ee2387f4d574abca (diff)
downloadhaskell-e992ea84248e2ac9f9d439cd9b25745e8c41e32d.tar.gz
ThreadPaused: Don't zero slop until free vars are pushed
When threadPaused blackholes a thunk it calls `OVERWRITING_CLOSURE` to zero the slop for the benefit of the sanity checker. Previously this was done *before* pushing the thunk's free variables to the update remembered set. Consequently we would pull zero'd pointers to the update remembered set.
-rw-r--r--includes/rts/storage/ClosureMacros.h4
-rw-r--r--rts/ThreadPaused.c13
2 files changed, 11 insertions, 6 deletions
diff --git a/includes/rts/storage/ClosureMacros.h b/includes/rts/storage/ClosureMacros.h
index 5674322bd2..b841ef8be0 100644
--- a/includes/rts/storage/ClosureMacros.h
+++ b/includes/rts/storage/ClosureMacros.h
@@ -520,11 +520,15 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n)
#if defined(PROFILING) || defined(DEBUG)
#define OVERWRITING_CLOSURE(c) \
overwritingClosure(c)
+#define OVERWRITING_CLOSURE_SIZE(c, size) \
+ overwritingClosureSize(c, size)
#define OVERWRITING_CLOSURE_MUTABLE(c, off) \
overwritingMutableClosureOfs(c, off)
#else
#define OVERWRITING_CLOSURE(c) \
do { (void) sizeof(c); } while(0)
+#define OVERWRITING_CLOSURE_SIZE(c, size) \
+ do { (void) sizeof(c); (void) sizeof(size); } while(0)
#define OVERWRITING_CLOSURE_MUTABLE(c, off) \
do { (void) sizeof(c); (void) sizeof(off); } while(0)
#endif
diff --git a/rts/ThreadPaused.c b/rts/ThreadPaused.c
index 13fc2b4ca0..9f41fa1ab3 100644
--- a/rts/ThreadPaused.c
+++ b/rts/ThreadPaused.c
@@ -314,10 +314,6 @@ threadPaused(Capability *cap, StgTSO *tso)
continue;
}
- // zero out the slop so that the sanity checker can tell
- // where the next closure is.
- OVERWRITING_CLOSURE(bh);
-
// an EAGER_BLACKHOLE or CAF_BLACKHOLE gets turned into a
// BLACKHOLE here.
#if defined(THREADED_RTS)
@@ -345,11 +341,16 @@ threadPaused(Capability *cap, StgTSO *tso)
// overwrite to the update remembered set.
// N.B. We caught the WHITEHOLE case above.
updateRemembSetPushThunkEager(cap,
- THUNK_INFO_PTR_TO_STRUCT(bh_info),
- (StgThunk *) bh);
+ THUNK_INFO_PTR_TO_STRUCT(bh_info),
+ (StgThunk *) bh);
}
}
+ // zero out the slop so that the sanity checker can tell
+ // where the next closure is. N.B. We mustn't do this until we have
+ // pushed the free variables to the update remembered set above.
+ OVERWRITING_CLOSURE_SIZE(bh, closure_sizeW_(bh, INFO_PTR_TO_STRUCT(bh_info)));
+
// The payload of the BLACKHOLE points to the TSO
RELAXED_STORE(&((StgInd *)bh)->indirectee, (StgClosure *)tso);
SET_INFO_RELEASE(bh,&stg_BLACKHOLE_info);