<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[204771] releases/WebKitGTK/webkit-2.12</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/204771">204771</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-08-23 00:09:17 -0700 (Tue, 23 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/202123">r202123</a> - Decouple the percent height and positioned descendants maps.
https://bugs.webkit.org/show_bug.cgi?id=158773

Reviewed by David Hyatt and Chris Dumez.

Source/WebCore:

We track renderers with percent height across multiple containers using
HashMap&lt;const RenderBox*, std::unique_ptr&lt;HashSet&lt;const RenderBlock*&gt;&gt;&gt;.
We also use the same data structure to track positioned descendants.
However a positioned renderer can have only one containing block so tracking it
with a 1:many type is defective.
It allows multiple inserts for positioned descendants, which could lead to
inconsistent layout state as the rendering logic expects these type of renderers
with only one containing block.
This patch decouples percent height and positioned tracking by introducing
the PositionedDescendantsMap class. This class is responsible for tracking
the positioned descendants inbetween layouts.

No change in functionality.

Tests: fast/block/positioning/change-containing-block-for-absolute-positioned.html
       fast/block/positioning/change-containing-block-for-fixed-positioned.html

* rendering/RenderBlock.cpp:
(WebCore::insertIntoTrackedRendererMaps):
(WebCore::removeFromTrackedRendererMaps):
(WebCore::PositionedDescendantsMap::addDescendant): Add more defensive ASSERT_NOT_REACHED
to the double insert branch when webkit.org/b/158772 gets fixed.
(WebCore::PositionedDescendantsMap::removeDescendant):
(WebCore::PositionedDescendantsMap::removeContainingBlock):
(WebCore::PositionedDescendantsMap::positionedRenderers):
(WebCore::positionedDescendantsMap):
(WebCore::removeBlockFromPercentageDescendantAndContainerMaps):
(WebCore::RenderBlock::~RenderBlock):
(WebCore::RenderBlock::positionedObjects):
(WebCore::RenderBlock::insertPositionedObject):
(WebCore::RenderBlock::removePositionedObject):
(WebCore::RenderBlock::addPercentHeightDescendant):
(WebCore::RenderBlock::removePercentHeightDescendant):
(WebCore::RenderBlock::percentHeightDescendants):
(WebCore::RenderBlock::checkPositionedObjectsNeedLayout):
(WebCore::removeBlockFromDescendantAndContainerMaps): Deleted.
* rendering/RenderBlock.h:

LayoutTests:

Various dynamic containing block changing tests.

