summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-11-16 09:48:19 -0500
committerMatthew Pickering <matthewtpickering@gmail.com>2023-01-06 15:21:48 +0000
commit98ec2167b6c8c7576fa752a6307a5a63e57a60ad (patch)
tree9d22c79c5c1aa008adaa0f27af7ccc9f28100966
parentce02950d71246bf2729ca84472e524d238e600fe (diff)
downloadhaskell-98ec2167b6c8c7576fa752a6307a5a63e57a60ad.tar.gz
nonmoving: Fix race in shortcutting
We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. (cherry picked from commit ab6cf893037f073fd3daf619579c84e58362b499)
-rw-r--r--rts/include/rts/storage/ClosureMacros.h6
-rw-r--r--rts/sm/NonMovingShortcut.c3
2 files changed, 8 insertions, 1 deletions
diff --git a/rts/include/rts/storage/ClosureMacros.h b/rts/include/rts/storage/ClosureMacros.h
index ba57df1699..ecfca8a81c 100644
--- a/rts/include/rts/storage/ClosureMacros.h
+++ b/rts/include/rts/storage/ClosureMacros.h
@@ -97,6 +97,12 @@ EXTERN_INLINE const StgInfoTable *get_itbl(const StgClosure *c)
return INFO_PTR_TO_STRUCT(RELAXED_LOAD(&c->header.info));
}
+EXTERN_INLINE const StgInfoTable *get_itbl_acquire(const StgClosure *c);
+EXTERN_INLINE const StgInfoTable *get_itbl_acquire(const StgClosure *c)
+{
+ return INFO_PTR_TO_STRUCT(ACQUIRE_LOAD(&c->header.info));
+}
+
EXTERN_INLINE const StgRetInfoTable *get_ret_itbl(const StgClosure *c);
EXTERN_INLINE const StgRetInfoTable *get_ret_itbl(const StgClosure *c)
{
diff --git a/rts/sm/NonMovingShortcut.c b/rts/sm/NonMovingShortcut.c
index 83c4857677..ee97ba1b70 100644
--- a/rts/sm/NonMovingShortcut.c
+++ b/rts/sm/NonMovingShortcut.c
@@ -153,7 +153,8 @@ selectee_changed:
// Selectee is a non-moving object, mark it.
markQueuePushClosure(queue, selectee, NULL);
- const StgInfoTable *selectee_info_tbl = get_itbl(selectee);
+ // This may synchronize with the release in updateWithIndirection.
+ const StgInfoTable *selectee_info_tbl = get_itbl_acquire(selectee);
switch (selectee_info_tbl->type) {
case WHITEHOLE: {
// Probably a loop. Abort.