diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-03-02 18:13:52 -0500 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-03-09 06:10:52 -0400 |
commit | 70d2b9956d1ecc9d40d1e2d4920983af00ea846d (patch) | |
tree | a1bda450d47a274098e779432415a18108c342f6 /rts/Sparks.c | |
parent | 067632342cf2f063b0f23c255740e2717e5e14c7 (diff) | |
download | haskell-70d2b9956d1ecc9d40d1e2d4920983af00ea846d.tar.gz |
nonmoving: Fix collection of sparks
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++; |