tor-browser

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

commit 2aa5d00aafd1fc32249ca4793093b9901b4f190c
parent 3f9a88662a74b47bd9537afd770f7d62fd7b5f3b
Author: Tooru Fujisawa <arai_a@mac.com>
Date:   Thu, 16 Oct 2025 09:03:22 +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:
Mdom/script/ScriptLoadHandler.cpp | 6+++---
Mdom/script/ScriptLoader.cpp | 75++++++++++++++++++++++++++++++++-------------------------------------------
Mjs/loader/LoadedScript.cpp | 1+
Mjs/loader/LoadedScript.h | 19+++++++++++++------
Mjs/loader/ScriptLoadRequest.cpp | 9++-------
Mjs/loader/ScriptLoadRequest.h | 13-------------
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;