diff --git a/chrome/VERSION b/chrome/VERSION
index 3d74a2f..2d9ec92 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=59
 MINOR=0
-BUILD=3038
+BUILD=3039
 PATCH=0
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 2feefd5c..5fb0b0ac 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -106,6 +106,18 @@
 
 crbug.com/644433 virtual/gpu/fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Failure ]
 
+crbug.com/688647 paint/invalidation/transform-inline-layered-child.html [ NeedsRebaseline ]
+crbug.com/688647 paint/invalidation/create-layer-repaint.html [ NeedsRebaseline ]
+crbug.com/688647 paint/invalidation/scroll-descendant-with-cached-cliprects.html [ NeedsRebaseline ]
+crbug.com/688647 paint/invalidation/svg/tabgroup.svg [ NeedsRebaseline ]
+crbug.com/688647 paint/invalidation/svg/text-repaint-including-stroke.svg [ NeedsRebaseline ]
+crbug.com/688647 virtual/disable-spinvalidation/paint/invalidation/transform-inline-layered-child.html [ NeedsRebaseline ]
+crbug.com/688647 virtual/disable-spinvalidation/paint/invalidation/create-layer-repaint.html [ NeedsRebaseline ]
+crbug.com/688647 virtual/disable-spinvalidation/paint/invalidation/scroll-descendant-with-cached-cliprects.html [ NeedsRebaseline ]
+crbug.com/688647 virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup.svg [ NeedsRebaseline ]
+crbug.com/688647 virtual/disable-spinvalidation/paint/invalidation/svg/text-repaint-including-stroke.svg [ NeedsRebaseline ]
+
+
 crbug.com/645389 [ Win ] virtual/gpu/fast/canvas/canvas-hit-regions-fallback-element-test.html [ Timeout ]
 crbug.com/645389 [ Win ] virtual/gpu/fast/canvas/canvas-hit-regions-event-test.html [ Timeout ]
 crbug.com/645389 [ Win ] fast/canvas/canvas-hit-regions-fallback-element-test.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/change-transform-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/change-transform-expected.txt
index 57cf85b..5a777528 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/change-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/change-transform-expected.txt
@@ -10,6 +10,11 @@
           "object": "LayoutBlockFlow DIV id='square'",
           "rect": [10, 10, 100, 100],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow DIV id='square'",
+          "rect": [35, 35, 50, 50],
+          "reason": "subtree"
         }
       ]
     }
@@ -18,6 +23,10 @@
     {
       "object": "LayoutBlockFlow DIV id='square'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV id='square'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-expected.txt
index efcdddbd..df25721 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-expected.txt
@@ -22,6 +22,16 @@
       "backgroundColor": "#0000FF",
       "paintInvalidations": [
         {
+          "object": "LayoutBlockFlow (positioned) DIV id='container'",
+          "rect": [0, 0, 100, 100],
+          "reason": "style change"
+        },
+        {
+          "object": "LayoutBlockFlow (positioned) DIV id='container'",
+          "rect": [0, 0, 100, 100],
+          "reason": "subtree"
+        },
+        {
           "object": "LayoutBlockFlow (positioned) DIV class='fixed'",
           "rect": [50, 50, 75, 75],
           "reason": "style change"
@@ -35,6 +45,18 @@
       "reason": "subtree"
     },
     {
+      "object": "LayoutBlockFlow (positioned) DIV id='container'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='fixed'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV id='container'",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutBlockFlow (positioned) DIV class='fixed'",
       "reason": "style change"
     }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt
index 7ca9085..9fe1ead 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt
@@ -60,6 +60,10 @@
     {
       "object": "LayoutBlockFlow (positioned) DIV id='target'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV id='target'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context-expected.png
new file mode 100644
index 0000000..dc85ee8b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context-expected.txt
new file mode 100644
index 0000000..c499330
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context-expected.txt
@@ -0,0 +1,86 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true
+    },
+    {
+      "name": "LayoutBlockFlow DIV",
+      "position": [8, 8],
+      "bounds": [100, 100],
+      "shouldFlattenTransform": false,
+      "drawsContent": true
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [100, 100],
+      "shouldFlattenTransform": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [200, 200],
+      "drawsContent": true,
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow DIV id='target'",
+          "rect": [0, 0, 200, 200],
+          "reason": "subtree"
+        }
+      ]
+    },
+    {
+      "name": "Overflow Controls Host Layer",
+      "bounds": [100, 100]
+    },
+    {
+      "name": "Horizontal Scrollbar Layer",
+      "position": [0, 100],
+      "bounds": [100, 0],
+      "drawsContent": true
+    },
+    {
+      "name": "Vertical Scrollbar Layer",
+      "position": [100, 0],
+      "bounds": [0, 100],
+      "drawsContent": true
+    },
+    {
+      "name": "LayoutBlockFlow DIV id='target'",
+      "position": [8, 8],
+      "bounds": [200, 200],
+      "opacity": 0.5,
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#008000",
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow DIV id='target'",
+          "rect": [0, 0, 200, 200],
+          "reason": "full"
+        },
+        {
+          "object": "LayoutBlockFlow DIV id='target'",
+          "rect": [0, 0, 200, 200],
+          "reason": "subtree"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutBlockFlow DIV id='target'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV id='target'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV id='target'",
+      "reason": "subtree"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context.html b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context.html
new file mode 100644
index 0000000..35f5f65
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/new-stacking-context.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<style>::-webkit-scrollbar {display: none;}</style>
+<script src="../resources/text-based-repaint.js"></script>
+<script>
+if (window.internals)
+  internals.settings.setPreferCompositingToLCDTextEnabled(true);
+function repaintTest() {
+  target.style.opacity = '.5';
+  target.style.backgroundColor = 'green';
+}
+onload = runRepaintAndPixelTest;
+</script>
+<div style="width: 100px; height: 100px; overflow: scroll">
+  <div id="target" style="width: 200px; height: 200px; background: red; overflow: hidden"></div>
+  <div></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/css-grid-layout/grid-item-z-index-change-repaint-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/css-grid-layout/grid-item-z-index-change-repaint-expected.txt
index df906021..3ebea7ec 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/css-grid-layout/grid-item-z-index-change-repaint-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/css-grid-layout/grid-item-z-index-change-repaint-expected.txt
@@ -12,6 +12,11 @@
           "reason": "subtree"
         },
         {
+          "object": "LayoutBlockFlow DIV id='item2' class='sizedToGridArea green'",
+          "rect": [8, 236, 200, 100],
+          "reason": "subtree"
+        },
+        {
           "object": "LayoutBlockFlow DIV id='item1' class='sizedToGridArea green negativeZIndex'",
           "rect": [8, 126, 200, 100],
           "reason": "subtree"
@@ -21,6 +26,10 @@
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutBlockFlow DIV id='item2' class='sizedToGridArea green'",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutBlockFlow DIV id='item1' class='sizedToGridArea green negativeZIndex'",
       "reason": "subtree"
     },
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/fixed-after-scroll-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/fixed-after-scroll-expected.txt
index 7e0079d..234b594 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/fixed-after-scroll-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/fixed-after-scroll-expected.txt
@@ -22,6 +22,10 @@
   "objectPaintInvalidations": [
     {
       "object": "LayoutBlockFlow (positioned) DIV id='t' class='green absolute'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV id='t' class='green absolute'",
       "reason": "style change"
     },
     {
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/fixed-position-transparency-with-overflow-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/fixed-position-transparency-with-overflow-expected.txt
index c00db9d..0a241bc2d 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/fixed-position-transparency-with-overflow-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/fixed-position-transparency-with-overflow-expected.txt
@@ -12,6 +12,16 @@
           "reason": "subtree"
         },
         {
+          "object": "LayoutBlockFlow (positioned) DIV class='absolute green'",
+          "rect": [108, 308, 100, 100],
+          "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow (relative positioned) DIV id='container' class='relative blue'",
+          "rect": [8, 208, 100, 100],
+          "reason": "subtree"
+        },
+        {
           "object": "LayoutBlockFlow (relative positioned) DIV id='container' class='relative blue'",
           "rect": [8, 208, 100, 100],
           "reason": "subtree"
@@ -27,6 +37,14 @@
     {
       "object": "LayoutBlockFlow (positioned) DIV class='absolute green'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (relative positioned) DIV id='container' class='relative blue'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='absolute green'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/flexbox/repaint-opacity-change-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/flexbox/repaint-opacity-change-expected.txt
index a6347be..be61e87 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/flexbox/repaint-opacity-change-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/flexbox/repaint-opacity-change-expected.txt
@@ -27,6 +27,10 @@
     {
       "object": "LayoutBlockFlow DIV id='target' class='item'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV id='target' class='item'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/invalidate-descendants-when-receiving-paint-layer-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/invalidate-descendants-when-receiving-paint-layer-expected.txt
index 49dc263..e803300 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/invalidate-descendants-when-receiving-paint-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/invalidate-descendants-when-receiving-paint-layer-expected.txt
@@ -76,6 +76,14 @@
     {
       "object": "LayoutBlockFlow DIV id='child'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV id='target'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV id='child'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/mix-blend-mode-separate-stacking-context-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/mix-blend-mode-separate-stacking-context-expected.txt
index a3636bb..1c9d14be 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/mix-blend-mode-separate-stacking-context-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/mix-blend-mode-separate-stacking-context-expected.txt
@@ -12,6 +12,16 @@
           "reason": "subtree"
         },
         {
+          "object": "LayoutBlockFlow (floating) DIV",
+          "rect": [348, 48, 60, 60],
+          "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow (floating) DIV id='fourth'",
+          "rect": [328, 28, 60, 60],
+          "reason": "subtree"
+        },
+        {
           "object": "LayoutBlockFlow (relative positioned) (floating) DIV id='fourth'",
           "rect": [328, 28, 60, 60],
           "reason": "subtree"
@@ -35,12 +45,25 @@
           "object": "LayoutBlockFlow (floating) DIV id='first'",
           "rect": [48, 48, 60, 60],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow (floating) DIV id='first'",
+          "rect": [48, 48, 60, 60],
+          "reason": "subtree"
         }
       ]
     }
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutBlockFlow (floating) DIV id='fourth'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (floating) DIV",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutBlockFlow (floating) DIV id='second'",
       "reason": "subtree"
     },
@@ -49,6 +72,10 @@
       "reason": "subtree"
     },
     {
+      "object": "LayoutBlockFlow (floating) DIV id='first'",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutBlockFlow (floating) DIV id='second'",
       "reason": "subtree"
     },
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/paint-invalidation-with-opacity-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/paint-invalidation-with-opacity-expected.txt
index 7398432..e978084 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/paint-invalidation-with-opacity-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/paint-invalidation-with-opacity-expected.txt
@@ -10,6 +10,11 @@
           "object": "LayoutBlockFlow DIV id='target'",
           "rect": [8, 8, 100, 100],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow DIV id='target'",
