tor-browser

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

commit 6423ed49a952e782dc5eed688ac47da5f36e0df9
parent 828e4c1ce857254ece8d7a93406125301a4f8c97
Author: Tooru Fujisawa <arai_a@mac.com>
Date:   Wed, 29 Oct 2025 23:24:57 +0000

Bug 1880453 - Part 2: Add testcase for in-memory cache. r=nbp

Differential Revision: https://phabricator.services.mozilla.com/D270114

Diffstat:
Mdom/base/test/browser_script_loader_js_cache.js | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdom/script/ScriptLoader.cpp | 3+++
2 files changed, 180 insertions(+), 0 deletions(-)

diff --git a/dom/base/test/browser_script_loader_js_cache.js b/dom/base/test/browser_script_loader_js_cache.js @@ -57,6 +57,14 @@ async function runTests(tests) { for (let i = 0; i < test.items.length; i++) { const item = test.items[i]; info(`start: ${test.title} (item ${i})`); + if (item.clearMemory) { + info("clear memory cache"); + ChromeUtils.clearResourceCache(); + } + if (item.clearDisk) { + info("clear disk cache"); + Services.cache2.clear(); + } await SpecialPowers.spawn(browser, [item], contentTask); } @@ -210,3 +218,172 @@ add_task(async function testDiskCache() { await SpecialPowers.popPrefEnv(); }); + +add_task(async function testMemoryCache() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.expose_test_interfaces", true], + ["dom.script_loader.experimental.navigation_cache", true], + ], + }); + + await runTests([ + // A small file should be saved to the memory on the 1st load, and used on + // the 2nd load. But it shouldn't be saved to the disk cache. + { + title: "small file", + items: [ + { + file: "file_js_cache_small.js", + events: [ + ev("load:source", "file_js_cache_small.js"), + ev("memorycache:saved", "file_js_cache_small.js"), + ev("evaluate:classic", "file_js_cache_small.js"), + ev("diskcache:disabled", "file_js_cache_small.js"), + ], + }, + { + file: "file_js_cache_small.js", + events: [ + ev("load:memorycache", "file_js_cache_small.js"), + ev("evaluate:classic", "file_js_cache_small.js"), + ev("diskcache:disabled", "file_js_cache_small.js"), + ], + }, + { + file: "file_js_cache_small.js", + events: [ + ev("load:memorycache", "file_js_cache_small.js"), + ev("evaluate:classic", "file_js_cache_small.js"), + ev("diskcache:disabled", "file_js_cache_small.js"), + ], + }, + { + file: "file_js_cache_small.js", + events: [ + ev("load:memorycache", "file_js_cache_small.js"), + ev("evaluate:classic", "file_js_cache_small.js"), + ev("diskcache:disabled", "file_js_cache_small.js"), + ], + }, + ], + }, + + // A large file should be saved to the memory on the 1st load, and used on + // the 2nd load. Also it should be saved to the disk on the 4th load. + // Also the 5th load shouldn't overwrite the cache. + // Once the memory cache is purged, it should be populated from the disk + // cache response. + { + title: "large file", + items: [ + { + file: "file_js_cache_large.js", + events: [ + ev("load:source", "file_js_cache_large.js"), + ev("memorycache:saved", "file_js_cache_large.js"), + ev("evaluate:classic", "file_js_cache_large.js"), + ev("diskcache:disabled", "file_js_cache_large.js"), + ], + }, + { + file: "file_js_cache_large.js", + events: [ + ev("load:memorycache", "file_js_cache_large.js"), + ev("evaluate:classic", "file_js_cache_large.js"), + ev("diskcache:disabled", "file_js_cache_large.js"), + ], + }, + { + file: "file_js_cache_large.js", + events: [ + ev("load:memorycache", "file_js_cache_large.js"), + ev("evaluate:classic", "file_js_cache_large.js"), + ev("diskcache:disabled", "file_js_cache_large.js"), + ], + }, + { + file: "file_js_cache_large.js", + events: [ + ev("load:memorycache", "file_js_cache_large.js"), + ev("evaluate:classic", "file_js_cache_large.js"), + ev("diskcache:register", "file_js_cache_large.js"), + ev("diskcache:saved", "file_js_cache_large.js", false), + ], + }, + { + file: "file_js_cache_large.js", + events: [ + ev("load:memorycache", "file_js_cache_large.js"), + ev("evaluate:classic", "file_js_cache_large.js"), + ev("diskcache:disabled", "file_js_cache_large.js"), + ], + }, + { + file: "file_js_cache_large.js", + events: [ + ev("load:memorycache", "file_js_cache_large.js"), + ev("evaluate:classic", "file_js_cache_large.js"), + ev("diskcache:disabled", "file_js_cache_large.js"), + ], + }, + + { + clearMemory: true, + file: "file_js_cache_large.js", + events: [ + ev("load:diskcache", "file_js_cache_large.js"), + ev("memorycache:saved", "file_js_cache_large.js"), + ev("evaluate:classic", "file_js_cache_large.js"), + ev("diskcache:disabled", "file_js_cache_large.js"), + ], + }, + { + file: "file_js_cache_large.js", + events: [ + ev("load:memorycache", "file_js_cache_large.js"), + ev("evaluate:classic", "file_js_cache_large.js"), + ev("diskcache:disabled", "file_js_cache_large.js"), + ], + }, + ], + }, + + // A file with compile error shouldn't be saved to any cache. + { + title: "syntax error", + items: [ + { + file: "file_js_cache_large_syntax_error.js", + events: [ + ev("load:source", "file_js_cache_large_syntax_error.js"), + ev("diskcache:disabled", "file_js_cache_large_syntax_error.js"), + ], + }, + { + file: "file_js_cache_large_syntax_error.js", + events: [ + ev("load:source", "file_js_cache_large_syntax_error.js"), + ev("diskcache:disabled", "file_js_cache_large_syntax_error.js"), + ], + }, + { + file: "file_js_cache_large_syntax_error.js", + events: [ + ev("load:source", "file_js_cache_large_syntax_error.js"), + ev("diskcache:disabled", "file_js_cache_large_syntax_error.js"), + ], + }, + { + file: "file_js_cache_large_syntax_error.js", + events: [ + ev("load:source", "file_js_cache_large_syntax_error.js"), + ev("diskcache:disabled", "file_js_cache_large_syntax_error.js"), + ], + }, + ], + }, + ]); + + await SpecialPowers.popPrefEnv(); +}); diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp @@ -1220,6 +1220,7 @@ void ScriptLoader::TryUseCache(ReferrerPolicy aReferrerPolicy, "ScriptLoadRequest(%p) %s.", this, aRequest->getLoadedScript(), aRequest, aRequest->URI()->GetSpecOrDefault().get())); + TRACE_FOR_TEST(aRequest, "load:memorycache"); if (cacheResult.mCompleteValue->mFetchCount < UINT8_MAX) { cacheResult.mCompleteValue->mFetchCount++; @@ -3322,6 +3323,7 @@ void ScriptLoader::TryCacheRequest(ScriptLoadRequest* aRequest) { mCache->Insert(*loadData); LOG(("ScriptLoader (%p): Inserting in-memory cache for %s.", this, aRequest->URI()->GetSpecOrDefault().get())); + TRACE_FOR_TEST(aRequest, "memorycache:saved"); } else { MOZ_ASSERT(cacheBehavior == CacheBehavior::Evict); ScriptHashKey key(this, aRequest, aRequest->getLoadedScript()); @@ -3332,6 +3334,7 @@ void ScriptLoader::TryCacheRequest(ScriptLoadRequest* aRequest) { if (!aRequest->PassedConditionForEitherCache()) { aRequest->ClearStencil(); } + TRACE_FOR_TEST(aRequest, "memorycache:evict"); } }