Title: [175505] trunk/Source/WebCore
Revision
175505
Author
akl...@apple.com
Date
2014-11-03 18:35:45 -0800 (Mon, 03 Nov 2014)

Log Message

Clarify RenderListMarker ownership model.
<https://webkit.org/b/138329>

Reviewed by Antti Koivisto.

A RenderListMarker is either in-tree and owned by the tree, or out-of-tree
and owned by a RenderListItem.

This patch changes RenderListItem::m_marker to be a raw pointer, and removes
the special handling of list markers in RenderElement child teardown.

We also remove the willBeDestroyed() hook. It was used to clear out the
m_marker pointer, but this is now done in the regular ~RenderListItem()
destructor with an assertion for marker sanity. m_marker is automatically
nulled out by a didDestroyListMarker() callback on RenderListItem.

* rendering/RenderElement.cpp:
(WebCore::RenderElement::destroyLeftoverChildren):

    Removed special handling of list marker renderers when deleting a
    RenderElement's children.

* rendering/RenderListItem.cpp:
(WebCore::RenderListItem::RenderListItem):
(WebCore::RenderListItem::~RenderListItem):
(WebCore::RenderListItem::styleDidChange):
(WebCore::RenderListItem::insertOrMoveMarkerRendererIfNeeded):
(WebCore::RenderListItem::positionListMarker):

    Made m_marker a raw pointer instead of a RenderPtr since the ownership
    really switches between weak and strong reference.

(WebCore::RenderListItem::willBeDestroyed):
* rendering/RenderListMarker.cpp:
(WebCore::RenderListMarker::~RenderListMarker):

    Added a regular destructor to replace the willBeDestroyed() hook.

* rendering/RenderListItem.h:
(WebCore::RenderListItem::didDestroyListMarker):

    Added. Called by ~RenderListMarker to null out RenderListItem::m_marker.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (175504 => 175505)


--- trunk/Source/WebCore/ChangeLog	2014-11-04 02:23:50 UTC (rev 175504)
+++ trunk/Source/WebCore/ChangeLog	2014-11-04 02:35:45 UTC (rev 175505)
@@ -1,3 +1,48 @@
+2014-11-03  Andreas Kling  <akl...@apple.com>
+
+        Clarify RenderListMarker ownership model.
+        <https://webkit.org/b/138329>
+
+        Reviewed by Antti Koivisto.
+
+        A RenderListMarker is either in-tree and owned by the tree, or out-of-tree
+        and owned by a RenderListItem.
+
+        This patch changes RenderListItem::m_marker to be a raw pointer, and removes
+        the special handling of list markers in RenderElement child teardown.
+
+        We also remove the willBeDestroyed() hook. It was used to clear out the
+        m_marker pointer, but this is now done in the regular ~RenderListItem()
+        destructor with an assertion for marker sanity. m_marker is automatically
+        nulled out by a didDestroyListMarker() callback on RenderListItem.
+
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::destroyLeftoverChildren):
+
+            Removed special handling of list marker renderers when deleting a
+            RenderElement's children.
+
+        * rendering/RenderListItem.cpp:
+        (WebCore::RenderListItem::RenderListItem):
+        (WebCore::RenderListItem::~RenderListItem):
+        (WebCore::RenderListItem::styleDidChange):
+        (WebCore::RenderListItem::insertOrMoveMarkerRendererIfNeeded):
+        (WebCore::RenderListItem::positionListMarker):
+
+            Made m_marker a raw pointer instead of a RenderPtr since the ownership
+            really switches between weak and strong reference.
+
+        (WebCore::RenderListItem::willBeDestroyed):
+        * rendering/RenderListMarker.cpp:
+        (WebCore::RenderListMarker::~RenderListMarker):
+
+            Added a regular destructor to replace the willBeDestroyed() hook.
+
+        * rendering/RenderListItem.h:
+        (WebCore::RenderListItem::didDestroyListMarker):
+
+            Added. Called by ~RenderListMarker to null out RenderListItem::m_marker.
+
 2014-11-03  Gyuyoung Kim  <gyuyoung....@samsung.com>
 
         Move WebCore/bridge to std::unique_ptr

Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (175504 => 175505)


