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:
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");
}
}