summaryrefslogtreecommitdiff
path: root/rts/Sparks.c
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-03-02 18:13:52 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-03-09 06:10:52 -0400
commit70d2b9956d1ecc9d40d1e2d4920983af00ea846d (patch)
treea1bda450d47a274098e779432415a18108c342f6 /rts/Sparks.c
parent067632342cf2f063b0f23c255740e2717e5e14c7 (diff)
downloadhaskell-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.c24
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++;