Bug 1742437 - Split ScriptLoadRequest into ScriptLoadRequest and DOMScriptLoadContext; r=jonco,smaug
Differential Revision: https://phabricator.services.mozilla.com/D134041
This commit is contained in:
@@ -201,33 +201,34 @@ ScriptLoader::~ScriptLoader() {
|
||||
mObservers.Clear();
|
||||
|
||||
if (mParserBlockingRequest) {
|
||||
mParserBlockingRequest->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
mParserBlockingRequest->GetLoadContext()->FireScriptAvailable(
|
||||
NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req = mXSLTRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
req->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
req->GetLoadContext()->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req = mDeferRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
req->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
req->GetLoadContext()->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req = mLoadingAsyncRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
req->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
req->GetLoadContext()->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req = mLoadedAsyncRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
req->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
req->GetLoadContext()->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req =
|
||||
mNonAsyncExternalScriptInsertedRequests.getFirst();
|
||||
req; req = req->getNext()) {
|
||||
req->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
req->GetLoadContext()->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
// Unblock the kids, in case any of them moved to a different document
|
||||
@@ -269,7 +270,7 @@ static void CollectScriptTelemetry(ScriptLoadRequest* aRequest) {
|
||||
// JavaScript Start-up Bytecode Cache, with the expectation of an almost zero
|
||||
// source-fallback and alternate-data being roughtly equal to source loads.
|
||||
if (aRequest->IsLoadingSource()) {
|
||||
if (aRequest->mIsInline) {
|
||||
if (aRequest->GetLoadContext()->mIsInline) {
|
||||
AccumulateCategorical(LABELS_DOM_SCRIPT_LOADING_SOURCE::Inline);
|
||||
} else if (aRequest->IsTextSource()) {
|
||||
AccumulateCategorical(LABELS_DOM_SCRIPT_LOADING_SOURCE::SourceFallback);
|
||||
@@ -343,7 +344,7 @@ static bool IsScriptEventHandler(ScriptKind kind, nsIContent* aScriptElement) {
|
||||
|
||||
nsContentPolicyType ScriptLoadRequestToContentPolicyType(
|
||||
ScriptLoadRequest* aRequest) {
|
||||
if (aRequest->IsPreload()) {
|
||||
if (aRequest->GetLoadContext()->IsPreload()) {
|
||||
return aRequest->IsModuleRequest()
|
||||
? nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD
|
||||
: nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD;
|
||||
@@ -758,8 +759,9 @@ void ScriptLoader::ProcessLoadedModuleTree(ModuleLoadRequest* aRequest) {
|
||||
RefPtr<ScriptLoadRequest> req =
|
||||
mModuleLoader->mDynamicImportRequests.Steal(aRequest);
|
||||
RunScriptWhenSafe(aRequest);
|
||||
} else if (aRequest->mIsInline &&
|
||||
aRequest->GetParserCreated() == NOT_FROM_PARSER) {
|
||||
} else if (aRequest->GetLoadContext()->mIsInline &&
|
||||
aRequest->GetLoadContext()->GetParserCreated() ==
|
||||
NOT_FROM_PARSER) {
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
RunScriptWhenSafe(aRequest);
|
||||
} else {
|
||||
@@ -768,16 +770,17 @@ void ScriptLoader::ProcessLoadedModuleTree(ModuleLoadRequest* aRequest) {
|
||||
}
|
||||
}
|
||||
|
||||
aRequest->MaybeUnblockOnload();
|
||||
aRequest->GetLoadContext()->MaybeUnblockOnload();
|
||||
}
|
||||
|
||||
nsresult ScriptLoader::RestartLoad(ScriptLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(aRequest->IsBytecode());
|
||||
aRequest->mScriptBytecode.clearAndFree();
|
||||
TRACE_FOR_TEST(aRequest->GetScriptElement(), "scriptloader_fallback");
|
||||
TRACE_FOR_TEST(aRequest->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_fallback");
|
||||
|
||||
// Notify preload restart so that we can register this preload request again.
|
||||
aRequest->NotifyRestart(mDocument);
|
||||
aRequest->GetLoadContext()->NotifyRestart(mDocument);
|
||||
|
||||
// Start a new channel from which we explicitly request to stream the source
|
||||
// instead of the bytecode.
|
||||
@@ -904,8 +907,8 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
|
||||
nsContentPolicyType contentPolicyType =
|
||||
ScriptLoadRequestToContentPolicyType(aRequest);
|
||||
nsCOMPtr<nsINode> context;
|
||||
if (aRequest->GetScriptElement()) {
|
||||
context = do_QueryInterface(aRequest->GetScriptElement());
|
||||
if (aRequest->GetLoadContext()->GetScriptElement()) {
|
||||
context = do_QueryInterface(aRequest->GetLoadContext()->GetScriptElement());
|
||||
} else {
|
||||
context = mDocument;
|
||||
}
|
||||
@@ -977,23 +980,25 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
|
||||
}
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): mode=%u tracking=%d", aRequest,
|
||||
unsigned(aRequest->mScriptMode), aRequest->IsTracking()));
|
||||
unsigned(aRequest->GetLoadContext()->mScriptMode),
|
||||
aRequest->GetLoadContext()->IsTracking()));
|
||||
|
||||
if (aRequest->IsLinkPreloadScript()) {
|
||||
if (aRequest->GetLoadContext()->IsLinkPreloadScript()) {
|
||||
// This is <link rel="preload" as="script"> initiated speculative load,
|
||||
// put it to the group that is not blocked by leaders and doesn't block
|
||||
// follower at the same time. Giving it a much higher priority will make
|
||||
// this request be processed ahead of other Unblocked requests, but with
|
||||
// the same weight as Leaders. This will make us behave similar way for
|
||||
// both http2 and http1.
|
||||
ScriptLoadRequest::PrioritizeAsPreload(channel);
|
||||
ScriptLoadRequest::AddLoadBackgroundFlag(channel);
|
||||
DOMScriptLoadContext::PrioritizeAsPreload(channel);
|
||||
DOMScriptLoadContext::AddLoadBackgroundFlag(channel);
|
||||
} else if (nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(channel)) {
|
||||
if (aRequest->mScriptFromHead && aRequest->IsBlockingScript()) {
|
||||
if (aRequest->GetLoadContext()->mScriptFromHead &&
|
||||
aRequest->GetLoadContext()->IsBlockingScript()) {
|
||||
// synchronous head scripts block loading of most other non js/css
|
||||
// content such as images, Leader implicitely disallows tailing
|
||||
cos->AddClassFlags(nsIClassOfService::Leader);
|
||||
} else if (aRequest->IsDeferredScript() &&
|
||||
} else if (aRequest->GetLoadContext()->IsDeferredScript() &&
|
||||
!StaticPrefs::network_http_tailing_enabled()) {
|
||||
// Bug 1395525 and the !StaticPrefs::network_http_tailing_enabled() bit:
|
||||
// We want to make sure that turing tailing off by the pref makes the
|
||||
@@ -1008,7 +1013,7 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
|
||||
// nor prioritized
|
||||
cos->AddClassFlags(nsIClassOfService::Unblocked);
|
||||
|
||||
if (aRequest->IsAsyncScript()) {
|
||||
if (aRequest->GetLoadContext()->IsAsyncScript()) {
|
||||
// async scripts are allowed tailing, since those and only those
|
||||
// don't block DOMContentLoaded; this flag doesn't enforce tailing,
|
||||
// just overweights the Unblocked flag when the channel is found
|
||||
@@ -1048,7 +1053,7 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
|
||||
// Set the initiator type
|
||||
nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChannel));
|
||||
if (timedChannel) {
|
||||
if (aRequest->IsLinkPreloadScript()) {
|
||||
if (aRequest->GetLoadContext()->IsLinkPreloadScript()) {
|
||||
timedChannel->SetInitiatorType(u"link"_ns);
|
||||
} else {
|
||||
timedChannel->SetInitiatorType(u"script"_ns);
|
||||
@@ -1074,16 +1079,17 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
|
||||
|
||||
auto key = PreloadHashKey::CreateAsScript(
|
||||
aRequest->mURI, aRequest->CORSMode(), aRequest->mKind);
|
||||
aRequest->NotifyOpen(key, channel, mDocument,
|
||||
aRequest->IsLinkPreloadScript());
|
||||
aRequest->GetLoadContext()->NotifyOpen(
|
||||
key, channel, mDocument,
|
||||
aRequest->GetLoadContext()->IsLinkPreloadScript());
|
||||
|
||||
rv = channel->AsyncOpen(loader);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// Make sure to inform any <link preload> tags about failure to load the
|
||||
// resource.
|
||||
aRequest->NotifyStart(channel);
|
||||
aRequest->NotifyStop(rv);
|
||||
aRequest->GetLoadContext()->NotifyStart(channel);
|
||||
aRequest->GetLoadContext()->NotifyStop(rv);
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@@ -1140,8 +1146,11 @@ ScriptLoadRequest* ScriptLoader::CreateLoadRequest(
|
||||
aCORSMode, aReferrerPolicy, domElement, aTriggeringPrincipal, nullptr);
|
||||
|
||||
if (aKind == ScriptKind::eClassic) {
|
||||
return new ScriptLoadRequest(aKind, aURI, fetchOptions, aIntegrity,
|
||||
referrer);
|
||||
ScriptLoadRequest* aRequest =
|
||||
new ScriptLoadRequest(aKind, aURI, fetchOptions, aIntegrity, referrer);
|
||||
DOMScriptLoadContext* aContext = new DOMScriptLoadContext(aRequest);
|
||||
aRequest->mLoadContext = aContext;
|
||||
return aRequest;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aKind == ScriptKind::eModule);
|
||||
@@ -1259,14 +1268,14 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
|
||||
// It's possible these attributes changed since we started the preload so
|
||||
// update them here.
|
||||
request->SetScriptMode(aElement->GetScriptDeferred(),
|
||||
aElement->GetScriptAsync(), false);
|
||||
request->GetLoadContext()->SetScriptMode(aElement->GetScriptDeferred(),
|
||||
aElement->GetScriptAsync(), false);
|
||||
|
||||
// The request will be added to another list or set as
|
||||
// mParserBlockingRequest below.
|
||||
if (request->mInCompilingList) {
|
||||
if (request->GetLoadContext()->mInCompilingList) {
|
||||
mOffThreadCompilingRequests.Remove(request);
|
||||
request->mInCompilingList = false;
|
||||
request->GetLoadContext()->mInCompilingList = false;
|
||||
}
|
||||
|
||||
AccumulateCategorical(LABELS_DOM_SCRIPT_PRELOAD_RESULT::Used);
|
||||
@@ -1284,11 +1293,12 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
|
||||
request = CreateLoadRequest(aScriptKind, scriptURI, aElement, principal,
|
||||
ourCORSMode, sriMetadata, referrerPolicy);
|
||||
request->mIsInline = false;
|
||||
request->SetScriptMode(aElement->GetScriptDeferred(),
|
||||
aElement->GetScriptAsync(), false);
|
||||
// keep request->mScriptFromHead to false so we don't treat non preloaded
|
||||
// scripts as blockers for full page load. See bug 792438.
|
||||
request->GetLoadContext()->mIsInline = false;
|
||||
request->GetLoadContext()->SetScriptMode(aElement->GetScriptDeferred(),
|
||||
aElement->GetScriptAsync(), false);
|
||||
// keep request->GetLoadContext()->mScriptFromHead to false so we don't
|
||||
// treat non preloaded scripts as blockers for full page load. See
|
||||
// bug 792438.
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Created request for external script",
|
||||
request.get()));
|
||||
@@ -1312,11 +1322,12 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
|
||||
// We should still be in loading stage of script unless we're loading a
|
||||
// module or speculatively off-main-thread parsing a script.
|
||||
NS_ASSERTION(SpeculativeOMTParsingEnabled() || !request->InCompilingStage() ||
|
||||
NS_ASSERTION(SpeculativeOMTParsingEnabled() ||
|
||||
!request->GetLoadContext()->CompileStarted() ||
|
||||
request->IsModuleRequest(),
|
||||
"Request should not yet be in compiling stage.");
|
||||
|
||||
if (request->IsAsyncScript()) {
|
||||
if (request->GetLoadContext()->IsAsyncScript()) {
|
||||
AddAsyncRequest(request);
|
||||
if (request->IsReadyToRun()) {
|
||||
// The script is available already. Run it ASAP when the event
|
||||
@@ -1332,7 +1343,7 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
// Violate the HTML5 spec in order to make LABjs and the "order" plug-in
|
||||
// for RequireJS work with their Gecko-sniffed code path. See
|
||||
// http://lists.w3.org/Archives/Public/public-html/2010Oct/0088.html
|
||||
request->mIsNonAsyncScriptInserted = true;
|
||||
request->GetLoadContext()->mIsNonAsyncScriptInserted = true;
|
||||
mNonAsyncExternalScriptInsertedRequests.AppendElement(request);
|
||||
if (request->IsReadyToRun()) {
|
||||
// The script is available already. Run it ASAP when the event
|
||||
@@ -1343,7 +1354,7 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
}
|
||||
// we now have a parser-inserted request that may or may not be still
|
||||
// loading
|
||||
if (request->IsDeferredScript()) {
|
||||
if (request->GetLoadContext()->IsDeferredScript()) {
|
||||
// We don't want to run this yet.
|
||||
// If we come here, the script is a parser-created script and it has
|
||||
// the defer attribute but not the async attribute. Since a
|
||||
@@ -1362,7 +1373,7 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
// Need to maintain order for XSLT-inserted scripts
|
||||
NS_ASSERTION(!mParserBlockingRequest,
|
||||
"Parser-blocking scripts and XSLT scripts in the same doc!");
|
||||
request->mIsXSLT = true;
|
||||
request->GetLoadContext()->mIsXSLT = true;
|
||||
mXSLTRequests.AppendElement(request);
|
||||
if (request->IsReadyToRun()) {
|
||||
// The script is available already. Run it ASAP when the event
|
||||
@@ -1425,18 +1436,20 @@ bool ScriptLoader::ProcessInlineScript(nsIScriptElement* aElement,
|
||||
mDocument->NodePrincipal(), corsMode,
|
||||
SRIMetadata(), // SRI doesn't apply
|
||||
referrerPolicy);
|
||||
request->mIsInline = true;
|
||||
request->GetLoadContext()->mIsInline = true;
|
||||
request->mLineNo = aElement->GetScriptLineNumber();
|
||||
request->mProgress = ScriptLoadRequest::Progress::eLoading_Source;
|
||||
request->SetTextSource();
|
||||
TRACE_FOR_TEST_BOOL(request->GetScriptElement(), "scriptloader_load_source");
|
||||
TRACE_FOR_TEST_BOOL(request->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_load_source");
|
||||
CollectScriptTelemetry(request);
|
||||
|
||||
// Only the 'async' attribute is heeded on an inline module script and
|
||||
// inline classic scripts ignore both these attributes.
|
||||
MOZ_ASSERT(!aElement->GetScriptDeferred());
|
||||
MOZ_ASSERT_IF(!request->IsModuleRequest(), !aElement->GetScriptAsync());
|
||||
request->SetScriptMode(false, aElement->GetScriptAsync(), false);
|
||||
request->GetLoadContext()->SetScriptMode(false, aElement->GetScriptAsync(),
|
||||
false);
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Created request for inline script",
|
||||
request.get()));
|
||||
@@ -1513,9 +1526,10 @@ ScriptLoadRequest* ScriptLoader::LookupPreloadRequest(
|
||||
// Found preloaded request. Note that a script-inserted script can steal a
|
||||
// preload!
|
||||
RefPtr<ScriptLoadRequest> request = mPreloads[i].mRequest;
|
||||
request->SetIsLoadRequest(aElement);
|
||||
request->GetLoadContext()->SetIsLoadRequest(aElement);
|
||||
|
||||
if (request->mWasCompiledOMT && !request->IsModuleRequest()) {
|
||||
if (request->GetLoadContext()->mWasCompiledOMT &&
|
||||
!request->IsModuleRequest()) {
|
||||
request->SetReady();
|
||||
}
|
||||
|
||||
@@ -1540,7 +1554,7 @@ ScriptLoadRequest* ScriptLoader::LookupPreloadRequest(
|
||||
// Don't cancel link preload requests, we want to deliver onload according
|
||||
// the result of the load, cancellation would unexpectedly lead to error
|
||||
// notification.
|
||||
if (!request->IsLinkPreloadScript()) {
|
||||
if (!request->GetLoadContext()->IsLinkPreloadScript()) {
|
||||
request->Cancel();
|
||||
}
|
||||
return nullptr;
|
||||
@@ -1551,11 +1565,11 @@ ScriptLoadRequest* ScriptLoader::LookupPreloadRequest(
|
||||
|
||||
// This makes sure the pending preload (if exists) for this resource is
|
||||
// properly marked as used and thus not notified in the console as unused.
|
||||
request->NotifyUsage();
|
||||
request->GetLoadContext()->NotifyUsage();
|
||||
// A used preload must no longer be found in the Document's hash table. Any
|
||||
// <link preload> tag after the <script> tag will start a new request, that
|
||||
// can be satisfied from a different cache, but not from the preload cache.
|
||||
request->RemoveSelf(mDocument);
|
||||
request->GetLoadContext()->RemoveSelf(mDocument);
|
||||
|
||||
return request;
|
||||
}
|
||||
@@ -1671,31 +1685,32 @@ void ScriptLoader::CancelScriptLoadRequests() {
|
||||
|
||||
nsresult ScriptLoader::ProcessOffThreadRequest(ScriptLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(aRequest->mProgress == ScriptLoadRequest::Progress::eCompiling);
|
||||
MOZ_ASSERT(!aRequest->mWasCompiledOMT);
|
||||
MOZ_ASSERT(!aRequest->GetLoadContext()->mWasCompiledOMT);
|
||||
|
||||
if (aRequest->IsCanceled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aRequest->mWasCompiledOMT = true;
|
||||
aRequest->GetLoadContext()->mWasCompiledOMT = true;
|
||||
|
||||
if (aRequest->mInCompilingList) {
|
||||
if (aRequest->GetLoadContext()->mInCompilingList) {
|
||||
mOffThreadCompilingRequests.Remove(aRequest);
|
||||
aRequest->mInCompilingList = false;
|
||||
aRequest->GetLoadContext()->mInCompilingList = false;
|
||||
}
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
MOZ_ASSERT(aRequest->mOffThreadToken);
|
||||
MOZ_ASSERT(aRequest->GetLoadContext()->mOffThreadToken);
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
return mModuleLoader->ProcessFetchedModuleSource(request);
|
||||
}
|
||||
|
||||
// Element may not be ready yet if speculatively compiling, so process the
|
||||
// request in ProcessPendingRequests when it is available.
|
||||
MOZ_ASSERT_IF(!SpeculativeOMTParsingEnabled(), aRequest->GetScriptElement());
|
||||
if (!aRequest->GetScriptElement()) {
|
||||
MOZ_ASSERT_IF(!SpeculativeOMTParsingEnabled(),
|
||||
aRequest->GetLoadContext()->GetScriptElement());
|
||||
if (!aRequest->GetLoadContext()->GetScriptElement()) {
|
||||
// Unblock onload here in case this request never gets executed.
|
||||
aRequest->MaybeUnblockOnload();
|
||||
aRequest->GetLoadContext()->MaybeUnblockOnload();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1718,7 +1733,8 @@ nsresult ScriptLoader::ProcessOffThreadRequest(ScriptLoadRequest* aRequest) {
|
||||
}
|
||||
|
||||
// Async scripts and blocking scripts can be executed right away.
|
||||
if ((aRequest->IsAsyncScript() || aRequest->IsBlockingScript()) &&
|
||||
if ((aRequest->GetLoadContext()->IsAsyncScript() ||
|
||||
aRequest->GetLoadContext()->IsBlockingScript()) &&
|
||||
!aRequest->isInList()) {
|
||||
return ProcessRequest(aRequest);
|
||||
}
|
||||
@@ -1749,7 +1765,7 @@ NotifyOffThreadScriptLoadCompletedRunnable::Run() {
|
||||
RefPtr<ScriptLoadRequest> request = std::move(mRequest);
|
||||
|
||||
// Runnable pointer should have been cleared in the offthread callback.
|
||||
MOZ_ASSERT(!request->mRunnable);
|
||||
MOZ_ASSERT(!request->GetLoadContext()->mRunnable);
|
||||
|
||||
if (profiler_is_active()) {
|
||||
ProfilerString8View scriptSourceString;
|
||||
@@ -1761,18 +1777,19 @@ NotifyOffThreadScriptLoadCompletedRunnable::Run() {
|
||||
}
|
||||
|
||||
nsAutoCString profilerLabelString;
|
||||
request->GetProfilerLabel(profilerLabelString);
|
||||
request->GetLoadContext()->GetProfilerLabel(profilerLabelString);
|
||||
PROFILER_MARKER_TEXT(
|
||||
scriptSourceString, JS,
|
||||
MarkerTiming::Interval(request->mOffThreadParseStartTime,
|
||||
request->mOffThreadParseStopTime),
|
||||
MarkerTiming::Interval(
|
||||
request->GetLoadContext()->mOffThreadParseStartTime,
|
||||
request->GetLoadContext()->mOffThreadParseStopTime),
|
||||
profilerLabelString);
|
||||
}
|
||||
|
||||
RefPtr<ScriptLoader> loader = std::move(mLoader);
|
||||
|
||||
// Request was already cancelled at some earlier point.
|
||||
if (!request->mOffThreadToken) {
|
||||
if (!request->GetLoadContext()->mOffThreadToken) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1783,16 +1800,19 @@ static void OffThreadScriptLoaderCallback(JS::OffThreadToken* aToken,
|
||||
void* aCallbackData) {
|
||||
RefPtr<NotifyOffThreadScriptLoadCompletedRunnable> aRunnable = dont_AddRef(
|
||||
static_cast<NotifyOffThreadScriptLoadCompletedRunnable*>(aCallbackData));
|
||||
MOZ_ASSERT(aRunnable.get() == aRunnable->GetScriptLoadRequest()->mRunnable);
|
||||
MOZ_ASSERT(aRunnable.get() ==
|
||||
aRunnable->GetScriptLoadRequest()->GetLoadContext()->mRunnable);
|
||||
|
||||
aRunnable->GetScriptLoadRequest()->mOffThreadParseStopTime = TimeStamp::Now();
|
||||
aRunnable->GetScriptLoadRequest()->GetLoadContext()->mOffThreadParseStopTime =
|
||||
TimeStamp::Now();
|
||||
|
||||
LogRunnable::Run run(aRunnable);
|
||||
|
||||
aRunnable->SetToken(aToken);
|
||||
|
||||
// If mRunnable was cleared then request was canceled so do nothing.
|
||||
if (!aRunnable->GetScriptLoadRequest()->mRunnable.exchange(nullptr)) {
|
||||
if (!aRunnable->GetScriptLoadRequest()->GetLoadContext()->mRunnable.exchange(
|
||||
nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1805,11 +1825,11 @@ nsresult ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
||||
// the element is not yet available.
|
||||
MOZ_ASSERT_IF(!SpeculativeOMTParsingEnabled() && !aRequest->IsModuleRequest(),
|
||||
aRequest->IsReadyToRun());
|
||||
MOZ_ASSERT(!aRequest->mWasCompiledOMT);
|
||||
MOZ_ASSERT(!aRequest->GetLoadContext()->mWasCompiledOMT);
|
||||
MOZ_ASSERT(aCouldCompileOut && !*aCouldCompileOut);
|
||||
|
||||
// Don't off-thread compile inline scripts.
|
||||
if (aRequest->mIsInline) {
|
||||
if (aRequest->GetLoadContext()->mIsInline) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1858,12 +1878,12 @@ nsresult ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
||||
// OffThreadScriptLoaderCallback were we will emulate run.
|
||||
LogRunnable::LogDispatch(runnable);
|
||||
|
||||
aRequest->mOffThreadParseStartTime = TimeStamp::Now();
|
||||
aRequest->GetLoadContext()->mOffThreadParseStartTime = TimeStamp::Now();
|
||||
|
||||
// Save the runnable so it can be properly cleared during cancellation.
|
||||
aRequest->mRunnable = runnable.get();
|
||||
auto signalOOM =
|
||||
mozilla::MakeScopeExit([&aRequest]() { aRequest->mRunnable = nullptr; });
|
||||
aRequest->GetLoadContext()->mRunnable = runnable.get();
|
||||
auto signalOOM = mozilla::MakeScopeExit(
|
||||
[&aRequest]() { aRequest->GetLoadContext()->mRunnable = nullptr; });
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
MOZ_ASSERT(aRequest->IsTextSource());
|
||||
@@ -1871,7 +1891,7 @@ nsresult ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
||||
nsresult rv = aRequest->GetScriptSource(cx, &maybeSource);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aRequest->mOffThreadToken =
|
||||
aRequest->GetLoadContext()->mOffThreadToken =
|
||||
maybeSource.constructed<SourceText<char16_t>>()
|
||||
? JS::CompileModuleToStencilOffThread(
|
||||
cx, options, maybeSource.ref<SourceText<char16_t>>(),
|
||||
@@ -1879,15 +1899,15 @@ nsresult ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
||||
: JS::CompileModuleToStencilOffThread(
|
||||
cx, options, maybeSource.ref<SourceText<Utf8Unit>>(),
|
||||
OffThreadScriptLoaderCallback, static_cast<void*>(runnable));
|
||||
if (!aRequest->mOffThreadToken) {
|
||||
if (!aRequest->GetLoadContext()->mOffThreadToken) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else if (aRequest->IsBytecode()) {
|
||||
JS::DecodeOptions decodeOptions(options);
|
||||
aRequest->mOffThreadToken = JS::DecodeStencilOffThread(
|
||||
aRequest->GetLoadContext()->mOffThreadToken = JS::DecodeStencilOffThread(
|
||||
cx, decodeOptions, aRequest->mScriptBytecode, aRequest->mBytecodeOffset,
|
||||
OffThreadScriptLoaderCallback, static_cast<void*>(runnable));
|
||||
if (!aRequest->mOffThreadToken) {
|
||||
if (!aRequest->GetLoadContext()->mOffThreadToken) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
@@ -1911,7 +1931,7 @@ nsresult ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
||||
nsresult rv = aRequest->GetScriptSource(cx, &maybeSource);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aRequest->mOffThreadToken =
|
||||
aRequest->GetLoadContext()->mOffThreadToken =
|
||||
maybeSource.constructed<SourceText<char16_t>>()
|
||||
? JS::CompileToStencilOffThread(
|
||||
cx, options, maybeSource.ref<SourceText<char16_t>>(),
|
||||
@@ -1919,13 +1939,13 @@ nsresult ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
||||
: JS::CompileToStencilOffThread(
|
||||
cx, options, maybeSource.ref<SourceText<Utf8Unit>>(),
|
||||
OffThreadScriptLoaderCallback, static_cast<void*>(runnable));
|
||||
if (!aRequest->mOffThreadToken) {
|
||||
if (!aRequest->GetLoadContext()->mOffThreadToken) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
signalOOM.release();
|
||||
|
||||
aRequest->BlockOnload(mDocument);
|
||||
aRequest->GetLoadContext()->BlockOnload(mDocument);
|
||||
|
||||
// Once the compilation is finished, an event would be added to the event loop
|
||||
// to call ScriptLoader::ProcessOffThreadRequest with the same request.
|
||||
@@ -1939,7 +1959,7 @@ nsresult ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
||||
// importing module.
|
||||
if (aRequest->IsTopLevel() && !aRequest->isInList()) {
|
||||
mOffThreadCompilingRequests.AppendElement(aRequest);
|
||||
aRequest->mInCompilingList = true;
|
||||
aRequest->GetLoadContext()->mInCompilingList = true;
|
||||
}
|
||||
|
||||
*aCouldCompileOut = true;
|
||||
@@ -1952,7 +1972,8 @@ nsresult ScriptLoader::CompileOffThreadOrProcessRequest(
|
||||
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
|
||||
"Processing requests when running scripts is unsafe.");
|
||||
|
||||
if (!aRequest->mOffThreadToken && !aRequest->InCompilingStage()) {
|
||||
if (!aRequest->GetLoadContext()->mOffThreadToken &&
|
||||
!aRequest->GetLoadContext()->CompileStarted()) {
|
||||
bool couldCompile = false;
|
||||
nsresult rv = AttemptAsyncScriptCompile(aRequest, &couldCompile);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1978,7 +1999,8 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
||||
|
||||
NS_ENSURE_ARG(aRequest);
|
||||
|
||||
auto unblockOnload = MakeScopeExit([&] { aRequest->MaybeUnblockOnload(); });
|
||||
auto unblockOnload =
|
||||
MakeScopeExit([&] { aRequest->GetLoadContext()->MaybeUnblockOnload(); });
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
@@ -1998,21 +2020,22 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> scriptElem =
|
||||
do_QueryInterface(aRequest->GetScriptElement());
|
||||
do_QueryInterface(aRequest->GetLoadContext()->GetScriptElement());
|
||||
|
||||
nsCOMPtr<Document> doc;
|
||||
if (!aRequest->mIsInline || aRequest->IsModuleRequest()) {
|
||||
if (!aRequest->GetLoadContext()->mIsInline || aRequest->IsModuleRequest()) {
|
||||
doc = scriptElem->OwnerDoc();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptElement> oldParserInsertedScript;
|
||||
uint32_t parserCreated = aRequest->GetParserCreated();
|
||||
uint32_t parserCreated = aRequest->GetLoadContext()->GetParserCreated();
|
||||
if (parserCreated) {
|
||||
oldParserInsertedScript = mCurrentParserInsertedScript;
|
||||
mCurrentParserInsertedScript = aRequest->GetScriptElement();
|
||||
mCurrentParserInsertedScript =
|
||||
aRequest->GetLoadContext()->GetScriptElement();
|
||||
}
|
||||
|
||||
aRequest->GetScriptElement()->BeginEvaluating();
|
||||
aRequest->GetLoadContext()->GetScriptElement()->BeginEvaluating();
|
||||
|
||||
FireScriptAvailable(NS_OK, aRequest);
|
||||
|
||||
@@ -2055,19 +2078,19 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
||||
|
||||
FireScriptEvaluated(rv, aRequest);
|
||||
|
||||
aRequest->GetScriptElement()->EndEvaluating();
|
||||
aRequest->GetLoadContext()->GetScriptElement()->EndEvaluating();
|
||||
|
||||
if (parserCreated) {
|
||||
mCurrentParserInsertedScript = oldParserInsertedScript;
|
||||
}
|
||||
|
||||
if (aRequest->mOffThreadToken) {
|
||||
if (aRequest->GetLoadContext()->mOffThreadToken) {
|
||||
// The request was parsed off-main-thread, but the result of the off
|
||||
// thread parse was not actually needed to process the request
|
||||
// (disappearing window, some other error, ...). Finish the
|
||||
// request to avoid leaks in the JS engine.
|
||||
MOZ_ASSERT(!aRequest->IsModuleRequest());
|
||||
aRequest->MaybeCancelOffThreadScript();
|
||||
aRequest->GetLoadContext()->MaybeCancelOffThreadScript();
|
||||
}
|
||||
|
||||
// Free any source data, but keep the bytecode content as we might have to
|
||||
@@ -2087,23 +2110,26 @@ void ScriptLoader::FireScriptAvailable(nsresult aResult,
|
||||
ScriptLoadRequest* aRequest) {
|
||||
for (int32_t i = 0; i < mObservers.Count(); i++) {
|
||||
nsCOMPtr<nsIScriptLoaderObserver> obs = mObservers[i];
|
||||
obs->ScriptAvailable(aResult, aRequest->GetScriptElement(),
|
||||
aRequest->mIsInline, aRequest->mURI,
|
||||
obs->ScriptAvailable(aResult,
|
||||
aRequest->GetLoadContext()->GetScriptElement(),
|
||||
aRequest->GetLoadContext()->mIsInline, aRequest->mURI,
|
||||
aRequest->mLineNo);
|
||||
}
|
||||
|
||||
aRequest->FireScriptAvailable(aResult);
|
||||
aRequest->GetLoadContext()->FireScriptAvailable(aResult);
|
||||
}
|
||||
|
||||
void ScriptLoader::FireScriptEvaluated(nsresult aResult,
|
||||
ScriptLoadRequest* aRequest) {
|
||||
for (int32_t i = 0; i < mObservers.Count(); i++) {
|
||||
nsCOMPtr<nsIScriptLoaderObserver> obs = mObservers[i];
|
||||
RefPtr<nsIScriptElement> scriptElement = aRequest->GetScriptElement();
|
||||
obs->ScriptEvaluated(aResult, scriptElement, aRequest->mIsInline);
|
||||
RefPtr<nsIScriptElement> scriptElement =
|
||||
aRequest->GetLoadContext()->GetScriptElement();
|
||||
obs->ScriptEvaluated(aResult, scriptElement,
|
||||
aRequest->GetLoadContext()->mIsInline);
|
||||
}
|
||||
|
||||
aRequest->FireScriptEvaluated(aResult);
|
||||
aRequest->GetLoadContext()->FireScriptEvaluated(aResult);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIGlobalObject> ScriptLoader::GetGlobalForRequest(
|
||||
@@ -2151,16 +2177,18 @@ nsresult ScriptLoader::FillCompileOptionsForRequest(
|
||||
}
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->NoteScriptTrackingStatus(aRequest->mURL, aRequest->IsTracking());
|
||||
mDocument->NoteScriptTrackingStatus(
|
||||
aRequest->mURL, aRequest->GetLoadContext()->IsTracking());
|
||||
}
|
||||
|
||||
const char* introductionType;
|
||||
if (aRequest->IsModuleRequest() &&
|
||||
!aRequest->AsModuleRequest()->IsTopLevel()) {
|
||||
introductionType = "importedModule";
|
||||
} else if (!aRequest->mIsInline) {
|
||||
} else if (!aRequest->GetLoadContext()->mIsInline) {
|
||||
introductionType = "srcScript";
|
||||
} else if (aRequest->GetParserCreated() == FROM_PARSER_NETWORK) {
|
||||
} else if (aRequest->GetLoadContext()->GetParserCreated() ==
|
||||
FROM_PARSER_NETWORK) {
|
||||
introductionType = "inlineScript";
|
||||
} else {
|
||||
introductionType = "injectedScript";
|
||||
@@ -2321,7 +2349,7 @@ nsresult ScriptLoader::EvaluateScriptElement(ScriptLoadRequest* aRequest) {
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> scriptContent(
|
||||
do_QueryInterface(aRequest->GetScriptElement()));
|
||||
do_QueryInterface(aRequest->GetLoadContext()->GetScriptElement()));
|
||||
MOZ_ASSERT(scriptContent);
|
||||
Document* ownerDoc = scriptContent->OwnerDoc();
|
||||
if (ownerDoc != mDocument) {
|
||||
@@ -2357,7 +2385,9 @@ nsresult ScriptLoader::EvaluateScriptElement(ScriptLoadRequest* aRequest) {
|
||||
// This must be destroyed after destroying nsAutoMicroTask, see:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1620505#c4
|
||||
nsIScriptElement* currentScript =
|
||||
aRequest->IsModuleRequest() ? nullptr : aRequest->GetScriptElement();
|
||||
aRequest->IsModuleRequest()
|
||||
? nullptr
|
||||
: aRequest->GetLoadContext()->GetScriptElement();
|
||||
AutoCurrentScriptUpdater scriptUpdater(this, currentScript);
|
||||
|
||||
Maybe<AutoSetProcessingScriptTag> setProcessingScriptTag;
|
||||
@@ -2371,17 +2401,48 @@ nsresult ScriptLoader::EvaluateScriptElement(ScriptLoadRequest* aRequest) {
|
||||
return EvaluateScript(globalObject, aRequest);
|
||||
}
|
||||
|
||||
nsresult ScriptLoader::CompileOrFinishModuleScript(
|
||||
JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::CompileOptions& aOptions,
|
||||
ModuleLoadRequest* aRequest, JS::MutableHandle<JSObject*> aModule) {
|
||||
if (aRequest->GetLoadContext()->mWasCompiledOMT) {
|
||||
JS::Rooted<JS::InstantiationStorage> storage(aCx);
|
||||
|
||||
RefPtr<JS::Stencil> stencil = JS::FinishCompileModuleToStencilOffThread(
|
||||
aCx, aRequest->GetLoadContext()->mOffThreadToken, storage.address());
|
||||
if (stencil) {
|
||||
JS::InstantiateOptions instantiateOptions(aOptions);
|
||||
aModule.set(JS::InstantiateModuleStencil(aCx, instantiateOptions, stencil,
|
||||
storage.address()));
|
||||
}
|
||||
|
||||
aRequest->GetLoadContext()->mOffThreadToken = nullptr;
|
||||
return aModule ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
MaybeSourceText maybeSource;
|
||||
nsresult rv = aRequest->GetScriptSource(aCx, &maybeSource);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return maybeSource.constructed<SourceText<char16_t>>()
|
||||
? nsJSUtils::CompileModule(
|
||||
aCx, maybeSource.ref<SourceText<char16_t>>(), aGlobal,
|
||||
aOptions, aModule)
|
||||
: nsJSUtils::CompileModule(
|
||||
aCx, maybeSource.ref<SourceText<Utf8Unit>>(), aGlobal,
|
||||
aOptions, aModule);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult ScriptLoader::CompileOrDecodeClassicScript(
|
||||
JSContext* aCx, JSExecutionContext& aExec, ScriptLoadRequest* aRequest) {
|
||||
nsAutoCString profilerLabelString;
|
||||
aRequest->GetProfilerLabel(profilerLabelString);
|
||||
aRequest->GetLoadContext()->GetProfilerLabel(profilerLabelString);
|
||||
|
||||
nsresult rv;
|
||||
if (aRequest->IsBytecode()) {
|
||||
if (aRequest->mOffThreadToken) {
|
||||
if (aRequest->GetLoadContext()->mOffThreadToken) {
|
||||
LOG(("ScriptLoadRequest (%p): Decode Bytecode & Join and Execute",
|
||||
aRequest));
|
||||
rv = aExec.JoinDecode(&aRequest->mOffThreadToken);
|
||||
rv = aExec.JoinDecode(&aRequest->GetLoadContext()->mOffThreadToken);
|
||||
} else {
|
||||
LOG(("ScriptLoadRequest (%p): Decode Bytecode and Execute", aRequest));
|
||||
AUTO_PROFILER_MARKER_TEXT("BytecodeDecodeMainThread", JS,
|
||||
@@ -2401,14 +2462,14 @@ nsresult ScriptLoader::CompileOrDecodeClassicScript(
|
||||
bool encodeBytecode = ShouldCacheBytecode(aRequest);
|
||||
aExec.SetEncodeBytecode(encodeBytecode);
|
||||
|
||||
if (aRequest->mOffThreadToken) {
|
||||
if (aRequest->GetLoadContext()->mOffThreadToken) {
|
||||
// Off-main-thread parsing.
|
||||
LOG(
|
||||
("ScriptLoadRequest (%p): Join (off-thread parsing) and "
|
||||
"Execute",
|
||||
aRequest));
|
||||
MOZ_ASSERT(aRequest->IsTextSource());
|
||||
rv = aExec.JoinCompile(&aRequest->mOffThreadToken);
|
||||
rv = aExec.JoinCompile(&aRequest->GetLoadContext()->mOffThreadToken);
|
||||
} else {
|
||||
// Main thread parsing (inline and small scripts)
|
||||
LOG(("ScriptLoadRequest (%p): Compile And Exec", aRequest));
|
||||
@@ -2437,7 +2498,8 @@ nsresult ScriptLoader::MaybePrepareForBytecodeEncoding(
|
||||
// Queue the current script load request to later save the bytecode.
|
||||
if (aScript && encodeBytecode) {
|
||||
aRequest->SetScript(aScript);
|
||||
TRACE_FOR_TEST(aRequest->GetScriptElement(), "scriptloader_encode");
|
||||
TRACE_FOR_TEST(aRequest->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_encode");
|
||||
MOZ_ASSERT(aRequest->mBytecodeOffset == aRequest->mScriptBytecode.length());
|
||||
RegisterForBytecodeEncoding(aRequest);
|
||||
} else {
|
||||
@@ -2445,7 +2507,8 @@ nsresult ScriptLoader::MaybePrepareForBytecodeEncoding(
|
||||
("ScriptLoadRequest (%p): Bytecode-cache: disabled (rv = %X, "
|
||||
"script = %p)",
|
||||
aRequest, unsigned(aRv), aScript.get()));
|
||||
TRACE_FOR_TEST_NONE(aRequest->GetScriptElement(), "scriptloader_no_encode");
|
||||
TRACE_FOR_TEST_NONE(aRequest->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_no_encode");
|
||||
aRequest->mCacheInfo = nullptr;
|
||||
}
|
||||
return aRv;
|
||||
@@ -2459,7 +2522,7 @@ nsresult ScriptLoader::EvaluateScript(nsIGlobalObject* aGlobalObject,
|
||||
JS::Rooted<JSObject*> global(cx, aGlobalObject->GetGlobalJSObject());
|
||||
|
||||
nsAutoCString profilerLabelString;
|
||||
aRequest->GetProfilerLabel(profilerLabelString);
|
||||
aRequest->GetLoadContext()->GetProfilerLabel(profilerLabelString);
|
||||
|
||||
// Create a ClassicScript object and associate it with the JSScript.
|
||||
RefPtr<ClassicScript> classicScript =
|
||||
@@ -2475,7 +2538,8 @@ nsresult ScriptLoader::EvaluateScript(nsIGlobalObject* aGlobalObject,
|
||||
return rv;
|
||||
}
|
||||
|
||||
TRACE_FOR_TEST(aRequest->GetScriptElement(), "scriptloader_execute");
|
||||
TRACE_FOR_TEST(aRequest->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_execute");
|
||||
JSExecutionContext exec(cx, global, options, classicScriptValue,
|
||||
introductionScript);
|
||||
|
||||
@@ -2634,7 +2698,7 @@ void ScriptLoader::EncodeRequestBytecode(JSContext* aCx,
|
||||
nsresult rv = NS_OK;
|
||||
MOZ_ASSERT(aRequest->mCacheInfo);
|
||||
auto bytecodeFailed = mozilla::MakeScopeExit([&]() {
|
||||
TRACE_FOR_TEST_NONE(aRequest->GetScriptElement(),
|
||||
TRACE_FOR_TEST_NONE(aRequest->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_bytecode_failed");
|
||||
});
|
||||
|
||||
@@ -2692,7 +2756,7 @@ void ScriptLoader::EncodeRequestBytecode(JSContext* aCx,
|
||||
MOZ_RELEASE_ASSERT(aRequest->mScriptBytecode.length() == n);
|
||||
|
||||
bytecodeFailed.release();
|
||||
TRACE_FOR_TEST_NONE(aRequest->GetScriptElement(),
|
||||
TRACE_FOR_TEST_NONE(aRequest->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_bytecode_saved");
|
||||
}
|
||||
|
||||
@@ -2720,7 +2784,7 @@ void ScriptLoader::GiveUpBytecodeEncoding() {
|
||||
while (!mBytecodeEncodingQueue.isEmpty()) {
|
||||
RefPtr<ScriptLoadRequest> request = mBytecodeEncodingQueue.StealFirst();
|
||||
LOG(("ScriptLoadRequest (%p): Cannot serialize bytecode", request.get()));
|
||||
TRACE_FOR_TEST_NONE(request->GetScriptElement(),
|
||||
TRACE_FOR_TEST_NONE(request->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_bytecode_failed");
|
||||
MOZ_ASSERT(!request->IsModuleRequest());
|
||||
MOZ_ASSERT(!request->GetWebExtGlobal());
|
||||
@@ -3097,10 +3161,10 @@ void ScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest,
|
||||
nsresult aResult) const {
|
||||
MOZ_ASSERT(aRequest);
|
||||
|
||||
if (aRequest->IsPreload()) {
|
||||
if (aRequest->GetLoadContext()->IsPreload()) {
|
||||
// Skip reporting errors in preload requests. If the request is actually
|
||||
// used then we will report the error in ReportPreloadErrorsToConsole below.
|
||||
aRequest->mUnreportedPreloadError = aResult;
|
||||
aRequest->GetLoadContext()->mUnreportedPreloadError = aResult;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3124,7 +3188,7 @@ void ScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest,
|
||||
AutoTArray<nsString, 1> params;
|
||||
CopyUTF8toUTF16(aRequest->mURI->GetSpecOrDefault(), *params.AppendElement());
|
||||
|
||||
nsIScriptElement* element = aRequest->GetScriptElement();
|
||||
nsIScriptElement* element = aRequest->GetLoadContext()->GetScriptElement();
|
||||
uint32_t lineNo = element ? element->GetScriptLineNumber() : 0;
|
||||
uint32_t columnNo = element ? element->GetScriptColumnNumber() : 0;
|
||||
|
||||
@@ -3135,9 +3199,10 @@ void ScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest,
|
||||
}
|
||||
|
||||
void ScriptLoader::ReportPreloadErrorsToConsole(ScriptLoadRequest* aRequest) {
|
||||
if (NS_FAILED(aRequest->mUnreportedPreloadError)) {
|
||||
ReportErrorToConsole(aRequest, aRequest->mUnreportedPreloadError);
|
||||
aRequest->mUnreportedPreloadError = NS_OK;
|
||||
if (NS_FAILED(aRequest->GetLoadContext()->mUnreportedPreloadError)) {
|
||||
ReportErrorToConsole(aRequest,
|
||||
aRequest->GetLoadContext()->mUnreportedPreloadError);
|
||||
aRequest->GetLoadContext()->mUnreportedPreloadError = NS_OK;
|
||||
}
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
@@ -3157,42 +3222,43 @@ void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
|
||||
*/
|
||||
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
aResult)) {
|
||||
nsCOMPtr<nsIContent> cont = do_QueryInterface(aRequest->GetScriptElement());
|
||||
nsCOMPtr<nsIContent> cont =
|
||||
do_QueryInterface(aRequest->GetLoadContext()->GetScriptElement());
|
||||
mDocument->AddBlockedNodeByClassifier(cont);
|
||||
}
|
||||
|
||||
if (aRequest->IsModuleRequest() && !aRequest->mIsInline) {
|
||||
if (aRequest->IsModuleRequest() && !aRequest->GetLoadContext()->mIsInline) {
|
||||
auto* request = aRequest->AsModuleRequest();
|
||||
mModuleLoader->SetModuleFetchFinishedAndResumeWaitingRequests(request,
|
||||
aResult);
|
||||
}
|
||||
|
||||
if (aRequest->mInDeferList) {
|
||||
if (aRequest->GetLoadContext()->mInDeferList) {
|
||||
MOZ_ASSERT_IF(aRequest->IsModuleRequest(),
|
||||
aRequest->AsModuleRequest()->IsTopLevel());
|
||||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req = mDeferRequests.Steal(aRequest);
|
||||
FireScriptAvailable(aResult, req);
|
||||
}
|
||||
} else if (aRequest->mInAsyncList) {
|
||||
} else if (aRequest->GetLoadContext()->mInAsyncList) {
|
||||
MOZ_ASSERT_IF(aRequest->IsModuleRequest(),
|
||||
aRequest->AsModuleRequest()->IsTopLevel());
|
||||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req = mLoadingAsyncRequests.Steal(aRequest);
|
||||
FireScriptAvailable(aResult, req);
|
||||
}
|
||||
} else if (aRequest->mIsNonAsyncScriptInserted) {
|
||||
} else if (aRequest->GetLoadContext()->mIsNonAsyncScriptInserted) {
|
||||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req =
|
||||
mNonAsyncExternalScriptInsertedRequests.Steal(aRequest);
|
||||
FireScriptAvailable(aResult, req);
|
||||
}
|
||||
} else if (aRequest->mIsXSLT) {
|
||||
} else if (aRequest->GetLoadContext()->mIsXSLT) {
|
||||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req = mXSLTRequests.Steal(aRequest);
|
||||
FireScriptAvailable(aResult, req);
|
||||
}
|
||||
} else if (aRequest->IsPreload()) {
|
||||
} else if (aRequest->GetLoadContext()->IsPreload()) {
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
aRequest->Cancel();
|
||||
}
|
||||
@@ -3226,12 +3292,14 @@ void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
|
||||
mParserBlockingRequest = nullptr;
|
||||
UnblockParser(aRequest);
|
||||
|
||||
// Ensure that we treat aRequest->GetScriptElement() as our current
|
||||
// parser-inserted script while firing onerror on it.
|
||||
MOZ_ASSERT(aRequest->GetScriptElement()->GetParserCreated());
|
||||
// Ensure that we treat aRequest->GetLoadContext()->GetScriptElement() as
|
||||
// our current parser-inserted script while firing onerror on it.
|
||||
MOZ_ASSERT(
|
||||
aRequest->GetLoadContext()->GetScriptElement()->GetParserCreated());
|
||||
nsCOMPtr<nsIScriptElement> oldParserInsertedScript =
|
||||
mCurrentParserInsertedScript;
|
||||
mCurrentParserInsertedScript = aRequest->GetScriptElement();
|
||||
mCurrentParserInsertedScript =
|
||||
aRequest->GetLoadContext()->GetScriptElement();
|
||||
FireScriptAvailable(aResult, aRequest);
|
||||
ContinueParserAsync(aRequest);
|
||||
mCurrentParserInsertedScript = oldParserInsertedScript;
|
||||
@@ -3239,18 +3307,21 @@ void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
|
||||
// This happens for blocking requests cancelled by ParsingComplete().
|
||||
// Ignore cancellation status for link-preload requests, as cancellation can
|
||||
// be omitted for them when SRI is stronger on consumer tags.
|
||||
MOZ_ASSERT(aRequest->IsCanceled() || aRequest->IsLinkPreloadScript());
|
||||
MOZ_ASSERT(aRequest->IsCanceled() ||
|
||||
aRequest->GetLoadContext()->IsLinkPreloadScript());
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptLoader::UnblockParser(ScriptLoadRequest* aParserBlockingRequest) {
|
||||
aParserBlockingRequest->GetScriptElement()->UnblockParser();
|
||||
aParserBlockingRequest->GetLoadContext()->GetScriptElement()->UnblockParser();
|
||||
}
|
||||
|
||||
void ScriptLoader::ContinueParserAsync(
|
||||
ScriptLoadRequest* aParserBlockingRequest) {
|
||||
aParserBlockingRequest->GetScriptElement()->ContinueParserAsync();
|
||||
aParserBlockingRequest->GetLoadContext()
|
||||
->GetScriptElement()
|
||||
->ContinueParserAsync();
|
||||
}
|
||||
|
||||
uint32_t ScriptLoader::NumberOfProcessors() {
|
||||
@@ -3327,20 +3398,20 @@ bool ScriptLoader::ShouldCompileOffThread(ScriptLoadRequest* aRequest) {
|
||||
if (SpeculativeOMTParsingEnabled()) {
|
||||
// Processing non async inserted scripts too early can potentially delay the
|
||||
// load event from firing so focus on other scripts instead.
|
||||
if (aRequest->mIsNonAsyncScriptInserted &&
|
||||
if (aRequest->GetLoadContext()->mIsNonAsyncScriptInserted &&
|
||||
!StaticPrefs::
|
||||
dom_script_loader_external_scripts_speculate_non_parser_inserted_enabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Async and link preload scripts do not need to be parsed right away.
|
||||
if (aRequest->IsAsyncScript() &&
|
||||
if (aRequest->GetLoadContext()->IsAsyncScript() &&
|
||||
!StaticPrefs::
|
||||
dom_script_loader_external_scripts_speculate_async_enabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aRequest->IsLinkPreloadScript() &&
|
||||
if (aRequest->GetLoadContext()->IsLinkPreloadScript() &&
|
||||
!StaticPrefs::
|
||||
dom_script_loader_external_scripts_speculate_link_preload_enabled()) {
|
||||
return false;
|
||||
@@ -3393,7 +3464,7 @@ nsresult ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest,
|
||||
MOZ_ASSERT(classifiedChannel);
|
||||
if (classifiedChannel &&
|
||||
classifiedChannel->IsThirdPartyTrackingResource()) {
|
||||
aRequest->SetIsTracking();
|
||||
aRequest->GetLoadContext()->SetIsTracking();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3515,7 +3586,7 @@ void ScriptLoader::ParsingComplete(bool aTerminated) {
|
||||
|
||||
// Cancel any unused scripts that were compiled speculatively
|
||||
for (size_t i = 0; i < mPreloads.Length(); i++) {
|
||||
mPreloads[i].mRequest->MaybeCancelOffThreadScript();
|
||||
mPreloads[i].mRequest->GetLoadContext()->MaybeCancelOffThreadScript();
|
||||
}
|
||||
|
||||
// Have to call this even if aTerminated so we'll correctly unblock
|
||||
@@ -3565,10 +3636,10 @@ void ScriptLoader::PreloadURI(nsIURI* aURI, const nsAString& aCharset,
|
||||
RefPtr<ScriptLoadRequest> request = CreateLoadRequest(
|
||||
scriptKind, aURI, nullptr, mDocument->NodePrincipal(),
|
||||
Element::StringToCORSMode(aCrossOrigin), sriMetadata, aReferrerPolicy);
|
||||
request->mIsInline = false;
|
||||
request->mScriptFromHead = aScriptFromHead;
|
||||
request->SetScriptMode(aDefer, aAsync, aLinkPreload);
|
||||
request->SetIsPreloadRequest();
|
||||
request->GetLoadContext()->mIsInline = false;
|
||||
request->GetLoadContext()->mScriptFromHead = aScriptFromHead;
|
||||
request->GetLoadContext()->SetScriptMode(aDefer, aAsync, aLinkPreload);
|
||||
request->GetLoadContext()->SetIsPreloadRequest();
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString url;
|
||||
@@ -3588,11 +3659,12 @@ void ScriptLoader::PreloadURI(nsIURI* aURI, const nsAString& aCharset,
|
||||
}
|
||||
|
||||
void ScriptLoader::AddDeferRequest(ScriptLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(aRequest->IsDeferredScript());
|
||||
MOZ_ASSERT(!aRequest->mInDeferList && !aRequest->mInAsyncList);
|
||||
MOZ_ASSERT(!aRequest->mInCompilingList);
|
||||
MOZ_ASSERT(aRequest->GetLoadContext()->IsDeferredScript());
|
||||
MOZ_ASSERT(!aRequest->GetLoadContext()->mInDeferList &&
|
||||
!aRequest->GetLoadContext()->mInAsyncList);
|
||||
MOZ_ASSERT(!aRequest->GetLoadContext()->mInCompilingList);
|
||||
|
||||
aRequest->mInDeferList = true;
|
||||
aRequest->GetLoadContext()->mInDeferList = true;
|
||||
mDeferRequests.AppendElement(aRequest);
|
||||
if (mDeferEnabled && aRequest == mDeferRequests.getFirst() && mDocument &&
|
||||
!mBlockingDOMContentLoaded) {
|
||||
@@ -3603,11 +3675,12 @@ void ScriptLoader::AddDeferRequest(ScriptLoadRequest* aRequest) {
|
||||
}
|
||||
|
||||
void ScriptLoader::AddAsyncRequest(ScriptLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(aRequest->IsAsyncScript());
|
||||
MOZ_ASSERT(!aRequest->mInDeferList && !aRequest->mInAsyncList);
|
||||
MOZ_ASSERT(!aRequest->mInCompilingList);
|
||||
MOZ_ASSERT(aRequest->GetLoadContext()->IsAsyncScript());
|
||||
MOZ_ASSERT(!aRequest->GetLoadContext()->mInDeferList &&
|
||||
!aRequest->GetLoadContext()->mInAsyncList);
|
||||
MOZ_ASSERT(!aRequest->GetLoadContext()->mInCompilingList);
|
||||
|
||||
aRequest->mInAsyncList = true;
|
||||
aRequest->GetLoadContext()->mInAsyncList = true;
|
||||
if (aRequest->IsReadyToRun()) {
|
||||
mLoadedAsyncRequests.AppendElement(aRequest);
|
||||
} else {
|
||||
@@ -3618,10 +3691,11 @@ void ScriptLoader::AddAsyncRequest(ScriptLoadRequest* aRequest) {
|
||||
void ScriptLoader::MaybeMoveToLoadedList(ScriptLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(aRequest->IsReadyToRun());
|
||||
|
||||
// If it's async, move it to the loaded list. aRequest->mInAsyncList really
|
||||
// _should_ be in a list, but the consequences if it's not are bad enough we
|
||||
// want to avoid trying to move it if it's not.
|
||||
if (aRequest->mInAsyncList) {
|
||||
// If it's async, move it to the loaded list.
|
||||
// aRequest->GetLoadContext()->mInAsyncList really _should_ be in a list, but
|
||||
// the consequences if it's not are bad enough we want to avoid trying to move
|
||||
// it if it's not.
|
||||
if (aRequest->GetLoadContext()->mInAsyncList) {
|
||||
MOZ_ASSERT(aRequest->isInList());
|
||||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req = mLoadingAsyncRequests.Steal(aRequest);
|
||||
|
||||
Reference in New Issue
Block a user