diff options
Diffstat (limited to 'rts/Weak.c')
-rw-r--r-- | rts/Weak.c | 18 |
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; |