tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mnetwerk/cache2/CacheStorageService.cpp | 12+++++++++---
Mnetwerk/cache2/Dictionary.cpp | 12+++++++++---
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