Bug 1374112 part 2 - Introduce nsCSSFrameConstructor::AllocateFCItem/FreeFCItem for allocating FrameConstructionItems from an arena/free list. r=dholbert
authorMats Palmgren <mats@mozilla.com>
Mon, 11 Sep 2017 00:27:12 +0200
changeset 429502 8bc4d3b25dfb1f7092b6bfd471ff94f88e2ca573
parent 429501 7ee14a111f8cc625e3f23516b7f7af15de66407b
child 429503 9dcca3ac0aaa19800a3f0c6a7c4ead1d9dfa14d8
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1374112
milestone57.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 1374112 part 2 - Introduce nsCSSFrameConstructor::AllocateFCItem/FreeFCItem for allocating FrameConstructionItems from an arena/free list. r=dholbert MozReview-Commit-ID: 5VVhEQOZMlU
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1604,16 +1604,18 @@ MoveChildrenTo(nsIFrame* aOldParent,
 nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument* aDocument,
                                              nsIPresShell* aPresShell)
   : nsFrameManager(aPresShell)
   , mDocument(aDocument)
   , mRootElementFrame(nullptr)
   , mRootElementStyleFrame(nullptr)
   , mDocElementContainingBlock(nullptr)
   , mPageSequenceFrame(nullptr)
+  , mFirstFreeFCItem(nullptr)
+  , mFCItemsInUse(0)
   , mCurrentDepth(0)
 #ifdef DEBUG
   , mUpdateCount(0)
 #endif
   , mQuotesDirty(false)
   , mCountersDirty(false)
   , mIsDestroyingFrameTree(false)
   , mHasRootAbsPosContainingBlock(false)
@@ -13463,8 +13465,38 @@ nsCSSFrameConstructor::QuotesDirty()
 
 void
 nsCSSFrameConstructor::CountersDirty()
 {
   NS_PRECONDITION(mUpdateCount != 0, "Instant counter updates are bad news");
   mCountersDirty = true;
   mPresShell->SetNeedLayoutFlush();
 }
+
+void*
+nsCSSFrameConstructor::AllocateFCItem()
+{
+  void* item;
+  if (mFirstFreeFCItem) {
+    item = mFirstFreeFCItem;
+    mFirstFreeFCItem = mFirstFreeFCItem->mNext;
+  } else {
+    item = mFCItemPool.Allocate(sizeof(FrameConstructionItem));
+  }
+  ++mFCItemsInUse;
+  return item;
+}
+
+void
+nsCSSFrameConstructor::FreeFCItem(FrameConstructionItem* aItem)
+{
+  MOZ_ASSERT(mFCItemsInUse != 0);
+  if (--mFCItemsInUse == 0) {
+    // The arena is now unused - clear it but retain one chunk.
+    mFirstFreeFCItem = nullptr;
+    mFCItemPool.Clear();
+  } else {
+    // Prepend it to the list of free items.
+    FreeFCItemLink* item = reinterpret_cast<FreeFCItemLink*>(aItem);
+    item->mNext = mFirstFreeFCItem;
+    mFirstFreeFCItem = item;
+  }
+}
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -6,16 +6,17 @@
 /*
  * construction of a frame tree that is nearly isomorphic to the content
  * tree and updating of that tree in response to dynamic changes
  */
 
 #ifndef nsCSSFrameConstructor_h___
 #define nsCSSFrameConstructor_h___
 
+#include "mozilla/ArenaAllocator.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/RestyleManager.h"
 
 #include "nsCOMPtr.h"
 #include "nsILayoutHistoryState.h"
 #include "nsQuoteList.h"
@@ -57,16 +58,17 @@ public:
 
   friend class mozilla::RestyleManager;
   friend class mozilla::GeckoRestyleManager;
   friend class mozilla::ServoRestyleManager;
 
   nsCSSFrameConstructor(nsIDocument* aDocument, nsIPresShell* aPresShell);
   ~nsCSSFrameConstructor() {
     MOZ_ASSERT(mUpdateCount == 0, "Dying in the middle of our own update?");
+    MOZ_ASSERT(mFCItemsInUse == 0);
   }
 
   // get the alternate text for a content node
   static void GetAlternateTextFor(nsIContent* aContent,
                                   nsIAtom* aTag,  // content object's tag
                                   nsAString& aAltText);
 
 private:
@@ -2137,30 +2139,41 @@ private:
                                           nsIFrame* aFrame,
                                           nsIContent* aDocElement);
 
 public:
 
   friend class nsFrameConstructorState;
 
 private:
+  // For allocating FrameConstructionItems from the mFCItemPool arena.
+  friend struct FrameConstructionItem;
+  void* AllocateFCItem();
+  void FreeFCItem(FrameConstructionItem*);
 
   nsIDocument*        mDocument;  // Weak ref
 
   // See the comment at the start of ConstructRootFrame for more details
   // about the following frames.
 
   // This is just the outermost frame for the root element.
   nsContainerFrame*   mRootElementFrame;
   // This is the frame for the root element that has no pseudo-element style.
   nsIFrame*           mRootElementStyleFrame;
   // This is the containing block that contains the root element ---
   // the real "initial containing block" according to CSS 2.1.
   nsContainerFrame*   mDocElementContainingBlock;
   nsIFrame*           mPageSequenceFrame;
+
+  // FrameConstructionItem arena + list of freed items available for re-use.
+  mozilla::ArenaAllocator<4096, 8> mFCItemPool;
+  struct FreeFCItemLink { FreeFCItemLink* mNext; };
+  FreeFCItemLink* mFirstFreeFCItem;
+  size_t mFCItemsInUse;
+
   nsQuoteList         mQuoteList;
   nsCounterManager    mCounterManager;
   // Current ProcessChildren depth.
   uint16_t            mCurrentDepth;
 #ifdef DEBUG
   uint16_t            mUpdateCount;
 #endif
   bool                mQuotesDirty : 1;