commit 3d93084ce35156797daf624969e2eb42445773f8
parent 98eababd98ed9ed750a9f691e6dfc470218996ce
Author: Randell Jesup <rjesup@mozilla.com>
Date: Mon, 27 Oct 2025 18:11:25 +0000
Bug 1996298: PurgeByFrecency was over-purging due to holding references r=necko-reviewers,jstutte,valentin
Differential Revision: https://phabricator.services.mozilla.com/D270001
Diffstat:
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/netwerk/cache2/CacheStorageService.cpp b/netwerk/cache2/CacheStorageService.cpp
@@ -1510,7 +1510,8 @@ Result<size_t, nsresult> CacheStorageService::MemoryPool::PurgeByFrecency(
} else {
if (entry->GetEnhanceID().EqualsLiteral("dict:")) {
LOG(
- ("*** Entry is a dictionary origin, metadata size %d, referenced "
+ ("*** Ignored Entry is a dictionary origin, metadata size %d, "
+ "referenced "
"%d, Frecency %f",
entry->GetMetadataMemoryConsumption(), entry->IsReferenced(),
entry->GetFrecency()));
@@ -1530,7 +1531,9 @@ Result<size_t, nsresult> CacheStorageService::MemoryPool::PurgeByFrecency(
break;
}
- RefPtr<CacheEntry> entry = checkPurge.mEntry;
+ // Ensure it's deleted immediately if purged so we can record the
+ // mMemorySize savings
+ RefPtr<CacheEntry> entry = std::move(checkPurge.mEntry);
if (entry->Purge(CacheEntry::PURGE_WHOLE)) {
numPurged++;
@@ -1544,7 +1547,10 @@ Result<size_t, nsresult> CacheStorageService::MemoryPool::PurgeByFrecency(
}
}
- LOG(("MemoryPool::PurgeByFrecency done"));
+ LOG(
+ ("MemoryPool::PurgeByFrecency done, purged %zu - mMemorySize %u, "
+ "memoryLimit %u",
+ numPurged, (uint32_t)mMemorySize, memoryLimit));
return numPurged;
}
diff --git a/netwerk/cache2/Dictionary.cpp b/netwerk/cache2/Dictionary.cpp
@@ -1301,10 +1301,16 @@ void DictionaryOrigin::DumpEntries() {
void DictionaryOrigin::Clear() {
mEntries.Clear();
mPendingEntries.Clear();
+ mPendingRemove.Clear();
// We may be under a lock; doom this asynchronously
- NS_DispatchBackgroundTask(NS_NewRunnableFunction(
- "DictionaryOrigin::Clear",
- [entry = mEntry]() { entry->AsyncDoom(nullptr); }));
+ if (mEntry) {
+ // This will attempt to delete the DictionaryOrigin, but we'll do
+ // that more directly
+ NS_DispatchBackgroundTask(NS_NewRunnableFunction(
+ "DictionaryOrigin::Clear",
+ [entry = mEntry]() { entry->AsyncDoom(nullptr); }));
+ }
+ DictionaryCache::RemoveOriginFor(mOrigin); // async
}
// caller will throw this into a RefPtr