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.