summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-08-10 13:37:39 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-08-10 13:37:39 +0000
commitafabd52e95235ab36c5ad7b3473b5d6a4d58360b (patch)
treecb646ed682345fe60f6460ca558f003db1f4c681 /rts/sm
parent7a50ff1e44710335e935ff199cd95616840b9f02 (diff)
downloadhaskell-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.c19
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);