Changeset 103030 in webkit
- Timestamp:
- Dec 15, 2011 11:14:30 PM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 1 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r103027 r103030 1 2011-12-15 Yongjun Zhang <yongjun_zhang@apple.com> 2 3 PODIntervalTree takes 1.7MB memory on www.nytimes.com. 4 https://bugs.webkit.org/show_bug.cgi?id=73712 5 6 Reviewed by Kenneth Russell. 7 8 For a RenderBlock which has floating objects inside, we will create a PODIntervalTree and a PODArena with 9 at least one 16KB chunk. A page could have a large number of such RenderBlocks and they could take huge 10 amount of memory. To fix that, we can create a shared PODArena in the root RenderView. Instead of having 11 their own PODArena, each RenderBlock with floating objects could share this PODArena to reduce memory consumption. 12 13 The shared PODArena could grow unboundedly if we keep removing and adding floating objects. We can fix that 14 by reusing the freed memory in each chunk. However, a PODArena could allocate objects of different sizes and 15 it would be complex to keep track of the size for each allocation in PODArena. To address that, this patch 16 added class PODFreeListArena<T> which only allocates objects of type T (hence the same size). We can then use a 17 free list to track freed nodes inside the chunk and reuse the free nodes in future allocations. 18 19 Manually tested on nytimes.com and the heap consumption of PODIntervalTree reduced from 1.7MB to 16KB. Performance 20 doesn't regress on test PerformanceTests/Layout/floats.html. 21 22 * WebCore.xcodeproj/project.pbxproj: add new header file PODFreeListArena.h. 23 * platform/PODArena.h: 24 (WebCore::PODArena::~PODArena): change dtor to virtual. 25 (WebCore::PODArena::Chunk::~Chunk): ditto. 26 * platform/PODFreeListArena.h: Added. 27 (WebCore::PODFreeListArena::create): 28 (WebCore::PODFreeListArena::allocateObject): allocate an object. 29 (WebCore::PODFreeListArena::freeObject): free an object, find the right chunk and update its free list. 30 (WebCore::PODFreeListArena::allocate): allocate memory from the free list or current chunk. 31 (WebCore::PODFreeListArena::FreeListChunk::FreeListChunk): add m_freeList to track freed cells. 32 (WebCore::PODFreeListArena::FreeListChunk::allocate): reuse a free cell if there is one. 33 (WebCore::PODFreeListArena::FreeListChunk::free): make the memory taken by this object is free, and link it to m_freeList. 34 (WebCore::PODFreeListArena::FreeListChunk::contains): check if a pointer is inside this chunk. 35 (WebCore::PODFreeListArena::FreeListChunk::hasFreeList): check if this chunk has free cells. 36 * platform/PODRedBlackTree.h: 37 (WebCore::PODRedBlackTree::PODRedBlackTree): take PODFreeListArena instead of PODArena, since nodes of a particular PODRedBlackTree 38 is always of the same size. 39 (WebCore::PODRedBlackTree::clear): mark all nodes before clearing the tree. 40 (WebCore::PODRedBlackTree::initIfNeeded): add initIfNeeded to take an external PODFreeListArena. 41 (WebCore::PODRedBlackTree::add): 42 (WebCore::PODRedBlackTree::deleteNode): mark the node free in arena after it is removed from the tree. 43 (WebCore::PODRedBlackTree::markFree): mark all node free in the tree. 44 * rendering/RenderBlock.cpp: 45 (WebCore::RenderBlock::insertFloatingObject): 46 (WebCore::RenderBlock::addOverhangingFloats): 47 (WebCore::RenderBlock::addIntrudingFloats): 48 (WebCore::RenderBlock::FloatingObjects::computePlacedFloatsTree): passing the shared PODFreeListArena to m_placedFloatsTree. 49 * rendering/RenderBlock.h: 50 (WebCore::RenderBlock::FloatingObjects::FloatingObjects): 51 * rendering/RenderView.cpp: 52 (WebCore::RenderView::intervalArena): create the shared PODFreeListArena lazily. 53 * rendering/RenderView.h: 54 1 55 2011-12-15 Tony Chang <tony@chromium.org> 2 56 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r103007 r103030 643 643 1F3C3BEA135CAF3C00B8C1AC /* MediaControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F3C3BE8135CAF3C00B8C1AC /* MediaControls.cpp */; }; 644 644 1F3C3BEB135CAF3C00B8C1AC /* MediaControls.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F3C3BE9135CAF3C00B8C1AC /* MediaControls.h */; }; 645 1F3F19531499CA7600A5AEA7 /* PODFreeListArena.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F3F19521499CA7600A5AEA7 /* PODFreeListArena.h */; settings = {ATTRIBUTES = (Private, ); }; }; 645 646 20D629261253690B00081543 /* InspectorInstrumentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 20D629241253690B00081543 /* InspectorInstrumentation.cpp */; }; 646 647 20D629271253690B00081543 /* InspectorInstrumentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 20D629251253690B00081543 /* InspectorInstrumentation.h */; }; … … 7779 7780 1F3C3BE8135CAF3C00B8C1AC /* MediaControls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaControls.cpp; sourceTree = "<group>"; }; 7780 7781 1F3C3BE9135CAF3C00B8C1AC /* MediaControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaControls.h; sourceTree = "<group>"; }; 7782 1F3F19521499CA7600A5AEA7 /* PODFreeListArena.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PODFreeListArena.h; sourceTree = "<group>"; }; 7781 7783 20D629241253690B00081543 /* InspectorInstrumentation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorInstrumentation.cpp; sourceTree = "<group>"; }; 7782 7784 20D629251253690B00081543 /* InspectorInstrumentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInstrumentation.h; sourceTree = "<group>"; }; … … 20256 20258 935C476A09AC4D4F00A6AAB4 /* PlatformWheelEvent.h */, 20257 20259 BCBB8AB413F1AFB000734DF0 /* PODArena.h */, 20260 1F3F19521499CA7600A5AEA7 /* PODFreeListArena.h */, 20258 20261 BCBB8AB513F1AFB000734DF0 /* PODInterval.h */, 20259 20262 BCBB8AB613F1AFB000734DF0 /* PODIntervalTree.h */, … … 24875 24878 0F580FA31496939100FB5BD8 /* WebTileCacheLayer.h in Headers */, 24876 24879 0F580FAF149800D400FB5BD8 /* AnimationUtilities.h in Headers */, 24880 1F3F19531499CA7600A5AEA7 /* PODFreeListArena.h in Headers */, 24877 24881 49ECEB681499790D00CDD3A4 /* FECompositeArithmeticNEON.h in Headers */, 24878 24882 49ECEB6A1499790D00CDD3A4 /* FEGaussianBlurNEON.h in Headers */, -
trunk/Source/WebCore/platform/PODArena.h
r95901 r103030 113 113 114 114 protected: 115 ~PODArena() { }115 virtual ~PODArena() { } 116 116 friend class WTF::RefCounted<PODArena>; 117 117 118 private:119 118 PODArena() 120 119 : m_allocator(FastMallocAllocator::create()) … … 174 173 // Frees the memory allocated from the Allocator in the 175 174 // constructor. 176 ~Chunk()175 virtual ~Chunk() 177 176 { 178 177 m_allocator->free(m_base); … … 195 194 } 196 195 197 pr ivate:196 protected: 198 197 Allocator* m_allocator; 199 198 uint8_t* m_base; -
trunk/Source/WebCore/platform/PODRedBlackTree.h
r95901 r103030 73 73 #define PODRedBlackTree_h 74 74 75 #include "POD Arena.h"75 #include "PODFreeListArena.h" 76 76 #include <wtf/Assertions.h> 77 77 #include <wtf/Noncopyable.h> … … 98 98 class PODRedBlackTree { 99 99 public: 100 class Node; 101 100 102 // Visitor interface for walking all of the tree's elements. 101 103 class Visitor { … … 120 122 121 123 // Constructs a new red-black tree, allocating temporary objects 122 // from a newly constructed POD Arena.124 // from a newly constructed PODFreeListArena. 123 125 PODRedBlackTree() 124 : m_arena(POD Arena::create())126 : m_arena(PODFreeListArena<Node>::create()) 125 127 , m_root(0) 126 128 , m_needsFullOrderingComparisons(false) … … 133 135 // Constructs a new red-black tree, allocating temporary objects 134 136 // from the given PODArena. 135 explicit PODRedBlackTree(PassRefPtr<POD Arena> arena)137 explicit PODRedBlackTree(PassRefPtr<PODFreeListArena<Node> > arena) 136 138 : m_arena(arena) 137 139 , m_root(0) … … 149 151 void clear() 150 152 { 153 markFree(m_root); 151 154 m_arena = 0; 152 155 m_root = 0; … … 161 164 { 162 165 if (!m_arena) 163 m_arena = PODArena::create(); 166 m_arena = PODFreeListArena<Node>::create(); 167 } 168 169 void initIfNeeded(PODFreeListArena<Node>* arena) 170 { 171 if (!m_arena) 172 m_arena = arena; 164 173 } 165 174 … … 167 176 { 168 177 ASSERT(isInitialized()); 169 Node* node = m_arena-> allocateObject<Node,T>(data);178 Node* node = m_arena->template allocateObject<T>(data); 170 179 insertNode(node); 171 180 } … … 236 245 #endif 237 246 238 protected:239 247 enum Color { 240 248 Red = 1, … … 291 299 }; 292 300 301 protected: 293 302 // Returns the root of the tree, which is needed by some subclasses. 294 303 Node* root() const { return m_root; } … … 691 700 if (y->color() == Black) 692 701 deleteFixup(x, xParent); 702 703 m_arena->freeObject(y); 693 704 } 694 705 … … 701 712 if (node->right()) 702 713 visitInorderImpl(node->right(), visitor); 714 } 715 716 void markFree(Node *node) 717 { 718 if (!node) 719 return; 720 721 if (node->left()) 722 markFree(node->left()); 723 if (node->right()) 724 markFree(node->right()); 725 m_arena->freeObject(node); 703 726 } 704 727 … … 793 816 // Data members 794 817 795 RefPtr<POD Arena> m_arena;818 RefPtr<PODFreeListArena<Node> > m_arena; 796 819 Node* m_root; 797 820 bool m_needsFullOrderingComparisons; -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r103020 r103030 39 39 #include "InlineTextBox.h" 40 40 #include "LayoutRepainter.h" 41 #include "PODFreeListArena.h" 41 42 #include "Page.h" 42 43 #include "PaintInfo.h" … … 3272 3273 // Create the list of special objects if we don't aleady have one 3273 3274 if (!m_floatingObjects) 3274 m_floatingObjects = adoptPtr(new FloatingObjects( isHorizontalWritingMode()));3275 m_floatingObjects = adoptPtr(new FloatingObjects(this, isHorizontalWritingMode())); 3275 3276 else { 3276 3277 // Don't insert the object again if it's already in the list … … 3937 3938 // We create the floating object list lazily. 3938 3939 if (!m_floatingObjects) 3939 m_floatingObjects = adoptPtr(new FloatingObjects( isHorizontalWritingMode()));3940 m_floatingObjects = adoptPtr(new FloatingObjects(this, isHorizontalWritingMode())); 3940 3941 3941 3942 m_floatingObjects->add(floatingObj); … … 4010 4011 // We create the floating object list lazily. 4011 4012 if (!m_floatingObjects) 4012 m_floatingObjects = adoptPtr(new FloatingObjects( isHorizontalWritingMode()));4013 m_floatingObjects = adoptPtr(new FloatingObjects(this, isHorizontalWritingMode())); 4013 4014 m_floatingObjects->add(floatingObj); 4014 4015 } … … 7011 7012 if (m_set.isEmpty()) 7012 7013 return; 7013 m_placedFloatsTree.initIfNeeded( );7014 m_placedFloatsTree.initIfNeeded(m_renderer->view()->intervalArena()); 7014 7015 FloatingObjectSetIterator it = m_set.begin(); 7015 7016 FloatingObjectSetIterator end = m_set.end(); -
trunk/Source/WebCore/rendering/RenderBlock.h
r103020 r103030 917 917 RenderRegion* clampToStartAndEndRegions(RenderRegion*) const; 918 918 919 pr ivate:919 protected: 920 920 struct FloatingObjectHashFunctions { 921 921 static unsigned hash(FloatingObject* key) { return DefaultHash<RenderBox*>::Hash::hash(key->m_renderer); } … … 931 931 typedef PODInterval<int, FloatingObject*> FloatingObjectInterval; 932 932 typedef PODIntervalTree<int, FloatingObject*> FloatingObjectTree; 933 typedef PODFreeListArena<PODRedBlackTree<FloatingObjectInterval>::Node> IntervalArena; 933 934 934 935 template <FloatingObject::Type FloatTypeValue> … … 958 959 class FloatingObjects { 959 960 public: 960 FloatingObjects( bool horizontalWritingMode)961 FloatingObjects(const RenderBlock* renderer, bool horizontalWritingMode) 961 962 : m_placedFloatsTree(UninitializedTree) 962 963 , m_leftObjectsCount(0) … … 964 965 , m_positionedObjectsCount(0) 965 966 , m_horizontalWritingMode(horizontalWritingMode) 967 , m_renderer(renderer) 966 968 { 967 969 } … … 1000 1002 unsigned m_positionedObjectsCount; 1001 1003 bool m_horizontalWritingMode; 1004 const RenderBlock* m_renderer; 1002 1005 }; 1003 1006 OwnPtr<FloatingObjects> m_floatingObjects; -
trunk/Source/WebCore/rendering/RenderView.cpp
r102333 r103030 926 926 } 927 927 928 RenderBlock::IntervalArena* RenderView::intervalArena() 929 { 930 if (!m_intervalArena) 931 m_intervalArena = IntervalArena::create(); 932 return m_intervalArena.get(); 933 } 934 928 935 } // namespace WebCore -
trunk/Source/WebCore/rendering/RenderView.h
r102333 r103030 25 25 #include "FrameView.h" 26 26 #include "LayoutState.h" 27 #include "PODFreeListArena.h" 27 28 #include "RenderBlock.h" 28 29 #include <wtf/ListHashSet.h> … … 193 194 void styleDidChange(StyleDifference, const RenderStyle* oldStyle); 194 195 196 IntervalArena* intervalArena(); 197 195 198 protected: 196 199 virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&, bool* wasFixed = 0) const; … … 235 238 friend class LayoutStateMaintainer; 236 239 friend class LayoutStateDisabler; 237 240 238 241 protected: 239 242 FrameView* m_frameView; … … 279 282 RenderFlowThread* m_currentRenderFlowThread; 280 283 RenderRegion* m_currentRenderRegion; 284 RefPtr<IntervalArena> m_intervalArena; 281 285 }; 282 286 -
trunk/Source/WebKit/chromium/ChangeLog
r103025 r103030 1 2011-12-15 Yongjun Zhang <yongjun_zhang@apple.com> 2 3 PODIntervalTree takes 1.7MB memory on www.nytimes.com. 4 https://bugs.webkit.org/show_bug.cgi?id=73712 5 6 Reviewed by Kenneth Russell. 7 8 Change the test code in chromium port since PODRedBlackTree now takes PODFreeListArena<T> 9 in its constructor. 10 11 * tests/PODRedBlackTreeTest.cpp: 12 (WebCore::TEST): 13 1 14 2011-12-15 Joshua Bell <jsbell@chromium.org> 2 15 -
trunk/Source/WebKit/chromium/tests/PODRedBlackTreeTest.cpp
r95901 r103030 46 46 RefPtr<TrackedAllocator> allocator = TrackedAllocator::create(); 47 47 { 48 RefPtr<PODArena> arena = PODArena::create(allocator); 48 typedef PODFreeListArena<PODRedBlackTree<int>::Node> PODIntegerArena; 49 RefPtr<PODIntegerArena> arena = PODIntegerArena::create(allocator); 49 50 PODRedBlackTree<int> tree(arena); 50 51 int numAdditions = 2 * PODArena::DefaultChunkSize / sizeof(int);
Note: See TracChangeset
for help on using the changeset viewer.