diff options
author | David Feuer <david.feuer@gmail.com> | 2018-08-29 16:34:21 -0400 |
---|---|---|
committer | David Feuer <David.Feuer@gmail.com> | 2018-08-29 16:34:22 -0400 |
commit | f48e276a5ba68d8b6fcb4a558022581fb30f9326 (patch) | |
tree | 8ea324b84d137d59cda566d6a559016d2c7437ea /rts/sm | |
parent | 65eec9cfd4410c0e30b0ed06116c15f8ce3de49d (diff) | |
download | haskell-f48e276a5ba68d8b6fcb4a558022581fb30f9326.tar.gz |
Finish stable split
Long ago, the stable name table and stable pointer tables were one.
Now, they are separate, and have significantly different
implementations. I believe the time has come to finish the split
that began in #7674.
* Divide `rts/Stable` into `rts/StableName` and `rts/StablePtr`.
* Give each table its own mutex.
* Add FFI functions `hs_lock_stable_ptr_table` and
`hs_unlock_stable_ptr_table` and document them.
These are intended to replace the previously undocumented
`hs_lock_stable_tables` and `hs_lock_stable_tables`,
which are now documented as deprecated synonyms.
* Make `eqStableName#` use pointer equality instead of unnecessarily
comparing stable name table indices.
Reviewers: simonmar, bgamari, erikd
Reviewed By: bgamari
Subscribers: rwbarton, carter
GHC Trac Issues: #15555
Differential Revision: https://phabricator.haskell.org/D5084
Diffstat (limited to 'rts/sm')
-rw-r--r-- | rts/sm/Compact.c | 8 | ||||
-rw-r--r-- | rts/sm/GC.c | 23 |
2 files changed, 20 insertions, 11 deletions
diff --git a/rts/sm/Compact.c b/rts/sm/Compact.c index 10ad73c7d7..004e042069 100644 --- a/rts/sm/Compact.c +++ b/rts/sm/Compact.c @@ -25,7 +25,8 @@ #include "Trace.h" #include "Weak.h" #include "MarkWeak.h" -#include "Stable.h" +#include "StablePtr.h" +#include "StableName.h" // Turn off inlining when debugging - it obfuscates things #if defined(DEBUG) @@ -1000,7 +1001,10 @@ compact(StgClosure *static_objects) thread_static(static_objects /* ToDo: ok? */); // the stable pointer table - threadStableTables((evac_fn)thread_root, NULL); + threadStablePtrTable((evac_fn)thread_root, NULL); + + // the stable name table + threadStableNameTable((evac_fn)thread_root, NULL); // the CAF list (used by GHCi) markCAFs((evac_fn)thread_root, NULL); diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 90857abe38..70d6d8efe5 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -46,7 +46,8 @@ #include "RetainerProfile.h" #include "LdvProfile.h" #include "RaiseAsync.h" -#include "Stable.h" +#include "StableName.h" +#include "StablePtr.h" #include "CheckUnload.h" #include "CNF.h" #include "RtsFlags.h" @@ -238,8 +239,9 @@ GarbageCollect (uint32_t collect_gen, // tell the stats department that we've started a GC stat_startGC(cap, gct); - // lock the StablePtr table - stableLock(); + // Lock the StablePtr table. This prevents FFI calls manipulating + // the table from occurring during GC. + stablePtrLock(); #if defined(DEBUG) mutlist_MUTVARS = 0; @@ -405,7 +407,10 @@ GarbageCollect (uint32_t collect_gen, initWeakForGC(); // Mark the stable pointer table. - markStableTables(mark_root, gct); + markStablePtrTable(mark_root, gct); + + // Remember old stable name addresses. + rememberOldStableNameAddresses (); /* ------------------------------------------------------------------------- * Repeatedly scavenge all the areas we know about until there's no @@ -431,7 +436,7 @@ GarbageCollect (uint32_t collect_gen, shutdown_gc_threads(gct->thread_index, idle_cap); // Now see which stable names are still alive. - gcStableTables(); + gcStableNameTable(); #if defined(THREADED_RTS) if (n_gc_threads == 1) { @@ -730,15 +735,15 @@ GarbageCollect (uint32_t collect_gen, if (major_gc) { gcCAFs(); } #endif - // Update the stable pointer hash table. - updateStableTables(major_gc); + // Update the stable name hash table + updateStableNameTable(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. - stableUnlock(); + stablePtrUnlock(); - // Must be after stableUnlock(), because it might free stable ptrs. + // Must be after stablePtrUnlock(), because it might free stable ptrs. if (major_gc) { checkUnload (gct->scavenged_static_objects); } |