Title: [184885] trunk
Revision
184885
Author
za...@apple.com
Date
2015-05-26 15:59:40 -0700 (Tue, 26 May 2015)

Log Message

Overhanging float sets are not cleaned up properly when floating renderer is destroyed.
https://bugs.webkit.org/show_bug.cgi?id=145323
rdar://problem/20980628

Reviewed by Dave Hyatt.

This patch ensures when an overhanging float renderer is destroyed,
all the sibling containers' floating object set(m_floatingObjects) gets properly cleaned up.

When an overhanging float is present, we cache the renderer on the parent and on the affected
sibling containers too. (RenderBlockFlow::m_floatingObjects) These caches(sets) get cleared and repopulated
during ::layout(). In order to have a float renderer removed from a set, a layout needs to be initiated on the container.
This is normally done through RenderBlockFlow::markSiblingsWithFloatsForLayout() and RenderBlockFlow::markAllDescendantsWithFloatsForLayout().
However, when the float container's parent's writing direction changes (and we promote the children containers to new formatting contexts),
the layout propagation through siblings does not work anymore.

The avoidsFloats() check in RenderBlockFlow::markSiblingsWithFloatsForLayout() has very little performance gain, but it prevents us
from propagating layout to siblings when certain properties of the parent container changes.

Source/WebCore:

Test: fast/block/float/crash-when-floating-object-is-removed.xhtml

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::markSiblingsWithFloatsForLayout):
* rendering/RenderBox.cpp:
(WebCore::outermostBlockContainingFloatingObject):
(WebCore::RenderBox::removeFloatingOrPositionedChildFromBlockLists):
(WebCore::RenderBox::outermostBlockContainingFloatingObject): Deleted.
* rendering/RenderBox.h:

LayoutTests:

* fast/block/float/crash-when-floating-object-is-removed-expected.txt: Added.
* fast/block/float/crash-when-floating-object-is-removed.xhtml: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (184884 => 184885)


--- trunk/LayoutTests/ChangeLog	2015-05-26 22:59:38 UTC (rev 184884)
+++ trunk/LayoutTests/ChangeLog	2015-05-26 22:59:40 UTC (rev 184885)
@@ -1,3 +1,27 @@
+2015-05-26  Zalan Bujtas  <za...@apple.com>
+
+        Overhanging float sets are not cleaned up properly when floating renderer is destroyed.
+        https://bugs.webkit.org/show_bug.cgi?id=145323
+        rdar://problem/20980628
+
+        Reviewed by Dave Hyatt.
+
+        This patch ensures when an overhanging float renderer is destroyed,
+        all the sibling containers' floating object set(m_floatingObjects) gets properly cleaned up.
+
+        When an overhanging float is present, we cache the renderer on the parent and on the affected
+        sibling containers too. (RenderBlockFlow::m_floatingObjects) These caches(sets) get cleared and repopulated
+        during ::layout(). In order to have a float renderer removed from a set, a layout needs to be initiated on the container.
+        This is normally done through RenderBlockFlow::markSiblingsWithFloatsForLayout() and RenderBlockFlow::markAllDescendantsWithFloatsForLayout().
+        However, when the float container's parent's writing direction changes (and we promote the children containers to new formatting contexts),
+        the layout propagation through siblings does not work anymore.
+
+        The avoidsFloats() check in RenderBlockFlow::markSiblingsWithFloatsForLayout() has very little performance gain, but it prevents us
+        from propagating layout to siblings when certain properties of the parent container changes.
+
+        * fast/block/float/crash-when-floating-object-is-removed-expected.txt: Added.
+        * fast/block/float/crash-when-floating-object-is-removed.xhtml: Added.
+
 2015-05-26  Beth Dakin  <bda...@apple.com>
 
         storage/indexeddb/deleteIndex-bug110792.html is flaky

Added: trunk/LayoutTests/fast/block/float/crash-when-floating-object-is-removed-expected.txt (0 => 184885)


--- trunk/LayoutTests/fast/block/float/crash-when-floating-object-is-removed-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/crash-when-floating-object-is-removed-expected.txt	2015-05-26 22:59:40 UTC (rev 184885)
@@ -0,0 +1 @@
+ PASS if no crash or ASSERT in debug.

Added: trunk/LayoutTests/fast/block/float/crash-when-floating-object-is-removed.xhtml (0 => 184885)


--- trunk/LayoutTests/fast/block/float/crash-when-floating-object-is-removed.xhtml	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/crash-when-floating-object-is-removed.xhtml	2015-05-26 22:59:40 UTC (rev 184885)
@@ -0,0 +1,45 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>This tests that sets for overhanging floating objects are cleaned up properly when the floating object is destroyed.</title>
+<script>
+  if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+<style>
+  html {
+    position: absolute;
+  }
+  
+  .float { 
+    float: left; 
+  }
+</style>
+</head>
+<head id="head1" style="-webkit-writing-mode: horizontal-bt;"></head>
+
+<i>
+  <button id="button1">PASS if no crash or ASSERT in debug.</button>
+</i>
+<td id="td1">
+  <body></body>
+</td>
+<i></i>
+
+<script>
+var docElement = document.documentElement;
+function crash() {
+    button1 = document.getElementById("button1");
+    button1.classList.toggle("float");
+
+    head1 = document.getElementById("head1");
+    td1 = document.getElementById("td1");
+    head1.appendChild(td1);
+
+    docElement.offsetTop;
+    head1.style.display = "list-item";
+    docElement.offsetTop;
+    button1.classList.toggle("float");
+}
+document.addEventListener("DOMContentLoaded", crash, false);
+</script>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (184884 => 184885)


