Skip to content

Nonmoving write barrier in shrinkSmallMutableArray# incorrect in case of zero-length

Currently shrinkSmallMutableArray# has this:

   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;
     }
   }

However, what if StgSmallMutArrPtrs_ptrs(mba) == 0? We end up pushing some random value (likely an info table pointer) to the update remembered set. This is obviously wrong.

The updateRemembSetPushClosure_ call should be beneath the if.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information