diff --git a/compiler-rt/lib/scudo/standalone/primary32.h b/compiler-rt/lib/scudo/standalone/primary32.h --- a/compiler-rt/lib/scudo/standalone/primary32.h +++ b/compiler-rt/lib/scudo/standalone/primary32.h @@ -788,8 +788,12 @@ continue; const uptr GroupBase = decompactGroupBase(BG.CompactPtrGroupBase); - uptr AllocatedGroupSize = - GroupBase == CurGroupBase ? Sci->CurrentRegionAllocated : GroupSize; + // The `GroupSize` may not be divided by `BlockSize`, which means there is + // an unused space at the end of Region. Exclude that space to avoid + // unused page map entry. + uptr AllocatedGroupSize = GroupBase == CurGroupBase + ? Sci->CurrentRegionAllocated + : roundDownSlow(GroupSize, BlockSize); if (AllocatedGroupSize == 0) continue; diff --git a/compiler-rt/lib/scudo/standalone/release.h b/compiler-rt/lib/scudo/standalone/release.h --- a/compiler-rt/lib/scudo/standalone/release.h +++ b/compiler-rt/lib/scudo/standalone/release.h @@ -499,12 +499,16 @@ // The last block in a region may not use the entire page, we mark the // following "pretend" memory block(s) as free in advance. const uptr RoundedRegionSize = roundUp(RegionSize, PageSize); - uptr PInRegion = LastBlockInRegion + BlockSize; - while (PInRegion < RoundedRegionSize) { - PageMap.incRange(RegionIndex, getPageIndex(PInRegion), - getPageIndex(PInRegion + BlockSize - 1)); - PInRegion += BlockSize; - } + const uptr PInRegion = LastBlockInRegion + BlockSize; + // Only the last page touched by the last block needs to mark the trailing + // blocks. If the difference between `RoundedRegionSize` and `PInRegion` + // is larger than a page, that implies the reported `RegionSize` may not + // be accurate. + DCHECK_LT(RoundedRegionSize - PInRegion, PageSize); + uptr NumTrailingBlocks = + roundUpSlow(RoundedRegionSize - PInRegion, BlockSize) / BlockSize; + if (NumTrailingBlocks > 0) + PageMap.incN(RegionIndex, getPageIndex(PInRegion), NumTrailingBlocks); } // Iterate over free chunks and count how many free chunks affect each