+          "rect": [8, 8, 100, 100],
+          "reason": "subtree"
         }
       ]
     }
@@ -18,6 +23,10 @@
     {
       "object": "LayoutBlockFlow DIV id='target'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV id='target'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/scroll-fixed-reflected-layer-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/scroll-fixed-reflected-layer-expected.txt
index 940d675..c9d7cec3 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/scroll-fixed-reflected-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/scroll-fixed-reflected-layer-expected.txt
@@ -10,6 +10,11 @@
           "object": "LayoutBlockFlow (positioned) DIV id='hideMe' class='absolute red'",
           "rect": [250, 280, 100, 100],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow (positioned) DIV id='hideMe' class='absolute red'",
+          "rect": [250, 280, 100, 100],
+          "reason": "subtree"
         }
       ]
     }
@@ -18,6 +23,10 @@
     {
       "object": "LayoutBlockFlow (positioned) DIV id='hideMe' class='absolute red'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV id='hideMe' class='absolute red'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/scroll-in-transformed-layer-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/scroll-in-transformed-layer-expected.txt
index b4ef93b..f40c5de 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/scroll-in-transformed-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/scroll-in-transformed-layer-expected.txt
@@ -15,6 +15,16 @@
           "object": "LayoutBlockFlow (positioned) DIV class='absolute red'",
           "rect": [114, 129, 107, 36],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow (positioned) DIV class='absolute red'",
+          "rect": [100, 150, 100, 100],
+          "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow (positioned) DIV id='moveMe' class='absolute clipped rotated'",
+          "rect": [100, 150, 100, 100],
+          "reason": "subtree"
         }
       ]
     }
@@ -31,6 +41,18 @@
     {
       "object": "LayoutBlockFlow (positioned) DIV class='absolute red'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV id='moveMe' class='absolute clipped rotated'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='absolute green'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='absolute red'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/transform-foreign-object-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/svg/transform-foreign-object-expected.txt
index 3c54f9d..9374328 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/transform-foreign-object-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/transform-foreign-object-expected.txt
@@ -12,6 +12,11 @@
           "reason": "subtree"
         },
         {
+          "object": "LayoutBlockFlow DIV",
+          "rect": [8, 8, 100, 100],
+          "reason": "subtree"
+        },
+        {
           "object": "LayoutSVGForeignObject foreignObject",
           "rect": [8, 8, 100, 100],
           "reason": "subtree"
@@ -27,6 +32,14 @@
     {
       "object": "LayoutBlockFlow DIV",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGForeignObject foreignObject",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/transform-text-element-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/svg/transform-text-element-expected.txt
index 8368667..c174a39f 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/transform-text-element-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/transform-text-element-expected.txt
@@ -12,6 +12,11 @@
           "reason": "subtree"
         },
         {
+          "object": "LayoutSVGInlineText #text",
+          "rect": [8, 8, 400, 100],
+          "reason": "subtree"
+        },
+        {
           "object": "LayoutSVGText text",
           "rect": [8, 8, 400, 100],
           "reason": "subtree"
@@ -35,6 +40,22 @@
     {
       "object": "InlineTextBox 'Test'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Test'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/create-layer-repaint-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/create-layer-repaint-expected.txt
index d5de693..4c352c66 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/create-layer-repaint-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/create-layer-repaint-expected.txt
@@ -10,6 +10,11 @@
           "object": "LayoutBlockFlow DIV id='test' class='stretchy'",
           "rect": [28, 56, 500, 50],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow DIV id='test' class='stretchy'",
+          "rect": [28, 56, 250, 50],
+          "reason": "subtree"
         }
       ]
     }
@@ -18,6 +23,10 @@
     {
       "object": "LayoutBlockFlow DIV id='test' class='stretchy'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV id='test' class='stretchy'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/scroll-descendant-with-cached-cliprects-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/scroll-descendant-with-cached-cliprects-expected.txt
index 53b3d9a..d3c275a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/scroll-descendant-with-cached-cliprects-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/scroll-descendant-with-cached-cliprects-expected.txt
@@ -12,17 +12,7 @@
           "reason": "subtree"
         },
         {
-          "object": "LayoutBlockFlow (relative positioned) DIV id='ul'",
-          "rect": [677, 252, 100, 100],
-          "reason": "subtree"
-        },
-        {
-          "object": "LayoutBlockFlow DIV",
-          "rect": [677, 252, 100, 100],
-          "reason": "subtree"
-        },
-        {
-          "object": "LayoutBlockFlow (positioned) DIV id='scrollpanel'",
+          "object": "LayoutBlockFlow (relative positioned) DIV class='container'",
           "rect": [677, 52, 100, 100],
           "reason": "subtree"
         },
@@ -35,12 +25,33 @@
           "object": "LayoutBlockFlow DIV",
           "rect": [677, 52, 100, 100],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow DIV id='scrollpanel'",
