commit d26b0876c94ee1d266304563731c43ba9853e721
parent 01d03687c09ed5fc7e396af1b2081d74f1e209a2
Author: Tooru Fujisawa <arai_a@mac.com>
Date: Thu, 23 Oct 2025 04:16:56 +0000
Bug 1992341 - Part 5: Stop using the cache queue for in-memory cache. r=nbp
Given the in-memory cache no longer need any operation once it's stored into
the in-memory cache and we start collecting the delazifications, the
cache queue needs to be used only for disk cache.
Differential Revision: https://phabricator.services.mozilla.com/D269522
Diffstat:
2 files changed, 61 insertions(+), 64 deletions(-)
diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp
@@ -175,7 +175,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoader)
NS_IMPL_CYCLE_COLLECTION_UNLINK(
mNonAsyncExternalScriptInsertedRequests, mLoadingAsyncRequests,
mLoadedAsyncRequests, mOffThreadCompilingRequests, mDeferRequests,
- mXSLTRequests, mParserBlockingRequest, mCachingQueue, mPreloads,
+ mXSLTRequests, mParserBlockingRequest, mDiskCacheQueue, mPreloads,
mPendingChildLoaders, mModuleLoader, mWebExtModuleLoaders,
mShadowRealmModuleLoaders)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@@ -184,7 +184,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoader)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(
mNonAsyncExternalScriptInsertedRequests, mLoadingAsyncRequests,
mLoadedAsyncRequests, mOffThreadCompilingRequests, mDeferRequests,
- mXSLTRequests, mParserBlockingRequest, mCachingQueue, mPreloads,
+ mXSLTRequests, mParserBlockingRequest, mDiskCacheQueue, mPreloads,
mPendingChildLoaders, mModuleLoader, mWebExtModuleLoaders,
mShadowRealmModuleLoaders)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -2710,12 +2710,6 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) {
LOG(("ScriptLoadRequest (%p): Bytecode-cache: Mark in-memory: Stencil",
aRequest));
aRequest->MarkPassedConditionForMemoryCache();
-
- if (aRequest->IsModuleRequest() &&
- aRequest->AsModuleRequest()->IsStaticImport()) {
- MOZ_ASSERT(!aRequest->isInList());
- mCacheableDependencyModules.AppendElement(aRequest);
- }
} else {
aRequest->MarkSkippedMemoryCaching();
}
@@ -2857,11 +2851,10 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) {
aRequest));
aRequest->MarkPassedConditionForDiskCache();
- if (!aRequest->PassedConditionForMemoryCache() &&
- aRequest->IsModuleRequest() &&
+ if (aRequest->IsModuleRequest() &&
aRequest->AsModuleRequest()->IsStaticImport()) {
MOZ_ASSERT(!aRequest->isInList());
- mCacheableDependencyModules.AppendElement(aRequest);
+ mDiskCacheableDependencyModules.AppendElement(aRequest);
}
}
@@ -3203,13 +3196,13 @@ void ScriptLoader::InstantiateClassicScriptFromCachedStencil(
LOG(("ScriptLoadRequest (%p): Bytecode-cache: Skip: IsAlreadyCollecting",
aRequest));
- // NOTE: non-top-level modules are added to mCacheableDependencyModules
+ // NOTE: non-top-level modules are added to mDiskCacheableDependencyModules
// at the same time as MarkPassedConditionForMemoryCache.
// Undo it here.
if (aRequest->IsModuleRequest() &&
!aRequest->AsModuleRequest()->IsTopLevel()) {
MOZ_ASSERT(aRequest->isInList());
- mCacheableDependencyModules.Remove(aRequest);
+ mDiskCacheableDependencyModules.Remove(aRequest);
}
aRequest->MarkSkippedMemoryCaching();
@@ -3342,29 +3335,33 @@ nsCString& ScriptLoader::BytecodeMimeTypeFor(
nsresult ScriptLoader::MaybePrepareForCacheAfterExecute(
ScriptLoadRequest* aRequest, nsresult aRv) {
- if (aRequest->PassedConditionForEitherCache() && aRequest->HasStencil()) {
- TRACE_FOR_TEST(aRequest, "scriptloader_encode");
- // Bytecode-encoding branch is used for 2 purposes right now:
- // * If the request is stencil, reflect delazifications to cached stencil
- // * otherwise, encode the initial stencil and delazifications
- //
- // For latter case, check that the TranscodeBuffer which is going to
- // receive the encoded bytecode only contains the SRI, and nothing more.
- //
- // NOTE: This assertion will fail once we start encoding more data after the
- // first encode.
- MOZ_ASSERT_IF(
- !aRequest->IsCachedStencil(),
- aRequest->GetSRILength() == aRequest->SRIAndBytecode().length());
- RegisterForCache(aRequest);
+ if (!aRequest->PassedConditionForDiskCache() || !aRequest->HasStencil()) {
+ LOG(("ScriptLoadRequest (%p): Bytecode-cache: disabled (rv = %X)", aRequest,
+ unsigned(aRv)));
+ TRACE_FOR_TEST_NONE(aRequest, "scriptloader_no_encode");
+
+ // For in-memory cached requests, the disk cache references are necessary
+ // for later load.
+ MOZ_ASSERT_IF(!aRequest->PassedConditionForMemoryCache(),
+ !aRequest->getLoadedScript()->HasDiskCacheReference());
return aRv;
}
- LOG(("ScriptLoadRequest (%p): Bytecode-cache: disabled (rv = %X)", aRequest,
- unsigned(aRv)));
- TRACE_FOR_TEST_NONE(aRequest, "scriptloader_no_encode");
- MOZ_ASSERT(!aRequest->getLoadedScript()->HasDiskCacheReference());
+ TRACE_FOR_TEST(aRequest, "scriptloader_encode");
+ // Bytecode-encoding branch is used for 2 purposes right now:
+ // * If the request is stencil, reflect delazifications to cached stencil
+ // * otherwise, encode the initial stencil and delazifications
+ //
+ // For latter case, check that the TranscodeBuffer which is going to
+ // receive the encoded bytecode only contains the SRI, and nothing more.
+ //
+ // NOTE: This assertion will fail once we start encoding more data after the
+ // first encode.
+ MOZ_ASSERT_IF(
+ !aRequest->IsCachedStencil(),
+ aRequest->GetSRILength() == aRequest->SRIAndBytecode().length());
+ RegisterForDiskCache(aRequest);
return aRv;
}
@@ -3376,7 +3373,7 @@ nsresult ScriptLoader::MaybePrepareModuleForCacheAfterExecute(
if (aRequest->isInList()) {
// Top-level modules are part of lists only while loading, or
// after queued for cache.
- // NOTE: Non-top-level modules are part of mCacheableDependencyModules
+ // NOTE: Non-top-level modules are part of mDiskCacheableDependencyModules
// after it's loaded.
//
// This filters out modules which is already queued for cache.
@@ -3385,9 +3382,9 @@ nsresult ScriptLoader::MaybePrepareModuleForCacheAfterExecute(
aRv = MaybePrepareForCacheAfterExecute(aRequest, aRv);
- for (auto* r = mCacheableDependencyModules.getFirst(); r;) {
+ for (auto* r = mDiskCacheableDependencyModules.getFirst(); r;) {
auto* dep = r->AsModuleRequest();
- MOZ_ASSERT(dep->PassedConditionForEitherCache());
+ MOZ_ASSERT(dep->PassedConditionForDiskCache());
r = r->getNext();
@@ -3395,7 +3392,7 @@ nsresult ScriptLoader::MaybePrepareModuleForCacheAfterExecute(
continue;
}
- mCacheableDependencyModules.Remove(dep);
+ mDiskCacheableDependencyModules.Remove(dep);
aRv = MaybePrepareForCacheAfterExecute(dep, aRv);
}
@@ -3497,13 +3494,12 @@ LoadedScript* ScriptLoader::GetActiveScript(JSContext* aCx) {
return static_cast<LoadedScript*>(value.toPrivate());
}
-void ScriptLoader::RegisterForCache(ScriptLoadRequest* aRequest) {
- MOZ_ASSERT(aRequest->PassedConditionForEitherCache());
+void ScriptLoader::RegisterForDiskCache(ScriptLoadRequest* aRequest) {
+ MOZ_ASSERT(aRequest->PassedConditionForDiskCache());
MOZ_ASSERT(aRequest->HasStencil());
- MOZ_ASSERT_IF(aRequest->PassedConditionForDiskCache(),
- aRequest->getLoadedScript()->HasDiskCacheReference());
+ MOZ_ASSERT(aRequest->getLoadedScript()->HasDiskCacheReference());
MOZ_DIAGNOSTIC_ASSERT(!aRequest->isInList());
- mCachingQueue.AppendElement(aRequest);
+ mDiskCacheQueue.AppendElement(aRequest);
}
void ScriptLoader::LoadEventFired() {
@@ -3540,8 +3536,9 @@ void ScriptLoader::MaybeUpdateCache() {
}
// No need to fire any event if there is no bytecode to be saved.
- if (mCachingQueue.isEmpty()) {
- LOG(("ScriptLoader (%p): No script in queue to be encoded.", this));
+ if (mDiskCacheQueue.isEmpty()) {
+ LOG(("ScriptLoader (%p): No script in queue to be saved to the disk.",
+ this));
return;
}
@@ -3586,20 +3583,24 @@ void ScriptLoader::UpdateCache() {
}
RefPtr<ScriptLoadRequest> request;
- while (!mCachingQueue.isEmpty()) {
- request = mCachingQueue.StealFirst();
+ while (!mDiskCacheQueue.isEmpty()) {
+ request = mDiskCacheQueue.StealFirst();
MOZ_ASSERT(!IsWebExtensionRequest(request),
"Bytecode for web extension content scrips is not cached");
// The bytecode encoding is performed only when there was no
// bytecode stored in the necko cache.
//
+ // For in-memory cached case, the save might already be performed
+ // by other request.
+ //
// TODO: Move this to SharedScriptCache.
- if (request->PassedConditionForDiskCache() &&
- request->getLoadedScript()->HasDiskCacheReference()) {
- EncodeBytecodeAndSave(fc, request->getLoadedScript());
+ if (!request->getLoadedScript()->HasDiskCacheReference()) {
+ continue;
}
+ EncodeBytecodeAndSave(fc, request->getLoadedScript());
+
request->DropBytecode();
request->getLoadedScript()->DropDiskCacheReference();
}
@@ -3689,8 +3690,8 @@ void ScriptLoader::GiveUpCaching() {
// to avoid queuing more scripts.
mGiveUpCaching = true;
- while (!mCachingQueue.isEmpty()) {
- RefPtr<ScriptLoadRequest> request = mCachingQueue.StealFirst();
+ while (!mDiskCacheQueue.isEmpty()) {
+ RefPtr<ScriptLoadRequest> request = mDiskCacheQueue.StealFirst();
LOG(("ScriptLoadRequest (%p): Cannot serialize bytecode", request.get()));
TRACE_FOR_TEST_NONE(request, "scriptloader_bytecode_failed");
MOZ_ASSERT(!IsWebExtensionRequest(request));
@@ -3699,9 +3700,9 @@ void ScriptLoader::GiveUpCaching() {
request->getLoadedScript()->DropDiskCacheReference();
}
- while (!mCacheableDependencyModules.isEmpty()) {
+ while (!mDiskCacheableDependencyModules.isEmpty()) {
RefPtr<ScriptLoadRequest> request =
- mCacheableDependencyModules.StealFirst();
+ mDiskCacheableDependencyModules.StealFirst();
}
}
diff --git a/dom/script/ScriptLoader.h b/dom/script/ScriptLoader.h
@@ -732,7 +732,7 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
ScriptLoadRequest* aRequest);
/**
- * Register the script load request to be cached.
+ * Register the script load request to be cached on the disk.
*
* The caller can call this at the same time instantiating the stencil,
* and also start collecting delazifications.
@@ -740,12 +740,8 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
* The cache handling will be performed when the page initialization ends.
* The page initialization end is defined as being the time when the load
* event got received, and when no more scripts are waiting to be executed.
- *
- * The initial stencil and collected delazifications will be stored into
- * - the in-memory cache, and/or
- * - the necko cache
*/
- void RegisterForCache(ScriptLoadRequest* aRequest);
+ void RegisterForDiskCache(ScriptLoadRequest* aRequest);
/**
* Check if all conditions are met, i-e that the onLoad event fired and that
@@ -814,7 +810,7 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
// * necko alternative stream as Stencil XDR
//
// If the request is a non-top-level module request and it passed the
- // condition, it's stored into mCacheableDependencyModules in order
+ // condition, it's stored into mDiskCacheableDependencyModules in order
// to iterate over them later.
void CalculateCacheFlag(ScriptLoadRequest* aRequest);
@@ -861,15 +857,15 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
// the original list if any.
JS::loader::ScriptLoadRequestList mOffThreadCompilingRequests;
- // Holds non-top-level module requests which passed caching conditions, until
- // it's queued to mCachingQueue.
+ // Holds non-top-level module requests which passed disk caching conditions,
+ // until it's queued to mDiskCacheQueue.
//
// TODO: Remove this and per-ScriptLoader caching queue (bug 1902951).
- JS::loader::ScriptLoadRequestList mCacheableDependencyModules;
+ JS::loader::ScriptLoadRequestList mDiskCacheableDependencyModules;
// Holds already-evaluted requests that are holding a buffer which has to be
- // saved on the cache, until it's cached or the caching is aborted.
- JS::loader::ScriptLoadRequestList mCachingQueue;
+ // saved on the disk cache, until it's cached or the caching is aborted.
+ JS::loader::ScriptLoadRequestList mDiskCacheQueue;
// In mRequests, the additional information here is stored by the element.
struct PreloadInfo {