Bug 1829127 - Add telemetry for PHC utilisation r=glandium

Differential Revision: https://phabricator.services.mozilla.com/D192303
This commit is contained in:
Paul Bone 2023-11-06 04:59:33 +00:00
Родитель c473d4c7a0
Коммит 62f879e4b6
4 изменённых файлов: 70 добавлений и 17 удалений

Просмотреть файл

@ -841,23 +841,20 @@ class GMut {
void IncPageAllocMisses(GMutLock) {}
#endif
#if PHC_LOGGING
struct PageStats {
size_t mNumAlloced = 0;
size_t mNumFreed = 0;
};
PageStats GetPageStats(GMutLock) {
PageStats stats;
phc::PHCStats GetPageStats(GMutLock) {
phc::PHCStats stats;
for (const auto& page : mAllocPages) {
stats.mNumAlloced += page.mState == AllocPageState::InUse ? 1 : 0;
stats.mNumFreed += page.mState == AllocPageState::Freed ? 1 : 0;
stats.mSlotsAllocated += page.mState == AllocPageState::InUse ? 1 : 0;
stats.mSlotsFreed += page.mState == AllocPageState::Freed ? 1 : 0;
}
stats.mSlotsUnused =
kNumAllocPages - stats.mSlotsAllocated - stats.mSlotsFreed;
return stats;
}
#if PHC_LOGGING
size_t PageAllocHits(GMutLock) { return mPageAllocHits; }
size_t PageAllocAttempts(GMutLock) {
return mPageAllocHits + mPageAllocMisses;
@ -1244,12 +1241,12 @@ static void* MaybePageAlloc(const Maybe<arena_id_t>& aArenaId, size_t aReqSize,
gMut->IncPageAllocHits(lock);
#if PHC_LOGGING
GMut::PageStats stats = gMut->GetPageStats(lock);
phc::PHCStats stats = gMut->GetPageStats(lock);
#endif
LOG("PageAlloc(%zu, %zu) -> %p[%zu]/%p (%zu) (z%zu), sAllocDelay <- %zu, "
"fullness %zu/%zu/%zu, hits %zu/%zu (%zu%%), lifetime %zu\n",
aReqSize, aAlignment, pagePtr, i, ptr, usableSize, size_t(aZero),
size_t(newAllocDelay), stats.mNumAlloced, stats.mNumFreed,
size_t(newAllocDelay), stats.mSlotsAllocated, stats.mSlotsFreed,
kNumAllocPages, gMut->PageAllocHits(lock),
gMut->PageAllocAttempts(lock), gMut->PageAllocHitRate(lock), lifetime);
break;
@ -1259,12 +1256,12 @@ static void* MaybePageAlloc(const Maybe<arena_id_t>& aArenaId, size_t aReqSize,
// No pages are available, or VirtualAlloc/mprotect failed.
gMut->IncPageAllocMisses(lock);
#if PHC_LOGGING
GMut::PageStats stats = gMut->GetPageStats(lock);
phc::PHCStats stats = gMut->GetPageStats(lock);
#endif
LOG("No PageAlloc(%zu, %zu), sAllocDelay <- %zu, fullness %zu/%zu/%zu, "
"hits %zu/%zu (%zu%%)\n",
aReqSize, aAlignment, size_t(newAllocDelay), stats.mNumAlloced,
stats.mNumFreed, kNumAllocPages, gMut->PageAllocHits(lock),
aReqSize, aAlignment, size_t(newAllocDelay), stats.mSlotsAllocated,
stats.mSlotsFreed, kNumAllocPages, gMut->PageAllocHits(lock),
gMut->PageAllocAttempts(lock), gMut->PageAllocHitRate(lock));
}
@ -1509,11 +1506,11 @@ MOZ_ALWAYS_INLINE static bool MaybePageFree(const Maybe<arena_id_t>& aArenaId,
FreePage(lock, index, aArenaId, freeStack, reuseDelay);
#if PHC_LOGGING
GMut::PageStats stats = gMut->GetPageStats(lock);
phc::PHCStats stats = gMut->GetPageStats(lock);
#endif
LOG("PageFree(%p[%zu]), %zu delay, reuse at ~%zu, fullness %zu/%zu/%zu\n",
aPtr, index, size_t(reuseDelay), size_t(GAtomic::Now()) + reuseDelay,
stats.mNumAlloced, stats.mNumFreed, kNumAllocPages);
stats.mSlotsAllocated, stats.mSlotsFreed, kNumAllocPages);
return true;
}
@ -1772,6 +1769,14 @@ void PHCMemoryUsage(MemoryUsage& aMemoryUsage) {
}
}
void GetPHCStats(PHCStats& aStats) {
if (gMut) {
MutexAutoLock lock(GMut::sMutex);
aStats = gMut->GetPageStats(lock);
}
}
// Enable or Disable PHC at runtime. If PHC is disabled it will still trap
// bad uses of previous allocations, but won't track any new allocations.
void SetPHCState(PHCState aState) { gMut->SetState(aState); }

Просмотреть файл

@ -141,6 +141,15 @@ struct MemoryUsage {
MOZ_JEMALLOC_API void PHCMemoryUsage(MemoryUsage& aMemoryUsage);
struct PHCStats {
size_t mSlotsAllocated = 0;
size_t mSlotsFreed = 0;
size_t mSlotsUnused = 0;
};
// Return PHC memory usage information by filling in the supplied structure.
MOZ_JEMALLOC_API void GetPHCStats(PHCStats& aStats);
} // namespace phc
} // namespace mozilla

Просмотреть файл

@ -1751,6 +1751,37 @@
"description": "Over-allocation due to PHC's rounding (aka internal fragmentation). Measured in bytes.",
"releaseChannelCollection": "opt-out"
},
"MEMORY_PHC_SLOTS_ALLOCATED": {
"record_in_processes": ["main", "content"],
"products": ["firefox"],
"alert_emails": [
"memshrink-telemetry-alerts@mozilla.com",
"pbone@mozilla.com"
],
"bug_numbers": [1829127],
"expires_in_version": "128",
"kind": "exponential",
"high": 16384,
"n_buckets": 64,
"description": "Number of PHC slots currently allocated",
"releaseChannelCollection": "opt-out"
},
"MEMORY_PHC_SLOTS_FREED": {
"record_in_processes": ["main", "content"],
"products": ["firefox"],
"alert_emails": [
"memshrink-telemetry-alerts@mozilla.com",
"pbone@mozilla.com"
],
"bug_numbers": [1829127],
"expires_in_version": "128",
"kind": "exponential",
"high": 16384,
"n_buckets": 64,
"description": "Number of PHC slots allocated-then-freed",
"releaseChannelCollection": "opt-out"
},
"FONTLIST_INITOTHERFAMILYNAMES": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec"],

Просмотреть файл

@ -38,6 +38,14 @@ void ReportPHCTelemetry() {
PHCMemoryUsage(usage);
Accumulate(Telemetry::MEMORY_PHC_SLOP, usage.mFragmentationBytes);
PHCStats stats;
GetPHCStats(stats);
Accumulate(Telemetry::MEMORY_PHC_SLOTS_ALLOCATED, stats.mSlotsAllocated);
Accumulate(Telemetry::MEMORY_PHC_SLOTS_FREED, stats.mSlotsFreed);
// There are also slots that are unused (neither free nor allocated) they
// can be calculated by knowing the total number of slots.
}
}; // namespace mozilla