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
.