Bug 1404181 - Part 18: Use nsPresArena for the display list builder arena since it supports recycling. r?mstange draft
authorMatt Woodrow <mwoodrow@mozilla.com>, Miko Mynttinen <mikokm@gmail.com>, Timothy Nikkel <tnikkel@gmail.com>
Wed, 18 Oct 2017 16:08:48 +1300
changeset 684529 c36fae7110d8d66ec584d4cc60d4a339b46702d5
parent 684528 9975d8374e55af116261d3e6a84db2281f65555b
child 684530 8b0fcd7c530d56446bfac887db7ca8a5f973ccee
push id85633
push usermwoodrow@mozilla.com
push dateSun, 22 Oct 2017 23:03:02 +0000
reviewersmstange
bugs1404181
milestone58.0a1
Bug 1404181 - Part 18: Use nsPresArena for the display list builder arena since it supports recycling. r?mstange MozReview-Commit-ID: LDzkGnCeU7L
layout/base/nsPresArena.h
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/layout/base/nsPresArena.h
+++ b/layout/base/nsPresArena.h
@@ -8,16 +8,17 @@
 /* arena allocation for the frame tree and closely-related objects */
 
 #ifndef nsPresArena_h___
 #define nsPresArena_h___
 
 #include "mozilla/ArenaAllocator.h"
 #include "mozilla/ArenaObjectID.h"
 #include "mozilla/ArenaRefPtr.h"
+#include "mozilla/Assertions.h"
 #include "mozilla/MemoryChecking.h" // Note: Do not remove this, needed for MOZ_HAVE_MEM_CHECKS below
 #include "mozilla/MemoryReporting.h"
 #include <stdint.h>
 #include "nscore.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
 #include "nsTHashtable.h"
@@ -50,16 +51,25 @@ public:
   {
     return Allocate(aID, aSize);
   }
   void FreeByObjectID(mozilla::ArenaObjectID aID, void* aPtr)
   {
     Free(aID, aPtr);
   }
 
+  void* AllocateByCustomID(uint32_t aID, size_t aSize)
+  {
+    return Allocate(aID, aSize);
+  }
+  void FreeByCustomID(uint32_t aID, void* ptr)
+  {
+    Free(aID, ptr);
+  }
+
   /**
    * Register an ArenaRefPtr to be cleared when this arena is about to
    * be destroyed.
    *
    * (Defined in ArenaRefPtrInlines.h.)
    *
    * @param aPtr The ArenaRefPtr to clear.
    * @param aObjectID The ArenaObjectID value that uniquely identifies
@@ -95,16 +105,22 @@ public:
   void ClearArenaRefPtrs(mozilla::ArenaObjectID aObjectID);
 
   /**
    * Increment nsWindowSizes with sizes of interesting objects allocated in this
    * arena.
    */
   void AddSizeOfExcludingThis(nsWindowSizes& aWindowSizes) const;
 
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  bool DebugContains(void* aPtr) {
+    return mPool.DebugContains(aPtr);
+  }
+#endif
+
 private:
   void* Allocate(uint32_t aCode, size_t aSize);
   void Free(uint32_t aCode, void* aPtr);
 
   inline void ClearArenaRefPtrWithoutDeregistering(
       void* aPtr,
       mozilla::ArenaObjectID aObjectID);
 
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -33,16 +33,17 @@
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsIFrameInlines.h"
 #include "nsThemeConstants.h"
 #include "BorderConsts.h"
 #include "LayerTreeInvalidation.h"
+#include "mozilla/MathAlgorithms.h"
 
 #include "imgIContainer.h"
 #include "BasicLayers.h"
 #include "nsBoxFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "SVGObserverUtils.h"
 #include "nsSVGElement.h"
 #include "nsSVGClipPathFrame.h"
@@ -1444,25 +1445,34 @@ nsDisplayListBuilder::MarkPreserve3DFram
       nsIFrame *child = childFrames.get();
       if (child->Combines3DTransformWithAncestors()) {
         MarkFrameForDisplay(child, aDirtyFrame);
       }
     }
   }
 }
 
+uint32_t gDisplayItemSizes[static_cast<uint32_t>(DisplayItemType::TYPE_MAX)] = { 0 };
+
 void*
 nsDisplayListBuilder::Allocate(size_t aSize, DisplayItemType aType)
 {
-  return mPool.Allocate(aSize);
+  size_t roundedUpSize = RoundUpPow2(aSize);
+  uint_fast8_t type = FloorLog2Size(roundedUpSize);
+
+  MOZ_ASSERT(gDisplayItemSizes[static_cast<uint32_t>(aType)] == type ||
+             gDisplayItemSizes[static_cast<uint32_t>(aType)] == 0);
+  gDisplayItemSizes[static_cast<uint32_t>(aType)] = type;
+  return mPool.AllocateByCustomID(type, roundedUpSize);
 }
 
 void
 nsDisplayListBuilder::Destroy(DisplayItemType aType, void* aPtr)
 {
+  mPool.FreeByCustomID(gDisplayItemSizes[static_cast<uint32_t>(aType)], aPtr);
 }
 
 ActiveScrolledRoot*
 nsDisplayListBuilder::AllocateActiveScrolledRoot(const ActiveScrolledRoot* aParent,
                                                  nsIScrollableFrame* aScrollableFrame)
 {
   RefPtr<ActiveScrolledRoot> asr = ActiveScrolledRoot::CreateASRForFrame(aParent, aScrollableFrame, IsRetainingDisplayList());
   mActiveScrolledRoots.AppendElement(asr);
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -34,16 +34,17 @@
 #include "FrameMetrics.h"
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/gfx/UserData.h"
 #include "mozilla/layers/LayerAttributes.h"
 #include "nsCSSRenderingBorders.h"
+#include "nsPresArena.h"
 #include "nsAutoLayoutPhase.h"
 #include "nsDisplayItemTypes.h"
 
 #include <stdint.h>
 #include "nsTHashtable.h"
 
 #include <stdlib.h>
 #include <algorithm>
@@ -1682,19 +1683,17 @@ private:
     nsIFrame* mFrame;
     uint32_t mUsage;
   };
 
   nsIFrame* const                mReferenceFrame;
   nsIFrame*                      mIgnoreScrollFrame;
   nsDisplayLayerEventRegions*    mLayerEventRegions;
 
-  static const size_t kArenaAlignment =
-      mozilla::tl::Max<NS_ALIGNMENT_OF(void*), NS_ALIGNMENT_OF(double)>::value;
-  mozilla::ArenaAllocator<4096, kArenaAlignment> mPool;
+  nsPresArena mPool;
 
   nsCOMPtr<nsISelection>         mBoundingSelection;
   AutoTArray<PresShellState,8> mPresShellStates;
   AutoTArray<nsIFrame*,400>    mFramesMarkedForDisplay;
   nsClassHashtable<nsPtrHashKey<nsIFrame>, nsTArray<ThemeGeometry>> mThemeGeometries;
   nsDisplayTableItem*            mCurrentTableItem;
   DisplayListClipState           mClipState;
   const ActiveScrolledRoot*      mCurrentActiveScrolledRoot;