Bug 1511237 - Store a TabChild reference in cached docshells, r=bzbarsky, r=smaug
authorNika Layzell <nika@thelayzells.com>
Thu, 29 Nov 2018 20:27:08 -0500
changeset 449432 dc7076b4b610403d4be2548ceec6ecba6ece9178
parent 449431 625c8d800f59c9a6fc6a31ad37c78766ba9e0ebd
child 449433 f3c4afc3c78040663a6c35e91e9f68ce1904c227
push id35163
push usershindli@mozilla.com
push dateWed, 05 Dec 2018 21:36:23 +0000
treeherdermozilla-central@643a4a6bbfe9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky, smaug
bugs1511237
milestone65.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 1511237 - Store a TabChild reference in cached docshells, r=bzbarsky, r=smaug Differential Revision: https://phabricator.services.mozilla.com/D13489
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -3188,16 +3188,32 @@ nsDocShell::SetTreeOwner(nsIDocShellTree
     nsCOMPtr<nsIDocShellTreeItem> child = do_QueryObject(iter.GetNext());
     NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
 
     if (child->ItemType() == mItemType) {
       child->SetTreeOwner(aTreeOwner);
     }
   }
 
+  // If we're in the content process and have had a TreeOwner set on us, extract
+  // our TabChild actor. If we've already had our TabChild set, assert that it
+  // hasn't changed.
+  if (mTreeOwner && XRE_IsContentProcess()) {
+    nsCOMPtr<nsITabChild> newTabChild = do_GetInterface(mTreeOwner);
+    MOZ_ASSERT(newTabChild, "No TabChild actor for tree owner in Content!");
+
+    if (mTabChild) {
+      nsCOMPtr<nsITabChild> oldTabChild = do_QueryReferent(mTabChild);
+      MOZ_RELEASE_ASSERT(oldTabChild == newTabChild,
+                         "Cannot cahnge TabChild during nsDocShell lifetime!");
+    } else {
+      mTabChild = do_GetWeakReference(newTabChild);
+    }
+  }
+
   // Our tree owner has changed. Recompute scriptability.
   //
   // Note that this is near-redundant with the recomputation in
   // SetDocLoaderParent(), but not so for the root DocShell, where the call to
   // SetTreeOwner() happens after the initial AddDocLoaderAsChildOfRoot(),
   // and we never set another parent. Given that this is neither expensive nor
   // performance-critical, let's be safe and unconditionally recompute this
   // state whenever dependent state changes.
@@ -5040,16 +5056,18 @@ nsDocShell::Destroy() {
     mSessionHistory->EvictLocalContentViewers();
     mSessionHistory = nullptr;
   }
 
   mBrowsingContext->Detach();
 
   SetTreeOwner(nullptr);
 
+  mTabChild = nullptr;
+
   mOnePermittedSandboxedNavigator = nullptr;
 
   // required to break ref cycle
   mSecurityUI = nullptr;
 
   // Cancel any timers that were set for this docshell; this is needed
   // to break the cycle between us and the timers.
   CancelRefreshURITimers();
@@ -13316,18 +13334,17 @@ nsDocShell::GetEditingSession(nsIEditing
 
 NS_IMETHODIMP
 nsDocShell::GetScriptableTabChild(nsITabChild** aTabChild) {
   *aTabChild = GetTabChild().take();
   return *aTabChild ? NS_OK : NS_ERROR_FAILURE;
 }
 
 already_AddRefed<nsITabChild> nsDocShell::GetTabChild() {
-  nsCOMPtr<nsIDocShellTreeOwner> owner(mTreeOwner);
-  nsCOMPtr<nsITabChild> tc = do_GetInterface(owner);
+  nsCOMPtr<nsITabChild> tc = do_QueryReferent(mTabChild);
   return tc.forget();
 }
 
 nsICommandManager* nsDocShell::GetCommandManager() {
   NS_ENSURE_SUCCESS(EnsureCommandHandler(), nullptr);
   return mCommandManager;
 }
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -916,16 +916,19 @@ class nsDocShell final : public nsDocLoa
   uint64_t mContentWindowID;
   nsCOMPtr<nsIContentViewer> mContentViewer;
   nsCOMPtr<nsIWidget> mParentWidget;
   RefPtr<mozilla::dom::ChildSHistory> mSessionHistory;
   nsCOMPtr<nsIWebBrowserFind> mFind;
   nsCOMPtr<nsICommandManager> mCommandManager;
   RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
 
+  // Weak reference to our TabChild actor.
+  nsWeakPtr mTabChild;
+
   // Dimensions of the docshell
   nsIntRect mBounds;
 
   /**
    * Content-Type Hint of the most-recently initiated load. Used for
    * session history entries.
    */
   nsCString mContentTypeHint;