Bug 1415645 - Part 4: Modify some shared runnables to not refer directly to nsGlobalWindow, r=smaug
authorNika Layzell <nika@thelayzells.com>
Wed, 08 Nov 2017 13:53:25 -0500
changeset 392018 55c0344711b64723b7653404ed9c4cd28ca9d6d9
parent 392017 9a766cc68671449c2c624816dff943d597a992a6
child 392019 c56352d90f678c2ad104da657aae116513502153
push id32909
push usercbrindusan@mozilla.com
push dateWed, 15 Nov 2017 22:25:14 +0000
treeherdermozilla-central@f41930a869a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1415645
milestone59.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 1415645 - Part 4: Modify some shared runnables to not refer directly to nsGlobalWindow, r=smaug MozReview-Commit-ID: ANdBkuhZ2xx
dom/base/nsGlobalWindow.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9746,21 +9746,31 @@ struct BrowserCompartmentMatcher : publi
     return nsContentUtils::IsSystemOrExpandedPrincipal(pc);
   }
 };
 
 
 class WindowDestroyedEvent final : public Runnable
 {
 public:
-  WindowDestroyedEvent(nsIDOMWindow* aWindow, uint64_t aID, const char* aTopic)
+  WindowDestroyedEvent(nsGlobalWindowInner* aWindow, uint64_t aID, const char* aTopic)
     : mozilla::Runnable("WindowDestroyedEvent")
     , mID(aID)
     , mPhase(Phase::Destroying)
     , mTopic(aTopic)
+    , mIsInnerWindow(true)
+  {
+    mWindow = do_GetWeakReference(aWindow);
+  }
+  WindowDestroyedEvent(nsGlobalWindowOuter* aWindow, uint64_t aID, const char* aTopic)
+    : mozilla::Runnable("WindowDestroyedEvent")
+    , mID(aID)
+    , mPhase(Phase::Destroying)
+    , mTopic(aTopic)
+    , mIsInnerWindow(false)
   {
     mWindow = do_GetWeakReference(aWindow);
   }
 
   enum class Phase
   {
     Destroying,
     Nuking
@@ -9815,60 +9825,69 @@ public:
         }
       }
       break;
 
       case Phase::Nuking:
       {
         nsCOMPtr<nsISupports> window = do_QueryReferent(mWindow);
         if (window) {
-          nsGlobalWindow* win = nsGlobalWindow::FromSupports(window);
-          nsGlobalWindowInner* currentInner = win->IsInnerWindow()
-            ? win->AssertInner()
-            : win->GetCurrentInnerWindowInternal();
+          nsGlobalWindowInner* currentInner;
+          if (mIsInnerWindow) {
+            currentInner = nsGlobalWindowInner::FromSupports(window);
+          } else {
+            nsGlobalWindowOuter* outer = nsGlobalWindowOuter::FromSupports(window);
+            currentInner = outer->GetCurrentInnerWindowInternal();
+          }
           NS_ENSURE_TRUE(currentInner, NS_OK);
 
           AutoSafeJSContext cx;
           JS::Rooted<JSObject*> obj(cx, currentInner->FastGetGlobalJSObject());
           if (obj && !js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
             JSCompartment* cpt = js::GetObjectCompartment(obj);
             nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
 
             if (BasePrincipal::Cast(pc)->AddonPolicy()) {
               // We want to nuke all references to the add-on compartment.
               xpc::NukeAllWrappersForCompartment(cx, cpt,
-                                                 win->IsInnerWindow() ? js::DontNukeWindowReferences
-                                                                      : js::NukeWindowReferences);
+                                                 mIsInnerWindow ? js::DontNukeWindowReferences
+                                                                : js::NukeWindowReferences);
             } else {
               // We only want to nuke wrappers for the chrome->content case
               js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt,
-                                               win->IsInnerWindow() ? js::DontNukeWindowReferences
-                                                                    : js::NukeWindowReferences,
+                                               mIsInnerWindow ? js::DontNukeWindowReferences
+                                                              : js::NukeWindowReferences,
                                                js::NukeIncomingReferences);
             }
           }
         }
       }
       break;
     }
 
     return NS_OK;
   }
 
 private:
   uint64_t mID;
   Phase mPhase;
   nsCString mTopic;
   nsWeakPtr mWindow;
