Bug 1024082: Remove nsFrameManagerBase. r=dholbert
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 06 Mar 2018 09:45:59 +0100
changeset 461894 5936540dc37961cca6280a0552d80fb20835cad5
parent 461893 8aaf118e2e16ddba53bac4c5649bb36269bf5f30
child 461895 a387ecebd587214959b79c39274f8b33dcafa3c1
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1024082
milestone60.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 1024082: Remove nsFrameManagerBase. r=dholbert Instead move UndisplayedNode to its own file, which is what causes the include hell due to requiring nsIContent / nsStyleContext. MozReview-Commit-ID: 1opiajueZNb
layout/base/GeckoRestyleManager.cpp
layout/base/UndisplayedNode.h
layout/base/moz.build
layout/base/nsFrameManager.cpp
layout/base/nsFrameManager.h
layout/base/nsFrameManagerBase.h
layout/base/nsIPresShell.h
--- a/layout/base/GeckoRestyleManager.cpp
+++ b/layout/base/GeckoRestyleManager.cpp
@@ -11,16 +11,17 @@
 
 #include "mozilla/GeckoRestyleManager.h"
 
 #include <algorithm> // For std::max
 #include "gfxContext.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/GeckoStyleContext.h"
 #include "mozilla/EventStates.h"
+#include "mozilla/UndisplayedNode.h"
 #include "mozilla/ViewportFrame.h"
 #include "mozilla/css/StyleRule.h" // For nsCSSSelector
 #include "mozilla/dom/MutationEventBinding.h"
 #include "nsLayoutUtils.h"
 #include "AnimationCommon.h" // For GetLayerAnimationInfo
 #include "FrameLayerBuilder.h"
 #include "GeckoProfiler.h"
 #include "nsAutoPtr.h"
