Fix SubtreeLayoutScope not to schedule relayout

This patch fixes SubtreeLayoutScope::setNeedsLayout() and
setChildNeedsLayout() not to schedule relayout when they call
markContainerChainForLayout().

The signature of markContainerChainForLayout() allows to schedule
relayout even when SubtreeLayoutScope exists. To not allow scheduling
relayout while we're in layout, this patch changes the signature.

BUG=590620

Review URL: https://codereview.chromium.org/1755543002

Cr-Commit-Position: refs/heads/master@{#378639}
diff --git a/third_party/WebKit/LayoutTests/fast/layout/subtree-layout-percent-height-assert-expected.txt b/third_party/WebKit/LayoutTests/fast/layout/subtree-layout-percent-height-assert-expected.txt
new file mode 100644
index 0000000..be11ba8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/layout/subtree-layout-percent-height-assert-expected.txt
@@ -0,0 +1,2 @@
+
+Test passes if it doesn't assert.
diff --git a/third_party/WebKit/LayoutTests/fast/layout/subtree-layout-percent-height-assert.html b/third_party/WebKit/LayoutTests/fast/layout/subtree-layout-percent-height-assert.html
new file mode 100644
index 0000000..f662d7ff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/layout/subtree-layout-percent-height-assert.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<style>
+.scope {
+  width: 200px;
+  height: 200px;
+  overflow: hidden;
+}
+</style>
+<div class="scope">
+  <table>
+    <tr>
+      <img src="autumn.jpg" width="150" height="148">
+      <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
+        <foreignObject width="100%" height="100%">
+          <div style="width:100%; height:100%;"></div>
+        </foreignObject>
+      </svg>
+    </tr>
+  </table>
+</div>
+<p>Test passes if it doesn't assert.</p>
+<script>
+if (window.testRunner)
+  testRunner.dumpAsText();
+</script>
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 111e984..95b7588 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -761,10 +761,24 @@
     return true;
 }
 
+void LayoutObject::markContainerChainForLayout(bool scheduleRelayout)
+{
+    markContainerChainForLayout(scheduleRelayout, nullptr);
+}
+
+void LayoutObject::markContainerChainForLayout(SubtreeLayoutScope* layouter)
+{
+    // When we have a layouter, it means that we're in layout and we're marking
+    // a descendant as needing layout with the intention of visiting it during
+    // this layout. We shouldn't be scheduling it to be laid out later.
+    markContainerChainForLayout(!layouter, layouter);
+}
+
 void LayoutObject::markContainerChainForLayout(bool scheduleRelayout, SubtreeLayoutScope* layouter)
 {
     ASSERT(!isSetNeedsLayoutForbidden());
     ASSERT(!layouter || this != layouter->root());
+    ASSERT(!scheduleRelayout || !layouter);
 
     LayoutObject* object = container();
     LayoutObject* last = this;
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h
index fdce251f..b0c2703 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -797,7 +797,8 @@
 
     Element* offsetParent() const;
 
-    void markContainerChainForLayout(bool scheduleRelayout = true, SubtreeLayoutScope* = nullptr);
+    void markContainerChainForLayout(bool scheduleRelayout = true);
+    void markContainerChainForLayout(SubtreeLayoutScope*);
     void setNeedsLayout(LayoutInvalidationReasonForTracing, MarkingBehavior = MarkContainerChain, SubtreeLayoutScope* = nullptr);
     void setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReasonForTracing, MarkingBehavior = MarkContainerChain, SubtreeLayoutScope* = nullptr);
     void clearNeedsLayout();
@@ -1578,6 +1579,8 @@
 
     void setNeedsOverflowRecalcAfterStyleChange();
 
+    void markContainerChainForLayout(bool scheduleRelayout, SubtreeLayoutScope*);
+
     // FIXME: This should be 'markContaingBoxChainForOverflowRecalc when we make LayoutBox
     // recomputeOverflow-capable. crbug.com/437012 and crbug.com/434700.
     inline void markContainingBlocksForOverflowRecalc();
@@ -1985,7 +1988,7 @@
             "data",
             InspectorLayoutInvalidationTrackingEvent::data(this, reason));
         if (markParents == MarkContainerChain && (!layouter || layouter->root() != this))
-            markContainerChainForLayout(true, layouter);
+            markContainerChainForLayout(layouter);
     }
 }
 
@@ -2022,7 +2025,7 @@
     setNormalChildNeedsLayout(true);
     // FIXME: Replace MarkOnlyThis with the SubtreeLayoutScope code path and remove the MarkingBehavior argument entirely.
     if (!alreadyNeededLayout && markParents == MarkContainerChain && (!layouter || layouter->root() != this))
-        markContainerChainForLayout(true, layouter);
+        markContainerChainForLayout(layouter);
 }
 
 inline void LayoutObject::setNeedsPositionedMovementLayout()