+  bool mIsInnerWindow;
 };
 
 void
 nsGlobalWindow::NotifyWindowIDDestroyed(const char* aTopic)
 {
-  nsCOMPtr<nsIRunnable> runnable = new WindowDestroyedEvent(this, mWindowID, aTopic);
+  nsCOMPtr<nsIRunnable> runnable;
+  if (IsInnerWindow()) {
+    runnable = new WindowDestroyedEvent(AssertInner(), mWindowID, aTopic);
+  } else {
+    runnable = new WindowDestroyedEvent(AssertOuter(), mWindowID, aTopic);
+  }
   nsresult rv = Dispatch(TaskCategory::Other, runnable.forget());
   if (NS_SUCCEEDED(rv)) {
     mNotifiedIDDestroyed = true;
   }
 }
 
 // static
 void
@@ -10116,44 +10135,39 @@ nsGlobalWindow::ConvertDialogOptions(con
       break;
     }
   }
 }
 
 class ChildCommandDispatcher : public Runnable
 {
 public:
-  ChildCommandDispatcher(nsGlobalWindow* aWindow,
+  ChildCommandDispatcher(nsPIWindowRoot* aRoot,
                          nsITabChild* aTabChild,
                          const nsAString& aAction)
     : mozilla::Runnable("ChildCommandDispatcher")
-    , mWindow(aWindow)
+    , mRoot(aRoot)
     , mTabChild(aTabChild)
     , mAction(aAction)
   {
   }
 
   NS_IMETHOD Run() override
   {
-    nsCOMPtr<nsPIWindowRoot> root = mWindow->GetTopWindowRoot();
-    if (!root) {
-      return NS_OK;
-    }
-
     nsTArray<nsCString> enabledCommands, disabledCommands;
-    root->GetEnabledDisabledCommands(enabledCommands, disabledCommands);
+    mRoot->GetEnabledDisabledCommands(enabledCommands, disabledCommands);
     if (enabledCommands.Length() || disabledCommands.Length()) {
       mTabChild->EnableDisableCommands(mAction, enabledCommands, disabledCommands);
     }
 
     return NS_OK;
   }
 
 private:
-  RefPtr<nsGlobalWindow>             mWindow;
+  nsCOMPtr<nsPIWindowRoot>             mRoot;
   nsCOMPtr<nsITabChild>                mTabChild;
   nsString                             mAction;
 };
 
 class CommandDispatcher : public Runnable
 {
 public:
   CommandDispatcher(nsIDOMXULCommandDispatcher* aDispatcher,
@@ -10174,18 +10188,21 @@ public:
 };
 
 nsresult
 nsGlobalWindow::UpdateCommands(const nsAString& anAction, nsISelection* aSel, int16_t aReason)
 {
   // If this is a child process, redirect to the parent process.
   if (nsIDocShell* docShell = GetDocShell()) {
     if (nsCOMPtr<nsITabChild> child = docShell->GetTabChild()) {
-      nsContentUtils::AddScriptRunner(new ChildCommandDispatcher(this, child,
-                                                                 anAction));
+      nsCOMPtr<nsPIWindowRoot> root = GetTopWindowRoot();
+      if (root) {
+        nsContentUtils::AddScriptRunner(
+          new ChildCommandDispatcher(root, child, anAction));
+      }
       return NS_OK;
     }
   }
 
   nsPIDOMWindowOuter *rootWindow = GetPrivateRoot();
   if (!rootWindow)
     return NS_OK;