summaryrefslogtreecommitdiff
path: root/rts/sm/GC.c
diff options
context:
space:
mode:
authorÖmer Sinan Ağacan <omeragacan@gmail.com>2020-05-25 11:59:11 +0300
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-11-11 03:20:35 -0500
commitc34a4b98b1f09ea3096d39a839a86f2d7185c796 (patch)
treebf3700fd70504a5676220df8702b41810e880846 /rts/sm/GC.c
parent584058ddff71460023712a8d816b83b581e6e78f (diff)
downloadhaskell-c34a4b98b1f09ea3096d39a839a86f2d7185c796.tar.gz
Fix and enable object unloading in GHCi
Fixes #16525 by tracking dependencies between object file symbols and marking symbol liveness during garbage collection See Note [Object unloading] in CheckUnload.c for details.
Diffstat (limited to 'rts/sm/GC.c')
-rw-r--r--rts/sm/GC.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index a5aa7e1f4e..0dc92a29a0 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -97,6 +97,13 @@
* See also: Note [STATIC_LINK fields] in Storage.h.
*/
+/* Hot GC globals
+ * ~~~~~~~~~~~~~~
+ * The globals below are quite hot during GC but read-only, initialized during
+ * the beginning of collection. It is important that they reside in the same
+ * cache-line to minimize unnecessary cache misses.
+ */
+
/* N is the oldest generation being collected, where the generations
* are numbered starting at 0. A major GC (indicated by the major_gc
* flag) is when we're collecting all generations. We only attempt to
@@ -105,6 +112,7 @@
uint32_t N;
bool major_gc;
bool deadlock_detect_gc;
+bool unload_mark_needed;
/* Data used for allocation area sizing.
*/
@@ -314,6 +322,12 @@ GarbageCollect (uint32_t collect_gen,
static_flag == STATIC_FLAG_A ? STATIC_FLAG_B : STATIC_FLAG_A;
}
+ if (major_gc) {
+ unload_mark_needed = prepareUnloadCheck();
+ } else {
+ unload_mark_needed = false;
+ }
+
#if defined(THREADED_RTS)
work_stealing = RtsFlags.ParFlags.parGcLoadBalancingEnabled &&
N >= RtsFlags.ParFlags.parGcLoadBalancingGen;
@@ -831,9 +845,12 @@ GarbageCollect (uint32_t collect_gen,
resetNurseries();
- // mark the garbage collected CAFs as dead
#if defined(DEBUG)
- if (major_gc && !RtsFlags.GcFlags.useNonmoving) { gcCAFs(); }
+ // Mark the garbage collected CAFs as dead. Done in `nonmovingGcCafs()` when
+ // non-moving GC is enabled.
+ if (major_gc && !RtsFlags.GcFlags.useNonmoving) {
+ gcCAFs();
+ }
#endif
// Update the stable name hash table
@@ -844,9 +861,14 @@ GarbageCollect (uint32_t collect_gen,
// hs_free_stable_ptr(), both of which access the StablePtr table.
stablePtrUnlock();
- // Must be after stablePtrUnlock(), because it might free stable ptrs.
- if (major_gc) {
- checkUnload (gct->scavenged_static_objects);
+ // Unload dynamically-loaded object code after a major GC.
+ // See Note [Object unloading] in CheckUnload.c for details.
+ //
+ // TODO: Similar to `nonmovingGcCafs` non-moving GC should have its own
+ // collector for these objects, but that's currently not implemented, so we
+ // simply don't unload object code when non-moving GC is enabled.
+ if (major_gc && !RtsFlags.GcFlags.useNonmoving) {
+ checkUnload();
}
#if defined(PROFILING)