Title: [183576] trunk
Revision
183576
Author
[email protected]
Date
2015-04-29 14:32:07 -0700 (Wed, 29 Apr 2015)

Log Message

Simple line layout: Web process spins endlessly below layoutSimpleLines.
https://bugs.webkit.org/show_bug.cgi?id=144403
rdar://problem/20742783

Reviewed by Antti Koivisto.

When a text fragment overlaps multiple renderes and it does not fit the current line,
we revert the text fragment iterator position so that the overlapping content
gets processed again for the next line.
However, TextFragmentIterator::revertToFragment() was reverting too much and
we started processing old content all over again -> infinite loop.

This patch ensures that text fragment iterator is reverted to the right position.

Source/WebCore:

Test: fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html

* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::createLineRuns):
* rendering/SimpleLineLayoutTextFragmentIterator.cpp:
(WebCore::SimpleLineLayout::TextFragmentIterator::revertToEndOfFragment):
(WebCore::SimpleLineLayout::TextFragmentIterator::revertToFragment): Deleted.
* rendering/SimpleLineLayoutTextFragmentIterator.h:

LayoutTests:

* fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html: Added.
* fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (183575 => 183576)


--- trunk/LayoutTests/ChangeLog	2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/LayoutTests/ChangeLog	2015-04-29 21:32:07 UTC (rev 183576)
@@ -1,3 +1,22 @@
+2015-04-29  Zalan Bujtas  <[email protected]>
+
+        Simple line layout: Web process spins endlessly below layoutSimpleLines.
+        https://bugs.webkit.org/show_bug.cgi?id=144403
+        rdar://problem/20742783
+
+        Reviewed by Antti Koivisto.
+
+        When a text fragment overlaps multiple renderes and it does not fit the current line,
+        we revert the text fragment iterator position so that the overlapping content
+        gets processed again for the next line.
+        However, TextFragmentIterator::revertToFragment() was reverting too much and
+        we started processing old content all over again -> infinite loop.
+
+        This patch ensures that text fragment iterator is reverted to the right position.
+
+        * fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html: Added.
+        * fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html: Added.
+
 2015-04-29  Antti Koivisto  <[email protected]>
 
         Mark newly added http/tests/cache/main-resource-304-reload.html failing on Windows.

Added: trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html (0 => 183576)


--- trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html	2015-04-29 21:32:07 UTC (rev 183576)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple line layout manages text fragments when they overlap multiple renderers.</title>
+<style>
+pre {
+    width: 45px; 
+    word-wrap: break-word;
+    white-space: pre-wrap;
+}
+</style>
+<script>
+    if (window.internals)
+        internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+</head>
+<body>
+The test passes if it does not hang or crash.
+<pre id=container></pre>
+<script>
+    var container = document.getElementById("container");
+    container.appendChild(document.createTextNode("A foo"));			
+    container.appendChild(document.createTextNode("bar foobar"));			
+    document.body.offsetWidth;			
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html (0 => 183576)


--- trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html	2015-04-29 21:32:07 UTC (rev 183576)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple line layout manages text fragments when they overlap multiple renderers.</title>
+<style>
+pre {
+    width: 45px; 
+    word-wrap: break-word;
+    white-space: pre-wrap;
+}
+</style>
+</head>
+<body>
+The test passes if it does not hang or crash.
+<pre id=container></pre>
+<script>
+    var container = document.getElementById("container");
+    container.appendChild(document.createTextNode("A foo"));			
+    container.appendChild(document.createTextNode("bar foobar"));			
+    document.body.offsetWidth;			
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (183575 => 183576)


--- trunk/Source/WebCore/ChangeLog	2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/Source/WebCore/ChangeLog	2015-04-29 21:32:07 UTC (rev 183576)
@@ -1,3 +1,28 @@
+2015-04-29  Zalan Bujtas  <[email protected]>
+
+        Simple line layout: Web process spins endlessly below layoutSimpleLines.
+        https://bugs.webkit.org/show_bug.cgi?id=144403
+        rdar://problem/20742783
+
+        Reviewed by Antti Koivisto.
+
+        When a text fragment overlaps multiple renderes and it does not fit the current line,
+        we revert the text fragment iterator position so that the overlapping content
+        gets processed again for the next line.
+        However, TextFragmentIterator::revertToFragment() was reverting too much and
+        we started processing old content all over again -> infinite loop.
+
+        This patch ensures that text fragment iterator is reverted to the right position.
+
+        Test: fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html
+
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::createLineRuns):
+        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
+        (WebCore::SimpleLineLayout::TextFragmentIterator::revertToEndOfFragment):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::revertToFragment): Deleted.
+        * rendering/SimpleLineLayoutTextFragmentIterator.h:
+
 2015-04-29  Filip Pizlo  <[email protected]>
 
         JSTypeInfo should have an inline type flag to indicate of getCallData() has been overridden

Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.cpp (183575 => 183576)


--- trunk/Source/WebCore/rendering/SimpleLineLayout.cpp	2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.cpp	2015-04-29 21:32:07 UTC (rev 183576)
@@ -567,8 +567,8 @@
             // Non-breakable non-whitespace fragment when there's already content on the line. Push it to the next line.
             if (line.lastFragment().overlapsToNextRenderer()) {
                 // Check if this fragment is a continuation of a previous segment. In such cases, we need to remove them all.
-                const auto& currentFragment = line.revertToLastCompleteFragment(runs);
-                textFragmentIterator.revertToFragment(currentFragment);
+                const auto& lastCompleteFragment = line.revertToLastCompleteFragment(runs);
+                textFragmentIterator.revertToEndOfFragment(lastCompleteFragment);
                 break;
             }
             line.setOverflowedFragment(fragment);

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp (183575 => 183576)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp	2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp	2015-04-29 21:32:07 UTC (rev 183576)
@@ -98,15 +98,14 @@
     return TextFragment(startPosition, endPosition, width, TextFragment::NonWhitespace, endPosition == segmentEndPosition, overlappingFragment, false, false, m_style.breakWordOnOverflow);
 }
 
-void TextFragmentIterator::revertToFragment(const TextFragment& fragment)
+void TextFragmentIterator::revertToEndOfFragment(const TextFragment& fragment)
 {
     ASSERT(m_position >= fragment.end());
-    // Revert segment first.
-    while (m_currentSegment->start > fragment.start())
+    while (m_currentSegment->start > fragment.end())
         --m_currentSegment;
     // TODO: It reverts to the last fragment on the same position, but that's ok for now as we don't need to
     // differentiate multiple renderers on the same position.
-    m_position = fragment.start();
+    m_position = fragment.end();
     m_atEndOfSegment = false;
 }
 

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h (183575 => 183576)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h	2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h	2015-04-29 21:32:07 UTC (rev 183576)
@@ -95,7 +95,7 @@
         bool m_isBreakable { false };
     };
     TextFragment nextTextFragment(float xPosition = 0);
-    void revertToFragment(const TextFragment&);
+    void revertToEndOfFragment(const TextFragment&);
     float textWidth(unsigned startPosition, unsigned endPosition, float xPosition) const;
 
     struct Style {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to