Backed out changeset 47a8380519cc (bug 916255) for tp timeouts.
authorRyan VanderMeulen <ryanvm@gmail.com>
Sat, 14 Sep 2013 21:25:31 -0400
changeset 147252 9366ee0396451492b3097fbb499b20fc5c63b82b
parent 147251 1f7fddaf46fdbc196bb8a5f92a23dc9584755a6c
child 147253 dd8abf7ff87fcbd0f86bc2f57f802685bfdf6a4d
child 147284 8a08b73e7616202f0b3f1471d5aa10fa2eb430eb
child 147305 cb094f8a5e2696f915f47c1e2bfdcc8a5305ba5b
child 155797 1f4c625b19a78bb5555790026f21c6e9260f7758
push id33811
push userryanvm@gmail.com
push dateSun, 15 Sep 2013 01:25:41 +0000
treeherdermozilla-inbound@9366ee039645 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs916255
milestone26.0a1
backs out47a8380519cc481cba1160132f5d4d2b5419cf37
first release with
nightly linux32
9366ee039645 / 26.0a1 / 20130915030208 / files
nightly linux64
9366ee039645 / 26.0a1 / 20130915030208 / files
nightly mac
9366ee039645 / 26.0a1 / 20130915030208 / files
nightly win32
9366ee039645 / 26.0a1 / 20130915030208 / files
nightly win64
9366ee039645 / 26.0a1 / 20130915030208 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 47a8380519cc (bug 916255) for tp timeouts.
content/base/src/nsScriptLoader.cpp
content/base/src/nsScriptLoader.h
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -692,110 +692,110 @@ nsScriptLoader::ProcessScriptElement(nsI
       "Not safe to run a parser-inserted script?");
   return ProcessRequest(request) == NS_ERROR_HTMLPARSER_BLOCK;
 }
 
 namespace {
 
 class NotifyOffThreadScriptLoadCompletedRunnable : public nsRunnable
 {
-  nsRefPtr<nsScriptLoadRequest> mRequest;
-  nsRefPtr<nsScriptLoader> mLoader;
-  void *mToken;
+    nsRefPtr<nsScriptLoader> mLoader;
+    void *mToken;
 
 public:
-  NotifyOffThreadScriptLoadCompletedRunnable(nsScriptLoadRequest* aRequest,
-                                             nsScriptLoader* aLoader)
-    : mRequest(aRequest), mLoader(aLoader), mToken(NULL)
-  {}
+    NotifyOffThreadScriptLoadCompletedRunnable(already_AddRefed<nsScriptLoader> aLoader,
+                                               void *aToken)
+      : mLoader(aLoader), mToken(aToken)
+    {}
 
-  void SetToken(void* aToken) {
-    MOZ_ASSERT(aToken && !mToken);
-    mToken = aToken;
-  }
-
-  NS_DECL_NSIRUNNABLE
+    NS_DECL_NSIRUNNABLE
 };
 
 } /* anonymous namespace */
 
 nsresult
-nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest, void **aOffThreadToken)
+nsScriptLoader::ProcessOffThreadRequest(void **aOffThreadToken)
 {
-  nsresult rv = ProcessRequest(aRequest, aOffThreadToken);
-  mDocument->UnblockOnload(false);
-  return rv;
+    nsCOMPtr<nsScriptLoadRequest> request = mOffThreadScriptRequest;
+    mOffThreadScriptRequest = nullptr;
+    mDocument->UnblockOnload(false);
+
+    return ProcessRequest(request, aOffThreadToken);
 }
 
 NS_IMETHODIMP
 NotifyOffThreadScriptLoadCompletedRunnable::Run()
 {
-  MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(NS_IsMainThread());
 
-  nsresult rv = mLoader->ProcessOffThreadRequest(mRequest, &mToken);
+    nsresult rv = mLoader->ProcessOffThreadRequest(&mToken);
 
-  if (mToken) {
-    // 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.
-    nsCOMPtr<nsIJSRuntimeService> svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
-    NS_ENSURE_TRUE(svc, NS_ERROR_FAILURE);
-    JSRuntime *rt;
-    svc->GetRuntime(&rt);
-    NS_ENSURE_TRUE(rt, NS_ERROR_FAILURE);
-    JS::FinishOffThreadScript(nullptr, rt, mToken);
-  }
+    if (mToken) {
+      // 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.
+      nsCOMPtr<nsIJSRuntimeService> svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
+      NS_ENSURE_TRUE(svc, NS_ERROR_FAILURE);
+      JSRuntime *rt;
+      svc->GetRuntime(&rt);
+      NS_ENSURE_TRUE(rt, NS_ERROR_FAILURE);
+      JS::FinishOffThreadScript(nullptr, rt, mToken);
+    }
 
-  return rv;
+    return rv;
 }
 
 static void
 OffThreadScriptLoaderCallback(void *aToken, void *aCallbackData)
 {
-  NotifyOffThreadScriptLoadCompletedRunnable* aRunnable =
-    static_cast<NotifyOffThreadScriptLoadCompletedRunnable*>(aCallbackData);
-  aRunnable->SetToken(aToken);
-  NS_DispatchToMainThread(aRunnable);
-  NS_RELEASE(aRunnable);
+    // Be careful not to adjust the refcount on the loader, as this callback
+    // may be invoked off the main thread.
+    nsScriptLoader* aLoader = static_cast<nsScriptLoader*>(aCallbackData);
+    nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> notify =
+        new NotifyOffThreadScriptLoadCompletedRunnable(
+            already_AddRefed<nsScriptLoader>(aLoader), aToken);
+    NS_DispatchToMainThread(notify);
 }
 
 nsresult
 nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
 {
   if (!aRequest->mElement->GetScriptAsync() || aRequest->mIsInline) {
     return NS_ERROR_FAILURE;
   }
 
+  if (mOffThreadScriptRequest) {
+    return NS_ERROR_FAILURE;
+  }
+
   JSObject *unrootedGlobal;
   nsCOMPtr<nsIScriptContext> context = GetScriptContext(&unrootedGlobal);
   if (!context) {
     return NS_ERROR_FAILURE;
   }
   AutoPushJSContext cx(context->GetNativeContext());
   JS::Rooted<JSObject*> global(cx, unrootedGlobal);
 
   JS::CompileOptions options(cx);
   FillCompileOptionsForRequest(aRequest, global, &options);
 
   if (!JS::CanCompileOffThread(cx, options)) {
     return NS_ERROR_FAILURE;
   }
 
-  nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> runnable =
-    new NotifyOffThreadScriptLoadCompletedRunnable(aRequest, this);
-
+  mOffThreadScriptRequest = aRequest;
   if (!JS::CompileOffThread(cx, global, options,
                             aRequest->mScriptText.get(), aRequest->mScriptText.Length(),
                             OffThreadScriptLoaderCallback,
-                            static_cast<void*>(runnable))) {
+                            static_cast<void*>(this))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  // This reference will be consumed by OffThreadScriptLoaderCallback.
-  runnable.forget();
+  // This reference will be consumed by the NotifyOffThreadScriptLoadCompletedRunnable.
+  NS_ADDREF(this);
 
   mDocument->BlockOnload();
 
   return NS_OK;
 }
 
 nsresult
 nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest, void **aOffThreadToken)
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -206,18 +206,17 @@ public:
                           const nsAString &aType,
                           const nsAString &aCrossOrigin,
                           bool aScriptFromHead);
 
   /**
    * Process a request that was deferred so that the script could be compiled
    * off thread.
    */
-  nsresult ProcessOffThreadRequest(nsScriptLoadRequest *aRequest,
-                                   void **aOffThreadToken);
+  nsresult ProcessOffThreadRequest(void **aOffThreadToken);
 
 private:
   /**
    * Unblocks the creator parser of the parser-blocking scripts.
    */
   void UnblockParser(nsScriptLoadRequest* aParserBlockingRequest);
 
   /**
@@ -312,16 +311,17 @@ private:
       return aRequest == aPi.mRequest;
     }
   };
   struct PreloadURIComparator {
     bool Equals(const PreloadInfo &aPi, nsIURI * const &aURI) const;
   };
   nsTArray<PreloadInfo> mPreloads;
 
+  nsCOMPtr<nsScriptLoadRequest> mOffThreadScriptRequest;
   nsCOMPtr<nsIScriptElement> mCurrentScript;
   nsCOMPtr<nsIScriptElement> mCurrentParserInsertedScript;
   // XXXbz do we want to cycle-collect these or something?  Not sure.
   nsTArray< nsRefPtr<nsScriptLoader> > mPendingChildLoaders;
   uint32_t mBlockerCount;
   bool mEnabled;
   bool mDeferEnabled;
   bool mDocumentParsingDone;