tor-browser

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

commit e2c0a7ace6f2f2229bc888646acc688e8f011761
parent 32c285e820a9af61686af64a34dd250ccec08da0
Author: Tooru Fujisawa <arai_a@mac.com>
Date:   Thu, 23 Oct 2025 04:16:57 +0000

Bug 1991438 - Use an array of LoadedScript for the disk queue. r=nbp

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

Diffstat:
Mdom/script/ScriptLoader.cpp | 49++++++++++++++++++++-----------------------------
Mdom/script/ScriptLoader.h | 7++++---
2 files changed, 24 insertions(+), 32 deletions(-)

diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp @@ -3197,7 +3197,7 @@ void ScriptLoader::InstantiateClassicScriptFromCachedStencil( aRequest)); // NOTE: non-top-level modules are added to mDiskCacheableDependencyModules - // at the same time as MarkPassedConditionForMemoryCache. + // at the same time as MarkPassedConditionForDiskCache. // Undo it here. if (aRequest->IsModuleRequest() && !aRequest->AsModuleRequest()->IsTopLevel()) { @@ -3370,15 +3370,10 @@ nsresult ScriptLoader::MaybePrepareModuleForDiskCacheAfterExecute( ModuleLoadRequest* aRequest, nsresult aRv) { MOZ_ASSERT(aRequest->IsTopLevel()); - 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 mDiskCacheableDependencyModules - // after it's loaded. - // - // This filters out modules which is already queued for cache. - return aRv; - } + // NOTE: If a module is passed to this multiple times, it can be + // enqueued multiple times. + // This is okay because ScriptLoader::UpdateCache filters out + // any script without the disk cache reference. aRv = MaybePrepareForDiskCacheAfterExecute(aRequest, aRv); @@ -3499,7 +3494,9 @@ void ScriptLoader::RegisterForDiskCache(ScriptLoadRequest* aRequest) { MOZ_ASSERT(aRequest->HasStencil()); MOZ_ASSERT(aRequest->getLoadedScript()->HasDiskCacheReference()); MOZ_DIAGNOSTIC_ASSERT(!aRequest->isInList()); - mDiskCacheQueue.AppendElement(aRequest); + MOZ_ASSERT(!IsWebExtensionRequest(aRequest), + "Bytecode for web extension content scrips is not cached"); + mDiskCacheQueue.AppendElement(aRequest->getLoadedScript()); } void ScriptLoader::LoadEventFired() { @@ -3536,7 +3533,7 @@ void ScriptLoader::MaybeUpdateDiskCache() { } // No need to fire any event if there is no bytecode to be saved. - if (mDiskCacheQueue.isEmpty()) { + if (mDiskCacheQueue.IsEmpty()) { LOG(("ScriptLoader (%p): No script in queue to be saved to the disk.", this)); return; @@ -3582,12 +3579,7 @@ void ScriptLoader::UpdateDiskCache() { return; } - RefPtr<ScriptLoadRequest> request; - while (!mDiskCacheQueue.isEmpty()) { - request = mDiskCacheQueue.StealFirst(); - MOZ_ASSERT(!IsWebExtensionRequest(request), - "Bytecode for web extension content scrips is not cached"); - + for (auto& loadedScript : mDiskCacheQueue) { // The bytecode encoding is performed only when there was no // bytecode stored in the necko cache. // @@ -3595,15 +3587,16 @@ void ScriptLoader::UpdateDiskCache() { // by other request. // // TODO: Move this to SharedScriptCache. - if (!request->getLoadedScript()->HasDiskCacheReference()) { + if (!loadedScript->HasDiskCacheReference()) { continue; } - EncodeBytecodeAndSave(fc, request->getLoadedScript()); + EncodeBytecodeAndSave(fc, loadedScript); - request->DropBytecode(); - request->getLoadedScript()->DropDiskCacheReference(); + loadedScript->DropDiskCacheReference(); + loadedScript->DropBytecode(); } + mDiskCacheQueue.Clear(); JS::DestroyFrontendContext(fc); } @@ -3690,15 +3683,13 @@ void ScriptLoader::GiveUpDiskCaching() { // to avoid queuing more scripts. mGiveUpDiskCaching = true; - 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)); + for (auto& loadedScript : mDiskCacheQueue) { + LOG(("LoadedScript (%p): Cannot serialize bytecode", loadedScript.get())); - request->getLoadedScript()->DropBytecode(); - request->getLoadedScript()->DropDiskCacheReference(); + loadedScript->DropDiskCacheReference(); + loadedScript->DropBytecode(); } + mDiskCacheQueue.Clear(); while (!mDiskCacheableDependencyModules.isEmpty()) { RefPtr<ScriptLoadRequest> request = diff --git a/dom/script/ScriptLoader.h b/dom/script/ScriptLoader.h @@ -856,9 +856,10 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface { // TODO: Remove this and per-ScriptLoader caching queue (bug 1902951). JS::loader::ScriptLoadRequestList mDiskCacheableDependencyModules; - // Holds already-evaluted requests that are holding a buffer which has to be - // saved on the disk cache, until it's cached or the caching is aborted. - JS::loader::ScriptLoadRequestList mDiskCacheQueue; + // Holds already-evaluted requests' script that are holding a stencil which + // has to be saved on the disk cache, until it's cached or the caching is + // aborted. + nsTArray<RefPtr<JS::loader::LoadedScript>> mDiskCacheQueue; // In mRequests, the additional information here is stored by the element. struct PreloadInfo {