diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-06-18 12:07:50 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-06-22 10:06:05 -0400 |
commit | b0d6bf2a34d5e2e0cfb2410f58e768935d527be0 (patch) | |
tree | 49764a535cb0d78102cedb8ead423de3f3c716e5 /rts | |
parent | 22e721c10e3790dac6113cdcb33c62c07db54cb0 (diff) | |
download | haskell-b0d6bf2a34d5e2e0cfb2410f58e768935d527be0.tar.gz |
rts: Reset STATIC_LINK field of reverted CAFs
When we revert a CAF we must reset the STATIC_LINK field lest the GC
might ignore the CAF (e.g. as it carries the STATIC_FLAG_LIST flag) and
will consequently overlook references to object code that we are trying
to unload. This would result in the reachable object code being
unloaded. See Note [CAF lists] and Note [STATIC_LINK fields].
This fixes #16842.
Idea-due-to: Phuong Trinh <lolotp@fb.com>
Diffstat (limited to 'rts')
-rw-r--r-- | rts/sm/GCAux.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/rts/sm/GCAux.c b/rts/sm/GCAux.c index 23ed3f0622..e8ca0c4002 100644 --- a/rts/sm/GCAux.c +++ b/rts/sm/GCAux.c @@ -114,16 +114,21 @@ isAlive(StgClosure *p) void revertCAFs( void ) { - StgIndStatic *c; + StgIndStatic *c = revertible_caf_list; - for (c = revertible_caf_list; - c != (StgIndStatic *)END_OF_CAF_LIST; - c = (StgIndStatic *)c->static_link) - { + while (c != (StgIndStatic *) END_OF_CAF_LIST) { c = (StgIndStatic *)UNTAG_STATIC_LIST_PTR(c); + StgIndStatic *next = (StgIndStatic *) c->static_link; + SET_INFO((StgClosure *)c, c->saved_info); c->saved_info = NULL; - // could, but not necessary: c->static_link = NULL; + // We must reset static_link lest the major GC finds that + // static_flag==3 and will consequently ignore references + // into code that we are trying to unload. This would result + // in reachable object code being unloaded prematurely. + // See #16842. + c->static_link = NULL; + c = next; } revertible_caf_list = (StgIndStatic*)END_OF_CAF_LIST; } |