Bug 1583400: Make IsCurrentInnerWindow Fission-compatible. r=bzbarsky
authorKris Maglione <maglione.k@gmail.com>
Fri, 11 Oct 2019 21:53:22 +0000
changeset 497324 686a306609ad01ed4749b40d97a2b5116055ef4e
parent 497323 e2153ccf7c79774e7556bf12191215e6ae420367
child 497325 dfbe8f0a9dec8fe20bbeeb767bfa47fa40808c50
push id36682
push userncsoregi@mozilla.com
push dateSat, 12 Oct 2019 09:52:03 +0000
treeherdermozilla-central@06ea2371f897 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1583400
milestone71.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 1583400: Make IsCurrentInnerWindow Fission-compatible. r=bzbarsky IsCurrentInnerWindow() should only return true when we are the current inner of our BrowsingContext, which has a longer lifetime than individual GlobalWindowOuter instances. In particular, if our BrowsingContext has no GlobalWindowOuter hanging off it, that means that currently it's hosting an inner window from some other process and we are not the current inner. If it _does_ have a GlobalWindowOuter hanging off it, it's possible that this is not the same as our mOuterWindow, if the BrowsingContext navigated to a different site and then navigated back to our site. Therefore, we need to check that we are the current inner of whatever the BrowsingContext's current GlobalWindowOuter is, if it has one at all. Differential Revision: https://phabricator.services.mozilla.com/D48595
dom/base/nsGlobalWindowInner.cpp
dom/base/nsPIDOMWindow.h
dom/base/nsPIDOMWindowInlines.h
js/xpconnect/tests/mochitest/mochitest.ini
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -2543,16 +2543,36 @@ void nsPIDOMWindowInner::UpdateWebSocket
 
 bool nsPIDOMWindowInner::HasOpenWebSockets() const {
   MOZ_ASSERT(NS_IsMainThread());
 
   return mNumOfOpenWebSockets ||
          (mTopInnerWindow && mTopInnerWindow->mNumOfOpenWebSockets);
 }
 
+bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
+  auto* bc = GetBrowsingContext();
+  MOZ_ASSERT(bc);
+
+  nsCOMPtr<nsPIDOMWindowOuter> outer;
+  // When a BC is discarded, it stops returning outer windows altogether. That
+  // doesn't work for this check, since we still want current inner window to be
+  // treated as current after that point. Simply falling back to `mOuterWindow`
+  // here isn't ideal, since it will start returning true for inner windows
+  // which were current before a remoteness switch once a BrowsingContext has
+  // been discarded, but it's not incorrect in a way which should cause
+  // significant issues.
+  if (!bc->IsDiscarded()) {
+    outer = bc->GetDOMWindow();
+  } else {
+    outer = mOuterWindow;
+  }
+  return outer && outer->GetCurrentInnerWindow() == this;
+}
+
 void nsPIDOMWindowInner::SetAudioCapture(bool aCapture) {
   RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
   if (service) {
     service->SetWindowAudioCaptured(GetOuterWindow(), mWindowID, aCapture);
   }
 }
 
 void nsGlobalWindowInner::SetActiveLoadingState(bool aIsLoading) {
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -153,23 +153,23 @@ class nsPIDOMWindowInner : public mozIDO
   const nsIGlobalObject* AsGlobal() const;
 
   nsPIDOMWindowOuter* GetOuterWindow() const { return mOuterWindow; }
 
   static nsPIDOMWindowInner* From(mozIDOMWindow* aFrom) {
     return static_cast<nsPIDOMWindowInner*>(aFrom);
   }
 
-  // Returns true if this object has an outer window and it is the current inner
-  // window of that outer.
-  inline bool IsCurrentInnerWindow() const;
+  // Returns true if this object is the currently-active inner window for its
+  // BrowsingContext.
+  bool IsCurrentInnerWindow() const;
 
   // Returns true if the document of this window is the active document.  This
-  // is not identical to IsCurrentInnerWindow() because document.open() will
-  // keep the same document active but create a new window.
+  // is identical to IsCurrentInnerWindow() now that document.open() no longer
+  // creates new inner windows for the document it is called on.
   inline bool HasActiveDocument();
 
   // Returns true if this window is the same as mTopInnerWindow
   inline bool IsTopInnerWindow() const;
 
   // Check whether a document is currently loading (really checks if the
   // load event has completed).  May not be reset to false on errors.
   inline bool IsLoading() const;
--- a/dom/base/nsPIDOMWindowInlines.h
+++ b/dom/base/nsPIDOMWindowInlines.h
@@ -43,24 +43,18 @@ bool nsPIDOMWindowInner::IsHandlingResiz
     NS_ERROR("IsHandlingResizeEvent() called on orphan inner window!");
 
     return false;
   }
 
   return mIsHandlingResizeEvent;
 }
 
-bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
-  return mOuterWindow && mOuterWindow->GetCurrentInnerWindow() == this;
-}
-
 bool nsPIDOMWindowInner::HasActiveDocument() {
-  return IsCurrentInnerWindow() ||
-         (mOuterWindow && mOuterWindow->GetCurrentInnerWindow() &&
-          mOuterWindow->GetCurrentInnerWindow()->GetDoc() == mDoc);
+  return IsCurrentInnerWindow();
 }
 
 bool nsPIDOMWindowInner::IsTopInnerWindow() const {
   return mTopInnerWindow == this;
 }
 
 nsIDocShell* nsPIDOMWindowOuter::GetDocShell() const { return mDocShell; }
 
--- a/js/xpconnect/tests/mochitest/mochitest.ini
+++ b/js/xpconnect/tests/mochitest/mochitest.ini
@@ -82,17 +82,16 @@ skip-if = toolkit == "android" && debug 
 [test_bug862380.html]
 [test_bug865260.html]
 [test_bug870423.html]
 [test_bug871887.html]
 [test_bug912322.html]
 [test_bug916945.html]
 [test_bug92773.html]
 [test_bug940783.html]
-fail-if = fission
 [test_bug965082.html]
 skip-if = fission && webrender && debug # Crashes intermittently: @ nsDocShell::SetParentWidget(nsIWidget*)
 [test_bug960820.html]
 [test_bug986542.html]
 [test_bug993423.html]
 [test_bug1005806.html]
 [test_bug1094930.html]
 [test_bug1158558.html]