2010-12-29 Kenichi Ishibashi <bashi@google.com>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 30 Dec 2010 03:16:05 +0000 (03:16 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 30 Dec 2010 03:16:05 +0000 (03:16 +0000)
        Reviewed by Darin Adler.

        Use a HashMap for m_continuation to save memory
        https://bugs.webkit.org/show_bug.cgi?id=43716

        Saving memory consumption by applying a HashMap convention to
        continuation pointers of RenderInline and RenderBlock classes.

        * rendering/RenderBlock.cpp: Removed m_continuation.
        (WebCore::RenderBlock::RenderBlock):
        (WebCore::RenderBlock::destroy):
        (WebCore::RenderBlock::inlineElementContinuation):
        (WebCore::RenderBlock::blockElementContinuation):
        * rendering/RenderBlock.h: Removed m_continuation.
        * rendering/RenderBoxModelObject.cpp: Added a hash map for continuations.
        (WebCore::RenderBoxModelObject::destroy): Added an assertion.
        (WebCore::RenderBoxModelObject::continuation): Added.
        (WebCore::RenderBoxModelObject::setContinuation): Added.
        * rendering/RenderBoxModelObject.h:
        * rendering/RenderInline.cpp: Removed m_continuation.
        (WebCore::RenderInline::RenderInline):
        (WebCore::RenderInline::destroy):
        (WebCore::RenderInline::inlineElementContinuation):
        * rendering/RenderInline.h: Removed m_continuation.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74775 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderBlock.h
WebCore/rendering/RenderBoxModelObject.cpp
WebCore/rendering/RenderBoxModelObject.h
WebCore/rendering/RenderInline.cpp
WebCore/rendering/RenderInline.h

index 534f492..115159b 100644 (file)
@@ -1,3 +1,30 @@
+2010-12-29  Kenichi Ishibashi  <bashi@google.com>
+
+        Reviewed by Darin Adler.
+
+        Use a HashMap for m_continuation to save memory
+        https://bugs.webkit.org/show_bug.cgi?id=43716
+
+        Saving memory consumption by applying a HashMap convention to
+        continuation pointers of RenderInline and RenderBlock classes.
+
+        * rendering/RenderBlock.cpp: Removed m_continuation.
+        (WebCore::RenderBlock::RenderBlock):
+        (WebCore::RenderBlock::destroy):
+        (WebCore::RenderBlock::inlineElementContinuation):
+        (WebCore::RenderBlock::blockElementContinuation):
+        * rendering/RenderBlock.h: Removed m_continuation.
+        * rendering/RenderBoxModelObject.cpp: Added a hash map for continuations.
+        (WebCore::RenderBoxModelObject::destroy): Added an assertion.
+        (WebCore::RenderBoxModelObject::continuation): Added.
+        (WebCore::RenderBoxModelObject::setContinuation): Added.
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderInline.cpp: Removed m_continuation.
+        (WebCore::RenderInline::RenderInline):
+        (WebCore::RenderInline::destroy):
+        (WebCore::RenderInline::inlineElementContinuation):
+        * rendering/RenderInline.h: Removed m_continuation.
+
 2010-12-27  Amruth Raj  <amruthraj@motorola.com> and Ravi Kasibhatla  <ravi.kasibhatla@motorola.com>
 
         Reviewed by Martin Robinson.
index 9d85744..9c07a6c 100644 (file)
@@ -110,7 +110,6 @@ RenderBlock::RenderBlock(Node* node)
       : RenderBox(node)
       , m_floatingObjects(0)
       , m_positionedObjects(0)
-      , m_continuation(0)
       , m_rareData(0)
       , m_lineHeight(-1)
 {
@@ -154,9 +153,10 @@ void RenderBlock::destroy()
     // Destroy our continuation before anything other than anonymous children.
     // The reason we don't destroy it before anonymous children is that they may
     // have continuations of their own that are anonymous children of our continuation.
-    if (m_continuation) {
-        m_continuation->destroy();
-        m_continuation = 0;
+    RenderBoxModelObject* continuation = this->continuation();
+    if (continuation) {
+        continuation->destroy();
+        setContinuation(0);
     }
     
     if (!documentBeingDestroyed()) {
@@ -2517,14 +2517,16 @@ void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
 
 RenderInline* RenderBlock::inlineElementContinuation() const
 { 
-    return m_continuation && m_continuation->isInline() ? toRenderInline(m_continuation) : 0;
+    RenderBoxModelObject* continuation = this->continuation();
+    return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
 }
 
 RenderBlock* RenderBlock::blockElementContinuation() const
 {
-    if (!m_continuation || m_continuation->isInline())
+    RenderBoxModelObject* currentContinuation = continuation();
+    if (!currentContinuation || currentContinuation->isInline())
         return 0;
-    RenderBlock* nextContinuation = toRenderBlock(m_continuation);
+    RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
     if (nextContinuation->isAnonymousBlock())
         return nextContinuation->blockElementContinuation();
     return nextContinuation;
index 5294ad4..bd8be2c 100644 (file)
@@ -128,13 +128,14 @@ public:
 
     void addContinuationWithOutline(RenderInline*);
 
-    RenderBoxModelObject* continuation() const { return m_continuation; }
-    void setContinuation(RenderBoxModelObject* c) { m_continuation = c; }
     virtual RenderBoxModelObject* virtualContinuation() const { return continuation(); }
     bool isAnonymousBlockContinuation() const { return continuation() && isAnonymousBlock(); }
     RenderInline* inlineElementContinuation() const;
     RenderBlock* blockElementContinuation() const;
 
+    using RenderBoxModelObject::continuation;
+    using RenderBoxModelObject::setContinuation;
+
     // This function is a convenience helper for creating an anonymous block that inherits its
     // style from this RenderBlock.
     RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const;
@@ -674,12 +675,6 @@ private:
     
     PositionedObjectsListHashSet* m_positionedObjects;
 
-    // An inline can be split with blocks occurring in between the inline content.
-    // When this occurs we need a pointer to our next object.  We can basically be
-    // split into a sequence of inlines and blocks.  The continuation will either be
-    // an anonymous block (that houses other blocks) or it will be an inline flow.
-    RenderBoxModelObject* m_continuation;
-    
     // Allocated only when some of these fields have non-default values
     struct RenderBlockRareData : Noncopyable {
         RenderBlockRareData(const RenderBlock* block) 
index d5fb13e..5098306 100644 (file)
@@ -53,6 +53,16 @@ static const double cLowQualityTimeThreshold = 0.500; // 500 ms
 typedef pair<RenderBoxModelObject*, const void*> LastPaintSizeMapKey;
 typedef HashMap<LastPaintSizeMapKey, IntSize> LastPaintSizeMap;
 
+// The HashMap for storing continuation pointers.
+// An inline can be split with blocks occuring in between the inline content.
+// When this occurs we need a pointer to the next object. We can basically be
+// split into a sequence of inlines and blocks. The continuation will either be
+// an anonymous block (that houses other blocks) or it will be an inline flow.
+// <b><i><p>Hello</p></i></b>. In this example the <i> will have a block as
+// its continuation but the <b> will just have an inline as its continuation.
+typedef HashMap<const RenderBoxModelObject*, RenderBoxModelObject*> ContinuationMap;
+static ContinuationMap* continuationMap = 0;
+
 class ImageQualityController : public Noncopyable {
 public:
     ImageQualityController();
@@ -229,6 +239,9 @@ void RenderBoxModelObject::destroy()
     if (m_layer)
         m_layer->clearClipRects();
 
+    // A continuation of this RenderObject should be destroyed at subclasses.
+    ASSERT(!continuation());
+
     // RenderObject::destroy calls back to destroyLayer() for layer destruction
     RenderObject::destroy();
 }
@@ -1823,4 +1836,23 @@ int RenderBoxModelObject::containingBlockLogicalWidthForContent() const
     return containingBlock()->availableLogicalWidth();
 }
 
+RenderBoxModelObject* RenderBoxModelObject::continuation() const
+{
+    if (!continuationMap)
+        return 0;
+    return continuationMap->get(this);
+}
+
+void RenderBoxModelObject::setContinuation(RenderBoxModelObject* continuation)
+{
+    if (continuation) {
+        if (!continuationMap)
+            continuationMap = new ContinuationMap;
+        continuationMap->set(this, continuation);
+    } else {
+        if (continuationMap)
+            continuationMap->remove(this);
+    }
+}
+
 } // namespace WebCore
index b697217..98e386b 100644 (file)
@@ -125,6 +125,9 @@ protected:
 
     bool shouldPaintAtLowQuality(GraphicsContext*, Image*, const void*, const IntSize&);
 
+    RenderBoxModelObject* continuation() const;
+    void setContinuation(RenderBoxModelObject*);
+
 private:
     virtual bool isBoxModelObject() const { return true; }
 
index 4b5298c..7466ace 100644 (file)
@@ -46,7 +46,6 @@ namespace WebCore {
 
 RenderInline::RenderInline(Node* node)
     : RenderBoxModelObject(node)
-    , m_continuation(0)
     , m_lineHeight(-1)
 {
     setChildrenInline(true);
@@ -61,9 +60,10 @@ void RenderInline::destroy()
     // Destroy our continuation before anything other than anonymous children.
     // The reason we don't destroy it before anonymous children is that they may
     // have continuations of their own that are anonymous children of our continuation.
-    if (m_continuation) {
-        m_continuation->destroy();
-        m_continuation = 0;
+    RenderBoxModelObject* continuation = this->continuation();
+    if (continuation) {
+        continuation->destroy();
+        setContinuation(0);
     }
     
     if (!documentBeingDestroyed()) {
@@ -95,9 +95,10 @@ void RenderInline::destroy()
 
 RenderInline* RenderInline::inlineElementContinuation() const
 {
-    if (!m_continuation || m_continuation->isInline())
-        return toRenderInline(m_continuation);
-    return toRenderBlock(m_continuation)->inlineElementContinuation();
+    RenderBoxModelObject* continuation = this->continuation();
+    if (!continuation || continuation->isInline())
+        return toRenderInline(continuation);
+    return toRenderBlock(continuation)->inlineElementContinuation();
 }
 
 void RenderInline::updateBoxModelInfoFromStyle()
index f6f3908..18b4a3c 100644 (file)
@@ -65,8 +65,6 @@ public:
     InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
     InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
 
-    RenderBoxModelObject* continuation() const { return m_continuation; }
-    void setContinuation(RenderBoxModelObject* c) { m_continuation = c; }
     virtual RenderBoxModelObject* virtualContinuation() const { return continuation(); }
     RenderInline* inlineElementContinuation() const;
 
@@ -77,6 +75,9 @@ public:
     virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
     void paintOutline(GraphicsContext*, int tx, int ty);
 
+    using RenderBoxModelObject::continuation;
+    using RenderBoxModelObject::setContinuation;
+
 protected:
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
@@ -153,8 +154,6 @@ private:
     RenderObjectChildList m_children;
     RenderLineBoxList m_lineBoxes;   // All of the line boxes created for this inline flow.  For example, <i>Hello<br>world.</i> will have two <i> line boxes.
 
-    RenderBoxModelObject* m_continuation; // Can be either a block or an inline. <b><i><p>Hello</p></i></b>. In this example the <i> will have a block as its continuation but the
-                                          // <b> will just have an inline as its continuation.
     mutable int m_lineHeight;
 };