tor-browser

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

commit f211bee4de135ca2126ff3d277c19e42b6975376
parent 905ed24b39020575a45bcd2e12ce5a99fe2f1b20
Author: Tooru Fujisawa <arai_a@mac.com>
Date:   Fri, 31 Oct 2025 05:22:08 +0000

Bug 1980154 - Part 3: Add SharedScriptCache::UpdateDiskCache that saves cached stencils into the disk cache. r=nbp

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

Diffstat:
Mdom/script/SharedScriptCache.cpp | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mdom/script/SharedScriptCache.h | 2++
Mjs/loader/LoadedScript.h | 5+++++
3 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/dom/script/SharedScriptCache.cpp b/dom/script/SharedScriptCache.cpp @@ -6,8 +6,9 @@ #include "SharedScriptCache.h" -#include "ScriptLoadHandler.h" // ScriptLoadHandler -#include "ScriptLoader.h" // ScriptLoader +#include "ScriptLoadHandler.h" // ScriptLoadHandler +#include "ScriptLoader.h" // ScriptLoader +#include "js/experimental/CompileScript.h" // JS::FrontendContext, JS::NewFrontendContext, JS::DestroyFrontendContext #include "mozilla/Maybe.h" // Maybe, Some, Nothing #include "mozilla/dom/ContentParent.h" // dom::ContentParent #include "nsIMemoryReporter.h" // nsIMemoryReporter, MOZ_DEFINE_MALLOC_SIZE_OF, RegisterWeakMemoryReporter, UnregisterWeakMemoryReporter, MOZ_COLLECT_REPORT, KIND_HEAP, UNITS_BYTES @@ -165,4 +166,64 @@ void SharedScriptCache::PrepareForLastCC() { } } +static bool ShouldSave(JS::loader::LoadedScript* aLoadedScript, + ScriptLoader::DiskCacheStrategy aStrategy) { + if (!aLoadedScript->HasDiskCacheReference()) { + return false; + } + + if (!aLoadedScript->HasSRI()) { + return false; + } + + if (aStrategy.mHasSourceLengthMin) { + size_t len = JS::GetScriptSourceLength(aLoadedScript->GetStencil()); + if (len < aStrategy.mSourceLengthMin) { + return false; + } + } + + if (aStrategy.mHasFetchCountMin) { + if (aLoadedScript->mFetchCount < aStrategy.mFetchCountMin) { + return false; + } + } + + return true; +} + +void SharedScriptCache::UpdateDiskCache() { + auto strategy = ScriptLoader::GetDiskCacheStrategy(); + if (strategy.mIsDisabled) { + return; + } + + JS::FrontendContext* fc = nullptr; + + for (auto iter = mComplete.Iter(); !iter.Done(); iter.Next()) { + JS::loader::LoadedScript* loadedScript = iter.Data().mResource; + if (!ShouldSave(loadedScript, strategy)) { + continue; + } + + if (!fc) { + // Lazily create the context only when there's at least one script + // that needs to be saved. + fc = JS::NewFrontendContext(); + if (!fc) { + return; + } + } + + ScriptLoader::EncodeBytecodeAndSave(fc, loadedScript); + + loadedScript->DropDiskCacheReference(); + loadedScript->DropBytecode(); + } + + if (fc) { + JS::DestroyFrontendContext(fc); + } +} + } // namespace mozilla::dom diff --git a/dom/script/SharedScriptCache.h b/dom/script/SharedScriptCache.h @@ -193,6 +193,8 @@ class SharedScriptCache final SharedScriptCache(); void Init(); + void UpdateDiskCache(); + // This has to be static because it's also called for loaders that don't have // a sheet cache (loaders that are not owned by a document). static void LoadCompleted(SharedScriptCache*, ScriptLoadData&); diff --git a/js/loader/LoadedScript.h b/js/loader/LoadedScript.h @@ -252,6 +252,11 @@ class LoadedScript : public nsIMemoryReporter { mSRIAndBytecode.clearAndFree(); } + bool HasSRI() { + MOZ_ASSERT(IsSource() || IsCachedStencil()); + return !mSRIAndBytecode.empty(); + } + void DropSRI() { MOZ_ASSERT(IsSource() || IsCachedStencil()); mSRIAndBytecode.clearAndFree();