* fast/block/fixed-position-reparent-when-transition-is-removed.html:
* fast/block/positioning/change-containing-block-for-absolute-positioned-expected.txt: Added.
* fast/block/positioning/change-containing-block-for-absolute-positioned.html: Added.
* fast/block/positioning/change-containing-block-for-fixed-positioned-expected.txt: Added.
* fast/block/positioning/change-containing-block-for-fixed-positioned.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsfastblockfixedpositionreparentwhentransitionisremovedexpectedtxt">releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsfastblockfixedpositionreparentwhentransitionisremovedhtml">releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed.html</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorerenderingRenderBlockcpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderBlock.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorerenderingRenderBlockh">releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderBlock.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsfastblockpositioningchangecontainingblockforabsolutepositionedexpectedtxt">releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-absolute-positioned-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsfastblockpositioningchangecontainingblockforabsolutepositionedhtml">releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-absolute-positioned.html</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsfastblockpositioningchangecontainingblockforfixedpositionedexpectedtxt">releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-fixed-positioned-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsfastblockpositioningchangecontainingblockforfixedpositionedhtml">releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-fixed-positioned.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit212LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog (204770 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog        2016-08-23 07:09:02 UTC (rev 204770)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2016-06-15  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Decouple the percent height and positioned descendants maps.
+        https://bugs.webkit.org/show_bug.cgi?id=158773
+
+        Reviewed by David Hyatt and Chris Dumez.
+
+        Various dynamic containing block changing tests.
+
+        * fast/block/fixed-position-reparent-when-transition-is-removed.html:
+        * fast/block/positioning/change-containing-block-for-absolute-positioned-expected.txt: Added.
+        * fast/block/positioning/change-containing-block-for-absolute-positioned.html: Added.
+        * fast/block/positioning/change-containing-block-for-fixed-positioned-expected.txt: Added.
+        * fast/block/positioning/change-containing-block-for-fixed-positioned.html: Added.
+
</ins><span class="cx"> 2016-06-12  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove positioned descendants when RenderBlock is no longer a containing block.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsfastblockfixedpositionreparentwhentransitionisremovedexpectedtxt"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed-expected.txt (204770 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed-expected.txt        2016-08-23 07:09:02 UTC (rev 204770)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed-expected.txt        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -1,2 +1 @@
</span><span class="cx"> PASS if no crash or assert.
</span><del>-
</del></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsfastblockfixedpositionreparentwhentransitionisremovedhtml"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed.html (204770 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed.html        2016-08-23 07:09:02 UTC (rev 204770)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed.html        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx">     removeThis.parentNode.removeChild(removeThis);
</span><span class="cx">       setTimeout(function() {
</span><span class="cx">         var newChild = document.createElement(&quot;div&quot;);
</span><del>-        newChild.style.positioned = &quot;absolute&quot;;
</del><ins>+        newChild.style.position = &quot;absolute&quot;;
</ins><span class="cx">         container.appendChild(newChild);
</span><span class="cx">         if (window.testRunner)
</span><span class="cx">           testRunner.notifyDone();
</span><span class="lines">@@ -37,4 +37,4 @@
</span><span class="cx"> }, 0);
</span><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;/body&gt;
</span><del>-&lt;/html&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+&lt;/html&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsfastblockpositioningchangecontainingblockforabsolutepositionedexpectedtxtfromrev204770releasesWebKitGTKwebkit212LayoutTestsfastblockfixedpositionreparentwhentransitionisremovedexpectedtxt"></a>
<div class="copfile"><h4>Copied: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-absolute-positioned-expected.txt (from rev 204770, releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed-expected.txt) (0 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-absolute-positioned-expected.txt                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-absolute-positioned-expected.txt        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+PASS if no crash or assert.
+
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsfastblockpositioningchangecontainingblockforabsolutepositionedhtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-absolute-positioned.html (0 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-absolute-positioned.html                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-absolute-positioned.html        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that we can adjust the contining block for absolute positioned element when containing block changes.&lt;/title&gt;
+&lt;style&gt;
+div {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+  top: 100px;
+  left: 100px;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+PASS if no crash or assert.
+&lt;div id=container style=&quot;background-color: blue; position: absolute;&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+if (window.testRunner) {
+  testRunner.waitUntilDone();
+  testRunner.dumpAsText();
+}
+var container = document.getElementById(&quot;container&quot;); 
+setTimeout(function() {
+  for (var i = 0; i &lt; 50; ++i) {
+    var newChild = document.createElement(&quot;div&quot;);
+    newChild.style.position = &quot;absolute&quot;;
+    container.appendChild(newChild);
+  }
+  setTimeout(function() {
+    container.style.position = &quot;static&quot;;
+    setTimeout(function() {
+      var newChild = document.createElement(&quot;div&quot;);
+      newChild.style.position = &quot;absolute&quot;;
+      container.appendChild(newChild);
+      if (window.testRunner)
+        testRunner.notifyDone();
+    }, 0);
+  }, 0);
+}, 0);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsfastblockpositioningchangecontainingblockforfixedpositionedexpectedtxtfromrev204770releasesWebKitGTKwebkit212LayoutTestsfastblockfixedpositionreparentwhentransitionisremovedexpectedtxt"></a>
<div class="copfile"><h4>Copied: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-fixed-positioned-expected.txt (from rev 204770, releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/fixed-position-reparent-when-transition-is-removed-expected.txt) (0 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-fixed-positioned-expected.txt                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-fixed-positioned-expected.txt        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+PASS if no crash or assert.
+
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsfastblockpositioningchangecontainingblockforfixedpositionedhtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-fixed-positioned.html (0 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-fixed-positioned.html                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/block/positioning/change-containing-block-for-fixed-positioned.html        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that we can adjust the contining block for absolute positioned element when containing block changes.&lt;/title&gt;
+&lt;style&gt;
+div {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+  top: 100px;
+  left: 100px;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+PASS if no crash or assert.
+&lt;div id=container style=&quot;background-color: blue;&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+if (window.testRunner) {
+  testRunner.waitUntilDone();
+  testRunner.dumpAsText();
+}
+var container = document.getElementById(&quot;container&quot;); 
+setTimeout(function() {
+  for (var i = 0; i &lt; 50; ++i) {
+    var newChild = document.createElement(&quot;div&quot;);
+    newChild.style.position = &quot;fixed&quot;;
+    container.appendChild(newChild);
+  }
+  setTimeout(function() {
+    container.style.transform = &quot;rotate(10deg)&quot;;
+    setTimeout(function() {
+      container.style.transform = &quot;&quot;;
+      setTimeout(function() {
+        var newChild = document.createElement(&quot;div&quot;);
+        newChild.style.position = &quot;absolute&quot;;
+        document.body.appendChild(newChild);
+        if (window.testRunner)
+          testRunner.notifyDone();
+      }, 0);
+    }, 0);
+  }, 0);
+}, 0);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog (204770 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog        2016-08-23 07:09:02 UTC (rev 204770)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2016-06-15  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Decouple the percent height and positioned descendants maps.
+        https://bugs.webkit.org/show_bug.cgi?id=158773
+
+        Reviewed by David Hyatt and Chris Dumez.
+
+        We track renderers with percent height across multiple containers using
+        HashMap&lt;const RenderBox*, std::unique_ptr&lt;HashSet&lt;const RenderBlock*&gt;&gt;&gt;.
+        We also use the same data structure to track positioned descendants.
+        However a positioned renderer can have only one containing block so tracking it
+        with a 1:many type is defective.
+        It allows multiple inserts for positioned descendants, which could lead to
+        inconsistent layout state as the rendering logic expects these type of renderers
+        with only one containing block.
+        This patch decouples percent height and positioned tracking by introducing
+        the PositionedDescendantsMap class. This class is responsible for tracking
+        the positioned descendants inbetween layouts.
+
+        No change in functionality.
+
+        Tests: fast/block/positioning/change-containing-block-for-absolute-positioned.html
+               fast/block/positioning/change-containing-block-for-fixed-positioned.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::insertIntoTrackedRendererMaps):
+        (WebCore::removeFromTrackedRendererMaps):
+        (WebCore::PositionedDescendantsMap::addDescendant): Add more defensive ASSERT_NOT_REACHED
+        to the double insert branch when webkit.org/b/158772 gets fixed.
+        (WebCore::PositionedDescendantsMap::removeDescendant):
+        (WebCore::PositionedDescendantsMap::removeContainingBlock):
+        (WebCore::PositionedDescendantsMap::positionedRenderers):
+        (WebCore::positionedDescendantsMap):
+        (WebCore::removeBlockFromPercentageDescendantAndContainerMaps):
+        (WebCore::RenderBlock::~RenderBlock):
+        (WebCore::RenderBlock::positionedObjects):
+        (WebCore::RenderBlock::insertPositionedObject):
+        (WebCore::RenderBlock::removePositionedObject):
+        (WebCore::RenderBlock::addPercentHeightDescendant):
+        (WebCore::RenderBlock::removePercentHeightDescendant):
+        (WebCore::RenderBlock::percentHeightDescendants):
+        (WebCore::RenderBlock::checkPositionedObjectsNeedLayout):
+        (WebCore::removeBlockFromDescendantAndContainerMaps): Deleted.
+        * rendering/RenderBlock.h:
+
</ins><span class="cx"> 2016-06-14  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Make RenderBlock::insertInto/RemoveFromTrackedRendererMaps functions static.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorerenderingRenderBlockcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderBlock.cpp (204770 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderBlock.cpp        2016-08-23 07:09:02 UTC (rev 204770)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderBlock.cpp        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -92,55 +92,44 @@
</span><span class="cx"> 
</span><span class="cx"> COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
</span><span class="cx"> 
</span><del>-typedef WTF::HashMap&lt;const RenderBlock*, std::unique_ptr&lt;TrackedRendererListHashSet&gt;&gt; TrackedDescendantsMap;
-typedef WTF::HashMap&lt;const RenderBox*, std::unique_ptr&lt;HashSet&lt;const RenderBlock*&gt;&gt;&gt; TrackedContainerMap;
</del><ins>+typedef HashMap&lt;const RenderBlock*, std::unique_ptr&lt;TrackedRendererListHashSet&gt;&gt; TrackedDescendantsMap;
+typedef HashMap&lt;const RenderBox*, std::unique_ptr&lt;HashSet&lt;const RenderBlock*&gt;&gt;&gt; TrackedContainerMap;
</ins><span class="cx"> 
</span><del>-static TrackedDescendantsMap* gPositionedDescendantsMap;
-static TrackedDescendantsMap* gPercentHeightDescendantsMap;
</del><ins>+static TrackedDescendantsMap* percentHeightDescendantsMap;
+static TrackedContainerMap* percentHeightContainerMap;
</ins><span class="cx"> 
</span><del>-static TrackedContainerMap* gPositionedContainerMap;
-static TrackedContainerMap* gPercentHeightContainerMap;
-
-static void insertIntoTrackedRendererMaps(const RenderBlock&amp; container, RenderBox&amp; descendant, TrackedDescendantsMap*&amp; descendantsMap, TrackedContainerMap*&amp; containerMap, bool forceNewEntry)
</del><ins>+static void insertIntoTrackedRendererMaps(const RenderBlock&amp; container, RenderBox&amp; descendant)
</ins><span class="cx"> {
</span><del>-    if (!descendantsMap) {
-        descendantsMap = new TrackedDescendantsMap;
-        containerMap = new TrackedContainerMap;
</del><ins>+    if (!percentHeightDescendantsMap) {
+        percentHeightDescendantsMap = new TrackedDescendantsMap;
+        percentHeightContainerMap = new TrackedContainerMap;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    auto* descendantSet = descendantsMap-&gt;get(&amp;container);
-    if (!descendantSet) {
-        descendantSet = new TrackedRendererListHashSet;
-        descendantsMap-&gt;set(&amp;container, std::unique_ptr&lt;TrackedRendererListHashSet&gt;(descendantSet));
-    }
-    
-    if (forceNewEntry) {
-        descendantSet-&gt;remove(&amp;descendant);
-        containerMap-&gt;remove(&amp;descendant);
-    }
-    
</del><ins>+    auto&amp; descendantSet = percentHeightDescendantsMap-&gt;ensure(&amp;container, [] {
+        return std::make_unique&lt;TrackedRendererListHashSet&gt;();
+    }).iterator-&gt;value;
+
</ins><span class="cx">     bool added = descendantSet-&gt;add(&amp;descendant).isNewEntry;
</span><span class="cx">     if (!added) {
</span><del>-        ASSERT(containerMap-&gt;get(&amp;descendant));
-        ASSERT(containerMap-&gt;get(&amp;descendant)-&gt;contains(&amp;container));
</del><ins>+        ASSERT(percentHeightContainerMap-&gt;get(&amp;descendant));
+        ASSERT(percentHeightContainerMap-&gt;get(&amp;descendant)-&gt;contains(&amp;container));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    auto* containerSet = containerMap-&gt;get(&amp;descendant);
-    if (!containerSet) {
-        containerSet = new HashSet&lt;const RenderBlock*&gt;;
-        containerMap-&gt;set(&amp;descendant, std::unique_ptr&lt;HashSet&lt;const RenderBlock*&gt;&gt;(containerSet));
-    }    
</del><ins>+    auto&amp; containerSet = percentHeightContainerMap-&gt;ensure(&amp;descendant, [] {
+        return std::make_unique&lt;HashSet&lt;const RenderBlock*&gt;&gt;();
+    }).iterator-&gt;value;
+
</ins><span class="cx">     ASSERT(!containerSet-&gt;contains(&amp;container));
</span><span class="cx">     containerSet-&gt;add(&amp;container);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void removeFromTrackedRendererMaps(RenderBox&amp; descendant, TrackedDescendantsMap*&amp; descendantsMap, TrackedContainerMap*&amp; containerMap)
</del><ins>+static void removeFromTrackedRendererMaps(RenderBox&amp; descendant)
</ins><span class="cx"> {
</span><del>-    if (!descendantsMap)
</del><ins>+    if (!percentHeightDescendantsMap)
</ins><span class="cx">         return;
</span><span class="cx">     
</span><del>-    std::unique_ptr&lt;HashSet&lt;const RenderBlock*&gt;&gt; containerSet = containerMap-&gt;take(&amp;descendant);
</del><ins>+    std::unique_ptr&lt;HashSet&lt;const RenderBlock*&gt;&gt; containerSet = percentHeightContainerMap-&gt;take(&amp;descendant);
</ins><span class="cx">     if (!containerSet)
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="lines">@@ -149,18 +138,91 @@
</span><span class="cx">         // bugs associated with positioned objects not properly cleared from
</span><span class="cx">         // their ancestor chain before being moved. See webkit bug 93766.
</span><span class="cx">         // ASSERT(descendant-&gt;isDescendantOf(container));
</span><del>-        auto descendantsMapIterator = descendantsMap-&gt;find(container);
-        ASSERT(descendantsMapIterator != descendantsMap-&gt;end());
-        if (descendantsMapIterator == descendantsMap-&gt;end())
</del><ins>+        auto descendantsMapIterator = percentHeightDescendantsMap-&gt;find(container);
+        ASSERT(descendantsMapIterator != percentHeightDescendantsMap-&gt;end());
+        if (descendantsMapIterator == percentHeightDescendantsMap-&gt;end())
</ins><span class="cx">             continue;
</span><del>-        auto* descendantSet = descendantsMapIterator-&gt;value.get();
</del><ins>+        auto&amp; descendantSet = descendantsMapIterator-&gt;value;
</ins><span class="cx">         ASSERT(descendantSet-&gt;contains(&amp;descendant));
</span><span class="cx">         descendantSet-&gt;remove(&amp;descendant);
</span><span class="cx">         if (descendantSet-&gt;isEmpty())
</span><del>-            descendantsMap-&gt;remove(descendantsMapIterator);
</del><ins>+            percentHeightDescendantsMap-&gt;remove(descendantsMapIterator);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+class PositionedDescendantsMap {
+public:
+    enum class MoveDescendantToEnd { No, Yes };
+    void addDescendant(const RenderBlock&amp; containingBlock, RenderBox&amp; positionedDescendant, MoveDescendantToEnd moveDescendantToEnd)
+    {
+        // Protect against double insert where a descendant would end up with multiple containing blocks.
+        auto* previousContainingBlock = m_containerMap.get(&amp;positionedDescendant);
+        if (previousContainingBlock &amp;&amp; previousContainingBlock != &amp;containingBlock) {
+            if (auto* descendants = m_descendantsMap.get(previousContainingBlock))
+                descendants-&gt;remove(&amp;positionedDescendant);
+        }
+
+        auto&amp; descendants = m_descendantsMap.ensure(&amp;containingBlock, [] {
+            return std::make_unique&lt;TrackedRendererListHashSet&gt;();
+        }).iterator-&gt;value;
+
+        bool isNewEntry = moveDescendantToEnd == MoveDescendantToEnd::Yes ? descendants-&gt;appendOrMoveToLast(&amp;positionedDescendant).isNewEntry
+            : descendants-&gt;add(&amp;positionedDescendant).isNewEntry;
+        if (!isNewEntry) {
+            ASSERT(m_containerMap.contains(&amp;positionedDescendant));
+            return;
+        }
+        m_containerMap.set(&amp;positionedDescendant, &amp;containingBlock);
+    }
+
+    void removeDescendant(const RenderBox&amp; positionedDescendant)
+    {
+        auto* containingBlock = m_containerMap.take(&amp;positionedDescendant);
+        if (!containingBlock)
+            return;
+
+        auto descendantsIterator = m_descendantsMap.find(containingBlock);
+        ASSERT(descendantsIterator != m_descendantsMap.end());
+        if (descendantsIterator == m_descendantsMap.end())
+            return;
+
+        auto&amp; descendants = descendantsIterator-&gt;value;
+        ASSERT(descendants-&gt;contains(const_cast&lt;RenderBox*&gt;(&amp;positionedDescendant)));
+
+        descendants-&gt;remove(const_cast&lt;RenderBox*&gt;(&amp;positionedDescendant));
+        if (descendants-&gt;isEmpty())
+            m_descendantsMap.remove(descendantsIterator);
+    }
+    
+    void removeContainingBlock(const RenderBlock&amp; containingBlock)
+    {
+        auto descendants = m_descendantsMap.take(&amp;containingBlock);
+        if (!descendants)
+            return;
+
+        for (auto* renderer : *descendants)
+            m_containerMap.remove(renderer);
+    }
+    
+    TrackedRendererListHashSet* positionedRenderers(const RenderBlock&amp; containingBlock) const
+    {
+        return m_descendantsMap.get(&amp;containingBlock);
+    }
+
+private:
+    using DescendantsMap = HashMap&lt;const RenderBlock*, std::unique_ptr&lt;TrackedRendererListHashSet&gt;&gt;;
+    using ContainerMap = HashMap&lt;const RenderBox*, const RenderBlock*&gt;;
+    
+    DescendantsMap m_descendantsMap;
+    ContainerMap m_containerMap;
+};
+
+static PositionedDescendantsMap&amp; positionedDescendantsMap()
+{
+    static NeverDestroyed&lt;PositionedDescendantsMap&gt; mapForPositionedDescendants;
+    return mapForPositionedDescendants;
+}
+
</ins><span class="cx"> typedef HashMap&lt;RenderBlock*, std::unique_ptr&lt;ListHashSet&lt;RenderInline*&gt;&gt;&gt; ContinuationOutlineTableMap;
</span><span class="cx"> 
</span><span class="cx"> struct UpdateScrollInfoAfterLayoutTransaction {
</span><span class="lines">@@ -255,21 +317,24 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*&amp; descendantMap, TrackedContainerMap*&amp; containerMap)
</del><ins>+static void removeBlockFromPercentageDescendantAndContainerMaps(RenderBlock* block)
</ins><span class="cx"> {
</span><del>-    if (std::unique_ptr&lt;TrackedRendererListHashSet&gt; descendantSet = descendantMap-&gt;take(block)) {
-        TrackedRendererListHashSet::iterator end = descendantSet-&gt;end();
-        for (TrackedRendererListHashSet::iterator descendant = descendantSet-&gt;begin(); descendant != end; ++descendant) {
-            TrackedContainerMap::iterator it = containerMap-&gt;find(*descendant);
-            ASSERT(it != containerMap-&gt;end());
-            if (it == containerMap-&gt;end())
-                continue;
-            auto* containerSet = it-&gt;value.get();
-            ASSERT(containerSet-&gt;contains(block));
-            containerSet-&gt;remove(block);
-            if (containerSet-&gt;isEmpty())
-                containerMap-&gt;remove(it);
-        }
</del><ins>+    if (!percentHeightDescendantsMap)
+        return;
+    std::unique_ptr&lt;TrackedRendererListHashSet&gt; descendantSet = percentHeightDescendantsMap-&gt;take(block);
+    if (!descendantSet)
+        return;
+    
+    for (auto* descendant : *descendantSet) {
+        auto it = percentHeightContainerMap-&gt;find(descendant);
+        ASSERT(it != percentHeightContainerMap-&gt;end());
+        if (it == percentHeightContainerMap-&gt;end())
+            continue;
+        auto* containerSet = it-&gt;value.get();
+        ASSERT(containerSet-&gt;contains(block));
+        containerSet-&gt;remove(block);
+        if (containerSet-&gt;isEmpty())
+            percentHeightContainerMap-&gt;remove(it);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -279,10 +344,8 @@
</span><span class="cx"> 
</span><span class="cx">     if (gRareDataMap)
</span><span class="cx">         gRareDataMap-&gt;remove(this);
</span><del>-    if (gPercentHeightDescendantsMap)
-        removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
-    if (gPositionedDescendantsMap)
-        removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
</del><ins>+    removeBlockFromPercentageDescendantAndContainerMaps(this);
+    positionedDescendantsMap().removeContainingBlock(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderBlock::willBeDestroyed()
</span><span class="lines">@@ -1226,10 +1289,10 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderBlock::dirtyForLayoutFromPercentageHeightDescendants()
</span><span class="cx"> {
</span><del>-    if (!gPercentHeightDescendantsMap)
</del><ins>+    if (!percentHeightDescendantsMap)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    TrackedRendererListHashSet* descendants = gPercentHeightDescendantsMap-&gt;get(this);
</del><ins>+    TrackedRendererListHashSet* descendants = percentHeightDescendantsMap-&gt;get(this);
</ins><span class="cx">     if (!descendants)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -2178,9 +2241,7 @@
</span><span class="cx"> 
</span><span class="cx"> TrackedRendererListHashSet* RenderBlock::positionedObjects() const
</span><span class="cx"> {
</span><del>-    if (gPositionedDescendantsMap)
-        return gPositionedDescendantsMap-&gt;get(this);
-    return nullptr;
</del><ins>+    return positionedDescendantsMap().positionedRenderers(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderBlock::insertPositionedObject(RenderBox&amp; positioned)
</span><span class="lines">@@ -2190,12 +2251,13 @@
</span><span class="cx">     if (positioned.isRenderFlowThread())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    insertIntoTrackedRendererMaps(*this, positioned, gPositionedDescendantsMap, gPositionedContainerMap, isRenderView());
</del><ins>+    positionedDescendantsMap().addDescendant(*this, positioned, isRenderView() ? PositionedDescendantsMap::MoveDescendantToEnd::Yes
+        : PositionedDescendantsMap::MoveDescendantToEnd::No);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderBlock::removePositionedObject(RenderBox&amp; rendererToRemove)
</del><ins>+void RenderBlock::removePositionedObject(const RenderBox&amp; rendererToRemove)
</ins><span class="cx"> {
</span><del>-    removeFromTrackedRendererMaps(rendererToRemove, gPositionedDescendantsMap, gPositionedContainerMap);
</del><ins>+    positionedDescendantsMap().removeDescendant(rendererToRemove);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderBlock::removePositionedObjects(const RenderBlock* newContainingBlockCandidate, ContainingBlockState containingBlockState)
</span><span class="lines">@@ -2225,31 +2287,31 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderBlock::addPercentHeightDescendant(RenderBox&amp; descendant)
</span><span class="cx"> {
</span><del>-    insertIntoTrackedRendererMaps(*this, descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap, false);
</del><ins>+    insertIntoTrackedRendererMaps(*this, descendant);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderBlock::removePercentHeightDescendant(RenderBox&amp; descendant)
</span><span class="cx"> {
</span><del>-    removeFromTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
</del><ins>+    removeFromTrackedRendererMaps(descendant);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> TrackedRendererListHashSet* RenderBlock::percentHeightDescendants() const
</span><span class="cx"> {
</span><del>-    return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap-&gt;get(this) : 0;
</del><ins>+    return percentHeightDescendantsMap ? percentHeightDescendantsMap-&gt;get(this) : nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool RenderBlock::hasPercentHeightContainerMap()
</span><span class="cx"> {
</span><del>-    return gPercentHeightContainerMap;
</del><ins>+    return percentHeightContainerMap;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool RenderBlock::hasPercentHeightDescendant(RenderBox&amp; descendant)
</span><span class="cx"> {
</span><del>-    // We don't null check gPercentHeightContainerMap since the caller
</del><ins>+    // We don't null check percentHeightContainerMap since the caller
</ins><span class="cx">     // already ensures this and we need to call this function on every
</span><span class="cx">     // descendant in clearPercentHeightDescendantsFrom().
</span><del>-    ASSERT(gPercentHeightContainerMap);
-    return gPercentHeightContainerMap-&gt;contains(&amp;descendant);
</del><ins>+    ASSERT(percentHeightContainerMap);
+    return percentHeightContainerMap-&gt;contains(&amp;descendant);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderBlock::removePercentHeightDescendantIfNeeded(RenderBox&amp; descendant)
</span><span class="lines">@@ -2268,7 +2330,7 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox&amp; parent)
</span><span class="cx"> {
</span><del>-    ASSERT(gPercentHeightContainerMap);
</del><ins>+    ASSERT(percentHeightContainerMap);
</ins><span class="cx">     for (RenderObject* child = parent.firstChild(); child; child = child-&gt;nextInPreOrder(&amp;parent)) {
</span><span class="cx">         if (!is&lt;RenderBox&gt;(*child))
</span><span class="cx">             continue;
</span><span class="lines">@@ -3768,17 +3830,12 @@
</span><span class="cx"> #ifndef NDEBUG
</span><span class="cx"> void RenderBlock::checkPositionedObjectsNeedLayout()
</span><span class="cx"> {
</span><del>-    if (!gPositionedDescendantsMap)
</del><ins>+    auto* positionedDescendants = positionedObjects();
+    if (!positionedDescendants)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    TrackedRendererListHashSet* positionedDescendantSet = positionedObjects();
-    if (!positionedDescendantSet)
-        return;
-
-    for (auto it = positionedDescendantSet-&gt;begin(), end = positionedDescendantSet-&gt;end(); it != end; ++it) {
-        RenderBox* currBox = *it;
-        ASSERT(!currBox-&gt;needsLayout());
-    }
</del><ins>+    for (auto* renderer : *positionedDescendants)
+        ASSERT(!renderer-&gt;needsLayout());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorerenderingRenderBlockh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderBlock.h (204770 => 204771)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderBlock.h        2016-08-23 07:09:02 UTC (rev 204770)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderBlock.h        2016-08-23 07:09:17 UTC (rev 204771)
</span><span class="lines">@@ -81,7 +81,7 @@
</span><span class="cx">     virtual void invalidateLineLayoutPath() { }
</span><span class="cx"> 
</span><span class="cx">     void insertPositionedObject(RenderBox&amp;);
</span><del>-    static void removePositionedObject(RenderBox&amp;);
</del><ins>+    static void removePositionedObject(const RenderBox&amp;);
</ins><span class="cx">     void removePositionedObjects(const RenderBlock*, ContainingBlockState = SameContainingBlock);
</span><span class="cx"> 
</span><span class="cx">     TrackedRendererListHashSet* positionedObjects() const;
</span></span></pre>
</div>
</div>

</body>
</html>