diff options
Diffstat (limited to 'rts/sm/NonMoving.c')
-rw-r--r-- | rts/sm/NonMoving.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c index 89b6d0dc7a..caa867f6a6 100644 --- a/rts/sm/NonMoving.c +++ b/rts/sm/NonMoving.c @@ -9,6 +9,7 @@ #include "Rts.h" #include "RtsUtils.h" #include "Capability.h" +#include "Sparks.h" #include "Printer.h" #include "Storage.h" // We call evacuate, which expects the thread-local gc_thread to be valid; @@ -367,6 +368,24 @@ Mutex concurrent_coll_finished_lock; * approximate due to concurrent collection and ultimately seems more costly * than the problem demands. * + * Note [Spark management under the nonmoving collector] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Every GC, both minor and major, prunes the spark queue (using + * Sparks.c:pruneSparkQueue) of sparks which are no longer reachable. + * Doing this with concurrent collection is a tad subtle since the minor + * collections cannot rely on the mark bitmap to accurately reflect the + * reachability of a spark. + * + * We use a conservative reachability approximation: + * + * - Minor collections assume that all sparks living in the non-moving heap + * are reachable. + * + * - Major collections prune the spark queue during the final sync. This pruning + * assumes that all sparks in the young generations are reachable (since the + * BF_EVACUATED flag won't be set on the nursery blocks) and will consequently + * only prune dead sparks living in the non-moving heap. + * */ memcount nonmoving_live_words = 0; @@ -1061,6 +1080,14 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * nonmoving_old_weak_ptr_list = NULL; } + // Prune spark lists + // See Note [Spark management under the nonmoving collector]. +#if defined(THREADED_RTS) + for (uint32_t n = 0; n < n_capabilities; n++) { + pruneSparkQueue(true, capabilities[n]); + } +#endif + // Everything has been marked; allow the mutators to proceed #if defined(THREADED_RTS) nonmoving_write_barrier_enabled = false; |