summaryrefslogtreecommitdiff
path: root/rts/Weak.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/Weak.c')
-rw-r--r--rts/Weak.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/rts/Weak.c b/rts/Weak.c
index ec998c214f..fe4516794a 100644
--- a/rts/Weak.c
+++ b/rts/Weak.c
@@ -93,9 +93,19 @@ scheduleFinalizers(Capability *cap, StgWeak *list)
StgWord size;
uint32_t n, i;
- ASSERT(n_finalizers == 0);
-
- finalizer_list = list;
+ // This assertion does not hold with non-moving collection because
+ // non-moving collector does not wait for the list to be consumed (by
+ // doIdleGcWork()) before appending the list with more finalizers.
+ ASSERT(RtsFlags.GcFlags.useNonmoving || n_finalizers == 0);
+
+ // Append finalizer_list with the new list. TODO: Perhaps cache tail of the
+ // list for faster append. NOTE: We can't append `list` here! Otherwise we
+ // end up traversing already visited weaks in the loops below.
+ StgWeak **tl = &finalizer_list;
+ while (*tl) {
+ tl = &(*tl)->link;
+ }
+ *tl = list;
// Traverse the list and
// * count the number of Haskell finalizers
@@ -130,7 +140,7 @@ scheduleFinalizers(Capability *cap, StgWeak *list)
SET_HDR(w, &stg_DEAD_WEAK_info, w->header.prof.ccs);
}
- n_finalizers = i;
+ n_finalizers += i;
// No Haskell finalizers to run?
if (n == 0) return;