--- trunk/Source/WebCore/ChangeLog	2015-05-26 22:59:38 UTC (rev 184884)
+++ trunk/Source/WebCore/ChangeLog	2015-05-26 22:59:40 UTC (rev 184885)
@@ -1,3 +1,34 @@
+2015-05-26  Zalan Bujtas  <za...@apple.com>
+
+        Overhanging float sets are not cleaned up properly when floating renderer is destroyed.
+        https://bugs.webkit.org/show_bug.cgi?id=145323
+        rdar://problem/20980628
+
+        Reviewed by Dave Hyatt.
+
+        This patch ensures when an overhanging float renderer is destroyed,
+        all the sibling containers' floating object set(m_floatingObjects) gets properly cleaned up.
+
+        When an overhanging float is present, we cache the renderer on the parent and on the affected
+        sibling containers too. (RenderBlockFlow::m_floatingObjects) These caches(sets) get cleared and repopulated
+        during ::layout(). In order to have a float renderer removed from a set, a layout needs to be initiated on the container.
+        This is normally done through RenderBlockFlow::markSiblingsWithFloatsForLayout() and RenderBlockFlow::markAllDescendantsWithFloatsForLayout().
+        However, when the float container's parent's writing direction changes (and we promote the children containers to new formatting contexts),
+        the layout propagation through siblings does not work anymore.
+
+        The avoidsFloats() check in RenderBlockFlow::markSiblingsWithFloatsForLayout() has very little performance gain, but it prevents us
+        from propagating layout to siblings when certain properties of the parent container changes.
+
+        Test: fast/block/float/crash-when-floating-object-is-removed.xhtml
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::markSiblingsWithFloatsForLayout):
+        * rendering/RenderBox.cpp:
+        (WebCore::outermostBlockContainingFloatingObject):
+        (WebCore::RenderBox::removeFloatingOrPositionedChildFromBlockLists):
+        (WebCore::RenderBox::outermostBlockContainingFloatingObject): Deleted.
+        * rendering/RenderBox.h:
+
 2015-05-26  Ryuan Choi  <ryuan.c...@navercorp.com>
 
         [EFL][CoordinatedGraphics] Remove CoordinatedTileClient and CoordinatedTileBackend

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (184884 => 184885)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2015-05-26 22:59:38 UTC (rev 184884)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2015-05-26 22:59:40 UTC (rev 184885)
@@ -2760,7 +2760,7 @@
     auto end = floatingObjectSet.end();
 
     for (RenderObject* next = nextSibling(); next; next = next->nextSibling()) {
-        if (!is<RenderBlockFlow>(*next) || next->isFloatingOrOutOfFlowPositioned() || downcast<RenderBlockFlow>(*next).avoidsFloats())
+        if (!is<RenderBlockFlow>(*next) || next->isFloatingOrOutOfFlowPositioned())
             continue;
 
         RenderBlockFlow& nextBlock = downcast<RenderBlockFlow>(*next);

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (184884 => 184885)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2015-05-26 22:59:38 UTC (rev 184884)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2015-05-26 22:59:40 UTC (rev 184885)
@@ -264,14 +264,14 @@
     return LayoutRect(0, logicalLeft, width(), logicalWidth);
 }
 
-RenderBlockFlow* RenderBox::outermostBlockContainingFloatingObject()
+static RenderBlockFlow* outermostBlockContainingFloatingObject(RenderBox& box)
 {
-    ASSERT(isFloating());
+    ASSERT(box.isFloating());
     RenderBlockFlow* parentBlock = nullptr;
-    for (auto& ancestor : ancestorsOfType<RenderBlockFlow>(*this)) {
+    for (auto& ancestor : ancestorsOfType<RenderBlockFlow>(box)) {
         if (ancestor.isRenderView())
             break;
-        if (!parentBlock || ancestor.containsFloat(*this))
+        if (!parentBlock || ancestor.containsFloat(box))
             parentBlock = &ancestor;
     }
     return parentBlock;
@@ -285,7 +285,7 @@
         return;
 
     if (isFloating()) {
-        if (RenderBlockFlow* parentBlock = outermostBlockContainingFloatingObject()) {
+        if (RenderBlockFlow* parentBlock = outermostBlockContainingFloatingObject(*this)) {
             parentBlock->markSiblingsWithFloatsForLayout(this);
             parentBlock->markAllDescendantsWithFloatsForLayout(this, false);
         }

Modified: trunk/Source/WebCore/rendering/RenderBox.h (184884 => 184885)


--- trunk/Source/WebCore/rendering/RenderBox.h	2015-05-26 22:59:38 UTC (rev 184884)
+++ trunk/Source/WebCore/rendering/RenderBox.h	2015-05-26 22:59:40 UTC (rev 184885)
@@ -518,8 +518,6 @@
 
     virtual VisiblePosition positionForPoint(const LayoutPoint&, const RenderRegion*) override;
 
-    RenderBlockFlow* outermostBlockContainingFloatingObject();
-
     void removeFloatingOrPositionedChildFromBlockLists();
     
     RenderLayer* enclosingFloatPaintingLayer() const;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to