diff options
-rw-r--r-- | rts/sm/NonMovingMark.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c index acf84d44f1..846c02bbfd 100644 --- a/rts/sm/NonMovingMark.c +++ b/rts/sm/NonMovingMark.c @@ -565,6 +565,7 @@ void updateRemembSetPushThunkEager(Capability *cap, StgThunk *thunk) { /* N.B. info->i.type mustn't be WHITEHOLE */ + MarkQueue *queue = &cap->upd_rem_set.queue; switch (info->i.type) { case THUNK: case THUNK_1_0: @@ -573,7 +574,6 @@ void updateRemembSetPushThunkEager(Capability *cap, case THUNK_1_1: case THUNK_0_2: { - MarkQueue *queue = &cap->upd_rem_set.queue; push_thunk_srt(queue, &info->i); for (StgWord i = 0; i < info->i.layout.payload.ptrs; i++) { @@ -587,7 +587,6 @@ void updateRemembSetPushThunkEager(Capability *cap, } case AP: { - MarkQueue *queue = &cap->upd_rem_set.queue; StgAP *ap = (StgAP *) thunk; if (check_in_nonmoving_heap(ap->fun)) { push_closure(queue, ap->fun, NULL); @@ -599,6 +598,16 @@ void updateRemembSetPushThunkEager(Capability *cap, case BLACKHOLE: // TODO: This is right, right? break; + // The selector optimization performed by the nonmoving mark may have + // overwritten a thunk which we are updating with an indirection. + case IND: + { + StgInd *ind = (StgInd *) thunk; + if (check_in_nonmoving_heap(ind->indirectee)) { + push_closure(queue, ind->indirectee, NULL); + } + break; + } default: barf("updateRemembSetPushThunk: invalid thunk pushed: p=%p, type=%d", thunk, info->i.type); |