commit 370f5bcd48a457bdab97a9af9d7895f4473544f3
parent 7eaf4f425f15e3fec6e81e2041d78ed77ebc3600
Author: Tooru Fujisawa <arai_a@mac.com>
Date: Wed, 15 Oct 2025 09:41:51 +0000
Bug 1991081 - Part 3: Store nsICacheInfoChannel to LoadedScript also in text and bytecode variants. r=nbp
Differential Revision: https://phabricator.services.mozilla.com/D266613
Diffstat:
6 files changed, 51 insertions(+), 72 deletions(-)
diff --git a/dom/script/ScriptLoadHandler.cpp b/dom/script/ScriptLoadHandler.cpp
@@ -469,9 +469,9 @@ ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
// later save the bytecode on the cache entry.
if (NS_SUCCEEDED(rv) && mRequest->IsSource() &&
StaticPrefs::dom_script_loader_bytecode_cache_enabled()) {
- mRequest->mCacheInfo = do_QueryInterface(channelRequest);
+ mRequest->getLoadedScript()->mCacheInfo = do_QueryInterface(channelRequest);
LOG(("ScriptLoadRequest (%p): nsICacheInfoChannel = %p", mRequest.get(),
- mRequest->mCacheInfo.get()));
+ mRequest->getLoadedScript()->mCacheInfo.get()));
}
// we have to mediate and use mRequest.
@@ -480,7 +480,7 @@ ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
// In case of failure, clear the mCacheInfoChannel to avoid keeping it alive.
if (NS_FAILED(rv)) {
- mRequest->DropDiskCacheReference();
+ mRequest->getLoadedScript()->DropDiskCacheReference();
}
return rv;
diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp
@@ -725,7 +725,7 @@ void ScriptLoader::PrepareCacheInfoChannel(nsIChannel* aChannel,
ScriptLoadRequest* aRequest) {
// To avoid decoding issues, the build-id is part of the bytecode MIME type
// constant.
- aRequest->DropDiskCacheReference();
+ aRequest->getLoadedScript()->DropDiskCacheReference();
nsCOMPtr<nsICacheInfoChannel> cic(do_QueryInterface(aChannel));
if (cic && StaticPrefs::dom_script_loader_bytecode_cache_enabled()) {
MOZ_ASSERT(!IsWebExtensionRequest(aRequest),
@@ -1191,17 +1191,14 @@ void ScriptLoader::TryUseCache(ScriptLoadRequest* aRequest,
void ScriptLoader::StoreCacheInfo(LoadedScript* aLoadedScript,
ScriptLoadRequest* aRequest) {
- MOZ_ASSERT(aRequest->mCacheInfo);
+ MOZ_ASSERT(aRequest->getLoadedScript()->HasDiskCacheReference());
MOZ_ASSERT(!aRequest->SRIAndBytecode().empty());
MOZ_ASSERT(aRequest->SRIAndBytecode().length() == aRequest->GetSRILength());
- MOZ_ASSERT(!aLoadedScript->mCacheInfo);
MOZ_ASSERT(aLoadedScript->mSRI.empty());
if (!aLoadedScript->mSRI.appendAll(aRequest->SRIAndBytecode())) {
return;
}
-
- aLoadedScript->mCacheInfo = aRequest->mCacheInfo;
}
void ScriptLoader::EmulateNetworkEvents(ScriptLoadRequest* aRequest) {
@@ -2741,28 +2738,13 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) {
// We need the nsICacheInfoChannel to exist to be able to open the alternate
// data output stream.
- if (aRequest->IsCachedStencil()) {
- // For in-memory cache, the pointer is cached in the LoadedScript,
- // if the cache had never been saved.
- if (!aRequest->getLoadedScript()->mCacheInfo) {
- LOG(
- ("ScriptLoadRequest (%p): Bytecode-cache: Skip disk: "
- "!LoadedScript::mCacheInfo",
- aRequest));
- aRequest->MarkSkippedDiskCaching();
- return;
- }
- } else {
- // This pointer would only be non-null if the bytecode was
- // activated at the time the channel got created in StartLoad.
- if (!aRequest->HasDiskCacheReference()) {
- LOG(
- ("ScriptLoadRequest (%p): Bytecode-cache: Skip disk: "
- "!HasDiskCacheReference",
- aRequest));
- aRequest->MarkSkippedDiskCaching();
- return;
- }
+ if (!aRequest->getLoadedScript()->HasDiskCacheReference()) {
+ LOG(
+ ("ScriptLoadRequest (%p): Bytecode-cache: Skip disk: "
+ "!LoadedScript::HasDiskCacheReference",
+ aRequest));
+ aRequest->MarkSkippedDiskCaching();
+ return;
}
// Look at the preference to know which strategy (parameters) should be used
@@ -2846,7 +2828,8 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) {
fetchCount = aRequest->mLoadedScript->mFetchCount;
} else {
if (NS_FAILED(
- aRequest->mCacheInfo->GetCacheTokenFetchCount(&fetchCount))) {
+ aRequest->getLoadedScript()->mCacheInfo->GetCacheTokenFetchCount(
+ &fetchCount))) {
LOG(
("ScriptLoadRequest (%p): Bytecode-cache: Skip disk: Cannot get "
"fetchCount.",
@@ -3111,7 +3094,7 @@ void ScriptLoader::InstantiateClassicScriptFromMaybeEncodedSource(
// We do not expect to be saving anything when we already have some
// bytecode.
- MOZ_ASSERT(!aRequest->HasDiskCacheReference());
+ MOZ_ASSERT(!aRequest->getLoadedScript()->HasDiskCacheReference());
return;
}
@@ -3301,7 +3284,7 @@ void ScriptLoader::TryCacheRequest(ScriptLoadRequest* aRequest) {
if (cacheBehavior == CacheBehavior::Insert) {
auto loadData = MakeRefPtr<ScriptLoadData>(this, aRequest);
- if (aRequest->HasDiskCacheReference()) {
+ if (aRequest->getLoadedScript()->HasDiskCacheReference()) {
StoreCacheInfo(aRequest->getLoadedScript(), aRequest);
}
mCache->Insert(*loadData);
@@ -3361,7 +3344,7 @@ nsresult ScriptLoader::MaybePrepareForCacheAfterExecute(
LOG(("ScriptLoadRequest (%p): Bytecode-cache: disabled (rv = %X)", aRequest,
unsigned(aRv)));
TRACE_FOR_TEST_NONE(aRequest, "scriptloader_no_encode");
- aRequest->DropDiskCacheReference();
+ aRequest->getLoadedScript()->DropDiskCacheReference();
return aRv;
}
@@ -3549,7 +3532,7 @@ LoadedScript* ScriptLoader::GetActiveScript(JSContext* aCx) {
void ScriptLoader::RegisterForCache(ScriptLoadRequest* aRequest) {
MOZ_ASSERT(aRequest->IsMarkedForEitherCache());
MOZ_ASSERT_IF(aRequest->IsMarkedForDiskCache(),
- aRequest->HasDiskCacheReference());
+ aRequest->getLoadedScript()->HasDiskCacheReference());
MOZ_DIAGNOSTIC_ASSERT(!aRequest->isInList());
mCachingQueue.AppendElement(aRequest);
}
@@ -3656,20 +3639,26 @@ void ScriptLoader::UpdateCache() {
//
// TODO: Move this to SharedScriptCache.
- if (request->IsMarkedForDiskCache()) {
- if (request->HasDiskCacheReference()) {
+ if (request->IsMarkedForDiskCache() &&
+ request->getLoadedScript()->HasDiskCacheReference()) {
+ if (request->getLoadedScript()->mSRI.empty()) {
+ // This is not a cached stencil.
+ //
// The nsICacheInfoChannel is stored when the this request
// receives a source text (See ScriptLoadHandler::OnStreamComplete),
// and also the SRI is calculated only in that case.
MOZ_ASSERT(request->SRIAndBytecode().length() ==
request->GetSRILength());
- EncodeBytecodeAndSave(aes.cx(), request, request->mCacheInfo,
+ EncodeBytecodeAndSave(aes.cx(), request,
+ request->getLoadedScript()->mCacheInfo,
BytecodeMimeTypeFor(request),
request->SRIAndBytecode(), stencil);
request->DropBytecode();
- } else if (request->getLoadedScript()->mCacheInfo) {
+ } else {
+ // This is cached stencil.
+ //
// The nsICacheInfoChannel is stored when the cached request
// received a source text (See ScriptLoadHandler::OnStreamComplete),
// and also the SRI is calculated and stored into the cache only in
@@ -3681,24 +3670,24 @@ void ScriptLoader::UpdateCache() {
// The cached nsICacheInfoChannel can be used only once.
// We don't overwrite the bytecode cache.
- request->getLoadedScript()->mCacheInfo = nullptr;
+ request->getLoadedScript()->DropDiskCacheReference();
request->getLoadedScript()->mSRI.clear();
}
}
}
- request->DropDiskCacheReference();
+ request->getLoadedScript()->DropDiskCacheReference();
} else {
if (stencil) {
MOZ_ASSERT(request->SRIAndBytecode().length() ==
request->GetSRILength());
- EncodeBytecodeAndSave(aes.cx(), request, request->mCacheInfo,
- BytecodeMimeTypeFor(request),
- request->SRIAndBytecode(), stencil);
+ EncodeBytecodeAndSave(
+ aes.cx(), request, request->getLoadedScript()->mCacheInfo,
+ BytecodeMimeTypeFor(request), request->SRIAndBytecode(), stencil);
request->DropBytecode();
}
- request->DropDiskCacheReference();
+ request->getLoadedScript()->DropDiskCacheReference();
}
}
}
@@ -3847,7 +3836,7 @@ void ScriptLoader::GiveUpCaching() {
}
}
- request->DropDiskCacheReference();
+ request->getLoadedScript()->DropDiskCacheReference();
}
while (!mCacheableDependencyModules.isEmpty()) {
diff --git a/js/loader/LoadedScript.cpp b/js/loader/LoadedScript.cpp
@@ -262,6 +262,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleScript, LoadedScript)
tmp->UnlinkModuleRecord();
tmp->mParseError.setUndefined();
tmp->mErrorToRethrow.setUndefined();
+ tmp->DropDiskCacheReference();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleScript, LoadedScript)
diff --git a/js/loader/LoadedScript.h b/js/loader/LoadedScript.h
@@ -269,9 +269,14 @@ class LoadedScript : public nsIMemoryReporter {
mStencil = aStencil;
}
- void ClearStencil() {
- mStencil = nullptr;
- }
+ void ClearStencil() { mStencil = nullptr; }
+
+ // Check the reference to the cache info channel, which is used by the disk
+ // cache.
+ bool HasDiskCacheReference() const { return !!mCacheInfo; }
+
+ // Drop the reference to the cache info channel.
+ void DropDiskCacheReference() { mCacheInfo = nullptr; }
public:
// Fields.
@@ -320,6 +325,10 @@ class LoadedScript : public nsIMemoryReporter {
RefPtr<Stencil> mStencil;
// The cache info channel used when saving the bytecode to the necko cache.
+ //
+ // This field is populated if the cache is enabled and this is either
+ // IsTextSource() or IsCachedStencil(), and it's cleared after saving the
+ // bytecode (Thus, used only once).
nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
// The SRI data and the padding, used when saving the bytecode.
@@ -422,9 +431,7 @@ class LoadedScriptDelegate {
void SetStencil(Stencil* aStencil) {
GetLoadedScript()->SetStencil(aStencil);
}
- void ClearStencil() {
- GetLoadedScript()->ClearStencil();
- }
+ void ClearStencil() { GetLoadedScript()->ClearStencil(); }
};
class ClassicScript final : public LoadedScript {
diff --git a/js/loader/ScriptLoadRequest.cpp b/js/loader/ScriptLoadRequest.cpp
@@ -20,7 +20,6 @@
#include "ModuleLoadRequest.h"
#include "nsContentUtils.h"
-#include "nsICacheInfoChannel.h"
#include "nsIClassOfService.h"
#include "nsISupportsPriority.h"
@@ -75,14 +74,12 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions, mOriginPrincipal, mBaseURL,
- mLoadedScript, mCacheInfo, mLoadContext)
+ mLoadedScript, mLoadContext)
tmp->mScriptForCache = nullptr;
- tmp->DropDiskCacheReference();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions, mCacheInfo, mLoadContext,
- mLoadedScript)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions, mLoadContext, mLoadedScript)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadRequest)
@@ -125,8 +122,6 @@ void ScriptLoadRequest::Cancel() {
}
}
-void ScriptLoadRequest::DropDiskCacheReference() { mCacheInfo = nullptr; }
-
bool ScriptLoadRequest::HasScriptLoadContext() const {
return HasLoadContext() && mLoadContext->IsWindowContext();
}
diff --git a/js/loader/ScriptLoadRequest.h b/js/loader/ScriptLoadRequest.h
@@ -29,8 +29,6 @@
#include "ScriptKind.h"
#include "ScriptFetchOptions.h"
-class nsICacheInfoChannel;
-
namespace mozilla::dom {
class ScriptLoadContext;
@@ -259,13 +257,6 @@ class ScriptLoadRequest : public nsISupports,
mozilla::CORSMode CORSMode() const { return mFetchOptions->mCORSMode; }
- // Check the reference to the cache info channel, which is used by the disk
- // cache.
- bool HasDiskCacheReference() const { return !!mCacheInfo; }
-
- // Drop the reference to the cache info channel.
- void DropDiskCacheReference();
-
bool HasLoadContext() const { return mLoadContext; }
bool HasScriptLoadContext() const;
bool HasWorkerLoadContext() const;
@@ -371,10 +362,6 @@ class ScriptLoadRequest : public nsISupports,
// NOTE: This field is not used for ModuleLoadRequest.
JS::Heap<JSScript*> mScriptForCache;
- // Holds the Cache information, which is used to register the bytecode
- // on the cache entry, such that we can load it the next time.
- nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
-
// LoadContext for augmenting the load depending on the loading
// context (DOM, Worker, etc.)
RefPtr<LoadContextBase> mLoadContext;