+          "rect": [677, 52, 100, 100],
+          "reason": "subtree"
         }
       ]
     }
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutBlockFlow DIV id='scrollpanel'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (relative positioned) DIV class='container'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (relative positioned) DIV id='ul'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutBlockFlow (positioned) DIV id='scrollpanel'",
       "reason": "style change"
     },
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/tabgroup-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/tabgroup-expected.txt
index b3ee5f8a..e18b053 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/tabgroup-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/tabgroup-expected.txt
@@ -329,6 +329,126 @@
       "reason": "layoutObject removal"
     },
     {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Geodata'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Browser'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Download'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Folder'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Your'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Account'",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutSVGPath path",
       "reason": "layoutObject removal"
     },
@@ -365,6 +485,46 @@
       "reason": "layoutObject removal"
     },
     {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Help'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox '& Info'",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutSVGPath path",
       "reason": "layoutObject removal"
     },
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/text-repaint-including-stroke-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/text-repaint-including-stroke-expected.txt
index e03f34c..4eda401 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/text-repaint-including-stroke-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/text-repaint-including-stroke-expected.txt
@@ -12,6 +12,11 @@
           "reason": "subtree"
         },
         {
+          "object": "LayoutSVGInlineText #text",
+          "rect": [30, 0, 404, 59],
+          "reason": "subtree"
+        },
+        {
           "object": "LayoutSVGText text id='bounce'",
           "rect": [30, 0, 404, 59],
           "reason": "subtree"
@@ -35,6 +40,22 @@
     {
       "object": "InlineTextBox 'Repaint me!'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGText text id='bounce'",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Repaint me!'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/transform-inline-layered-child-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/transform-inline-layered-child-expected.txt
index 8df5a1d..7381642 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/transform-inline-layered-child-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/transform-inline-layered-child-expected.txt
@@ -17,8 +17,8 @@
           "reason": "subtree"
         },
         {
-          "object": "LayoutText #text",
-          "rect": [135, 361, 159, 194],
+          "object": "LayoutBlockFlow (positioned) DIV id='box'",
+          "rect": [100, 100, 100, 180],
           "reason": "subtree"
         },
         {
@@ -126,6 +126,98 @@
     {
       "object": "LayoutText #text",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV id='box'",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutInline (relative positioned) SPAN id='child'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'A B C'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'D E F'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'G H I'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'J K L'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'M N O'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'P Q R'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'S T U'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'V W X'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Y Z'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/scroll-descendant-with-cached-cliprects-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/scroll-descendant-with-cached-cliprects-expected.txt
index f587970..97d288d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/scroll-descendant-with-cached-cliprects-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/scroll-descendant-with-cached-cliprects-expected.txt
@@ -27,11 +27,6 @@
           "reason": "subtree"
         },
         {
-          "object": "LayoutBlockFlow (positioned) DIV id='scrollpanel'",
-          "rect": [677, 52, 100, 100],
-          "reason": "subtree"
-        },
-        {
           "object": "LayoutBlockFlow (relative positioned) DIV class='container'",
           "rect": [677, 52, 100, 100],
           "reason": "subtree"
@@ -45,12 +40,33 @@
           "object": "LayoutBlockFlow DIV",
           "rect": [677, 52, 100, 100],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow DIV id='scrollpanel'",
+          "rect": [677, 52, 100, 100],
+          "reason": "subtree"
         }
       ]
     }
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutBlockFlow DIV id='scrollpanel'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (relative positioned) DIV class='container'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (relative positioned) DIV id='ul'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutBlockFlow (positioned) DIV id='scrollpanel'",
       "reason": "style change"
     },
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.txt
index 561d111..a93d452 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.txt
@@ -834,6 +834,126 @@
       "reason": "layoutObject removal"
     },
     {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Geodata'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Browser'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Download'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Folder'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Your'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Account'",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutSVGPath path",
       "reason": "layoutObject removal"
     },
@@ -870,6 +990,46 @@
       "reason": "layoutObject removal"
     },
     {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Help'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox '& Info'",
+      "reason": "subtree"
+    },
+    {
       "object": "LayoutSVGPath path",
       "reason": "layoutObject removal"
     },
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/text-repaint-including-stroke-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/text-repaint-including-stroke-expected.txt
index 7d3df63..d6cb3420 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/text-repaint-including-stroke-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/text-repaint-including-stroke-expected.txt
@@ -45,6 +45,22 @@
     {
       "object": "InlineTextBox 'Repaint me!'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGText text id='bounce'",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Repaint me!'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/transform-inline-layered-child-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/transform-inline-layered-child-expected.txt
index 33ee647e..13c834da 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/transform-inline-layered-child-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/transform-inline-layered-child-expected.txt
@@ -22,6 +22,11 @@
           "reason": "subtree"
         },
         {
+          "object": "LayoutBlockFlow (positioned) DIV id='box'",
+          "rect": [100, 100, 100, 180],
+          "reason": "subtree"
+        },
+        {
           "object": "LayoutInline (relative positioned) SPAN id='child'",
           "rect": [300, 300, 80, 179],
           "reason": "subtree"
@@ -131,6 +136,98 @@
     {
       "object": "LayoutText #text",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV id='box'",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutInline (relative positioned) SPAN id='child'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'A B C'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'D E F'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'G H I'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'J K L'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'M N O'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'P Q R'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'S T U'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'V W X'",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Y Z'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/scroll-in-transformed-layer-expected.txt b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/scroll-in-transformed-layer-expected.txt
index cb3027f..0baea79 100644
--- a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/scroll-in-transformed-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/scroll-in-transformed-layer-expected.txt
@@ -20,6 +20,11 @@
           "object": "LayoutBlockFlow (positioned) DIV class='absolute red'",
           "rect": [100, 150, 100, 100],
           "reason": "subtree"
+        },
+        {
+          "object": "LayoutBlockFlow (positioned) DIV id='moveMe' class='absolute clipped rotated'",
+          "rect": [100, 150, 100, 100],
+          "reason": "subtree"
         }
       ]
     }
@@ -36,6 +41,18 @@
     {
       "object": "LayoutBlockFlow (positioned) DIV class='absolute red'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV id='moveMe' class='absolute clipped rotated'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='absolute green'",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='absolute red'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/svg/transform-foreign-object-expected.txt b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/svg/transform-foreign-object-expected.txt
index d051621..524e40f 100644
--- a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/svg/transform-foreign-object-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/svg/transform-foreign-object-expected.txt
@@ -37,6 +37,14 @@
     {
       "object": "LayoutBlockFlow DIV",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGForeignObject foreignObject",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutBlockFlow DIV",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/svg/transform-text-element-expected.txt b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/svg/transform-text-element-expected.txt
index 9b8351f2..ef7d1ca 100644
--- a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/svg/transform-text-element-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/svg/transform-text-element-expected.txt
@@ -45,6 +45,22 @@
     {
       "object": "InlineTextBox 'Test'",
       "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGText text",
+      "reason": "subtree"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "subtree"
+    },
+    {
+      "object": "InlineTextBox 'Test'",
+      "reason": "subtree"
     }
   ]
 }
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 898288d9..db22eac 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1316,6 +1316,8 @@
     "layout/ng/geometry/ng_logical_offset_test.cc",
     "layout/ng/geometry/ng_physical_rect_test.cc",
     "layout/ng/ng_absolute_utils_test.cc",
+    "layout/ng/ng_base_layout_algorithm_test.cc",
+    "layout/ng/ng_base_layout_algorithm_test.h",
     "layout/ng/ng_block_child_iterator_test.cc",
     "layout/ng/ng_block_layout_algorithm_test.cc",
     "layout/ng/ng_block_node_test.cc",
@@ -1326,6 +1328,7 @@
     "layout/ng/ng_length_utils_test.cc",
     "layout/ng/ng_min_max_content_size_test.cc",
     "layout/ng/ng_out_of_flow_layout_part_test.cc",
