Bug 1475228 - Don't ignore errors returned from ScriptLoader::AttemptAsyncScriptCompile() r=baku
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 17 Jul 2018 14:30:23 +0100
changeset 429632 0c94a41970e21db5398970b168e6dd1c6a922ce8
parent 429631 b1a05b0af0274777350fdee29416570102745326
child 429633 771c40992e319e091a6b39cfd793ccd7b696bee0
push id34369
push userdvarga@mozilla.com
push dateWed, 01 Aug 2018 22:10:16 +0000
treeherdermozilla-central@b72cd47198be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1475228
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1475228 - Don't ignore errors returned from ScriptLoader::AttemptAsyncScriptCompile() r=baku
dom/script/ScriptLoader.cpp
dom/script/ScriptLoader.h
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -1772,24 +1772,26 @@ OffThreadScriptLoaderCallback(JS::OffThr
 {
   RefPtr<NotifyOffThreadScriptLoadCompletedRunnable> aRunnable =
     dont_AddRef(static_cast<NotifyOffThreadScriptLoadCompletedRunnable*>(aCallbackData));
   aRunnable->SetToken(aToken);
   NotifyOffThreadScriptLoadCompletedRunnable::Dispatch(aRunnable.forget());
 }
 
 nsresult
-ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest)
+ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
+                                        bool* aCouldCompileOut)
 {
   MOZ_ASSERT_IF(!aRequest->IsModuleRequest(), aRequest->IsReadyToRun());
   MOZ_ASSERT(!aRequest->mWasCompiledOMT);
+  MOZ_ASSERT(aCouldCompileOut && !*aCouldCompileOut);
 
   // Don't off-thread compile inline scripts.
   if (aRequest->mIsInline) {
-    return NS_ERROR_FAILURE;
+    return NS_OK;
   }
 
   nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
   if (!globalObject) {
     return NS_ERROR_FAILURE;
   }
 
   AutoJSAPI jsapi;
@@ -1803,38 +1805,38 @@ ScriptLoader::AttemptAsyncScriptCompile(
 
   nsresult rv = FillCompileOptionsForRequest(jsapi, aRequest, global, &options);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (aRequest->IsTextSource()) {
     if (!JS::CanCompileOffThread(cx, options, aRequest->ScriptText().length())) {
-      return NS_ERROR_FAILURE;
+      return NS_OK;
     }
 #ifdef JS_BUILD_BINAST
   } else if (aRequest->IsBinASTSource()) {
     if (!JS::CanDecodeBinASTOffThread(cx, options, aRequest->ScriptBinASTData().length())) {
-      return NS_ERROR_FAILURE;
+      return NS_OK;
     }
 #endif
   } else {
     MOZ_ASSERT(aRequest->IsBytecode());
     size_t length = aRequest->mScriptBytecode.length() - aRequest->mBytecodeOffset;
     if (!JS::CanDecodeOffThread(cx, options, length)) {
-      return NS_ERROR_FAILURE;
+      return NS_OK;
     }
   }
 
   RefPtr<NotifyOffThreadScriptLoadCompletedRunnable> runnable =
     new NotifyOffThreadScriptLoadCompletedRunnable(aRequest, this);
 
   if (aRequest->IsModuleRequest()) {
     MOZ_ASSERT(aRequest->IsTextSource());
-    JS::SourceBufferHolder srcBuf = GetScriptSource(cx, aRequest);
+    SourceBufferHolder srcBuf = GetScriptSource(cx, aRequest);
     if (!JS::CompileOffThreadModule(cx, options,
                                     srcBuf,
                                     OffThreadScriptLoaderCallback,
                                     static_cast<void*>(runnable))) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   } else if (aRequest->IsBytecode()) {
     if (!JS::DecodeOffThreadScript(cx, options,
@@ -1852,50 +1854,57 @@ ScriptLoader::AttemptAsyncScriptCompile(
                                    aRequest->ScriptBinASTData().length(),
                                    OffThreadScriptLoaderCallback,
                                    static_cast<void*>(runnable))) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 #endif
   } else {
     MOZ_ASSERT(aRequest->IsTextSource());
-    JS::SourceBufferHolder srcBuf = GetScriptSource(cx, aRequest);
+    SourceBufferHolder srcBuf = GetScriptSource(cx, aRequest);
     if (!JS::CompileOffThread(cx, options,
                               srcBuf,
                               OffThreadScriptLoaderCallback,
                               static_cast<void*>(runnable))) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   mDocument->BlockOnload();
 
   // Once the compilation is finished, an event would be added to the event loop
   // to call ScriptLoader::ProcessOffThreadRequest with the same request.
   aRequest->mProgress = ScriptLoadRequest::Progress::eCompiling;
 
+  *aCouldCompileOut = true;
   Unused << runnable.forget();
   return NS_OK;
 }
 
 nsresult
 ScriptLoader::CompileOffThreadOrProcessRequest(ScriptLoadRequest* aRequest)
 {
   NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
                "Processing requests when running scripts is unsafe.");
   NS_ASSERTION(!aRequest->mOffThreadToken,
                "Candidate for off-thread compile is already parsed off-thread");
   NS_ASSERTION(!aRequest->InCompilingStage(),
                "Candidate for off-thread compile is already in compiling stage.");
 
-  nsresult rv = AttemptAsyncScriptCompile(aRequest);
-  if (NS_SUCCEEDED(rv)) {
+  bool couldCompile = false;
+  nsresult rv = AttemptAsyncScriptCompile(aRequest, &couldCompile);
+  if (NS_FAILED(rv)) {
+    HandleLoadError(aRequest, rv);
     return rv;
   }
 
+  if (couldCompile) {
+    return NS_OK;
+  }
+
   return ProcessRequest(aRequest);
 }
 
 SourceBufferHolder
 ScriptLoader::GetScriptSource(JSContext* aCx, ScriptLoadRequest* aRequest)
 {
   // Return a SourceBufferHolder object holding the script's source text.
 
@@ -3190,45 +3199,43 @@ ScriptLoader::PrepareLoadedRequest(Scrip
     // Fixup moz-extension: and resource: URIs, because the channel URI will
     // point to file:, which won't be allowed to load.
     if (uri && IsInternalURIScheme(uri)) {
       request->mBaseURL = uri;
     } else {
       channel->GetURI(getter_AddRefs(request->mBaseURL));
     }
 
-
     // Attempt to compile off main thread.
-    rv = AttemptAsyncScriptCompile(request);
-    if (NS_SUCCEEDED(rv)) {
-      return rv;
+    bool couldCompile = false;
+    rv = AttemptAsyncScriptCompile(request, &couldCompile);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (couldCompile) {
+      return NS_OK;
     }
 
     // Otherwise compile it right away and start fetching descendents.
     return ProcessFetchedModuleSource(request);
   }
 
   // The script is now loaded and ready to run.
   aRequest->SetReady();
 
   // If this is currently blocking the parser, attempt to compile it off-main-thread.
   if (aRequest == mParserBlockingRequest && NumberOfProcessors() > 1) {
     MOZ_ASSERT(!aRequest->IsModuleRequest());
-    nsresult rv = AttemptAsyncScriptCompile(aRequest);
-    if (rv == NS_OK) {
+    bool couldCompile = false;
+    nsresult rv = AttemptAsyncScriptCompile(aRequest, &couldCompile);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (couldCompile) {
       MOZ_ASSERT(aRequest->mProgress == ScriptLoadRequest::Progress::eCompiling,
                  "Request should be off-thread compiling now.");
       return NS_OK;
     }
 
-    // If off-thread compile errored, return the error.
-    if (rv != NS_ERROR_FAILURE) {
-      return rv;
-    }
-
     // If off-thread compile was rejected, continue with regular processing.
   }
 
   MaybeMoveToLoadedList(aRequest);
 
   return NS_OK;
 }
 
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -449,17 +449,18 @@ private:
                      nsresult aSRIStatus,
                      SRICheckDataVerifier* aSRIDataVerifier) const;
 
   nsresult SaveSRIHash(ScriptLoadRequest *aRequest,
                        SRICheckDataVerifier* aSRIDataVerifier) const;
 
   void ReportErrorToConsole(ScriptLoadRequest *aRequest, nsresult aResult) const;
 
-  nsresult AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest);
+  nsresult AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
+                                     bool* aCouldCompileOut);
   nsresult ProcessRequest(ScriptLoadRequest* aRequest);
   nsresult CompileOffThreadOrProcessRequest(ScriptLoadRequest* aRequest);
   void FireScriptAvailable(nsresult aResult,
                            ScriptLoadRequest* aRequest);
   void FireScriptEvaluated(nsresult aResult,
                            ScriptLoadRequest* aRequest);
   nsresult EvaluateScript(ScriptLoadRequest* aRequest);