--- trunk/Source/WebCore/rendering/RenderElement.cpp	2014-11-04 02:23:50 UTC (rev 175504)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp	2014-11-04 02:35:45 UTC (rev 175505)
@@ -521,8 +521,8 @@
 void RenderElement::destroyLeftoverChildren()
 {
     while (m_firstChild) {
-        if (m_firstChild->isListMarker() || (m_firstChild->style().styleType() == FIRST_LETTER && !m_firstChild->isText())) {
-            m_firstChild->removeFromParent(); // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
+        if (m_firstChild->style().styleType() == FIRST_LETTER && !m_firstChild->isText()) {
+            m_firstChild->removeFromParent(); // :first-letter fragment renderers are destroyed by their remaining text fragment.
         } else {
             // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
             if (m_firstChild->node())

Modified: trunk/Source/WebCore/rendering/RenderListItem.cpp (175504 => 175505)


--- trunk/Source/WebCore/rendering/RenderListItem.cpp	2014-11-04 02:23:50 UTC (rev 175504)
+++ trunk/Source/WebCore/rendering/RenderListItem.cpp	2014-11-04 02:35:45 UTC (rev 175505)
@@ -45,6 +45,7 @@
 
 RenderListItem::RenderListItem(Element& element, PassRef<RenderStyle> style)
     : RenderBlockFlow(element, WTF::move(style))
+    , m_marker(nullptr)
     , m_hasExplicitValue(false)
     , m_isValueUpToDate(false)
     , m_notInList(false)
@@ -52,12 +53,24 @@
     setInline(false);
 }
 
+RenderListItem::~RenderListItem()
+{
+    ASSERT(!m_marker || !m_marker->parent());
+    if (m_marker) {
+        m_marker->destroy();
+        ASSERT(!m_marker);
+    }
+}
+
 void RenderListItem::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 {
     RenderBlockFlow::styleDidChange(diff, oldStyle);
 
     if (style().listStyleType() == NoneListStyle && (!style().listStyleImage() || style().listStyleImage()->errorOccurred())) {
-        m_marker = nullptr;
+        if (m_marker) {
+            m_marker->destroy();
+            ASSERT(!m_marker);
+        }
         return;
     }
 
@@ -66,18 +79,12 @@
     // up (e.g., in some deeply nested line box). See CSS3 spec.
     newStyle.get().inheritFrom(&style());
     if (!m_marker) {
-        m_marker = createRenderer<RenderListMarker>(*this, WTF::move(newStyle));
+        m_marker = createRenderer<RenderListMarker>(*this, WTF::move(newStyle)).leakPtr();
         m_marker->initializeStyle();
     } else
         m_marker->setStyle(WTF::move(newStyle));
 }
 
-void RenderListItem::willBeDestroyed()
-{
-    m_marker = nullptr;
-    RenderBlockFlow::willBeDestroyed();
-}
-
 void RenderListItem::insertedIntoTree()
 {
     RenderBlockFlow::insertedIntoTree();
@@ -273,7 +280,7 @@
         return;
 
     RenderElement* currentParent = m_marker->parent();
-    RenderBlock* newParent = getParentOfFirstLineBox(this, m_marker.get());
+    RenderBlock* newParent = getParentOfFirstLineBox(this, m_marker);
     if (!newParent) {
         // If the marker is currently contained inside an anonymous box,
         // then we are the only item in that anonymous box (since no line box
@@ -292,7 +299,7 @@
         // containers other than ourselves, so we need to disable LayoutState.
         LayoutStateDisabler layoutStateDisabler(&view());
         m_marker->removeFromParent();
-        newParent->addChild(m_marker.get(), firstNonMarkerChild(newParent));
+        newParent->addChild(m_marker, firstNonMarkerChild(newParent));
         m_marker->updateMarginsAndContent();
         // If current parent is an anonymous block that has lost all its children, destroy it.
         if (currentParent && currentParent->isAnonymousBlock() && !currentParent->firstChild() && !downcast<RenderBlock>(*currentParent).continuation())
@@ -400,7 +407,7 @@
             LayoutRect markerRect(markerLogicalLeft + lineOffset, blockOffset, m_marker->width(), m_marker->height());
             if (!style().isHorizontalWritingMode())
                 markerRect = markerRect.transposedRect();
-            RenderBox* o = m_marker.get();
+            RenderBox* o = m_marker;
             bool propagateVisualOverflow = true;
             bool propagateLayoutOverflow = true;
             do {

Modified: trunk/Source/WebCore/rendering/RenderListItem.h (175504 => 175505)


--- trunk/Source/WebCore/rendering/RenderListItem.h	2014-11-04 02:23:50 UTC (rev 175504)
+++ trunk/Source/WebCore/rendering/RenderListItem.h	2014-11-04 02:35:45 UTC (rev 175505)
@@ -34,6 +34,7 @@
 class RenderListItem final : public RenderBlockFlow {
 public:
     RenderListItem(Element&, PassRef<RenderStyle>);
+    virtual ~RenderListItem();
     Element& element() const { return downcast<Element>(nodeForNonAnonymous()); }
 
     int value() const { if (!m_isValueUpToDate) updateValueNow(); return m_value; }
@@ -55,13 +56,13 @@
     static void updateItemValuesForOrderedList(const HTMLOListElement*);
     static unsigned itemCountForOrderedList(const HTMLOListElement*);
 
+    void didDestroyListMarker() { m_marker = nullptr; }
+
 private:
     virtual const char* renderName() const override { return "RenderListItem"; }
 
     virtual bool isListItem() const override { return true; }
     
-    virtual void willBeDestroyed() override;
-
     virtual void insertedIntoTree() override;
     virtual void willBeRemovedFromTree() override;
 
@@ -85,7 +86,7 @@
     void explicitValueChanged();
 
     int m_explicitValue;
-    RenderPtr<RenderListMarker> m_marker;
+    RenderListMarker* m_marker;
     mutable int m_value;
 
     bool m_hasExplicitValue : 1;

Modified: trunk/Source/WebCore/rendering/RenderListMarker.cpp (175504 => 175505)


--- trunk/Source/WebCore/rendering/RenderListMarker.cpp	2014-11-04 02:23:50 UTC (rev 175504)
+++ trunk/Source/WebCore/rendering/RenderListMarker.cpp	2014-11-04 02:35:45 UTC (rev 175505)
@@ -1128,6 +1128,7 @@
 
 RenderListMarker::~RenderListMarker()
 {
+    m_listItem.didDestroyListMarker();
     if (m_image)
         m_image->removeClient(this);
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to