+    "layout/ng/ng_text_layout_algorithm_test.cc",
     "layout/shapes/BoxShapeTest.cpp",
     "layout/svg/LayoutSVGRootTest.cpp",
     "loader/DocumentLoadTimingTest.cpp",
diff --git a/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp b/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
index 0990fdef..5ad7545a 100644
--- a/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
+++ b/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
@@ -133,9 +133,17 @@
     if (m_layoutBlock)
       m_layoutBlock->setMayNeedPaintInvalidation();
     m_layoutBlock = newLayoutBlock;
-    if (newLayoutBlock)
-      m_needsPaintInvalidation = true;
     m_visualRect = LayoutRect();
+    if (newLayoutBlock) {
+      m_needsPaintInvalidation = true;
+      if (newLayoutBlock == m_previousLayoutBlock) {
+        // The caret has disappeared and is reappearing in the same block,
+        // since the last paint invalidation. Set m_visualRect as if the caret
+        // has always been there as paint invalidation doesn't care about the
+        // intermediate changes.
+        m_visualRect = m_visualRectInPreviousLayoutBlock;
+      }
+    }
   }
 
   if (!newLayoutBlock) {
diff --git a/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp b/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp
index 8cb6cd6b..4bd3154 100644
--- a/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp
+++ b/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp
@@ -19,6 +19,7 @@
   void SetUp() override {
     RenderingTest::SetUp();
     enableCompositing();
+    selection().setCaretBlinkingSuspended(true);
   }
 
   const RasterInvalidationTracking* getRasterInvalidationTracking() const {
@@ -222,4 +223,52 @@
   document().view()->setTracksPaintInvalidations(false);
 }
 
+TEST_F(CaretDisplayItemClientTest, CaretHideMoveAndShow) {
+  document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION);
+  document().page()->focusController().setActive(true);
+  document().page()->focusController().setFocused(true);
+
+  Text* text = appendTextNode("Hello, World!");
+  document().body()->focus();
+  updateAllLifecyclePhases();
+  const auto* block = toLayoutBlock(document().body()->layoutObject());
+
+  LayoutRect caretVisualRect = caretDisplayItemClient().visualRect();
+  EXPECT_EQ(1, caretVisualRect.width());
+  EXPECT_EQ(block->location(), caretVisualRect.location());
+
+  // Simulate that the blinking cursor becomes invisible.
+  selection().setCaretVisible(false);
+  // Move the caret to the end of the text.
+  document().view()->setTracksPaintInvalidations(true);
+  selection().setSelection(
+      SelectionInDOMTree::Builder().collapse(Position(text, 5)).build());
+  // Simulate that the cursor blinking is restarted.
+  selection().setCaretVisible(true);
+  updateAllLifecyclePhases();
+
+  LayoutRect newCaretVisualRect = caretDisplayItemClient().visualRect();
+  EXPECT_EQ(caretVisualRect.size(), newCaretVisualRect.size());
+  EXPECT_EQ(caretVisualRect.y(), newCaretVisualRect.y());
+  EXPECT_LT(caretVisualRect.x(), newCaretVisualRect.x());
+
+  const auto& rasterInvalidations =
+      getRasterInvalidationTracking()->trackedRasterInvalidations;
+  ASSERT_EQ(2u, rasterInvalidations.size());
+  EXPECT_EQ(enclosingIntRect(caretVisualRect), rasterInvalidations[0].rect);
+  EXPECT_EQ(block, rasterInvalidations[0].client);
+  EXPECT_EQ(PaintInvalidationCaret, rasterInvalidations[0].reason);
+  EXPECT_EQ(enclosingIntRect(newCaretVisualRect), rasterInvalidations[1].rect);
+  EXPECT_EQ(block, rasterInvalidations[1].client);
+  EXPECT_EQ(PaintInvalidationCaret, rasterInvalidations[1].reason);
+
+  auto objectInvalidations =
+      document().view()->trackedObjectPaintInvalidationsAsJSON();
+  ASSERT_EQ(1u, objectInvalidations->size());
+  String s;
+  JSONObject::cast(objectInvalidations->at(0))->get("object")->asString(&s);
+  EXPECT_EQ("Caret", s);
+  document().view()->setTracksPaintInvalidations(false);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
index 54951eb..0507c39 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -262,12 +262,14 @@
 
 void LayoutBoxModelObject::styleWillChange(StyleDifference diff,
                                            const ComputedStyle& newStyle) {
-  // This object's layer may cease to be a stacking context, in which case the
-  // paint invalidation container of the children may change. Thus we need to
-  // invalidate paint eagerly for all such children.
-  if (hasLayer() && enclosingLayer()->stackingNode() &&
-      enclosingLayer()->stackingNode()->isStackingContext() &&
-      !newStyle.isStackingContext()) {
+  // This object's layer may begin or cease to be a stacking context, in which
+  // case the paint invalidation container of this object and descendants may
+  // change. Thus we need to invalidate paint eagerly for all such children.
+  // PaintLayerCompositor::paintInvalidationOnCompositingChange() doesn't work
+  // for the case because we can only see the new paintInvalidationContainer
+  // during compositing update.
+  if (style() &&
+      (style()->isStackingContext() != newStyle.isStackingContext())) {
     // The following disablers are valid because we need to invalidate based on
     // the current status.
     DisableCompositingQueryAsserts compositingDisabler;
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_offset.cc b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_offset.cc
index 5c7edf0b..c00d7d7 100644
--- a/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_offset.cc
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_offset.cc
@@ -56,6 +56,10 @@
          std::tie(inline_offset, block_offset);
 }
 
+bool NGLogicalOffset::operator!=(const NGLogicalOffset& other) const {
+  return !operator==(other);
+}
+
 NGLogicalOffset NGLogicalOffset::operator+(const NGLogicalOffset& other) const {
   NGLogicalOffset result;
   result.inline_offset = this->inline_offset + other.inline_offset;
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_offset.h b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_offset.h
index c27a569..8439d50 100644
--- a/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_offset.h
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_offset.h
@@ -38,6 +38,7 @@
                                      NGPhysicalSize inner_size) const;
 
   bool operator==(const NGLogicalOffset& other) const;
+  bool operator!=(const NGLogicalOffset& other) const;
 
   NGLogicalOffset operator+(const NGLogicalOffset& other) const;
   NGLogicalOffset& operator+=(const NGLogicalOffset& other);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_base_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_base_layout_algorithm_test.cc
new file mode 100644
index 0000000..32399911
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_base_layout_algorithm_test.cc
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/layout/ng/ng_base_layout_algorithm_test.h"
+
+#include "core/layout/ng/layout_ng_block_flow.h"
+#include "core/layout/ng/ng_block_layout_algorithm.h"
+#include "core/layout/ng/ng_physical_fragment.h"
+namespace blink {
+
+NGBaseLayoutAlgorithmTest::NGBaseLayoutAlgorithmTest() {
+  RuntimeEnabledFeatures::setLayoutNGEnabled(true);
+  RuntimeEnabledFeatures::setLayoutNGInlineEnabled(true);
+}
+
+NGBaseLayoutAlgorithmTest::~NGBaseLayoutAlgorithmTest() {
+  RuntimeEnabledFeatures::setLayoutNGEnabled(false);
+  RuntimeEnabledFeatures::setLayoutNGInlineEnabled(false);
+}
+
+void NGBaseLayoutAlgorithmTest::SetUp() {
+  RenderingTest::SetUp();
+  enableCompositing();
+}
+
+std::pair<RefPtr<NGPhysicalBoxFragment>, RefPtr<NGConstraintSpace>>
+NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithmForElement(Element* element) {
+  LayoutNGBlockFlow* block_flow = toLayoutNGBlockFlow(element->layoutObject());
+  NGBlockNode* node = new NGBlockNode(block_flow);
+  RefPtr<NGConstraintSpace> space =
+      NGConstraintSpace::CreateFromLayoutObject(*block_flow);
+
+  RefPtr<NGLayoutResult> result =
+      NGBlockLayoutAlgorithm(node, space.get()).Layout();
+  return std::make_pair(
+      toNGPhysicalBoxFragment(result->PhysicalFragment().get()), space);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_base_layout_algorithm_test.h b/third_party/WebKit/Source/core/layout/ng/ng_base_layout_algorithm_test.h
new file mode 100644
index 0000000..1e007240
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_base_layout_algorithm_test.h
@@ -0,0 +1,30 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/layout/LayoutTestHelper.h"
+
+#include "core/dom/Element.h"
+#include "core/layout/ng/ng_constraint_space.h"
+#include "core/layout/ng/ng_physical_box_fragment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+// Base class for all LayoutNG Algorithms unit test classes.
+typedef bool TestParamLayoutNG;
+class NGBaseLayoutAlgorithmTest
+    : public ::testing::WithParamInterface<TestParamLayoutNG>,
+      public RenderingTest {
+ public:
+  NGBaseLayoutAlgorithmTest();
+  ~NGBaseLayoutAlgorithmTest();
+
+ protected:
+  void SetUp() override;
+
+  std::pair<RefPtr<NGPhysicalBoxFragment>, RefPtr<NGConstraintSpace>>
+  RunBlockLayoutAlgorithmForElement(Element* element);
+};
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index f3a53a8a..75f6bc60 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -697,6 +697,7 @@
     PositionPendingFloats(curr_bfc_offset_.block_offset,
                           MutableConstraintSpace(), &builder_);
     curr_margin_strut_ = {};
+    space_builder_.SetBfcOffset(curr_bfc_offset_);
 
     return space_builder_.ToConstraintSpace(
         FromPlatformWritingMode(Style().getWritingMode()));
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
index c9648b95..2d850cc 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -8,6 +8,7 @@
 #include "core/dom/TagCollection.h"
 #include "core/layout/LayoutTestHelper.h"
 #include "core/layout/ng/layout_ng_block_flow.h"
+#include "core/layout/ng/ng_base_layout_algorithm_test.h"
 #include "core/layout/ng/ng_block_break_token.h"
 #include "core/layout/ng/ng_block_node.h"
 #include "core/layout/ng/ng_constraint_space.h"
@@ -18,7 +19,6 @@
 #include "core/layout/ng/ng_physical_fragment.h"
 #include "core/style/ComputedStyle.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
 namespace {
@@ -48,25 +48,11 @@
       .ToConstraintSpace(writing_mode);
 }
 
-typedef bool TestParamLayoutNG;
-class NGBlockLayoutAlgorithmTest
-    : public ::testing::WithParamInterface<TestParamLayoutNG>,
-      public RenderingTest {
- public:
-  NGBlockLayoutAlgorithmTest() {
-    RuntimeEnabledFeatures::setLayoutNGEnabled(true);
-    RuntimeEnabledFeatures::setLayoutNGInlineEnabled(true);
-  }
-  ~NGBlockLayoutAlgorithmTest() {
-    RuntimeEnabledFeatures::setLayoutNGEnabled(false);
-    RuntimeEnabledFeatures::setLayoutNGInlineEnabled(false);
-  }
-
+class NGBlockLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest {
  protected:
   void SetUp() override {
+    NGBaseLayoutAlgorithmTest::SetUp();
     style_ = ComputedStyle::create();
-    RenderingTest::SetUp();
-    enableCompositing();
   }
 
   RefPtr<NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
@@ -78,20 +64,6 @@
     return toNGPhysicalBoxFragment(result->PhysicalFragment().get());
   }
 
-  std::pair<RefPtr<NGPhysicalBoxFragment>, RefPtr<NGConstraintSpace>>
-  RunBlockLayoutAlgorithmForElement(Element* element) {
-    LayoutNGBlockFlow* block_flow =
-        toLayoutNGBlockFlow(element->layoutObject());
-    NGBlockNode* node = new NGBlockNode(block_flow);
-    RefPtr<NGConstraintSpace> space =
-        NGConstraintSpace::CreateFromLayoutObject(*block_flow);
-
-    RefPtr<NGLayoutResult> result =
-        NGBlockLayoutAlgorithm(node, space.get()).Layout();
-    return std::make_pair(
-        toNGPhysicalBoxFragment(result->PhysicalFragment().get()), space);
-  }
-
   MinMaxContentSize RunComputeMinAndMax(NGBlockNode* node) {
     // The constraint space is not used for min/max computation, but we need
     // it to create the algorithm.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
index 95a0349..1b6669b 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
@@ -135,10 +135,14 @@
   return static_cast<NGFragmentationType>(block_direction_fragmentation_type_);
 }
 
-NGLayoutOpportunityIterator* NGConstraintSpace::LayoutOpportunityIterator() {
+NGLayoutOpportunityIterator* NGConstraintSpace::LayoutOpportunityIterator(
+    const NGLogicalOffset& iter_offset) {
+  if (layout_opp_iter_ && layout_opp_iter_->Offset() != iter_offset)
+    layout_opp_iter_.reset();
+
   if (!layout_opp_iter_) {
     layout_opp_iter_ =
-        WTF::makeUnique<NGLayoutOpportunityIterator>(this, this->bfc_offset_);
+        WTF::makeUnique<NGLayoutOpportunityIterator>(this, iter_offset);
   }
   return layout_opp_iter_.get();
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
index 9fdb2b09..a3e36d4a 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
@@ -108,7 +108,11 @@
   // blockSize if possible.
   NGFragmentationType BlockFragmentationType() const;
 
-  NGLayoutOpportunityIterator* LayoutOpportunityIterator();
+  // Returns a pointer to already existing Layout Opportunity iterator
+  // associated with this constraint space and {@code iter_offset} or creates a
+  // new one.
+  NGLayoutOpportunityIterator* LayoutOpportunityIterator(
+      const NGLogicalOffset& iter_offset);
 
   // Return true if this contraint space participates in a fragmentation
   // context.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
index d2956df..5ddce39 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "core/layout/ng/ng_layout_opportunity_iterator.h"
-
 #include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_exclusion.h"
 #include "wtf/NonCopyingSort.h"
@@ -277,25 +276,23 @@
 
 NGLayoutOpportunityIterator::NGLayoutOpportunityIterator(
     const NGConstraintSpace* space,
-    const WTF::Optional<NGLogicalOffset>& opt_origin_point,
+    const WTF::Optional<NGLogicalOffset>& opt_offset,
     const WTF::Optional<NGLogicalOffset>& opt_leader_point)
-    : constraint_space_(space) {
+    : constraint_space_(space),
+      offset_(opt_offset ? opt_offset.value() : space->BfcOffset()) {
   // TODO(chrome-layout-team): Combine exclusions that shadow each other.
   auto& exclusions = constraint_space_->Exclusions();
   DCHECK(std::is_sorted(exclusions->storage.begin(), exclusions->storage.end(),
                         &CompareNGExclusionsByTopAsc))
       << "Exclusions are expected to be sorted by TOP";
 
-  NGLogicalOffset origin_point =
-      opt_origin_point ? opt_origin_point.value() : NGLogicalOffset();
   NGLayoutOpportunity initial_opportunity =
-      CreateLayoutOpportunityFromConstraintSpace(*constraint_space_,
-                                                 origin_point);
+      CreateLayoutOpportunityFromConstraintSpace(*constraint_space_, Offset());
   opportunity_tree_root_ = new NGLayoutOpportunityTreeNode(initial_opportunity);
 
   if (opt_leader_point) {
     const NGExclusion leader_exclusion =
-        ToLeaderExclusion(origin_point, opt_leader_point.value());
+        ToLeaderExclusion(Offset(), opt_leader_point.value());
     InsertExclusion(MutableOpportunityTreeRoot(), &leader_exclusion,
                     opportunities_);
   }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
index 9ecf8bd4..dc06eca2 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
@@ -10,6 +10,7 @@
 #include "platform/heap/Handle.h"
 #include "wtf/Optional.h"
 #include "wtf/Vector.h"
+#include "wtf/text/StringBuilder.h"
 
 namespace blink {
 
@@ -23,21 +24,25 @@
   //
   // @param space Constraint space with exclusions for which this iterator needs
   //              to generate layout opportunities.
-  // @param opt_origin_point Optional origin_point parameter that is used as a
-  //                         default start point for layout opportunities.
+  // @param opt_offset Optional offset parameter that is used as a
+  //                   default start point for layout opportunities.
   // @param opt_leader_point Optional 'leader' parameter that is used to specify
   //                         the ending point of temporary excluded rectangle
   //                         which starts from 'origin'. This rectangle may
   //                         represent a text fragment for example.
   NGLayoutOpportunityIterator(
       const NGConstraintSpace* space,
-      const WTF::Optional<NGLogicalOffset>& opt_origin_point = WTF::nullopt,
+      const WTF::Optional<NGLogicalOffset>& opt_offset = WTF::nullopt,
       const WTF::Optional<NGLogicalOffset>& opt_leader_point = WTF::nullopt);
 
   // Gets the next Layout Opportunity or nullptr if the search is exhausted.
   // TODO(chrome-layout-team): Refactor with using C++ <iterator> library.
   const NGLayoutOpportunity Next();
 
+  // Offset that specifies the starting point to search layout opportunities.
+  // It's either {@code opt_offset} or space->BfcOffset().
+  NGLogicalOffset Offset() const { return offset_; }
+
 #ifndef NDEBUG
   // Prints Layout Opportunity tree for debug purposes.
   void ShowLayoutOpportunityTree() const;
@@ -59,6 +64,7 @@
   NGLayoutOpportunities opportunities_;
   NGLayoutOpportunities::const_iterator opportunity_iter_;
   Persistent<NGLayoutOpportunityTreeNode> opportunity_tree_root_;
+  NGLogicalOffset offset_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
index 40fcb42..de7113fd 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
@@ -20,7 +20,7 @@
 namespace blink {
 
 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box,
-                             const NGConstraintSpace* constraint_space)
+                             NGConstraintSpace* constraint_space)
     : inline_box_(inline_box),
       constraint_space_(constraint_space),
       baseline_type_(constraint_space->WritingMode() ==
@@ -35,7 +35,7 @@
 }
 
 bool NGLineBuilder::CanFitOnLine() const {
-  LayoutUnit available_size = constraint_space_->AvailableSize().inline_size;
+  LayoutUnit available_size = current_opportunity_.InlineSize();
   if (available_size == NGSizeIndefinite)
     return true;
   return end_position_ <= available_size;
@@ -59,6 +59,8 @@
   start_index_ = last_index_ = last_break_opportunity_index_ = index;
   start_offset_ = end_offset_ = last_break_opportunity_offset_ = offset;
   end_position_ = last_break_opportunity_position_ = LayoutUnit();
+
+  FindNextLayoutOpportunity();
 }
 
 void NGLineBuilder::SetEnd(unsigned end_offset) {
@@ -146,6 +148,8 @@
 #if DCHECK_IS_ON()
   is_bidi_reordered_ = false;
 #endif
+
+  FindNextLayoutOpportunity();
 }
 
 void NGLineBuilder::BidiReorder(Vector<LineItemChunk, 32>* line_item_chunks) {
@@ -189,7 +193,7 @@
 
   NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText,
                                  inline_box_);
-  text_builder.SetWritingMode(constraint_space_->WritingMode());
+  text_builder.SetWritingMode(ConstraintSpace().WritingMode());
   line_box_data_list_.grow(line_box_data_list_.size() + 1);
   LineBoxData& line_box_data = line_box_data_list_.back();
 
@@ -238,7 +242,12 @@
         line_item_chunk.index, line_item_chunk.start_offset,
         line_item_chunk.end_offset);
     fragments_.push_back(std::move(text_fragment));
-    offsets_.push_back(NGLogicalOffset(line_box_data.inline_size, top));
+
+    NGLogicalOffset logical_offset(
+        line_box_data.inline_size + current_opportunity_.InlineStartOffset() -
+            ConstraintSpace().BfcOffset().inline_offset,
+        top);
+    offsets_.push_back(logical_offset);
     line_box_data.inline_size += line_item_chunk.inline_size;
   }
   DCHECK_EQ(fragments_.size(), offsets_.size());
@@ -319,6 +328,15 @@
   }
 }
 
+void NGLineBuilder::FindNextLayoutOpportunity() {
+  NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
+  iter_offset.block_offset += content_size_;
+  auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset);
+  NGLayoutOpportunity opportunity = iter->Next();
+  if (!opportunity.IsEmpty())
+    current_opportunity_ = opportunity;
+}
+
 void NGLineBuilder::CreateFragments(NGFragmentBuilder* container_builder) {
   DCHECK(!HasItems()) << "Must call CreateLine()";
   DCHECK_EQ(fragments_.size(), offsets_.size());
@@ -330,7 +348,6 @@
   }
 
   // TODO(kojii): Check if the line box width should be content or available.
-  // TODO(kojii): Need to take constraint_space into account.
   container_builder->SetInlineSize(max_inline_size_)
       .SetInlineOverflow(max_inline_size_)
       .SetBlockSize(content_size_)
@@ -387,7 +404,7 @@
     BidiRun* run = bidi_runs.firstRun();
     for (auto* physical_fragment : fragments_for_bidi_runs) {
       DCHECK(run);
-      NGTextFragment fragment(constraint_space_->WritingMode(),
+      NGTextFragment fragment(ConstraintSpace().WritingMode(),
                               toNGPhysicalTextFragment(physical_fragment));
       InlineBox* inline_box = run->m_box;
       inline_box->setLogicalWidth(fragment.InlineSize());
@@ -412,5 +429,4 @@
     fragments_for_bidi_runs.clear();
   }
 }
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.h
index fb5651b..6dcb0ef 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.h
@@ -7,6 +7,7 @@
 
 #include "core/CoreExport.h"
 #include "core/layout/ng/geometry/ng_logical_offset.h"
+#include "core/layout/ng/ng_layout_opportunity_iterator.h"
 #include "core/layout/ng/ng_physical_fragment.h"
 #include "platform/fonts/FontBaseline.h"
 #include "platform/heap/Handle.h"
@@ -30,7 +31,7 @@
   STACK_ALLOCATED();
 
  public:
-  NGLineBuilder(NGInlineNode*, const NGConstraintSpace*);
+  NGLineBuilder(NGInlineNode*, NGConstraintSpace*);
 
   const NGConstraintSpace& ConstraintSpace() const {
     return *constraint_space_;
@@ -139,8 +140,11 @@
                            const LineItemChunk&,
                            LineBoxData*);
 
+  // Finds the next layout opportunity for the next text fragment.
+  void FindNextLayoutOpportunity();
+
   Persistent<NGInlineNode> inline_box_;
-  const NGConstraintSpace* constraint_space_;  // Not owned as STACK_ALLOCATED.
+  NGConstraintSpace* constraint_space_;  // Not owned as STACK_ALLOCATED.
   Vector<RefPtr<NGPhysicalFragment>, 32> fragments_;
   Vector<NGLogicalOffset, 32> offsets_;
   Vector<LineBoxData, 32> line_box_data_list_;
@@ -156,6 +160,9 @@
   LayoutUnit max_inline_size_;
   FontBaseline baseline_type_;
 
+  NGLogicalOffset bfc_offset_;
+  NGLogicalRect current_opportunity_;
+
 #if DCHECK_IS_ON()
   unsigned is_bidi_reordered_ : 1;
 #endif
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc
index ab37fec..ec6a203 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc
@@ -9,6 +9,7 @@
 #include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_fragment_builder.h"
 #include "core/layout/ng/ng_inline_node.h"
+#include "core/layout/ng/ng_layout_opportunity_iterator.h"
 #include "core/layout/ng/ng_line_builder.h"
 #include "core/layout/ng/ng_text_fragment.h"
 #include "core/style/ComputedStyle.h"
@@ -72,6 +73,8 @@
 
     // If there are more available spaces, mark the break opportunity and fetch
     // more text.
+    // TODO(layout-ng): check if the height of the linebox can fit within
+    // the current opportunity.
     if (line_builder->CanFitOnLine()) {
       line_builder->SetBreakOpportunity();
       continue;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm_test.cc
new file mode 100644
index 0000000..242428f
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm_test.cc
@@ -0,0 +1,101 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/layout/ng/ng_base_layout_algorithm_test.h"
+
+#include "core/dom/TagCollection.h"
+#include "core/layout/line/InlineTextBox.h"
+#include "core/layout/ng/ng_inline_node.h"
+#include "core/layout/ng/ng_physical_text_fragment.h"
+#include "platform/geometry/LayoutPoint.h"
+#include "platform/geometry/LayoutRect.h"
+
+namespace blink {
+namespace {
+
+class NGTextLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest {};
+
+// Verifies that text can flow correctly around floats that were positioned
+// before the inline block.
+TEST_F(NGTextLayoutAlgorithmTest, TextFloatsAroundFloatsBefore) {
+  setBodyInnerHTML(R"HTML(
+    <!DOCTYPE html>
+    <style>
+      * {
+        font-family: "Arial", sans-serif;
+        font-size: 19px;
+      }
+      #container {
+        height: 200px; width: 200px; outline: solid blue;
+      }
+      #left-float1 {
+        float: left; width: 30px; height: 30px; background-color: blue;
+      }
+      #left-float2 {
+        float: left; width: 10px; height: 10px;
+        background-color: purple;
+      }
+      #right-float {
+        float: right; width: 40px; height: 40px; background-color: yellow;
+      }
+    </style>
+    <div id="container">
+      <div id="left-float1"></div>
+      <div id="left-float2"></div>
+      <div id="right-float"></div>
+      <span id="text">The quick brown fox jumps over the lazy dog</span>
+    </div>
+  )HTML");
+  // ** Run LayoutNG algorithm **
+  RefPtr<NGConstraintSpace> space;
+  RefPtr<NGPhysicalBoxFragment> html_fragment;
+  std::tie(html_fragment, space) = RunBlockLayoutAlgorithmForElement(
+      document().getElementsByTagName("html")->item(0));
+  auto* body_fragment =
+      toNGPhysicalBoxFragment(html_fragment->Children()[0].get());
+  auto* container_fragment =
+      toNGPhysicalBoxFragment(body_fragment->Children()[0].get());
+  auto* text_fragments_wrapper =
+      toNGPhysicalBoxFragment(container_fragment->Children()[0].get());
+
+  LayoutText* layout_text =
+      toLayoutText(getLayoutObjectByElementId("text")->slowFirstChild());
+  ASSERT(layout_text->hasTextBoxes());
+
+  // TODO(glebl): Should have only 3 text fragments. For some reason we have a
+  // left over fragment with text == "dog".
+  ASSERT_EQ(4UL, text_fragments_wrapper->Children().size());
+
+  auto* text_fragment1 =
+      toNGPhysicalTextFragment(text_fragments_wrapper->Children()[0].get());
+  auto* text_node = text_fragment1->Node();
+  // 40 = #left-float1' width 30 + #left-float2 10
+  EXPECT_EQ(LayoutUnit(40), text_fragment1->LeftOffset());
+  EXPECT_EQ("The quick ", text_node->Text(text_fragment1->StartOffset(),
+                                          text_fragment1->EndOffset()));
+  InlineTextBox* inline_text_box1 = layout_text->firstTextBox();
+  EXPECT_EQ(LayoutPoint(40, 0), inline_text_box1->frameRect().location());
+
+  auto* text_fragment2 =
+      toNGPhysicalTextFragment(text_fragments_wrapper->Children()[1].get());
+  // 40 = #left-float1' width 30
+  EXPECT_EQ(LayoutUnit(30), text_fragment2->LeftOffset());
+  EXPECT_EQ("brown fox jumps over",
+            text_node->Text(text_fragment2->StartOffset(),
+                            text_fragment2->EndOffset()));
+  InlineTextBox* inline_text_box2 = inline_text_box1->nextTextBox();
+  EXPECT_EQ(LayoutPoint(30, 22), inline_text_box2->frameRect().location());
+
+  auto* text_fragment3 =
+      toNGPhysicalTextFragment(text_fragments_wrapper->Children()[2].get());
+  EXPECT_EQ(LayoutUnit(), text_fragment3->LeftOffset());
+  EXPECT_EQ("jumps over the lazy dog",
+            text_node->Text(text_fragment3->StartOffset(),
+                            text_fragment3->EndOffset()));
+  InlineTextBox* inline_text_box3 = inline_text_box2->nextTextBox();
+  EXPECT_EQ(LayoutPoint(0, 44), inline_text_box3->frameRect().location());
+}
+
+}  // namespace
+}  // namespace blink
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
index ea1cca8..76acb99e 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
@@ -81,13 +81,8 @@
     super(Profiler.CPUProfileType.TypeId, Common.UIString('Record JavaScript CPU Profile'));
     this._recording = false;
 
-    this._nextAnonymousConsoleProfileNumber = 1;
-    this._anonymousConsoleProfileIdToTitle = {};
-
     Profiler.CPUProfileType.instance = this;
     SDK.targetManager.addModelListener(
-        SDK.CPUProfilerModel, SDK.CPUProfilerModel.Events.ConsoleProfileStarted, this._consoleProfileStarted, this);
-    SDK.targetManager.addModelListener(
         SDK.CPUProfilerModel, SDK.CPUProfilerModel.Events.ConsoleProfileFinished, this._consoleProfileFinished, this);
   }
 
@@ -136,56 +131,12 @@
   /**
    * @param {!Common.Event} event
    */
-  _consoleProfileStarted(event) {
-    var data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data);
-    var resolvedTitle = data.title;
-    if (!resolvedTitle) {
-      resolvedTitle = Common.UIString('Profile %s', this._nextAnonymousConsoleProfileNumber++);
-      this._anonymousConsoleProfileIdToTitle[data.id] = resolvedTitle;
-    }
-    this._addMessageToConsole(
-        SDK.ConsoleMessage.MessageType.Profile, data.scriptLocation,
-        Common.UIString('Profile \'%s\' started.', resolvedTitle));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
   _consoleProfileFinished(event) {
     var data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data);
     var cpuProfile = /** @type {!Protocol.Profiler.Profile} */ (data.cpuProfile);
-    var resolvedTitle = data.title;
-    if (typeof resolvedTitle === 'undefined') {
-      resolvedTitle = this._anonymousConsoleProfileIdToTitle[data.id];
-      delete this._anonymousConsoleProfileIdToTitle[data.id];
-    }
-    var profile = new Profiler.CPUProfileHeader(data.scriptLocation.debuggerModel.target(), this, resolvedTitle);
+    var profile = new Profiler.CPUProfileHeader(data.scriptLocation.debuggerModel.target(), this, data.title);
     profile.setProtocolProfile(cpuProfile);
     this.addProfile(profile);
-    this._addMessageToConsole(
-        SDK.ConsoleMessage.MessageType.ProfileEnd, data.scriptLocation,
-        Common.UIString('Profile \'%s\' finished.', resolvedTitle));
-  }
-
-  /**
-   * @param {string} type
-   * @param {!SDK.DebuggerModel.Location} scriptLocation
-   * @param {string} messageText
-   */
-  _addMessageToConsole(type, scriptLocation, messageText) {
-    var script = scriptLocation.script();
-    var target = scriptLocation.debuggerModel.target();
-    var message = new SDK.ConsoleMessage(
-        target, SDK.ConsoleMessage.MessageSource.ConsoleAPI, SDK.ConsoleMessage.MessageLevel.Verbose, messageText, type,
-        undefined, undefined, undefined, undefined, [{
-          functionName: '',
-          scriptId: scriptLocation.scriptId,
-          url: script ? script.contentURL() : '',
-          lineNumber: scriptLocation.lineNumber,
-          columnNumber: scriptLocation.columnNumber || 0
-        }]);
-
-    target.consoleModel.addMessage(message);
   }
 
   startRecordingProfile() {
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfilerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfilerModel.js
index 560bf8f..18d5369 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfilerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfilerModel.js
@@ -36,6 +36,8 @@
   constructor(target) {
     super(target);
     this._isRecording = false;
+    this._nextAnonymousConsoleProfileNumber = 1;
+    this._anonymousConsoleProfileIdToTitle = new Map();
     this._profilerAgent = target.profilerAgent();
     target.registerProfilerDispatcher(this);
     this._profilerAgent.enable();
@@ -49,6 +51,10 @@
    * @param {string=} title
    */
   consoleProfileStarted(id, scriptLocation, title) {
+    if (!title) {
+      title = Common.UIString('Profile %d', this._nextAnonymousConsoleProfileNumber++);
+      this._anonymousConsoleProfileIdToTitle.set(id, title);
+    }
     this._dispatchProfileEvent(SDK.CPUProfilerModel.Events.ConsoleProfileStarted, id, scriptLocation, title);
   }
 
@@ -60,8 +66,15 @@
    * @param {string=} title
    */
   consoleProfileFinished(id, scriptLocation, cpuProfile, title) {
-    this._dispatchProfileEvent(
-        SDK.CPUProfilerModel.Events.ConsoleProfileFinished, id, scriptLocation, title, cpuProfile);
+    if (!title) {
+      title = this._anonymousConsoleProfileIdToTitle.get(id);
+      this._anonymousConsoleProfileIdToTitle.delete(id);
+    }
+    // Make sure ProfilesPanel is initialized and CPUProfileType is created.
+    self.runtime.loadModulePromise('profiler').then(() => {
+      this._dispatchProfileEvent(
+          SDK.CPUProfilerModel.Events.ConsoleProfileFinished, id, scriptLocation, title, cpuProfile);
+    });
   }
 
   /**
@@ -72,14 +85,11 @@
    * @param {!Protocol.Profiler.Profile=} cpuProfile
    */
   _dispatchProfileEvent(eventName, id, scriptLocation, title, cpuProfile) {
-    // Make sure ProfilesPanel is initialized and CPUProfileType is created.
-    self.runtime.loadModulePromise('profiler').then(() => {
-      var debuggerLocation = SDK.DebuggerModel.Location.fromPayload(this._debuggerModel, scriptLocation);
-      var globalId = this.target().id() + '.' + id;
-      var data = /** @type {!SDK.CPUProfilerModel.EventData} */ (
-          {id: globalId, scriptLocation: debuggerLocation, cpuProfile: cpuProfile, title: title});
-      this.dispatchEventToListeners(eventName, data);
-    });
+    var debuggerLocation = SDK.DebuggerModel.Location.fromPayload(this._debuggerModel, scriptLocation);
+    var globalId = this.target().id() + '.' + id;
+    var data = /** @type {!SDK.CPUProfilerModel.EventData} */ (
+        {id: globalId, scriptLocation: debuggerLocation, cpuProfile: cpuProfile, title: title});
+    this.dispatchEventToListeners(eventName, data);
   }
 
   /**
@@ -142,5 +152,5 @@
   ConsoleProfileFinished: Symbol('ConsoleProfileFinished')
 };
 
-/** @typedef {!{id: string, scriptLocation: !SDK.DebuggerModel.Location, title: (string|undefined), cpuProfile: (!Protocol.Profiler.Profile|undefined)}} */
+/** @typedef {!{id: string, scriptLocation: !SDK.DebuggerModel.Location, title: string, cpuProfile: (!Protocol.Profiler.Profile|undefined)}} */
 SDK.CPUProfilerModel.EventData;
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
index 1b915c3..67e3143 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
@@ -58,6 +58,14 @@
         ]);
       }
     }
