Backed out changeset 4643e46ff8d3 (bug 1397426)
authorMike Conley <mconley@mozilla.com>
Wed, 06 Dec 2017 16:03:32 -0500
changeset 447176 6b919b7a1161e73537625a0f2a9371b2ab8d38ff
parent 447175 94528f4b8ff969def6dc0a8ffff30be0d2763fd4
child 447177 15b69b6abbf8dfe06a35568429fc31173620ba0d
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1397426
milestone59.0a1
backs out4643e46ff8d3e84d10ff178e15a1be7f734b020f
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
Backed out changeset 4643e46ff8d3 (bug 1397426)
docshell/base/nsDocShell.cpp
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
ipc/glue/BackgroundChildImpl.cpp
xpcom/threads/LabeledEventQueue.cpp
xpcom/threads/LabeledEventQueue.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -6445,16 +6445,20 @@ nsDocShell::SetIsActive(bool aIsActive)
   // We disallow setting active on chrome docshells.
   if (mItemType == nsIDocShellTreeItem::typeChrome) {
     return NS_ERROR_INVALID_ARG;
   }
 
   // Keep track ourselves.
   mIsActive = aIsActive;
 
+  if (TabChild* tc = TabChild::GetFrom(this)) {
+    tc->OnDocShellActivated(aIsActive);
+  }
+
   // Clear prerender flag if necessary.
   if (mIsPrerendered && aIsActive) {
     MOZ_ASSERT(mPrerenderGlobalHistory.get());
     mIsPrerendered = false;
     nsCOMPtr<IHistory> history = services::GetHistoryService();
     nsresult rv = NS_OK;
     if (history) {
       rv = mPrerenderGlobalHistory->ApplyChanges(history);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -160,17 +160,17 @@ using mozilla::layers::GeckoContentContr
 NS_IMPL_ISUPPORTS(ContentListener, nsIDOMEventListener)
 NS_IMPL_ISUPPORTS(TabChildSHistoryListener,
                   nsISHistoryListener,
                   nsIPartialSHistoryListener,
                   nsISupportsWeakReference)
 
 static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
 
-nsTHashtable<nsPtrHashKey<TabChild>>* TabChild::sVisibleTabs;
+nsTHashtable<nsPtrHashKey<TabChild>>* TabChild::sActiveTabs;
 
 typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
 static TabChildMap* sTabChildren;
 StaticMutex sTabChildrenMutex;
 
 TabChildBase::TabChildBase()
   : mTabChildGlobal(nullptr)
 {
@@ -1145,21 +1145,21 @@ TabChild::ActorDestroy(ActorDestroyReaso
 
   if (GetTabId() != 0) {
     NestedTabChildMap().erase(GetTabId());
   }
 }
 
 TabChild::~TabChild()
 {
-  if (sVisibleTabs) {
-    sVisibleTabs->RemoveEntry(this);
-    if (sVisibleTabs->IsEmpty()) {
-      delete sVisibleTabs;
-      sVisibleTabs = nullptr;
+  if (sActiveTabs) {
+    sActiveTabs->RemoveEntry(this);
+    if (sActiveTabs->IsEmpty()) {
+      delete sActiveTabs;
+      sActiveTabs = nullptr;
     }
   }
 
   DestroyWindow();
 
   nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(WebNavigation());
   if (webBrowser) {
     webBrowser->SetContainerWindow(nullptr);
@@ -2661,16 +2661,33 @@ TabChild::RemovePendingDocShellBlocker()
   mPendingDocShellBlockers--;
   if (!mPendingDocShellBlockers && mPendingDocShellReceivedMessage) {
     mPendingDocShellReceivedMessage = false;
     InternalSetDocShellIsActive(mPendingDocShellIsActive);
   }
 }
 
 void
+TabChild::OnDocShellActivated(bool aIsActive)
+{
+  if (aIsActive) {
+    if (!sActiveTabs) {
+      sActiveTabs = new nsTHashtable<nsPtrHashKey<TabChild>>();
+    }
+    sActiveTabs->PutEntry(this);
+  } else {
+    if (sActiveTabs) {
+      sActiveTabs->RemoveEntry(this);
+      // We don't delete sActiveTabs here when it's empty since that
+      // could cause a lot of churn. Instead, we wait until ~TabChild.
+    }
+  }
+}
+
+void
 TabChild::InternalSetDocShellIsActive(bool aIsActive)
 {
   // docshell is consider prerendered only if not active yet
   mIsPrerendered &= !aIsActive;
   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
 
   if (docShell) {
     docShell->SetIsActive(aIsActive);
@@ -2733,21 +2750,16 @@ TabChild::RecvRenderLayers(const bool& a
       // notification to fire in the parent (so that it knows that the child has
       // updated its epoch). ForcePaintNoOp does that.
       if (IPCOpen()) {
         Unused << SendForcePaintNoOp(mLayerObserverEpoch);
         return IPC_OK();
       }
     }
 
-    if (!sVisibleTabs) {
-      sVisibleTabs = new nsTHashtable<nsPtrHashKey<TabChild>>();
-    }
-    sVisibleTabs->PutEntry(this);
-
     MakeVisible();
 
     nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
     if (!docShell) {
       return IPC_OK();
     }
 
     // We don't use TabChildBase::GetPresShell() here because that would create
@@ -2776,22 +2788,16 @@ TabChild::RecvRenderLayers(const bool& a
         if (nsView* view = vm->GetRootView()) {
           presShell->Paint(view, view->GetBounds(),
                            nsIPresShell::PAINT_LAYERS);
         }
       }
       APZCCallbackHelper::SuppressDisplayport(false, presShell);
     }
   } else {
-    if (sVisibleTabs) {
-      sVisibleTabs->RemoveEntry(this);
-      // We don't delete sVisibleTabs here when it's empty since that
-      // could cause a lot of churn. Instead, we wait until ~TabChild.
-    }
-
     MakeHidden();
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvNavigateByKey(const bool& aForward, const bool& aForDocumentNavigation)
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -576,16 +576,18 @@ public:
    * Signal to this TabChild that it should be made visible:
    * activated widget, retained layer tree, etc.  (Respectively,
    * made not visible.)
    */
   void MakeVisible();
   void MakeHidden();
   bool IsVisible();
 
+  void OnDocShellActivated(bool aIsActive);
+
   nsIContentChild* Manager() const { return mManager; }
 
   static inline TabChild*
   GetFrom(nsIDocShell* aDocShell)
   {
     if (!aDocShell) {
       return nullptr;
     }
@@ -771,30 +773,30 @@ public:
   // dispatching some mouse events other than mousemove.
   void FlushAllCoalescedMouseData();
   void ProcessPendingCoalescedMouseDataAndDispatchEvents();
 
   void HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
                                   const ScrollableLayerGuid& aGuid,
                                   const uint64_t& aInputBlockId);
 
-  static bool HasVisibleTabs()
+  static bool HasActiveTabs()
   {
-    return sVisibleTabs && !sVisibleTabs->IsEmpty();
+    return sActiveTabs && !sActiveTabs->IsEmpty();
   }
 
-  // Returns the set of TabChilds that are currently rendering layers. There
-  // can be multiple TabChilds in this state if Firefox has multiple windows
-  // open or is warming tabs up. There can also be zero TabChilds in this
-  // state. Note that this function should only be called if HasVisibleTabs()
-  // returns true.
-  static const nsTHashtable<nsPtrHashKey<TabChild>>& GetVisibleTabs()
+  // Returns the set of TabChilds that are currently in the foreground. There
+  // can be multiple foreground TabChilds if Firefox has multiple windows
+  // open. There can also be zero foreground TabChilds if the foreground tab is
+  // in a different content process. Note that this function should only be
+  // called if HasActiveTabs() returns true.
+  static const nsTHashtable<nsPtrHashKey<TabChild>>& GetActiveTabs()
   {
-    MOZ_ASSERT(HasVisibleTabs());
-    return *sVisibleTabs;
+    MOZ_ASSERT(HasActiveTabs());
+    return *sActiveTabs;
   }
 
 protected:
   virtual ~TabChild();
 
   virtual PRenderFrameChild* AllocPRenderFrameChild() override;
 
   virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) override;
@@ -984,21 +986,21 @@ private:
   bool mCoalesceMouseMoveEvents;
 
   bool mPendingDocShellIsActive;
   bool mPendingDocShellReceivedMessage;
   uint32_t mPendingDocShellBlockers;
 
   WindowsHandle mWidgetNativeData;
 
-  // This state is used to keep track of the current visible tabs (the ones rendering
-  // layers). There may be more than one if there are multiple browser windows open, or
-  // tabs are being warmed up. There may be none if this process does not host any
-  // visible or warming tabs.
-  static nsTHashtable<nsPtrHashKey<TabChild>>* sVisibleTabs;
+  // This state is used to keep track of the current active tabs (the ones in
+  // the foreground). There may be more than one if there are multiple browser
+  // windows open. There may be none if this process does not host any
+  // foreground tabs.
+  static nsTHashtable<nsPtrHashKey<TabChild>>* sActiveTabs;
 
   DISALLOW_EVIL_CONSTRUCTORS(TabChild);
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_TabChild_h
--- a/ipc/glue/BackgroundChildImpl.cpp
+++ b/ipc/glue/BackgroundChildImpl.cpp
@@ -657,18 +657,18 @@ BackgroundChildImpl::RecvDispatchLocalSt
 }
 
 bool
 BackgroundChildImpl::GetMessageSchedulerGroups(const Message& aMsg, SchedulerGroupSet& aGroups)
 {
   if (aMsg.type() == layout::PVsync::MessageType::Msg_Notify__ID) {
     MOZ_ASSERT(NS_IsMainThread());
     aGroups.Clear();
-    if (dom::TabChild::HasVisibleTabs()) {
-      for (auto iter = dom::TabChild::GetVisibleTabs().ConstIter();
+    if (dom::TabChild::HasActiveTabs()) {
+      for (auto iter = dom::TabChild::GetActiveTabs().ConstIter();
            !iter.Done(); iter.Next()) {
         aGroups.Put(iter.Get()->GetKey()->TabGroup());
       }
     }
     return true;
   }
 
   return false;
--- a/xpcom/threads/LabeledEventQueue.cpp
+++ b/xpcom/threads/LabeledEventQueue.cpp
@@ -161,46 +161,46 @@ LabeledEventQueue::GetEvent(EventPriorit
     MOZ_ASSERT(entry.mRunnable.get());
     return entry.mRunnable.forget();
   }
 
   if (!sCurrentSchedulerGroup) {
     return nullptr;
   }
 
-  // Move visible tabs to the front of the queue. The mAvoidVisibleTabCount field
-  // prevents us from preferentially processing events from visible tabs twice in
+  // Move active tabs to the front of the queue. The mAvoidActiveTabCount field
+  // prevents us from preferentially processing events from active tabs twice in
   // a row. This scheme is designed to prevent starvation.
-  if (TabChild::HasVisibleTabs() && mAvoidVisibleTabCount <= 0) {
-    for (auto iter = TabChild::GetVisibleTabs().ConstIter();
+  if (TabChild::HasActiveTabs() && mAvoidActiveTabCount <= 0) {
+    for (auto iter = TabChild::GetActiveTabs().ConstIter();
          !iter.Done(); iter.Next()) {
       SchedulerGroup* group = iter.Get()->GetKey()->TabGroup();
       if (!group->isInList() || group == sCurrentSchedulerGroup) {
         continue;
       }
 
-      // For each visible tab we move to the front of the queue, we have to
-      // process two SchedulerGroups (the visible tab and another one, presumably
-      // a background group) before we prioritize visible tabs again.
-      mAvoidVisibleTabCount += 2;
+      // For each active tab we move to the front of the queue, we have to
+      // process two SchedulerGroups (the active tab and another one, presumably
+      // a background group) before we prioritize active tabs again.
+      mAvoidActiveTabCount += 2;
 
       // We move |group| right before sCurrentSchedulerGroup and then set
       // sCurrentSchedulerGroup to group.
       MOZ_ASSERT(group != sCurrentSchedulerGroup);
       group->removeFrom(*sSchedulerGroups);
       sCurrentSchedulerGroup->setPrevious(group);
       sCurrentSchedulerGroup = group;
     }
   }
 
   // Iterate over each SchedulerGroup once, starting at sCurrentSchedulerGroup.
   SchedulerGroup* firstGroup = sCurrentSchedulerGroup;
   SchedulerGroup* group = firstGroup;
   do {
-    mAvoidVisibleTabCount--;
+    mAvoidActiveTabCount--;
 
     auto queueEntry = mLabeled.Lookup(group);
     if (!queueEntry) {
       // This can happen if |group| is in a different LabeledEventQueue than |this|.
       group = NextSchedulerGroup(group);
       continue;
     }
 
--- a/xpcom/threads/LabeledEventQueue.h
+++ b/xpcom/threads/LabeledEventQueue.h
@@ -144,18 +144,18 @@ private:
   static size_t sLabeledEventQueueCount;
   static SchedulerGroup* sCurrentSchedulerGroup;
 
   LabeledMap mLabeled;
   RunnableEpochQueue mUnlabeled;
   EpochQueue mEpochs;
   size_t mNumEvents = 0;
 
-  // Number of SchedulerGroups that must be processed before we prioritize a
-  // visible tab. This field is designed to guarantee a 1:1 interleaving between
+  // Number of SchedulerGroups that must be processed before we prioritize an
+  // active tab. This field is designed to guarantee a 1:1 interleaving between
   // foreground and background SchedulerGroups. For details, see its usage in
   // LabeledEventQueue.cpp.
-  int64_t mAvoidVisibleTabCount = 0;
+  int64_t mAvoidActiveTabCount = 0;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_LabeledEventQueue_h