[commit: ghc] master: Fix crashes in hash table scanning with THREADED_RTS (9043a40)

git at git.haskell.org git at git.haskell.org
Wed Dec 7 14:15:48 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/9043a4002623679989a2fdc4e97d484a9d58d619/ghc

>---------------------------------------------------------------

commit 9043a4002623679989a2fdc4e97d484a9d58d619
Author: Simon Marlow <marlowsd at gmail.com>
Date:   Wed Dec 7 13:20:03 2016 +0000

    Fix crashes in hash table scanning with THREADED_RTS
    
    See comments.


>---------------------------------------------------------------

9043a4002623679989a2fdc4e97d484a9d58d619
 rts/sm/Scav.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c
index 10ce1e4..bbe049c 100644
--- a/rts/sm/Scav.c
+++ b/rts/sm/Scav.c
@@ -105,13 +105,26 @@ scavengeTSO (StgTSO *tso)
    Scavenging compact objects
    ------------------------------------------------------------------------- */
 
+typedef struct {
+    // We must save gct when calling mapHashTable(), which is compiled
+    // without GCThread.h and so uses a different calling convention.
+    // See also GC.c:mark_root where we do a similar thing.
+    gc_thread *saved_gct;
+    HashTable *newHash;
+} MapHashData;
+
 static void
-evacuate_hash_entry(HashTable *newHash, StgWord key, const void *value)
+evacuate_hash_entry(MapHashData *dat, StgWord key, const void *value)
 {
     StgClosure *p = (StgClosure*)key;
+#ifdef THREADED_RTS
+    gc_thread *old_gct = gct;
+#endif
 
+    SET_GCT(dat->saved_gct);
     evacuate(&p);
-    insertHashTable(newHash, (StgWord)p, value);
+    insertHashTable(dat->newHash, (StgWord)p, value);
+    SET_GCT(old_gct);
 }
 
 static void
@@ -122,8 +135,11 @@ scavenge_compact(StgCompactNFData *str)
     gct->eager_promotion = false;
 
     if (str->hash) {
+        MapHashData dat;
+        dat.saved_gct = gct;
         HashTable *newHash = allocHashTable();
-        mapHashTable(str->hash, (void*)newHash, (MapHashFn)evacuate_hash_entry);
+        dat.newHash = newHash;
+        mapHashTable(str->hash, (void*)&dat, (MapHashFn)evacuate_hash_entry);
         freeHashTable(str->hash, NULL);
         str->hash = newHash;
     }



More information about the ghc-commits mailing list