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:
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();