Skip to content

Commit ba7cb62

Browse files
committed
[scudo] Support dumping fragmentation data in SizeClassAllocator32
This is the same fragmentation data as in SizeClassAllocator64. Reviewed By: cferris Differential Revision: https://reviews.llvm.org/D158454
1 parent fe0cb7b commit ba7cb62

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

compiler-rt/lib/scudo/standalone/primary32.h

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,15 @@ template <typename Config> class SizeClassAllocator32 {
312312
}
313313

314314
void getFragmentationInfo(ScopedString *Str) {
315-
// TODO(chiahungduan): Organize the steps in releaseToOSMaybe() into
316-
// functions which make the collection of fragmentation data easier.
317-
Str->append("Fragmentation Stats: SizeClassAllocator32: Unsupported yet\n");
315+
Str->append(
316+
"Fragmentation Stats: SizeClassAllocator32: page size = %zu bytes\n",
317+
getPageSizeCached());
318+
319+
for (uptr I = 1; I < NumClasses; I++) {
320+
SizeClassInfo *Sci = getSizeClassInfo(I);
321+
ScopedLock L(Sci->Mutex);
322+
getSizeClassFragmentationInfo(Sci, I, Str);
323+
}
318324
}
319325

320326
bool setOption(Option O, sptr Value) {
@@ -862,6 +868,52 @@ template <typename Config> class SizeClassAllocator32 {
862868
PushedBytesDelta >> 10);
863869
}
864870

871+
void getSizeClassFragmentationInfo(SizeClassInfo *Sci, uptr ClassId,
872+
ScopedString *Str) REQUIRES(Sci->Mutex) {
873+
const uptr BlockSize = getSizeByClassId(ClassId);
874+
const uptr First = Sci->MinRegionIndex;
875+
const uptr Last = Sci->MaxRegionIndex;
876+
const uptr Base = First * RegionSize;
877+
const uptr NumberOfRegions = Last - First + 1U;
878+
auto SkipRegion = [this, First, ClassId](uptr RegionIndex) {
879+
ScopedLock L(ByteMapMutex);
880+
return (PossibleRegions[First + RegionIndex] - 1U) != ClassId;
881+
};
882+
883+
FragmentationRecorder Recorder;
884+
if (!Sci->FreeListInfo.BlockList.empty()) {
885+
PageReleaseContext Context =
886+
markFreeBlocks(Sci, ClassId, BlockSize, Base, NumberOfRegions,
887+
ReleaseToOS::ForceAll);
888+
releaseFreeMemoryToOS(Context, Recorder, SkipRegion);
889+
}
890+
891+
const uptr PageSize = getPageSizeCached();
892+
const uptr TotalBlocks = Sci->AllocatedUser / BlockSize;
893+
const uptr InUseBlocks =
894+
Sci->FreeListInfo.PoppedBlocks - Sci->FreeListInfo.PushedBlocks;
895+
uptr AllocatedPagesCount = 0;
896+
if (TotalBlocks != 0U) {
897+
for (uptr I = 0; I < NumberOfRegions; ++I) {
898+
if (SkipRegion(I))
899+
continue;
900+
AllocatedPagesCount += RegionSize / PageSize;
901+
}
902+
903+
DCHECK_NE(AllocatedPagesCount, 0U);
904+
}
905+
906+
DCHECK_GE(AllocatedPagesCount, Recorder.getReleasedPagesCount());
907+
const uptr InUsePages =
908+
AllocatedPagesCount - Recorder.getReleasedPagesCount();
909+
const uptr InUseBytes = InUsePages * PageSize;
910+
911+
Str->append(" %02zu (%6zu): inuse/total blocks: %6zu/%6zu inuse/total "
912+
"pages: %6zu/%6zu inuse bytes: %6zuK\n",
913+
ClassId, BlockSize, InUseBlocks, TotalBlocks, InUsePages,
914+
AllocatedPagesCount, InUseBytes >> 10);
915+
}
916+
865917
NOINLINE uptr releaseToOSMaybe(SizeClassInfo *Sci, uptr ClassId,
866918
ReleaseToOS ReleaseType = ReleaseToOS::Normal)
867919
REQUIRES(Sci->Mutex) {

compiler-rt/lib/scudo/standalone/primary64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,7 @@ template <typename Config> class SizeClassAllocator64 {
10181018
Region->FreeListInfo.PoppedBlocks - Region->FreeListInfo.PushedBlocks;
10191019
const uptr AllocatedPagesCount =
10201020
roundUp(Region->MemMapInfo.AllocatedUser, PageSize) / PageSize;
1021+
DCHECK_GE(AllocatedPagesCount, Recorder.getReleasedPagesCount());
10211022
const uptr InUsePages =
10221023
AllocatedPagesCount - Recorder.getReleasedPagesCount();
10231024
const uptr InUseBytes = InUsePages * PageSize;

0 commit comments

Comments
 (0)