diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index 65bc2d01df6b9a610045e19a7cd3853d3ce9ec63..2b32e12d2a143bbd49a2cab58c04e41f2945c178 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -233,6 +233,22 @@ stg_shrinkSmallMutableArrayzh ( gcptr mba, W_ new_size ) OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgSmallMutArrPtrs) + new_size)); + + IF_NONMOVING_WRITE_BARRIER_ENABLED { + // Ensure that the elements we are about to shrink out of existence + // remain visible to the non-moving collector. + W_ p, end; + p = mba + SIZEOF_StgSmallMutArrPtrs + WDS(new_size); + end = mba + SIZEOF_StgSmallMutArrPtrs + WDS(StgSmallMutArrPtrs_ptrs(mba)); +again: + ccall updateRemembSetPushClosure_(BaseReg "ptr", + W_[p] "ptr"); + if (p < end) { + p = p + SIZEOF_W; + goto again; + } + } + StgSmallMutArrPtrs_ptrs(mba) = new_size; // See the comments in overwritingClosureOfs for an explanation // of the interaction with LDV profiling.