diff options
Diffstat (limited to 'rts/sm/NonMovingMark.c')
-rw-r--r-- | rts/sm/NonMovingMark.c | 24 |
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; } |