diff options
author | Ben Gamari <ben@smart-cactus.org> | 2021-11-17 12:08:57 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2021-11-17 12:12:45 -0500 |
commit | 00ed82eaec449c0747f989ce232da9fda2c94520 (patch) | |
tree | 3d55e1f785a8c9252366aa92d29cd1463bf35796 | |
parent | cc635da167fdec2dead0603b0026cb841f0aa645 (diff) | |
download | haskell-wip/T20649.tar.gz |
rts: Ensure that markCAFs marks object codewip/T20649
Previously `markCAFs` would only evacuate CAFs' indirectees. This would
allow reachable object code to be unloaded by the linker as `evacuate`
may never be called on the CAF itself, despite it being reachable via
the `{dyn,revertible}_caf_list`s.
To fix this we teach `markCAFs` to explicit call `markObjectCode`,
ensuring that the linker is aware of objects reachable via the CAF
lists.
Fixes #20649.
-rw-r--r-- | rts/sm/GCAux.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/rts/sm/GCAux.c b/rts/sm/GCAux.c index f0e18a5ca5..41c24634c2 100644 --- a/rts/sm/GCAux.c +++ b/rts/sm/GCAux.c @@ -11,6 +11,7 @@ #include "Rts.h" #include "GC.h" +#include "CheckUnload.h" #include "Storage.h" #include "Compact.h" #include "Task.h" @@ -145,20 +146,26 @@ revertCAFs( void ) void markCAFs (evac_fn evac, void *user) { - StgIndStatic *c; - - for (c = dyn_caf_list; + /* N.B. We must both ensure that the indirectee is + * evacuated and that we let the linker know that the CAF + * itself is still reachable, lest it be collected (see + * #20649). + */ + for (StgIndStatic *c = dyn_caf_list; ((StgWord) c | STATIC_FLAG_LIST) != (StgWord)END_OF_CAF_LIST; c = (StgIndStatic *)c->static_link) { c = (StgIndStatic *)UNTAG_STATIC_LIST_PTR(c); evac(user, &c->indirectee); + markObjectCode(c); } - for (c = revertible_caf_list; + + for (StgIndStatic *c = revertible_caf_list; ((StgWord) c | STATIC_FLAG_LIST) != (StgWord)END_OF_CAF_LIST; c = (StgIndStatic *)c->static_link) { c = (StgIndStatic *)UNTAG_STATIC_LIST_PTR(c); evac(user, &c->indirectee); + markObjectCode(c); } } |