diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-03-02 18:13:52 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-03-04 12:56:40 -0500 |
commit | 92bc36885a8866714fce5cb44e298562ac29b5b8 (patch) | |
tree | 63771e09bb27a2bcf04f30ce21c93cb7df5b7d17 /rts/Sparks.c | |
parent | 2bf7b5b54065a6aa6ab7e70a9b5ba87aed1c84cf (diff) | |
download | haskell-wip/gc-backports.tar.gz |
nonmoving: Fix collection of sparkswip/gc-backports
Previously sparks living in the non-moving heap would be promptly GC'd
by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag,
which non-moving heap blocks do not have set.
Fix this by implementing proper support in pruneSparkQueue for
determining reachability in the non-moving heap. The story is told in
Note [Spark management in the nonmoving heap].
Diffstat (limited to 'rts/Sparks.c')
-rw-r--r-- | rts/Sparks.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/rts/Sparks.c b/rts/Sparks.c index 4022691da2..2012b0682b 100644 --- a/rts/Sparks.c +++ b/rts/Sparks.c @@ -15,6 +15,7 @@ #include "Prelude.h" #include "Sparks.h" #include "ThreadLabels.h" +#include "sm/NonMovingMark.h" #include "sm/HeapAlloc.h" #if defined(THREADED_RTS) @@ -86,7 +87,7 @@ newSpark (StgRegTable *reg, StgClosure *p) * -------------------------------------------------------------------------- */ void -pruneSparkQueue (Capability *cap) +pruneSparkQueue (bool nonmovingMarkFinished, Capability *cap) { SparkPool *pool; StgClosurePtr spark, tmp, *elements; @@ -196,7 +197,26 @@ pruneSparkQueue (Capability *cap) traceEventSparkFizzle(cap); } } else if (HEAP_ALLOCED(spark)) { - if ((Bdescr((P_)spark)->flags & BF_EVACUATED)) { + bdescr *spark_bd = Bdescr((P_) spark); + bool is_alive = false; + if (nonmovingMarkFinished) { + // See Note [Spark management under the nonmoving collector] + // in NonMoving.c. + // If we just concluded concurrent marking then we can rely + // on the mark bitmap to reflect whether sparks living in the + // non-moving heap have died. + if (spark_bd->flags & BF_NONMOVING) { + is_alive = nonmovingIsAlive(spark); + } else { + // The nonmoving collector doesn't collect anything + // outside of the non-moving heap. + is_alive = true; + } + } else if (spark_bd->flags & (BF_EVACUATED | BF_NONMOVING)) { + is_alive = true; + } + + if (is_alive) { if (closure_SHOULD_SPARK(spark)) { elements[botInd] = spark; // keep entry (new address) botInd++; |