diff options
author | Simon Marlow <marlowsd@gmail.com> | 2010-08-10 13:37:39 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2010-08-10 13:37:39 +0000 |
commit | afabd52e95235ab36c5ad7b3473b5d6a4d58360b (patch) | |
tree | cb646ed682345fe60f6460ca558f003db1f4c681 /rts/sm | |
parent | 7a50ff1e44710335e935ff199cd95616840b9f02 (diff) | |
download | haskell-afabd52e95235ab36c5ad7b3473b5d6a4d58360b.tar.gz |
Run finalizers *after* updating the stable pointer table (#4221)
Silly bug really, we were running the C finalizers while the StablePtr
table was still in a partially-updated state during GC, but finalizers
are allowed to call freeStablePtr() (via hs_free_fun_ptr(), for
example), and chaos ensues.
Diffstat (limited to 'rts/sm')
-rw-r--r-- | rts/sm/GC.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c index ee3e17089a..18a87bdbfa 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -727,11 +727,6 @@ SET_GCT(gc_threads[0]); // Reset the nursery resetNurseries(); - // start any pending finalizers - RELEASE_SM_LOCK; - scheduleFinalizers(cap, old_weak_ptr_list); - ACQUIRE_SM_LOCK; - // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); @@ -740,6 +735,17 @@ SET_GCT(gc_threads[0]); // Update the stable pointer hash table. updateStablePtrTable(major_gc); + // unlock the StablePtr table. Must be before scheduleFinalizers(), + // because a finalizer may call hs_free_fun_ptr() or + // hs_free_stable_ptr(), both of which access the StablePtr table. + stablePtrPostGC(); + + // Start any pending finalizers. Must be after + // updateStablePtrTable() and stablePtrPostGC() (see #4221). + RELEASE_SM_LOCK; + scheduleFinalizers(cap, old_weak_ptr_list); + ACQUIRE_SM_LOCK; + // check sanity after GC IF_DEBUG(sanity, checkSanity(rtsTrue)); @@ -771,9 +777,6 @@ SET_GCT(gc_threads[0]); slop = calcLiveBlocks() * BLOCK_SIZE_W - live; stat_endGC(allocated, live, copied, N, max_copied, avg_copied, slop); - // unlock the StablePtr table - stablePtrPostGC(); - // Guess which generation we'll collect *next* time initialise_N(force_major_gc); |