+
+    var cpuProfilerModel = target.model(SDK.CPUProfilerModel);
+    if (cpuProfilerModel) {
+      cpuProfilerModel.addEventListener(
+          SDK.CPUProfilerModel.Events.ConsoleProfileStarted, this._consoleProfileStarted, this);
+      cpuProfilerModel.addEventListener(
+          SDK.CPUProfilerModel.Events.ConsoleProfileFinished, this._consoleProfileFinished, this);
+    }
   }
 
   /**
@@ -150,6 +158,44 @@
   }
 
   /**
+   * @param {!Common.Event} event
+   */
+  _consoleProfileStarted(event) {
+    var data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data);
+    this._addConsoleProfileMessage(
+        SDK.ConsoleMessage.MessageType.Profile, data.scriptLocation,
+        Common.UIString('Profile \'%s\' started.', data.title));
+  }
+
+  /**
+   * @param {!Common.Event} event
+   */
+  _consoleProfileFinished(event) {
+    var data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data);
+    this._addConsoleProfileMessage(
+        SDK.ConsoleMessage.MessageType.ProfileEnd, data.scriptLocation,
+        Common.UIString('Profile \'%s\' finished.', data.title));
+  }
+
+  /**
+   * @param {string} type
+   * @param {!SDK.DebuggerModel.Location} scriptLocation
+   * @param {string} messageText
+   */
+  _addConsoleProfileMessage(type, scriptLocation, messageText) {
+    var stackTrace = [{
+      functionName: '',
+      scriptId: scriptLocation.scriptId,
+      url: scriptLocation.script() ? scriptLocation.script().contentURL() : '',
+      lineNumber: scriptLocation.lineNumber,
+      columnNumber: scriptLocation.columnNumber || 0
+    }];
+    this.addMessage(new SDK.ConsoleMessage(
+        this.target(), SDK.ConsoleMessage.MessageSource.ConsoleAPI, SDK.ConsoleMessage.MessageLevel.Info, messageText,
+        type, undefined, undefined, undefined, undefined, stackTrace));
+  }
+
+  /**
    * @param {!SDK.ConsoleMessage} msg
    */
   _incrementErrorWarningCount(msg) {
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
index e132c7c..f8404c1 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -40,7 +40,7 @@
 
     target.registerDebuggerDispatcher(new SDK.DebuggerDispatcher(this));
     this._agent = target.debuggerAgent();
-    this._runtimeModel = target.runtimeModel;
+    this._runtimeModel = target.model(SDK.RuntimeModel);
 
     /** @type {?SDK.DebuggerPausedDetails} */
     this._debuggerPausedDetails = null;
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
index a86b299..a6ebdd04 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
@@ -222,7 +222,7 @@
     var frame = this._frames.get(frameId);
     if (frame && !frame.isMainFrame())
       return;
-    if (!Common.moduleSetting('preserveConsoleLog').get())
+    if (!Common.moduleSetting('preserveConsoleLog').get() && this.target().consoleModel)
       this.target().consoleModel.clear();
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
index 2f7119f..47a3b32 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
@@ -244,9 +244,6 @@
     var target = new SDK.Target(this, id, name, capabilitiesMask, connectionFactory, parentTarget);
     this._pendingTargets.add(target);
 
-    /** @type {!SDK.ConsoleModel} */
-    target.consoleModel = /** @type {!SDK.ConsoleModel} */ (target.model(SDK.ConsoleModel));
-
     var networkManager = target.model(SDK.NetworkManager);
     var resourceTreeModel = target.model(SDK.ResourceTreeModel);
     if (networkManager && resourceTreeModel)
@@ -255,6 +252,8 @@
     /** @type {!SDK.RuntimeModel} */
     target.runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel));
     target.model(SDK.DebuggerModel);
+    /** @type {!SDK.ConsoleModel} */
+    target.consoleModel = /** @type {!SDK.ConsoleModel} */ (target.model(SDK.ConsoleModel));
     target.model(SDK.DOMModel);
     target.model(SDK.CSSModel);
     target.model(SDK.CPUProfilerModel);