summaryrefslogtreecommitdiff
path: root/rts/sm/NonMovingMark.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/sm/NonMovingMark.c')
-rw-r--r--rts/sm/NonMovingMark.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c
index 19776afb8c..d10cd018f3 100644
--- a/rts/sm/NonMovingMark.c
+++ b/rts/sm/NonMovingMark.c
@@ -1213,10 +1213,16 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin)
StgWord tag = GET_CLOSURE_TAG(p);
p = UNTAG_CLOSURE(p);
+ // Push an immutable field to the mark queue.
# define PUSH_FIELD(obj, field) \
markQueuePushClosure(queue, \
(StgClosure *) (obj)->field, \
(StgClosure **) &(obj)->field)
+ // Push a mutable field to the mark queue.
+# define PUSH_FIELD_MUT(obj, field) \
+ markQueuePushClosure(queue, \
+ (StgClosure *) ACQUIRE_LOAD(&(obj)->field), \
+ (StgClosure **) &(obj)->field)
if (!HEAP_ALLOCED_GC(p)) {
const StgInfoTable *info = get_itbl(p);
@@ -1391,16 +1397,16 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin)
case MVAR_CLEAN:
case MVAR_DIRTY: {
StgMVar *mvar = (StgMVar *) p;
- PUSH_FIELD(mvar, head);
- PUSH_FIELD(mvar, tail);
- PUSH_FIELD(mvar, value);
+ PUSH_FIELD_MUT(mvar, head);
+ PUSH_FIELD_MUT(mvar, tail);
+ PUSH_FIELD_MUT(mvar, value);
break;
}
case TVAR: {
StgTVar *tvar = ((StgTVar *)p);
- PUSH_FIELD(tvar, current_value);
- PUSH_FIELD(tvar, first_watch_queue_entry);
+ PUSH_FIELD_MUT(tvar, current_value);
+ PUSH_FIELD_MUT(tvar, first_watch_queue_entry);
break;
}
@@ -1531,7 +1537,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin)
case MUT_VAR_CLEAN:
case MUT_VAR_DIRTY:
- PUSH_FIELD((StgMutVar *)p, var);
+ PUSH_FIELD_MUT((StgMutVar *)p, var);
break;
case BLOCKING_QUEUE: {
@@ -1586,7 +1592,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin)
StgSmallMutArrPtrs *arr = (StgSmallMutArrPtrs *) p;
for (StgWord i = 0; i < arr->ptrs; i++) {
StgClosure **field = &arr->payload[i];
- markQueuePushClosure(queue, *field, field);
+ markQueuePushClosure(queue, ACQUIRE_LOAD(field), field);
}
break;
}
@@ -1648,6 +1654,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin)
}
# undef PUSH_FIELD
+# undef PUSH_FIELD_MUT
/* Set the mark bit: it's important that we do this only after we actually push
* the object's pointers since in the case of marking stacks there may be a
@@ -1728,7 +1735,8 @@ nonmovingMark (MarkQueue *queue)
end = arr->ptrs;
}
for (StgWord i = start; i < end; i++) {
- markQueuePushClosure_(queue, arr->payload[i]);
+ StgClosure *c = ACQUIRE_LOAD(&arr->payload[i]);
+ markQueuePushClosure_(queue, c);
}
break;
}