summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-06-18 12:07:50 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-06-22 10:06:05 -0400
commitb0d6bf2a34d5e2e0cfb2410f58e768935d527be0 (patch)
tree49764a535cb0d78102cedb8ead423de3f3c716e5
parent22e721c10e3790dac6113cdcb33c62c07db54cb0 (diff)
downloadhaskell-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>
-rw-r--r--rts/sm/GCAux.c17
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;
}