commit dee0f66355afa91c2540e289c946141e20e79ecd
parent 58730279e1f1346b898e5c95c301e237e188d49d
Author: Tooru Fujisawa <arai_a@mac.com>
Date: Wed, 26 Nov 2025 04:10:51 +0000
Bug 1907011 - Part 2: Split LoadedScript::SRIAndBytecode into LoadedScript::SRI and LoadedScript::SRIAndSerializedStencil for each cosnumer. r=nbp
Differential Revision: https://phabricator.services.mozilla.com/D273955
Diffstat:
4 files changed, 87 insertions(+), 50 deletions(-)
diff --git a/dom/script/ScriptLoadHandler.cpp b/dom/script/ScriptLoadHandler.cpp
@@ -190,7 +190,7 @@ ScriptLoadHandler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
}
} else {
MOZ_ASSERT(mRequest->IsSerializedStencil());
- if (!mRequest->SRIAndBytecode().append(aData, aDataLength)) {
+ if (!mRequest->SRIAndSerializedStencil().append(aData, aDataLength)) {
return NS_ERROR_OUT_OF_MEMORY;
}
@@ -301,7 +301,7 @@ nsresult ScriptLoadHandler::MaybeDecodeSRI(uint32_t* sriLength) {
}
// Skip until the content is large enough to be decoded.
- JS::TranscodeBuffer& receivedData = mRequest->SRIAndBytecode();
+ JS::TranscodeBuffer& receivedData = mRequest->SRIAndSerializedStencil();
if (receivedData.length() <= mSRIDataVerifier->DataSummaryLength()) {
return NS_OK;
}
@@ -422,7 +422,7 @@ ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
}
} else {
MOZ_ASSERT(mRequest->IsSerializedStencil());
- JS::TranscodeBuffer& bytecode = mRequest->SRIAndBytecode();
+ JS::TranscodeBuffer& bytecode = mRequest->SRIAndSerializedStencil();
if (!bytecode.append(aData, aDataLength)) {
return NS_ERROR_OUT_OF_MEMORY;
}
diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp
@@ -2757,7 +2757,7 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) {
MOZ_ASSERT(!aRequest->getLoadedScript()->HasDiskCacheReference());
// NOTE: An inline script tag can have an SRI, but we don't calculate it
// for this case.
- MOZ_ASSERT(aRequest->SRIAndBytecode().empty());
+ MOZ_ASSERT(aRequest->HasNoSRIOrSRIAndSerializedStencil());
return;
}
@@ -2769,7 +2769,7 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) {
// have to be cached.
aRequest->MarkNotCacheable();
MOZ_ASSERT(!aRequest->getLoadedScript()->HasDiskCacheReference());
- MOZ_ASSERT(aRequest->SRIAndBytecode().empty());
+ MOZ_ASSERT(aRequest->HasNoSRIOrSRIAndSerializedStencil());
return;
}
@@ -2779,7 +2779,8 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) {
aRequest));
aRequest->MarkNotCacheable();
MOZ_ASSERT(!aRequest->getLoadedScript()->HasDiskCacheReference());
- MOZ_ASSERT_IF(aRequest->IsSource(), aRequest->SRIAndBytecode().empty());
+ MOZ_ASSERT_IF(aRequest->IsSource(),
+ aRequest->HasNoSRIOrSRIAndSerializedStencil());
return;
}
@@ -2824,7 +2825,8 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) {
"!LoadedScript::HasDiskCacheReference",
aRequest));
aRequest->MarkSkippedDiskCaching();
- MOZ_ASSERT_IF(aRequest->IsSource(), aRequest->SRIAndBytecode().empty());
+ MOZ_ASSERT_IF(aRequest->IsSource(),
+ aRequest->HasNoSRIOrSRIAndSerializedStencil());
return;
}
@@ -3418,9 +3420,8 @@ nsresult ScriptLoader::MaybePrepareForDiskCacheAfterExecute(
//
// NOTE: This assertion will fail once we start encoding more data after the
// first encode.
- MOZ_ASSERT_IF(
- !aRequest->IsCachedStencil(),
- aRequest->GetSRILength() == aRequest->SRIAndBytecode().length());
+ MOZ_ASSERT_IF(!aRequest->IsCachedStencil(),
+ aRequest->GetSRILength() == aRequest->SRI().length());
RegisterForDiskCache(aRequest);
return aRv;
@@ -3664,7 +3665,7 @@ void ScriptLoader::UpdateDiskCache() {
Vector<uint8_t> compressed;
if (!EncodeAndCompress(fc, loadedScript, loadedScript->GetStencil(),
- loadedScript->SRIAndBytecode(), compressed)) {
+ loadedScript->SRI(), compressed)) {
loadedScript->DropDiskCacheReference();
loadedScript->DropBytecode();
TRACE_FOR_TEST(loadedScript, "diskcache:failed");
@@ -3695,13 +3696,14 @@ bool ScriptLoader::EncodeAndCompress(
size_t SRILength = aSRI.length();
MOZ_ASSERT(JS::IsTranscodingBytecodeOffsetAligned(SRILength));
- JS::TranscodeBuffer SRIAndBytecode;
- if (!SRIAndBytecode.appendAll(aSRI)) {
+ JS::TranscodeBuffer SRIAndSerializedStencil;
+ if (!SRIAndSerializedStencil.appendAll(aSRI)) {
LOG(("LoadedScript (%p): Cannot allocate buffer", aLoadedScript));
return false;
}
- JS::TranscodeResult result = JS::EncodeStencil(aFc, aStencil, SRIAndBytecode);
+ JS::TranscodeResult result =
+ JS::EncodeStencil(aFc, aStencil, SRIAndSerializedStencil);
if (result != JS::TranscodeResult::Ok) {
// Encoding can be aborted for non-supported syntax (e.g. asm.js), or
@@ -3714,7 +3716,8 @@ bool ScriptLoader::EncodeAndCompress(
}
// TODO probably need to move this to a helper thread
- if (!ScriptBytecodeCompress(SRIAndBytecode, SRILength, aCompressed)) {
+ if (!ScriptBytecodeCompress(SRIAndSerializedStencil, SRILength,
+ aCompressed)) {
return false;
}
@@ -4208,54 +4211,54 @@ nsresult ScriptLoader::VerifySRI(ScriptLoadRequest* aRequest,
nsresult ScriptLoader::SaveSRIHash(
ScriptLoadRequest* aRequest, SRICheckDataVerifier* aSRIDataVerifier) const {
MOZ_ASSERT(aRequest->IsSource());
- JS::TranscodeBuffer& bytecode = aRequest->SRIAndBytecode();
- MOZ_ASSERT(bytecode.empty());
+ JS::TranscodeBuffer& sri = aRequest->SRI();
+ MOZ_ASSERT(sri.empty());
uint32_t len = 0;
// If the integrity metadata does not correspond to a valid hash function,
// IsComplete would be false.
if (!aRequest->mIntegrity.IsEmpty() && aSRIDataVerifier->IsComplete()) {
- MOZ_ASSERT(bytecode.length() == 0);
+ MOZ_ASSERT(sri.length() == 0);
// Encode the SRI computed hash.
len = aSRIDataVerifier->DataSummaryLength();
- if (!bytecode.resize(len)) {
+ if (!sri.resize(len)) {
return NS_ERROR_OUT_OF_MEMORY;
}
DebugOnly<nsresult> res =
- aSRIDataVerifier->ExportDataSummary(len, bytecode.begin());
+ aSRIDataVerifier->ExportDataSummary(len, sri.begin());
MOZ_ASSERT(NS_SUCCEEDED(res));
} else {
- MOZ_ASSERT(bytecode.length() == 0);
+ MOZ_ASSERT(sri.length() == 0);
// Encode a dummy SRI hash.
len = SRICheckDataVerifier::EmptyDataSummaryLength();
- if (!bytecode.resize(len)) {
+ if (!sri.resize(len)) {
return NS_ERROR_OUT_OF_MEMORY;
}
DebugOnly<nsresult> res =
- SRICheckDataVerifier::ExportEmptyDataSummary(len, bytecode.begin());
+ SRICheckDataVerifier::ExportEmptyDataSummary(len, sri.begin());
MOZ_ASSERT(NS_SUCCEEDED(res));
}
// Verify that the exported and predicted length correspond.
DebugOnly<uint32_t> srilen{};
MOZ_ASSERT(NS_SUCCEEDED(
- SRICheckDataVerifier::DataSummaryLength(len, bytecode.begin(), &srilen)));
+ SRICheckDataVerifier::DataSummaryLength(len, sri.begin(), &srilen)));
MOZ_ASSERT(srilen == len);
- MOZ_ASSERT(bytecode.length() == len);
+ MOZ_ASSERT(sri.length() == len);
aRequest->SetSRILength(len);
if (aRequest->GetSRILength() != len) {
- // The bytecode is aligned in the bytecode buffer, and space might be
+ // The serialized stencil is aligned in the buffer, and space might be
// reserved for padding after the SRI hash.
- if (!bytecode.resize(aRequest->GetSRILength())) {
+ if (!sri.resize(aRequest->GetSRILength())) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
diff --git a/dom/script/SharedScriptCache.cpp b/dom/script/SharedScriptCache.cpp
@@ -315,7 +315,7 @@ void SharedScriptCache::UpdateDiskCache() {
}
if (!mEncodeItems.emplaceBack(loadedScript->GetStencil(),
- std::move(loadedScript->SRIAndBytecode()),
+ std::move(loadedScript->SRI()),
loadedScript)) {
continue;
}
diff --git a/js/loader/LoadedScript.h b/js/loader/LoadedScript.h
@@ -144,6 +144,8 @@ class LoadedScript : public nsIMemoryReporter {
using MaybeSourceText =
mozilla::MaybeOneOf<SourceText<char16_t>, SourceText<Utf8Unit>>;
+ // ==== Methods to query the data type ====
+
bool IsUnknownDataType() const { return mDataType == DataType::eUnknown; }
bool IsTextSource() const { return mDataType == DataType::eTextSource; }
bool IsSource() const { return IsTextSource(); }
@@ -152,6 +154,8 @@ class LoadedScript : public nsIMemoryReporter {
}
bool IsCachedStencil() const { return mDataType == DataType::eCachedStencil; }
+ // ==== Methods to convert the data type ====
+
void SetUnknownDataType() {
mDataType = DataType::eUnknown;
mScriptData.reset();
@@ -181,6 +185,8 @@ class LoadedScript : public nsIMemoryReporter {
return mScriptData->is<ScriptTextBuffer<Utf8Unit>>();
}
+ // ==== Methods to access the text soutce ====
+
template <typename Unit>
const ScriptTextBuffer<Unit>& ScriptText() const {
MOZ_ASSERT(IsTextSource());
@@ -221,49 +227,68 @@ class LoadedScript : public nsIMemoryReporter {
mReceivedScriptTextLength = aLength;
}
- bool CanHaveBytecode() const {
- return IsSerializedStencil() || IsSource() || IsCachedStencil();
+ // ==== Methods to access the serialized data or the SRI part ====
+ // mSRIAndBytecode field is shared between two separate consumers.
+ // See mSRIAndBytecode comment for more info.
+
+ // ---- For SRI-only consumers ----
+
+ bool CanHaveSRIOnly() const { return IsSource() || IsCachedStencil(); }
+
+ bool HasSRI() {
+ MOZ_ASSERT(CanHaveSRIOnly());
+ return !mSRIAndBytecode.empty();
}
- TranscodeBuffer& SRIAndBytecode() {
- // Note: SRIAndBytecode might be called even if the IsSource() returns true,
- // as we want to be able to save the bytecode content when we are loading
- // from source.
- MOZ_ASSERT(CanHaveBytecode());
+ TranscodeBuffer& SRI() {
+ MOZ_ASSERT(CanHaveSRIOnly());
+ return mSRIAndBytecode;
+ }
+
+ void DropSRI() {
+ MOZ_ASSERT(CanHaveSRIOnly());
+ mSRIAndBytecode.clearAndFree();
+ }
+
+ // ---- For SRI and serialized Stencil consumers ---
+
+ bool CanHaveSRIAndSerializedStencil() const { return IsSerializedStencil(); }
+
+ TranscodeBuffer& SRIAndSerializedStencil() {
+ MOZ_ASSERT(CanHaveSRIAndSerializedStencil());
return mSRIAndBytecode;
}
TranscodeRange Bytecode() const {
- MOZ_ASSERT(IsSerializedStencil());
+ MOZ_ASSERT(CanHaveSRIAndSerializedStencil());
const auto& bytecode = mSRIAndBytecode;
auto offset = mBytecodeOffset;
return TranscodeRange(bytecode.begin() + offset,
bytecode.length() - offset);
}
+ // ---- Methods shared between both consumers ----
+
size_t GetSRILength() const {
- MOZ_ASSERT(CanHaveBytecode());
+ MOZ_ASSERT(CanHaveSRIOnly() || CanHaveSRIAndSerializedStencil());
return mBytecodeOffset;
}
void SetSRILength(size_t sriLength) {
- MOZ_ASSERT(CanHaveBytecode());
+ MOZ_ASSERT(CanHaveSRIOnly() || CanHaveSRIAndSerializedStencil());
mBytecodeOffset = AlignTranscodingBytecodeOffset(sriLength);
}
- void DropBytecode() {
- MOZ_ASSERT(CanHaveBytecode());
- mSRIAndBytecode.clearAndFree();
- }
-
- bool HasSRI() {
- MOZ_ASSERT(IsSource() || IsCachedStencil());
- return !mSRIAndBytecode.empty();
+ bool HasNoSRIOrSRIAndSerializedStencil() const {
+ MOZ_ASSERT(CanHaveSRIOnly() || CanHaveSRIAndSerializedStencil());
+ return mSRIAndBytecode.empty();
}
- void DropSRI() {
- MOZ_ASSERT(IsSource() || IsCachedStencil());
+ void DropBytecode() {
+ MOZ_ASSERT(CanHaveSRIOnly() || CanHaveSRIAndSerializedStencil());
mSRIAndBytecode.clearAndFree();
}
+ // ==== Methods to access the stencil ====
+
bool HasStencil() const { return mStencil; }
Stencil* GetStencil() const {
@@ -280,6 +305,8 @@ class LoadedScript : public nsIMemoryReporter {
void ClearStencil() { mStencil = nullptr; }
+ // ==== Methods to access the disk cache reference ====
+
// Check the reference to the cache info channel, which is used by the disk
// cache.
bool HasDiskCacheReference() const { return !!mCacheInfo; }
@@ -294,6 +321,8 @@ class LoadedScript : public nsIMemoryReporter {
}
}
+ // ==== Other methods ====
+
/*
* Set the mBaseURL, based on aChannel.
* aOriginalURI is the result of aChannel->GetOriginalURI.
@@ -521,8 +550,13 @@ class LoadedScriptDelegate {
void ClearScriptText() { GetLoadedScript()->ClearScriptText(); }
- TranscodeBuffer& SRIAndBytecode() {
- return GetLoadedScript()->SRIAndBytecode();
+ bool HasNoSRIOrSRIAndSerializedStencil() const {
+ return GetLoadedScript()->HasNoSRIOrSRIAndSerializedStencil();
+ }
+
+ TranscodeBuffer& SRI() { return GetLoadedScript()->SRI(); }
+ TranscodeBuffer& SRIAndSerializedStencil() {
+ return GetLoadedScript()->SRIAndSerializedStencil();
}
TranscodeRange Bytecode() const { return GetLoadedScript()->Bytecode(); }