new file mode 100644
--- /dev/null
+++ b/layout/base/UndisplayedNode.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Linked list node for undisplayed element */
+
+#ifndef mozilla_UndisplayedNode_h
+#define mozilla_UndisplayedNode_h
+
+#include "nsIContent.h"
+#include "nsStyleContext.h"
+
+namespace mozilla {
+
+/**
+ * Node in a linked list, containing the style for an element that
+ * does not have a frame but whose parent does have a frame.
+ */
+struct UndisplayedNode : public LinkedListElement<UndisplayedNode>
+{
+  UndisplayedNode(nsIContent* aContent, nsStyleContext* aStyle)
+    : mContent(aContent)
+    , mStyle(aStyle)
+  {
+    MOZ_COUNT_CTOR(mozilla::UndisplayedNode);
+  }
+
+  ~UndisplayedNode() { MOZ_COUNT_DTOR(mozilla::UndisplayedNode); }
+
+  nsCOMPtr<nsIContent> mContent;
+  RefPtr<nsStyleContext> mStyle;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_UndisplayedNode_h
--- a/layout/base/moz.build
+++ b/layout/base/moz.build
@@ -40,17 +40,16 @@ EXPORTS += [
     'nsAutoLayoutPhase.h',
     'nsBidi.h',
     'nsBidiPresUtils.h',
     'nsCaret.h',
     'nsChangeHint.h',
     'nsCompatibility.h',
     'nsCSSFrameConstructor.h',
     'nsFrameManager.h',
-    'nsFrameManagerBase.h',
     'nsFrameTraversal.h',
     'nsIFrameTraversal.h',
     'nsILayoutDebugger.h',
     'nsIPercentBSizeObserver.h',
     'nsIPresShell.h',
     'nsIPresShellInlines.h',
     'nsIReflowCallback.h',
     'nsLayoutUtils.h',
@@ -78,16 +77,17 @@ EXPORTS.mozilla += [
     'OverflowChangedTracker.h',
     'PresShell.h',
     'RestyleLogging.h',
     'RestyleManager.h',
     'RestyleManagerInlines.h',
     'ServoRestyleManager.h',
     'ShapeUtils.h',
     'StaticPresData.h',
+    'UndisplayedNode.h',
 ]
 
 if CONFIG['MOZ_OLD_STYLE']:
     EXPORTS.mozilla += [
         'GeckoRestyleManager.h',
     ]
 
 UNIFIED_SOURCES += [
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -11,16 +11,17 @@
 #include "nsStyleContext.h"
 #include "nsCOMPtr.h"
 #include "plhash.h"
 #include "nsPlaceholderFrame.h"
 #include "nsGkAtoms.h"
 #include "nsILayoutHistoryState.h"
 #include "nsPresState.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/UndisplayedNode.h"
 #include "nsIDocument.h"
 
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsAutoPtr.h"
 #include "nsAbsoluteContainingBlock.h"
 #include "ChildIterator.h"
 
@@ -32,37 +33,24 @@
 #include "mozilla/MemoryReporting.h"
 
 // #define DEBUG_UNDISPLAYED_MAP
 // #define DEBUG_DISPLAY_CONTENTS_MAP
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-//----------------------------------------------------------------------
-
-nsFrameManagerBase::nsFrameManagerBase()
-  : mPresShell(nullptr)
-  , mRootFrame(nullptr)
-  , mDisplayNoneMap(nullptr)
-  , mDisplayContentsMap(nullptr)
-  , mIsDestroyingFrames(false)
-{
-}
-
-//----------------------------------------------------------------------
-
 /**
  * The undisplayed map is a class that maps a parent content node to the
  * undisplayed content children, and their style contexts.
  *
  * The linked list of nodes holds strong references to the style contexts and
  * the content.
  */
-class nsFrameManagerBase::UndisplayedMap :
+class nsFrameManager::UndisplayedMap :
   private nsClassHashtable<nsPtrHashKey<nsIContent>,
                            LinkedList<UndisplayedNode>>
 {
   typedef nsClassHashtable<nsPtrHashKey<nsIContent>, LinkedList<UndisplayedNode>> base_type;
 
 public:
   UndisplayedMap();
   ~UndisplayedMap();
@@ -710,151 +698,151 @@ nsFrameManager::AddSizeOfIncludingThis(n
   }
   if (mDisplayContentsMap) {
     mDisplayContentsMap->AddSizeOfIncludingThis(aSizes, isServo);
   }
 }
 
 //----------------------------------------------------------------------
 
-nsFrameManagerBase::UndisplayedMap::UndisplayedMap()
+nsFrameManager::UndisplayedMap::UndisplayedMap()
 {
-  MOZ_COUNT_CTOR(nsFrameManagerBase::UndisplayedMap);
+  MOZ_COUNT_CTOR(nsFrameManager::UndisplayedMap);
 }
 
-nsFrameManagerBase::UndisplayedMap::~UndisplayedMap(void)
+nsFrameManager::UndisplayedMap::~UndisplayedMap(void)
 {
-  MOZ_COUNT_DTOR(nsFrameManagerBase::UndisplayedMap);
+  MOZ_COUNT_DTOR(nsFrameManager::UndisplayedMap);
   Clear();
 }
 
 void
-nsFrameManagerBase::UndisplayedMap::Clear()
+nsFrameManager::UndisplayedMap::Clear()
 {
   for (auto iter = Iter(); !iter.Done(); iter.Next()) {
     auto* list = iter.UserData();
     while (auto* node = list->popFirst()) {
       delete node;
     }
     iter.Remove();
   }
 }
 
 
 nsIContent*
-nsFrameManagerBase::UndisplayedMap::GetApplicableParent(nsIContent* aParent)
+nsFrameManager::UndisplayedMap::GetApplicableParent(nsIContent* aParent)
 {
   // In the case of XBL default content, <xbl:children> elements do not get a
   // frame causing a mismatch between the content tree and the frame tree.
   // |GetEntryFor| is sometimes called with the content tree parent (which may
   // be a <xbl:children> element) but the parent in the frame tree would be the
   // insertion parent (parent of the <xbl:children> element). Here the children
   // elements are normalized to the insertion parent to correct for the mismatch.
   if (aParent && aParent->IsActiveChildrenElement()) {
     return aParent->GetParent();
   }
 
   return aParent;
 }
 
 LinkedList<UndisplayedNode>*
-nsFrameManagerBase::UndisplayedMap::GetListFor(nsIContent* aParent)
+nsFrameManager::UndisplayedMap::GetListFor(nsIContent* aParent)
 {
   MOZ_ASSERT(aParent == GetApplicableParent(aParent),
              "The parent that we use as the hash key must have been normalized");
 
   LinkedList<UndisplayedNode>* list;
   if (Get(aParent, &list)) {
     return list;
   }
 
   return nullptr;
 }
 
 LinkedList<UndisplayedNode>*
-nsFrameManagerBase::UndisplayedMap::GetOrCreateListFor(nsIContent* aParent)
+nsFrameManager::UndisplayedMap::GetOrCreateListFor(nsIContent* aParent)
 {
   MOZ_ASSERT(aParent == GetApplicableParent(aParent),
              "The parent that we use as the hash key must have been normalized");
 
   return LookupOrAdd(aParent);
 }
 
 
 UndisplayedNode*
-nsFrameManagerBase::UndisplayedMap::GetFirstNode(nsIContent* aParentContent)
+nsFrameManager::UndisplayedMap::GetFirstNode(nsIContent* aParentContent)
 {
   auto* list = GetListFor(aParentContent);
   return list ? list->getFirst() : nullptr;
 }
 
 
 void
-nsFrameManagerBase::UndisplayedMap::AppendNodeFor(UndisplayedNode* aNode,
-                                                  nsIContent* aParentContent)
+nsFrameManager::UndisplayedMap::AppendNodeFor(UndisplayedNode* aNode,
+                                              nsIContent* aParentContent)
 {
   LinkedList<UndisplayedNode>* list = GetOrCreateListFor(aParentContent);
 
 #ifdef DEBUG
   for (UndisplayedNode* node = list->getFirst(); node; node = node->getNext()) {
     // NOTE: In the original code there was a work around for this case, I want
     // to check it still happens before hacking around it the same way.
     MOZ_ASSERT(node->mContent != aNode->mContent,
                "Duplicated content in undisplayed list!");
   }
 #endif
 
   list->insertBack(aNode);
 }
 
 void
-nsFrameManagerBase::UndisplayedMap::AddNodeFor(nsIContent* aParentContent,
-                                               nsIContent* aChild,
-                                               nsStyleContext* aStyle)
+nsFrameManager::UndisplayedMap::AddNodeFor(nsIContent* aParentContent,
+                                           nsIContent* aChild,
+                                           nsStyleContext* aStyle)
 {
   UndisplayedNode*  node = new UndisplayedNode(aChild, aStyle);
   AppendNodeFor(node, aParentContent);
 }
 
 void
-nsFrameManagerBase::UndisplayedMap::RemoveNodeFor(nsIContent* aParentContent,
-                                                  UndisplayedNode* aNode)
+nsFrameManager::UndisplayedMap::RemoveNodeFor(nsIContent* aParentContent,
+                                              UndisplayedNode* aNode)
 {
 #ifdef DEBUG
   auto list = GetListFor(aParentContent);
   MOZ_ASSERT(list, "content not in map");
   aNode->removeFrom(*list);
 #else
   aNode->remove();
 #endif
   delete aNode;
 }
 
 
 nsAutoPtr<LinkedList<UndisplayedNode>>
-nsFrameManagerBase::UndisplayedMap::UnlinkNodesFor(nsIContent* aParentContent)
+nsFrameManager::UndisplayedMap::UnlinkNodesFor(nsIContent* aParentContent)
 {
   nsAutoPtr<LinkedList<UndisplayedNode>> list;
   Remove(GetApplicableParent(aParentContent), &list);
   return list;
 }
 
 void
-nsFrameManagerBase::UndisplayedMap::RemoveNodesFor(nsIContent* aParentContent)
+nsFrameManager::UndisplayedMap::RemoveNodesFor(nsIContent* aParentContent)
 {
   nsAutoPtr<LinkedList<UndisplayedNode>> list = UnlinkNodesFor(aParentContent);
   if (list) {
     while (auto* node = list->popFirst()) {
       delete node;
     }
   }
 }
 
 void
-nsFrameManagerBase::UndisplayedMap::
+nsFrameManager::UndisplayedMap::
 AddSizeOfIncludingThis(nsWindowSizes& aSizes, bool aIsServo) const
 {
   MallocSizeOf mallocSizeOf = aSizes.mState.mMallocSizeOf;
   aSizes.mLayoutPresShellSize += ShallowSizeOfIncludingThis(mallocSizeOf);
 
   nsWindowSizes staleSizes(aSizes.mState);
   for (auto iter = ConstIter(); !iter.Done(); iter.Next()) {
     const LinkedList<UndisplayedNode>* list = iter.UserData();
--- a/layout/base/nsFrameManager.h
+++ b/layout/base/nsFrameManager.h
@@ -4,70 +4,71 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* storage of the frame tree and information about it */
 
 #ifndef _nsFrameManager_h_
 #define _nsFrameManager_h_
 
-#include "nsFrameManagerBase.h"
-
+#include "nsDebug.h"
+#include "mozilla/Attributes.h"
 #include "nsFrameList.h"
-#include "nsIContent.h"
-#include "nsStyleContext.h"
 
 class nsContainerFrame;
+class nsIFrame;
+class nsILayoutHistoryState;
+class nsIPresShell;
 class nsPlaceholderFrame;
+class nsStyleContext;
 class nsWindowSizes;
-
 namespace mozilla {
-/**
- * Node in a linked list, containing the style for an element that
- * does not have a frame but whose parent does have a frame.
- */
-struct UndisplayedNode : public LinkedListElement<UndisplayedNode>
-{
-  UndisplayedNode(nsIContent* aContent, nsStyleContext* aStyle)
-    : mContent(aContent)
-    , mStyle(aStyle)
-  {
-    MOZ_COUNT_CTOR(mozilla::UndisplayedNode);
-  }
-
-  ~UndisplayedNode() { MOZ_COUNT_DTOR(mozilla::UndisplayedNode); }
-
-  nsCOMPtr<nsIContent> mContent;
-  RefPtr<nsStyleContext> mStyle;
-};
-
-} // namespace mozilla
+struct UndisplayedNode;
+}
 
 /**
  * Frame manager interface. The frame manager serves one purpose:
  * <li>handles structural modifications to the frame model. If the frame model
  * lock can be acquired, then the changes are processed immediately; otherwise,
  * they're queued and processed later.
  *
- * Do not add virtual methods (a vtable pointer) or members to this class, or
- * else you'll break the validity of the reinterpret_cast in nsIPresShell's
- * FrameManager() method.
+ * FIXME(emilio): The comment above doesn't make any sense, there's no "frame
+ * model lock" of any sort afaict.
  */
-class nsFrameManager : public nsFrameManagerBase
+class nsFrameManager
 {
   typedef mozilla::layout::FrameChildListID ChildListID;
   typedef mozilla::UndisplayedNode UndisplayedNode;
 
 public:
-  explicit nsFrameManager(nsIPresShell* aPresShell) {
-    mPresShell = aPresShell;
+  explicit nsFrameManager(nsIPresShell* aPresShell)
+    : mPresShell(aPresShell)
+    , mRootFrame(nullptr)
+    , mDisplayNoneMap(nullptr)
+    , mDisplayContentsMap(nullptr)
+    , mIsDestroyingFrames(false)
+  {
     MOZ_ASSERT(mPresShell, "need a pres shell");
   }
   ~nsFrameManager();
 
+  bool IsDestroyingFrames() const { return mIsDestroyingFrames; }
+
+  /*
+   * Gets and sets the root frame (typically the viewport). The lifetime of the
+   * root frame is controlled by the frame manager. When the frame manager is
+   * destroyed, it destroys the entire frame hierarchy.
+   */
+  nsIFrame* GetRootFrame() const { return mRootFrame; }
+  void SetRootFrame(nsIFrame* aRootFrame)
+  {
+    NS_ASSERTION(!mRootFrame, "already have a root frame");
+    mRootFrame = aRootFrame;
+  }
+
   /*
    * After Destroy is called, it is an error to call any FrameManager methods.
    * Destroy should be called when the frame tree managed by the frame
    * manager is no longer being displayed.
    */
   void Destroy();
 
 
@@ -199,29 +200,36 @@ public:
 
   void RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState);
 
   void DestroyAnonymousContent(already_AddRefed<nsIContent> aContent);
 
   void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;
 
 protected:
+  class UndisplayedMap;
+
   static nsIContent* ParentForUndisplayedMap(const nsIContent* aContent);
 
   void ClearAllMapsFor(nsIContent* aParentContent);
 
   static nsStyleContext* GetStyleContextInMap(UndisplayedMap* aMap,
                                               const nsIContent* aContent);
-  static mozilla::UndisplayedNode*
-    GetUndisplayedNodeInMapFor(UndisplayedMap* aMap,
-                               const nsIContent* aContent);
-  static mozilla::UndisplayedNode*
-    GetAllUndisplayedNodesInMapFor(UndisplayedMap* aMap,
-                                   nsIContent* aParentContent);
+  static UndisplayedNode* GetUndisplayedNodeInMapFor(UndisplayedMap* aMap,
+                                                     const nsIContent* aContent);
+  static UndisplayedNode* GetAllUndisplayedNodesInMapFor(UndisplayedMap* aMap,
+                                                         nsIContent* aParentContent);
   static void SetStyleContextInMap(UndisplayedMap* aMap,
                                    nsIContent* aContent,
                                    nsStyleContext* aStyleContext);
   static void ChangeStyleContextInMap(UndisplayedMap* aMap,
                                       nsIContent* aContent,
                                       nsStyleContext* aStyleContext);
+
+  // weak link, because the pres shell owns us
+  nsIPresShell* MOZ_NON_OWNING_REF mPresShell;
+  nsIFrame* mRootFrame;
+  UndisplayedMap* mDisplayNoneMap;
+  UndisplayedMap* mDisplayContentsMap;
+  bool mIsDestroyingFrames;  // The frame manager is destroying some frame(s).
 };
 
 #endif
deleted file mode 100644
--- a/layout/base/nsFrameManagerBase.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* part of nsFrameManager, to work around header inclusionordering */
-
-#ifndef _nsFrameManagerBase_h_
-#define _nsFrameManagerBase_h_
-
-#include "nsDebug.h"
-#include "PLDHashTable.h"
-#include "mozilla/Attributes.h"
-
-class nsIFrame;
-class nsIPresShell;
-
-class nsFrameManagerBase
-{
-public:
-  nsFrameManagerBase();
-
-  bool IsDestroyingFrames() { return mIsDestroyingFrames; }
-
-  /*
-   * Gets and sets the root frame (typically the viewport). The lifetime of the
-   * root frame is controlled by the frame manager. When the frame manager is
-   * destroyed, it destroys the entire frame hierarchy.
-   */
-  nsIFrame* GetRootFrame() const { return mRootFrame; }
-  void      SetRootFrame(nsIFrame* aRootFrame)
-  {
-    NS_ASSERTION(!mRootFrame, "already have a root frame");
-    mRootFrame = aRootFrame;
-  }
-
-protected:
-  class UndisplayedMap;
-
-  // weak link, because the pres shell owns us
-  nsIPresShell* MOZ_NON_OWNING_REF mPresShell;
-  nsIFrame*                       mRootFrame;
-  UndisplayedMap*                 mDisplayNoneMap;
-  UndisplayedMap*                 mDisplayContentsMap;
-  bool                            mIsDestroyingFrames;  // The frame manager is destroying some frame(s).
-};
-
-#endif
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -23,17 +23,17 @@
 #include "nsHashKeys.h"
 #include "nsISupports.h"
 #include "nsIContent.h"
 #include "nsISelectionController.h"
 #include "nsQueryFrame.h"
 #include "nsStringFwd.h"
 #include "nsCoord.h"
 #include "nsColor.h"
-#include "nsFrameManagerBase.h"
+#include "nsFrameManager.h"
 #include "nsRect.h"
 #include "nsRegionFwd.h"
 #include "nsWeakReference.h"
 #include <stdio.h> // for FILE definition
 #include "nsChangeHint.h"
 #include "nsRefPtrHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsPresArena.h"
@@ -277,22 +277,17 @@ public:
     mDocAccessible = aDocAccessible;
   }
 #endif
 
   mozilla::StyleSetHandle StyleSet() const { return mStyleSet; }
 
   nsCSSFrameConstructor* FrameConstructor() const { return mFrameConstructor; }
 
-  nsFrameManager* FrameManager() const {
-    // reinterpret_cast is valid since nsFrameManager does not add
-    // any members over nsFrameManagerBase.
-    return reinterpret_cast<nsFrameManager*>
-                           (const_cast<nsIPresShell*>(this)->mFrameManager);
-  }
+  nsFrameManager* FrameManager() const { return mFrameManager; }
 
   /* Enable/disable author style level. Disabling author style disables the entire
    * author level of the cascade, including the HTML preshint level.
    */
   // XXX these could easily be inlined, but there is a circular #include
   // problem with nsStyleSet.
   void SetAuthorStyleDisabled(bool aDisabled);
   bool GetAuthorStyleDisabled() const;
@@ -1669,19 +1664,19 @@ protected:
   // we must share ownership.
   nsCOMPtr<nsIDocument>     mDocument;
   RefPtr<nsPresContext>   mPresContext;
   mozilla::StyleSetHandle   mStyleSet;      // [OWNS]
   nsCSSFrameConstructor*    mFrameConstructor; // [OWNS]
   nsViewManager*           mViewManager;   // [WEAK] docViewer owns it so I don't have to
   nsPresArena               mFrameArena;
   RefPtr<nsFrameSelection> mSelection;
-  // Pointer into mFrameConstructor - this is purely so that FrameManager() and
-  // GetRootFrame() can be inlined:
-  nsFrameManagerBase*       mFrameManager;
+  // Pointer into mFrameConstructor - this is purely so that GetRootFrame() can
+  // be inlined:
+  nsFrameManager*       mFrameManager;
   mozilla::WeakPtr<nsDocShell>                 mForwardingContainer;
 #ifdef ACCESSIBILITY
   mozilla::a11y::DocAccessible* mDocAccessible;
 #endif
 
   // At least on Win32 and Mac after interupting a reflow we need to post
   // the resume reflow event off a timer to avoid event starvation because
   // posted messages are processed before other messages when the modal