diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index aef0ec84..fd70b5e 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-9050.0.0
\ No newline at end of file
+9052.0.0
\ No newline at end of file
diff --git a/content/public/test/async_file_test_helper.h b/content/public/test/async_file_test_helper.h
index 562e5a52..c770a822 100644
--- a/content/public/test/async_file_test_helper.h
+++ b/content/public/test/async_file_test_helper.h
@@ -12,13 +12,12 @@
 #include "storage/common/fileapi/file_system_types.h"
 #include "storage/common/quota/quota_status_code.h"
 
-namespace storage {
-class QuotaManager;
-}
+class GURL;
 
 namespace storage {
 class FileSystemContext;
 class FileSystemURL;
+class QuotaManager;
 }
 
 namespace content {
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index b78c429..a5cf95b2 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -76,6 +76,8 @@
   {'name': 'cull_face'},
   {'name': 'depth_test', 'state_flag': 'framebuffer_state_.clear_state_dirty'},
   {'name': 'dither', 'default': True},
+  {'name': 'framebuffer_srgb_ext', 'default': True, 'no_init': True,
+   'extension_flag': 'ext_srgb_write_control'},
   {'name': 'polygon_offset_fill'},
   {'name': 'sample_alpha_to_coverage'},
   {'name': 'sample_coverage'},
@@ -10177,6 +10179,10 @@
       def WriteCapabilities(test_prev, es3_caps):
         for capability in _CAPABILITY_FLAGS:
           capability_name = capability['name']
+          capability_no_init = 'no_init' in capability and \
+              capability['no_init'] == True
+          if capability_no_init:
+            continue
           capability_es3 = 'es3' in capability and capability['es3'] == True
           if capability_es3 and not es3_caps or not capability_es3 and es3_caps:
             continue
@@ -10462,6 +10468,10 @@
 """void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations(
       bool es3_capable) {""")
       for capability in _CAPABILITY_FLAGS:
+        capability_no_init = 'no_init' in capability and \
+            capability['no_init'] == True
+        if capability_no_init:
+            continue
         capability_es3 = 'es3' in capability and capability['es3'] == True
         if capability_es3:
           continue
diff --git a/gpu/command_buffer/service/context_state_autogen.h b/gpu/command_buffer/service/context_state_autogen.h
index c0da2cd..38fae6e 100644
--- a/gpu/command_buffer/service/context_state_autogen.h
+++ b/gpu/command_buffer/service/context_state_autogen.h
@@ -22,6 +22,8 @@
   bool cached_depth_test;
   bool dither;
   bool cached_dither;
+  bool framebuffer_srgb_ext;
+  bool cached_framebuffer_srgb_ext;
   bool polygon_offset_fill;
   bool cached_polygon_offset_fill;
   bool sample_alpha_to_coverage;
@@ -143,6 +145,12 @@
         return;
       enable_flags.cached_dither = enable;
       break;
+    case GL_FRAMEBUFFER_SRGB_EXT:
+      if (enable_flags.cached_framebuffer_srgb_ext == enable &&
+          !ignore_cached_state)
+        return;
+      enable_flags.cached_framebuffer_srgb_ext = enable;
+      break;
     case GL_POLYGON_OFFSET_FILL:
       if (enable_flags.cached_polygon_offset_fill == enable &&
           !ignore_cached_state)
diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h
index 6bc4a82..e3c3900 100644
--- a/gpu/command_buffer/service/context_state_impl_autogen.h
+++ b/gpu/command_buffer/service/context_state_impl_autogen.h
@@ -21,6 +21,8 @@
       cached_depth_test(false),
       dither(true),
       cached_dither(true),
+      framebuffer_srgb_ext(true),
+      cached_framebuffer_srgb_ext(true),
       polygon_offset_fill(false),
       cached_polygon_offset_fill(false),
       sample_alpha_to_coverage(false),
@@ -433,6 +435,8 @@
       return enable_flags.depth_test;
     case GL_DITHER:
       return enable_flags.dither;
+    case GL_FRAMEBUFFER_SRGB_EXT:
+      return enable_flags.framebuffer_srgb_ext;
     case GL_POLYGON_OFFSET_FILL:
       return enable_flags.polygon_offset_fill;
     case GL_SAMPLE_ALPHA_TO_COVERAGE:
@@ -835,6 +839,12 @@
         params[0] = static_cast<GLint>(enable_flags.dither);
       }
       return true;
+    case GL_FRAMEBUFFER_SRGB_EXT:
+      *num_written = 1;
+      if (params) {
+        params[0] = static_cast<GLint>(enable_flags.framebuffer_srgb_ext);
+      }
+      return true;
     case GL_POLYGON_OFFSET_FILL:
       *num_written = 1;
       if (params) {
@@ -1269,6 +1279,12 @@
         params[0] = static_cast<GLfloat>(enable_flags.dither);
       }
       return true;
+    case GL_FRAMEBUFFER_SRGB_EXT:
+      *num_written = 1;
+      if (params) {
+        params[0] = static_cast<GLfloat>(enable_flags.framebuffer_srgb_ext);
+      }
+      return true;
     case GL_POLYGON_OFFSET_FILL:
       *num_written = 1;
       if (params) {
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 3a34afa..4e80bfb 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -572,11 +572,13 @@
     validators_.index_type.AddValue(GL_UNSIGNED_INT);
   }
 
+  bool has_srgb_framebuffer_support = false;
   if (gl_version_info_->IsAtLeastGL(3, 2) ||
       (gl_version_info_->IsAtLeastGL(2, 0) &&
        (extensions.Contains("GL_EXT_framebuffer_sRGB") ||
         extensions.Contains("GL_ARB_framebuffer_sRGB")))) {
     feature_flags_.desktop_srgb_support = true;
+    has_srgb_framebuffer_support = true;
   }
   // With EXT_sRGB, unsized SRGB_EXT and SRGB_ALPHA_EXT are accepted by the
   // <format> and <internalformat> parameter of TexImage2D. GLES3 adds support
@@ -599,6 +601,22 @@
         GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT);
     validators_.texture_unsized_internal_format.AddValue(GL_SRGB_EXT);
     validators_.texture_unsized_internal_format.AddValue(GL_SRGB_ALPHA_EXT);
+    has_srgb_framebuffer_support = true;
+  }
+  if (gl_version_info_->is_es3)
+    has_srgb_framebuffer_support = true;
+
+  if (has_srgb_framebuffer_support && !IsWebGLContext()) {
+    // GL_FRAMEBUFFER_SRGB_EXT is exposed by the GLES extension
+    // GL_EXT_sRGB_write_control (which is not part of the core, even in GLES3),
+    // and the desktop extension GL_ARB_framebuffer_sRGB (part of the core in
+    // 3.0).
+    if (feature_flags_.desktop_srgb_support ||
+        extensions.Contains("GL_EXT_sRGB_write_control")) {
+      feature_flags_.ext_srgb_write_control = true;
+      AddExtensionString("GL_EXT_sRGB_write_control");
+      validators_.capability.AddValue(GL_FRAMEBUFFER_SRGB_EXT);
+    }
   }
 
   // On desktop, GL_EXT_texture_sRGB is required regardless of GL version,
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index d72dfc1..8128c72 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -98,6 +98,7 @@
     bool khr_debug = false;
     bool chromium_bind_generates_resource = false;
     bool angle_webgl_compatibility = false;
+    bool ext_srgb_write_control = false;
   };
 
   FeatureInfo();
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index 49b8d19..902a9531 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -246,8 +246,11 @@
       NOTREACHED();
       break;
   }
+  // Note that because GL_EXT_sRGB is a substring of GL_EXT_sRGB_write_control,
+  // which is not part of the ES3 core, we have to be careful to search for
+  // "GL_EXT_sRGB ", and append a space to the end of the extension string.
   if (expect_ext_srgb) {
-    EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_sRGB"));
+    EXPECT_THAT(info_->extensions() + " ", HasSubstr("GL_EXT_sRGB "));
     EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_SRGB_EXT));
     EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_SRGB_ALPHA_EXT));
     EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(
@@ -259,7 +262,7 @@
     EXPECT_TRUE(info_->validators()->framebuffer_parameter.IsValid(
         GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT));
   } else {
-    EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_sRGB")));
+    EXPECT_THAT(info_->extensions() + " ", Not(HasSubstr("GL_EXT_sRGB ")));
     EXPECT_FALSE(info_->validators()->texture_format.IsValid(GL_SRGB_EXT));
     EXPECT_FALSE(info_->validators()->texture_format.IsValid(
         GL_SRGB_ALPHA_EXT));
@@ -593,7 +596,7 @@
   SetupInitExpectations("GL_EXT_sRGB GL_OES_rgb8_rgba8");
 
   if (GetContextType() == CONTEXT_TYPE_OPENGLES3) {
-    EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_sRGB")));
+    EXPECT_THAT(info_->extensions() + " ", Not(HasSubstr("GL_EXT_sRGB ")));
     EXPECT_FALSE(info_->validators()->texture_format.IsValid(GL_SRGB_EXT));
     EXPECT_FALSE(
         info_->validators()->texture_format.IsValid(GL_SRGB_ALPHA_EXT));
@@ -606,7 +609,7 @@
     EXPECT_FALSE(info_->validators()->framebuffer_parameter.IsValid(
         GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT));
   } else {
-    EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_sRGB"));
+    EXPECT_THAT(info_->extensions() + " ", HasSubstr("GL_EXT_sRGB "));
     EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_SRGB_EXT));
     EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_SRGB_ALPHA_EXT));
     EXPECT_TRUE(
@@ -922,7 +925,7 @@
 
 TEST_P(FeatureInfoTest, Initialize_sRGBGLES3) {
   SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0");
-  EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_sRGB")));
+  EXPECT_THAT(info_->extensions() + " ", Not(HasSubstr("GL_EXT_sRGB ")));
   EXPECT_FALSE(info_->validators()->texture_format.IsValid(
       GL_SRGB_EXT));
   EXPECT_FALSE(info_->validators()->texture_format.IsValid(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 4f93174..289898a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -4308,17 +4308,26 @@
 }
 
 void GLES2DecoderImpl::UpdateFramebufferSRGB(Framebuffer* framebuffer) {
+  // Manually set the value of FRAMEBUFFER_SRGB based on the state that was set
+  // by the client.
+  bool needs_enable_disable_framebuffer_srgb = false;
+  bool enable_framebuffer_srgb = true;
+  if (feature_info_->feature_flags().ext_srgb_write_control) {
+    needs_enable_disable_framebuffer_srgb = true;
+    enable_framebuffer_srgb &= state_.GetEnabled(GL_FRAMEBUFFER_SRGB);
+  }
   // On desktop, enable FRAMEBUFFER_SRGB only if the framebuffer contains sRGB
   // attachments. In theory, we can just leave FRAMEBUFFER_SRGB enabled,
   // however,
   // many drivers behave incorrectly when no attachments are sRGB. When at
   // least one attachment is sRGB, then they behave correctly.
   if (feature_info_->feature_flags().desktop_srgb_support) {
+    needs_enable_disable_framebuffer_srgb = true;
     // Assume that the default fbo does not have an sRGB image.
-    bool enable_framebuffer_srgb =
-        framebuffer && framebuffer->HasSRGBAttachments();
-    state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
+    enable_framebuffer_srgb &= framebuffer && framebuffer->HasSRGBAttachments();
   }
+  if (needs_enable_disable_framebuffer_srgb)
+    state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
 }
 
 bool GLES2DecoderImpl::CheckBoundReadFramebufferValid(
@@ -7433,6 +7442,11 @@
       // DrawElements* for old desktop GL.
       return;
     }
+    if (cap == GL_FRAMEBUFFER_SRGB) {
+      // Enable and Disable GL_FRAMEBUFFER_SRGB is done manually in
+      // CheckBoundDrawFramebufferValid.
+      return;
+    }
     glDisable(cap);
   }
 }
@@ -7445,6 +7459,11 @@
       // DrawElements* for old desktop GL.
       return;
     }
+    if (cap == GL_FRAMEBUFFER_SRGB) {
+      // Enable and Disable GL_FRAMEBUFFER_SRGB is done manually in
+      // CheckBoundDrawFramebufferValid.
+      return;
+    }
     glEnable(cap);
   }
 }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 0895cdd..1f961d1 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5140,6 +5140,14 @@
         return true;
       }
       return false;
+    case GL_FRAMEBUFFER_SRGB_EXT:
+      state_.enable_flags.framebuffer_srgb_ext = enabled;
+      if (state_.enable_flags.cached_framebuffer_srgb_ext != enabled ||
+          state_.ignore_cached_state) {
+        state_.enable_flags.cached_framebuffer_srgb_ext = enabled;
+        return true;
+      }
+      return false;
     case GL_POLYGON_OFFSET_FILL:
       state_.enable_flags.polygon_offset_fill = enabled;
       if (state_.enable_flags.cached_polygon_offset_fill != enabled ||
diff --git a/gpu/command_buffer/tests/gl_test_utils.cc b/gpu/command_buffer/tests/gl_test_utils.cc
index bf860a6..f10a919 100644
--- a/gpu/command_buffer/tests/gl_test_utils.cc
+++ b/gpu/command_buffer/tests/gl_test_utils.cc
@@ -71,9 +71,13 @@
 }
 
 bool GLTestHelper::HasExtension(const char* extension) {
-  std::string extensions(
-      reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
-  return extensions.find(extension) != std::string::npos;
+  // Pad with an extra space to ensure that |extension| is not a substring of
+  // another extension.
+  std::string extensions =
+      std::string(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))) +
+      " ";
+  std::string extension_padded = std::string(extension) + " ";
+  return extensions.find(extension_padded) != std::string::npos;
 }
 
 bool GLTestHelper::CheckGLError(const char* msg, int line) {
diff --git a/storage/browser/blob/blob_entry.h b/storage/browser/blob/blob_entry.h
index 72d21fcb..4dfa7a8 100644
--- a/storage/browser/blob/blob_entry.h
+++ b/storage/browser/blob/blob_entry.h
@@ -22,7 +22,6 @@
 namespace storage {
 class BlobDataHandle;
 class ShareableBlobDataItem;
-class ViewBlobInternalsJob;
 
 // Represents a blob in BlobStorageRegistry. Exported only for unit tests.
 class STORAGE_EXPORT BlobEntry {
diff --git a/storage/browser/blob/blob_memory_controller.h b/storage/browser/blob/blob_memory_controller.h
index 865d3e0..6f9e15f 100644
--- a/storage/browser/blob/blob_memory_controller.h
+++ b/storage/browser/blob/blob_memory_controller.h
@@ -34,7 +34,6 @@
 }
 
 namespace storage {
-class DataElement;
 class ShareableBlobDataItem;
 class ShareableFileReference;
 
diff --git a/storage/browser/blob/blob_reader.h b/storage/browser/blob/blob_reader.h
index a7b1d12..9553a169 100644
--- a/storage/browser/blob/blob_reader.h
+++ b/storage/browser/blob/blob_reader.h
@@ -39,7 +39,6 @@
 class BlobDataHandle;
 class BlobDataSnapshot;
 class FileStreamReader;
-class FileSystemContext;
 
 // The blob reader is used to read a blob.  This can only be used in the browser
 // process, and we need to be on the IO thread.
diff --git a/storage/browser/blob/blob_storage_context.h b/storage/browser/blob/blob_storage_context.h
index 9e068a7..3dc5a03 100644
--- a/storage/browser/blob/blob_storage_context.h
+++ b/storage/browser/blob/blob_storage_context.h
@@ -27,12 +27,6 @@
 
 class GURL;
 
-namespace base {
-class FilePath;
-class Time;
-class TaskRunner;
-}
-
 namespace content {
 class BlobDispatcherHost;
 class BlobDispatcherHostTest;
@@ -42,7 +36,6 @@
 namespace storage {
 class BlobDataBuilder;
 class BlobDataHandle;
-class BlobDataItem;
 class BlobDataSnapshot;
 class ShareableBlobDataItem;
 
diff --git a/storage/browser/blob/blob_storage_registry.h b/storage/browser/blob/blob_storage_registry.h
index 2b2dbdd..f27e7ea 100644
--- a/storage/browser/blob/blob_storage_registry.h
+++ b/storage/browser/blob/blob_storage_registry.h
@@ -21,9 +21,7 @@
 class GURL;
 
 namespace storage {
-class BlobDataHandle;
 class BlobEntry;
-class ShareableBlobDataItem;
 
 // This class stores the blob data in the various states of construction, as
 // well as URL mappings to blob uuids.
diff --git a/storage/browser/blob/blob_url_request_job.h b/storage/browser/blob/blob_url_request_job.h
index 1dadbd4f..e36e1fb 100644
--- a/storage/browser/blob/blob_url_request_job.h
+++ b/storage/browser/blob/blob_url_request_job.h
@@ -24,7 +24,6 @@
 }
 
 namespace net {
-class DrainableIOBuffer;
 class IOBuffer;
 }
 
diff --git a/storage/browser/fileapi/copy_or_move_operation_delegate.h b/storage/browser/fileapi/copy_or_move_operation_delegate.h
index 9d5bd24..651d5a54 100644
--- a/storage/browser/fileapi/copy_or_move_operation_delegate.h
+++ b/storage/browser/fileapi/copy_or_move_operation_delegate.h
@@ -23,13 +23,11 @@
 
 namespace storage {
 class FileStreamReader;
-class ShareableFileReference;
 enum class FlushPolicy;
 }
 
 namespace storage {
 
-class CopyOrMoveFileValidator;
 class FileStreamWriter;
 
 // A delegate class for recursive copy or move operations.
diff --git a/storage/browser/fileapi/file_system_backend.h b/storage/browser/fileapi/file_system_backend.h
index c17c889..b41a74a 100644
--- a/storage/browser/fileapi/file_system_backend.h
+++ b/storage/browser/fileapi/file_system_backend.h
@@ -31,7 +31,6 @@
 class FileStreamReader;
 class FileStreamWriter;
 class FileSystemContext;
-class FileSystemFileUtil;
 class FileSystemOperation;
 class FileSystemQuotaUtil;
 class WatcherManager;
diff --git a/storage/browser/fileapi/file_system_context.h b/storage/browser/fileapi/file_system_context.h
index d5d4e86..0da374c 100644
--- a/storage/browser/fileapi/file_system_context.h
+++ b/storage/browser/fileapi/file_system_context.h
@@ -32,10 +32,6 @@
 class SingleThreadTaskRunner;
 }
 
-namespace chrome {
-class NativeMediaFileUtilTest;
-}
-
 namespace storage {
 class QuotaManagerProxy;
 class SpecialStoragePolicy;
@@ -46,7 +42,6 @@
 }
 
 namespace storage {
-class BlobURLRequestJobTest;
 class FileStreamReader;
 }
 
@@ -58,7 +53,6 @@
 class ExternalMountPoints;
 class FileStreamWriter;
 class FileSystemBackend;
-class FileSystemFileUtil;
 class FileSystemOperation;
 class FileSystemOperationRunner;
 class FileSystemOptions;
@@ -68,7 +62,6 @@
 class MountPoints;
 class QuotaReservation;
 class SandboxFileSystemBackend;
-class WatchManager;
 
 struct DefaultContextDeleter;
 struct FileSystemInfo;
diff --git a/storage/browser/fileapi/file_system_file_stream_reader.h b/storage/browser/fileapi/file_system_file_stream_reader.h
index a65a736..ba69b1f 100644
--- a/storage/browser/fileapi/file_system_file_stream_reader.h
+++ b/storage/browser/fileapi/file_system_file_stream_reader.h
@@ -21,7 +21,6 @@
 
 namespace base {
 class FilePath;
-class SequencedTaskRunner;
 }
 
 namespace content {
diff --git a/storage/browser/fileapi/file_system_operation.h b/storage/browser/fileapi/file_system_operation.h
index 3e0c49a..1172258 100644
--- a/storage/browser/fileapi/file_system_operation.h
+++ b/storage/browser/fileapi/file_system_operation.h
@@ -30,8 +30,6 @@
 class ShareableFileReference;
 }
 
-class GURL;
-
 namespace storage {
 
 class FileSystemContext;
diff --git a/storage/browser/fileapi/file_system_quota_util.h b/storage/browser/fileapi/file_system_quota_util.h
index 14f3eb89..b12cf6c 100644
--- a/storage/browser/fileapi/file_system_quota_util.h
+++ b/storage/browser/fileapi/file_system_quota_util.h
@@ -15,10 +15,6 @@
 #include "storage/common/fileapi/file_system_types.h"
 #include "url/gurl.h"
 
-namespace base {
-class SequencedTaskRunner;
-}
-
 namespace storage {
 class QuotaManagerProxy;
 }
diff --git a/storage/browser/fileapi/file_system_url_request_job.h b/storage/browser/fileapi/file_system_url_request_job.h
index 183ef434..59b286ab 100644
--- a/storage/browser/fileapi/file_system_url_request_job.h
+++ b/storage/browser/fileapi/file_system_url_request_job.h
@@ -22,10 +22,6 @@
 
 class GURL;
 
-namespace base {
-class FilePath;
-}
-
 namespace storage {
 class FileStreamReader;
 }
diff --git a/storage/browser/fileapi/local_file_util.h b/storage/browser/fileapi/local_file_util.h
index f2ede6c..a886014 100644
--- a/storage/browser/fileapi/local_file_util.h
+++ b/storage/browser/fileapi/local_file_util.h
@@ -19,8 +19,6 @@
 class Time;
 }
 
-class GURL;
-
 namespace storage {
 
 class FileSystemOperationContext;
diff --git a/storage/browser/fileapi/obfuscated_file_util.h b/storage/browser/fileapi/obfuscated_file_util.h
index fc56e81..027b8a59 100644
--- a/storage/browser/fileapi/obfuscated_file_util.h
+++ b/storage/browser/fileapi/obfuscated_file_util.h
@@ -28,7 +28,6 @@
 
 namespace base {
 class SequencedTaskRunner;
-class TimeTicks;
 }
 
 namespace content {
diff --git a/storage/browser/fileapi/quota/quota_reservation_manager.h b/storage/browser/fileapi/quota/quota_reservation_manager.h
index fcd774e..4ab6d7d6 100644
--- a/storage/browser/fileapi/quota/quota_reservation_manager.h
+++ b/storage/browser/fileapi/quota/quota_reservation_manager.h
@@ -28,8 +28,6 @@
 
 class QuotaReservation;
 class QuotaReservationBuffer;
-class OpenFileHandle;
-class OpenFileHandleContext;
 
 class STORAGE_EXPORT QuotaReservationManager {
  public:
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.h b/storage/browser/fileapi/sandbox_file_stream_writer.h
index f0dd1087..1a8f97e 100644
--- a/storage/browser/fileapi/sandbox_file_stream_writer.h
+++ b/storage/browser/fileapi/sandbox_file_stream_writer.h
@@ -24,7 +24,6 @@
 namespace storage {
 
 class FileSystemContext;
-class FileSystemQuotaUtil;
 class FileStreamWriter;
 
 class STORAGE_EXPORT SandboxFileStreamWriter
diff --git a/storage/browser/fileapi/sandbox_file_system_backend_delegate.h b/storage/browser/fileapi/sandbox_file_system_backend_delegate.h
index 1a1696f4..254a1889 100644
--- a/storage/browser/fileapi/sandbox_file_system_backend_delegate.h
+++ b/storage/browser/fileapi/sandbox_file_system_backend_delegate.h
@@ -53,7 +53,6 @@
 class FileSystemUsageCache;
 class ObfuscatedFileUtil;
 class QuotaReservationManager;
-class SandboxFileSystemBackend;
 class SandboxQuotaObserver;
 
 // Delegate implementation of the some methods in Sandbox/SyncFileSystemBackend.
diff --git a/storage/browser/fileapi/watcher_manager.h b/storage/browser/fileapi/watcher_manager.h
index 470a988..64c3106 100644
--- a/storage/browser/fileapi/watcher_manager.h
+++ b/storage/browser/fileapi/watcher_manager.h
@@ -12,7 +12,6 @@
 
 namespace storage {
 
-class FileSystemOperationContext;
 class FileSystemURL;
 
 // An interface for providing entry observing capability for file system
diff --git a/storage/browser/quota/quota_task.h b/storage/browser/quota/quota_task.h
index 9fd51c3..2ae85f14 100644
--- a/storage/browser/quota/quota_task.h
+++ b/storage/browser/quota/quota_task.h
@@ -14,7 +14,6 @@
 
 namespace base {
 class SingleThreadTaskRunner;
-class TaskRunner;
 }
 
 namespace storage {
diff --git a/storage/common/database/database_connections.h b/storage/common/database/database_connections.h
index fe66ac2..7164cf5 100644
--- a/storage/common/database/database_connections.h
+++ b/storage/common/database/database_connections.h
@@ -18,7 +18,6 @@
 #include "storage/common/storage_common_export.h"
 
 namespace base {
-class SingleThreadTaskRunner;
 class WaitableEvent;
 }
 
diff --git a/third_party/WebKit/LayoutTests/fast/dom/NodeList/nodelist-reachable-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/NodeList/nodelist-reachable-expected.txt
index 871653e..50943e4 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/NodeList/nodelist-reachable-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/NodeList/nodelist-reachable-expected.txt
@@ -2,7 +2,7 @@
 PASS document.getElementsByClassName("class").customProperty is 2
 PASS document.getElementsByName("name").customProperty is 3
 PASS document.getElementsByTagName("body").customProperty is 4
-FAIL document.querySelector("form").elements["radios"].customProperty should be 5 (of type number). Was undefined (of type undefined).
+PASS document.querySelector("form").elements["radios"].customProperty is 5
 PASS document.querySelector("input").labels.customProperty is 6
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt b/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt
index 866cc57..1971f8d0 100644
--- a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt
@@ -23,7 +23,7 @@
 checksum : 84637740
 PASS exception correctly thrown when xhr.responseText is accessed but responseType is 'arraybuffer' : InvalidStateError: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'arraybuffer')..
 PASS exception correctly thrown when xhr.responseXML is accessed but responseType is 'arraybuffer' : InvalidStateError: Failed to read the 'responseXML' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'document' (was 'arraybuffer')..
-FAIL xhr.response.foo should be bar (of type string). Was undefined (of type undefined).
+PASS xhr.response.foo is 'bar'
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files-expected.txt
index 1575b301..42c26de6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files-expected.txt
@@ -1,7 +1,7 @@
 Tests that ScriptSearchScope performs search across all sources correctly.
 
 See bug 41350.
-Total uiSourceCodes: 13
+Total uiSourceCodes: 14
 
 Running: testIgnoreCase
 Search result #1: uiSourceCode.url = file:///var/www/search.css
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table-cell-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table-cell-collapsed-border-expected.txt
index c8b10b4..cd078c63 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table-cell-collapsed-border-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table-cell-collapsed-border-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [3, 60, 441, 405],
-          "reason": "invalidate paint rectangle"
-        },
-        {
           "object": "LayoutTableCell TD id='t3'",
           "rect": [220, 260, 122, 110],
           "reason": "style change"
@@ -31,8 +26,48 @@
   ],
   "objectPaintInvalidations": [
     {
-      "object": "LayoutTable TABLE",
-      "reason": "invalidate paint rectangle"
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD id='t1'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD id='t2'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD id='t3'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
     },
     {
       "object": "LayoutTableCell TD id='t1'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table-outer-border-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table-outer-border-expected.txt
index dd21182..b06d1cb 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table-outer-border-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table-outer-border-expected.txt
@@ -95,6 +95,14 @@
       "reason": "layoutObject removal"
     },
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE id='table' class='green'",
       "reason": "layoutObject insertion"
     },
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table-section-repaint-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table-section-repaint-expected.txt
index ca5147f..34142075 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table-section-repaint-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table-section-repaint-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 308, 60, 83],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutTableCell TD class='half'",
           "rect": [8, 353, 60, 38],
           "reason": "bounds change"
@@ -105,6 +100,11 @@
           "object": "LayoutTableCell TD class='red half'",
           "rect": [8, 8, 60, 30],
           "reason": "bounds change"
+        },
+        {
+          "object": "LayoutTable TABLE",
+          "rect": [8, 372, 60, 19],
+          "reason": "incremental"
         }
       ]
     }
@@ -172,7 +172,7 @@
     },
     {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableRow TR",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/border-collapse-change-separate-to-collapse-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/border-collapse-change-separate-to-collapse-expected.txt
index ba69534..18cc801 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/border-collapse-change-separate-to-collapse-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/border-collapse-change-separate-to-collapse-expected.txt
@@ -51,6 +51,14 @@
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE id='table'",
       "reason": "style change"
     },
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-cell-append-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-cell-append-expected.txt
index e9f5d7b..59ef756 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-cell-append-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-cell-append-expected.txt
@@ -8,8 +8,8 @@
       "paintInvalidations": [
         {
           "object": "LayoutTable TABLE",
-          "rect": [8, 8, 120, 56],
-          "reason": "forced by layout"
+          "rect": [8, 59, 120, 5],
+          "reason": "incremental"
         },
         {
           "object": "LayoutTableCell TD",
@@ -17,6 +17,11 @@
           "reason": "layoutObject insertion"
         },
         {
+          "object": "LayoutTable TABLE",
+          "rect": [65, 8, 63, 56],
+          "reason": "incremental"
+        },
+        {
           "object": "LayoutTableCell TD",
           "rect": [8, 8, 62, 56],
           "reason": "location change"
@@ -26,8 +31,16 @@
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableRow TR id='row'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-cell-border-color-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-cell-border-color-expected.txt
index 89451a0..76964c5 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-cell-border-color-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-cell-border-color-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 8, 114, 54],
-          "reason": "invalidate paint rectangle"
-        },
-        {
           "object": "LayoutTableCell TD id='foo'",
           "rect": [8, 8, 60, 54],
           "reason": "style change"
@@ -21,8 +16,12 @@
   ],
   "objectPaintInvalidations": [
     {
-      "object": "LayoutTable TABLE",
-      "reason": "invalidate paint rectangle"
+      "object": "LayoutTableCell TD id='foo'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
     },
     {
       "object": "LayoutTableCell TD id='foo'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-cell-border-width-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-cell-border-width-expected.txt
index 7b946e8..6a5f6dc0 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-cell-border-width-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-cell-border-width-expected.txt
@@ -8,8 +8,8 @@
       "paintInvalidations": [
         {
           "object": "LayoutTable TABLE",
-          "rect": [8, 8, 114, 54],
-          "reason": "forced by layout"
+          "rect": [8, 58, 114, 4],
+          "reason": "incremental"
         },
         {
           "object": "LayoutTableCell TD id='foo'",
@@ -25,14 +25,27 @@
           "object": "LayoutTableCell TD",
           "rect": [62, 8, 55, 52],
           "reason": "bounds change"
+        },
+        {
+          "object": "LayoutTable TABLE",
+          "rect": [116, 8, 6, 54],
+          "reason": "incremental"
         }
       ]
     }
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD id='foo'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableRow TR",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-col-border-color-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-col-border-color-expected.txt
index 09774d8..27c93b4 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-col-border-color-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-col-border-color-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 8, 113, 104],
-          "reason": "invalidate paint rectangle"
-        },
-        {
           "object": "LayoutTableCol COL id='col'",
           "rect": [8, 8, 113, 104],
           "reason": "style change"
@@ -21,8 +16,20 @@
   ],
   "objectPaintInvalidations": [
     {
-      "object": "LayoutTable TABLE",
-      "reason": "invalidate paint rectangle"
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
     },
     {
       "object": "LayoutTableCol COL id='col'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-col-border-width-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-col-border-width-expected.txt
index e54cf9ba..5ba2070 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-col-border-width-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-col-border-width-expected.txt
@@ -7,16 +7,16 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 8, 113, 104],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutTableCol COL id='col'",
           "rect": [8, 8, 113, 104],
           "reason": "style change"
         },
         {
+          "object": "LayoutTable TABLE",
+          "rect": [8, 108, 113, 4],
+          "reason": "incremental"
+        },
+        {
           "object": "LayoutTableCell TD",
           "rect": [8, 59, 60, 53],
           "reason": "bounds change"
@@ -50,14 +50,35 @@
           "object": "LayoutTableCell TD",
           "rect": [63, 59, 54, 51],
           "reason": "bounds change"
+        },
+        {
+          "object": "LayoutTable TABLE",
+          "rect": [116, 8, 5, 104],
+          "reason": "incremental"
         }
       ]
     }
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableCol COL id='col'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-colgroup-border-color-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-colgroup-border-color-expected.txt
index 5629d33..71449ce 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-colgroup-border-color-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-colgroup-border-color-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [7, 7, 167, 104],
-          "reason": "invalidate paint rectangle"
-        },
-        {
           "object": "LayoutTableCol COLGROUP id='colgroup'",
           "rect": [8, 8, 166, 102],
           "reason": "style change"
@@ -21,8 +16,28 @@
   ],
   "objectPaintInvalidations": [
     {
-      "object": "LayoutTable TABLE",
-      "reason": "invalidate paint rectangle"
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
     },
     {
       "object": "LayoutTableCol COLGROUP id='colgroup'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-colgroup-border-width-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-colgroup-border-width-expected.txt
index 8f3e28c..7f1d98f 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-colgroup-border-width-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-colgroup-border-width-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 8, 166, 102],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutTableCol COLGROUP id='colgroup'",
           "rect": [8, 8, 166, 102],
           "reason": "style change"
@@ -65,14 +60,43 @@
           "object": "LayoutTableCell TD",
           "rect": [116, 9, 54, 50],
           "reason": "bounds change"
+        },
+        {
+          "object": "LayoutTable TABLE",
+          "rect": [169, 8, 5, 102],
+          "reason": "incremental"
         }
       ]
     }
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableCol COLGROUP id='colgroup'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-row-border-width-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-row-border-width-expected.txt
index 42b0a3b9..4013197 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-row-border-width-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-row-border-width-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 8, 60, 103],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutTableCell TD",
           "rect": [8, 8, 60, 54],
           "reason": "forced by layout"
@@ -22,6 +17,11 @@
           "reason": "location change"
         },
         {
+          "object": "LayoutTable TABLE",
+          "rect": [8, 109, 60, 2],
+          "reason": "incremental"
+        },
+        {
           "object": "LayoutTableRow TR id='row'",
           "rect": [10, 10, 56, 50],
           "reason": "style change"
@@ -30,14 +30,27 @@
           "object": "LayoutTableRow TR id='row'",
           "rect": [9, 9, 54, 50],
           "reason": "style change"
+        },
+        {
+          "object": "LayoutTable TABLE",
+          "rect": [62, 8, 6, 103],
+          "reason": "incremental"
         }
       ]
     }
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableRow TR id='row'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-table-border-color-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-table-border-color-expected.txt
index e9ea09b..5a9447d 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-table-border-color-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-table-border-color-expected.txt
@@ -16,6 +16,10 @@
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE id='tbl'",
       "reason": "style change"
     }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-table-border-width-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-table-border-width-expected.txt
index c2f06f30..7ebee422 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-table-border-width-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-table-border-width-expected.txt
@@ -21,6 +21,10 @@
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE id='tbl'",
       "reason": "style change"
     },
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-tbody-border-width-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-tbody-border-width-expected.txt
index 87ac20939..2b0dc2a 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-tbody-border-width-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-change-tbody-border-width-expected.txt
@@ -8,8 +8,8 @@
       "paintInvalidations": [
         {
           "object": "LayoutTable TABLE",
-          "rect": [8, 8, 114, 153],
-          "reason": "forced by layout"
+          "rect": [8, 159, 114, 2],
+          "reason": "incremental"
         },
         {
           "object": "LayoutTableSection TBODY id='tbody'",
@@ -70,14 +70,43 @@
           "object": "LayoutTableCell TD",
           "rect": [63, 59, 54, 51],
           "reason": "bounds change"
+        },
+        {
+          "object": "LayoutTable TABLE",
+          "rect": [115, 8, 7, 153],
+          "reason": "incremental"
         }
       ]
     }
   ],
   "objectPaintInvalidations": [
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableSection TBODY id='tbody'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/collapsed-border-cell-resize-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/collapsed-border-cell-resize-expected.txt
index 1ef83120..b34767d 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/collapsed-border-cell-resize-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/collapsed-border-cell-resize-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 8, 104, 204],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutTableCell TD id='target'",
           "rect": [8, 8, 104, 204],
           "reason": "border box change"
@@ -21,10 +16,6 @@
   ],
   "objectPaintInvalidations": [
     {
-      "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
-    },
-    {
       "object": "LayoutTableCell TD id='target'",
       "reason": "border box change"
     }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color-expected.html
deleted file mode 100644
index cf6608bf..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color-expected.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<p style="height: 50px">Passes if green borders are visible surrounding A's cell and no red.
-<table style="border-collapse: collapse;">
-  <tr>
-    <td id="a" style="border: 5px solid green; width: 100px; height: 100px">A</td>
-  </tr>
-</table>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color-expected.txt
deleted file mode 100644
index bf4df5b..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color-expected.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "paintInvalidations": [
-        {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 82, 112, 112],
-          "reason": "invalidate paint rectangle"
-        }
-      ]
-    },
-    {
-      "name": "LayoutTableCell TD id='a'",
-      "position": [10, 84],
-      "bounds": [107, 107],
-      "drawsContent": true,
-      "paintInvalidations": [
-        {
-          "object": "LayoutTableCell TD id='a'",
-          "rect": [-2, -2, 112, 112],
-          "reason": "style change"
-        }
-      ]
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutTable TABLE",
-      "reason": "invalidate paint rectangle"
-    },
-    {
-      "object": "LayoutTableCell TD id='a'",
-      "reason": "style change"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "style change"
-    },
-    {
-      "object": "RowBackground",
-      "reason": "style change"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color.html b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color.html
deleted file mode 100644
index 96981e21..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-cell-change-collapsed-border-color.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<p style="height: 50px">Passes if green borders are visible surrounding A's cell and no red.
-<table style="border-collapse: collapse;">
-  <tr>
-    <td id="a" style="border: 5px solid red; width: 100px; height: 100px; will-change: transform">A</td>
-  </tr>
-</table>
-<script src="../resources/text-based-repaint.js"></script>
-<script>
-function repaintTest() {
-  a.style.borderColor = 'green';
-}
-onload = runRepaintAndPixelTest;
-</script>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color-expected.html
deleted file mode 100644
index dc1f099..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color-expected.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<p style="height: 50px">Passes if green borders are visible surrounding A's cell and no red.
-<table style="border-collapse: collapse;">
-  <tr id="a" style="border: 5px solid green">
-    <td style="width: 100px; height: 100px">A</td>
-  </tr>
-</table>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color-expected.txt
deleted file mode 100644
index c26169aa2..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color-expected.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "paintInvalidations": [
-        {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 82, 112, 112],
-          "reason": "invalidate paint rectangle"
-        }
-      ]
-    },
-    {
-      "name": "LayoutTableRow TR id='a'",
-      "position": [10, 84],
-      "bounds": [107, 107],
-      "drawsContent": true,
-      "paintInvalidations": [
-        {
-          "object": "LayoutTableRow TR id='a'",
-          "rect": [0, 0, 107, 107],
-          "reason": "style change"
-        }
-      ]
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutTable TABLE",
-      "reason": "invalidate paint rectangle"
-    },
-    {
-      "object": "LayoutTableRow TR id='a'",
-      "reason": "style change"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color.html b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color.html
deleted file mode 100644
index b3f51b3..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-row-change-collapsed-border-color.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<p style="height: 50px">Passes if green borders are visible surrounding A's cell and no red.
-<table style="border-collapse: collapse;">
-  <tr id="a" style="border: 5px solid red; will-change: transform">
-    <td style="width: 100px; height: 100px">A</td>
-  </tr>
-</table>
-<script src="../resources/text-based-repaint.js"></script>
-<script>
-function repaintTest() {
-  a.style.borderColor = 'green';
-}
-onload = runRepaintAndPixelTest;
-</script>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color-expected.html
deleted file mode 100644
index b76f9bf..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color-expected.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<p style="height: 50px">Passes if green borders are visible surrounding A's cell and no red.
-<table style="border-collapse: collapse;">
-  <thead id="a" style="border: 5px solid green">
-    <tr>
-      <td style="width: 100px; height: 100px">A</td>
-    </tr>
-  </head>
-</table>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color-expected.txt
deleted file mode 100644
index 8505bd02..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color-expected.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "paintInvalidations": [
-        {
-          "object": "LayoutTable TABLE",
-          "rect": [8, 82, 112, 112],
-          "reason": "invalidate paint rectangle"
-        }
-      ]
-    },
-    {
-      "name": "LayoutTableSection THEAD id='a'",
-      "position": [10, 84],
-      "bounds": [107, 107],
-      "drawsContent": true,
-      "paintInvalidations": [
-        {
-          "object": "LayoutTableSection THEAD id='a'",
-          "rect": [0, 0, 107, 107],
-          "reason": "style change"
-        }
-      ]
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutTable TABLE",
-      "reason": "invalidate paint rectangle"
-    },
-    {
-      "object": "LayoutTableSection THEAD id='a'",
-      "reason": "style change"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color.html b/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color.html
deleted file mode 100644
index c7b9932..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/table/composited-section-change-collapsed-border-color.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<p style="height: 50px">Passes if green borders are visible surrounding A's cell and no red.
-<table style="border-collapse: collapse;">
-  <thead id="a" style="border: 5px solid red; will-change: transform">
-    <tr>
-      <td style="width: 100px; height: 100px">A</td>
-    </tr>
-  </head>
-</table>
-<script src="../resources/text-based-repaint.js"></script>
-<script>
-function repaintTest() {
-  a.style.borderColor = 'green';
-}
-onload = runRepaintAndPixelTest;
-</script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table-cell-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table-cell-collapsed-border-expected.txt
index b1b1bfb..e452e1f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table-cell-collapsed-border-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table-cell-collapsed-border-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable TABLE",
-          "rect": [3, 64, 441, 405],
-          "reason": "invalidate paint rectangle"
-        },
-        {
           "object": "LayoutTableCell TD id='t3'",
           "rect": [220, 264, 122, 110],
           "reason": "style change"
@@ -31,8 +26,48 @@
   ],
   "objectPaintInvalidations": [
     {
-      "object": "LayoutTable TABLE",
-      "reason": "invalidate paint rectangle"
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD id='t1'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD id='t2'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD id='t3'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
     },
     {
       "object": "LayoutTableCell TD id='t1'",
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table-collapsed-border-expected.txt
index bf2ed89b..71fa8da 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table-collapsed-border-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table-collapsed-border-expected.txt
@@ -13,11 +13,6 @@
         },
         {
           "object": "LayoutTable TABLE",
-          "rect": [8, 286, 95, 82],
-          "reason": "forced by layout"
-        },
-        {
-          "object": "LayoutTable TABLE",
           "rect": [8, 102, 95, 82],
           "reason": "full"
         },
@@ -107,6 +102,11 @@
           "reason": "layoutObject removal"
         },
         {
+          "object": "LayoutTable TABLE",
+          "rect": [74, 286, 29, 82],
+          "reason": "incremental"
+        },
+        {
           "object": "LayoutTableCell TD",
           "rect": [8, 224, 14, 22],
           "reason": "forced by layout"
@@ -147,6 +147,30 @@
       "reason": "layoutObject removal"
     },
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE id='t'",
       "reason": "style change"
     },
@@ -232,7 +256,7 @@
     },
     {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableCell TD",
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
index 2882c0c..6bb9255 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable (relative positioned) TABLE",
-          "rect": [8, 8, 114, 54],
-          "reason": "invalidate paint rectangle"
-        },
-        {
           "object": "LayoutTableCell TD id='foo'",
           "rect": [8, 8, 60, 54],
           "reason": "style change"
@@ -35,8 +30,12 @@
       "reason": "layoutObject removal"
     },
     {
-      "object": "LayoutTable (relative positioned) TABLE",
-      "reason": "invalidate paint rectangle"
+      "object": "LayoutTableCell TD id='foo'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
     },
     {
       "object": "LayoutTableCell TD id='foo'",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table-collapsed-border-expected.txt
index 4aabc19..d64d6549 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table-collapsed-border-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table-collapsed-border-expected.txt
@@ -18,11 +18,6 @@
         },
         {
           "object": "LayoutTable TABLE",
-          "rect": [8, 268, 101, 76],
-          "reason": "forced by layout"
-        },
-        {
-          "object": "LayoutTable TABLE",
           "rect": [8, 96, 101, 76],
           "reason": "full"
         },
@@ -107,6 +102,11 @@
           "reason": "layoutObject removal"
         },
         {
+          "object": "LayoutTable TABLE",
+          "rect": [79, 268, 30, 76],
+          "reason": "incremental"
+        },
+        {
           "object": "LayoutTableCell TD",
           "rect": [8, 210, 14, 20],
           "reason": "forced by layout"
@@ -147,6 +147,30 @@
       "reason": "layoutObject removal"
     },
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE id='t'",
       "reason": "style change"
     },
@@ -232,7 +256,7 @@
     },
     {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableCell TD",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
index d682150..1804202 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable (relative positioned) TABLE",
-          "rect": [8, 8, 114, 54],
-          "reason": "invalidate paint rectangle"
-        },
-        {
           "object": "LayoutTableCell TD id='foo'",
           "rect": [8, 8, 60, 54],
           "reason": "style change"
@@ -35,8 +30,12 @@
       "reason": "layoutObject removal"
     },
     {
-      "object": "LayoutTable (relative positioned) TABLE",
-      "reason": "invalidate paint rectangle"
+      "object": "LayoutTableCell TD id='foo'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
     },
     {
       "object": "LayoutTableCell TD id='foo'",
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table-collapsed-border-expected.txt
index ce4853e..5eba99d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table-collapsed-border-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table-collapsed-border-expected.txt
@@ -18,11 +18,6 @@
         },
         {
           "object": "LayoutTable TABLE",
-          "rect": [8, 268, 101, 76],
-          "reason": "forced by layout"
-        },
-        {
-          "object": "LayoutTable TABLE",
           "rect": [8, 96, 101, 76],
           "reason": "full"
         },
@@ -107,6 +102,11 @@
           "reason": "layoutObject removal"
         },
         {
+          "object": "LayoutTable TABLE",
+          "rect": [79, 268, 30, 76],
+          "reason": "incremental"
+        },
+        {
           "object": "LayoutTableCell TD",
           "rect": [8, 210, 14, 20],
           "reason": "forced by layout"
@@ -147,6 +147,30 @@
       "reason": "layoutObject removal"
     },
     {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
+    },
+    {
       "object": "LayoutTable TABLE id='t'",
       "reason": "style change"
     },
@@ -232,7 +256,7 @@
     },
     {
       "object": "LayoutTable TABLE",
-      "reason": "forced by layout"
+      "reason": "incremental"
     },
     {
       "object": "LayoutTableCell TD",
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
index 1904492..560cab9 100644
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table/cached-change-cell-sl-border-color-expected.txt
@@ -7,11 +7,6 @@
       "drawsContent": true,
       "paintInvalidations": [
         {
-          "object": "LayoutTable (relative positioned) TABLE",
-          "rect": [8, 8, 114, 54],
-          "reason": "invalidate paint rectangle"
-        },
-        {
           "object": "LayoutTableCell TD id='foo'",
           "rect": [8, 8, 60, 54],
           "reason": "style change"
@@ -35,8 +30,12 @@
       "reason": "layoutObject removal"
     },
     {
-      "object": "LayoutTable (relative positioned) TABLE",
-      "reason": "invalidate paint rectangle"
+      "object": "LayoutTableCell TD id='foo'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutTableCell TD",
+      "reason": "style change"
     },
     {
       "object": "LayoutTableCell TD id='foo'",
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
index 07d63b5a..745ff4af 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
@@ -162,12 +162,6 @@
 
 #undef DECLARE_DISPATCH_TRACE_WRAPPERS
 
-  void dispatchTraceWrappers(const void*) const override {
-    // Getting here means that we lack the proper infrastructure for handling
-    // a specific type. Crash instead of failing silently to flush out issues.
-    NOTREACHED();
-  }
-
   void traceWrappers(const TraceWrapperV8Reference<v8::Value>&) const override;
   void markWrapper(const v8::PersistentBase<v8::Value>*) const override;
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorVerifier.h b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorVerifier.h
index 956293b..27c8dc12 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorVerifier.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorVerifier.h
@@ -31,7 +31,6 @@
   WRAPPER_VISITOR_SPECIAL_CLASSES(DECLARE_DISPATCH_TRACE_WRAPPERS);
 
 #undef DECLARE_DISPATCH_TRACE_WRAPPERS
-  void dispatchTraceWrappers(const void*) const override {}
 
   void traceWrappers(const TraceWrapperV8Reference<v8::Value>&) const override {
   }
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index b20f845a..62a694a 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1295,7 +1295,6 @@
     "paint/SVGInlineTextBoxPainterTest.cpp",
     "paint/StubChromeClientForSPv2.h",
     "paint/TableCellPainterTest.cpp",
-    "paint/TablePainterTest.cpp",
     "paint/TextPainterTest.cpp",
     "paint/VideoPainterTest.cpp",
     "streams/ReadableStreamOperationsTest.cpp",
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 918fe89..c34dd18 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -87,6 +87,7 @@
 #include "core/dom/FrameRequestCallback.h"
 #include "core/dom/IntersectionObserverController.h"
 #include "core/dom/LayoutTreeBuilderTraversal.h"
+#include "core/dom/LiveNodeList.h"
 #include "core/dom/MainThreadTaskRunner.h"
 #include "core/dom/MutationObserver.h"
 #include "core/dom/NodeChildRemovalTracker.h"
@@ -506,10 +507,11 @@
     if (registry && m_registrationContext)
       registry->entangle(m_registrationContext);
   } else if (m_importsController) {
-    m_fetcher = FrameFetchContext::createContextAndFetcher(nullptr, this);
+    m_fetcher = FrameFetchContext::createFetcherFromDocument(this);
   } else {
     m_fetcher = ResourceFetcher::create(nullptr);
   }
+  DCHECK(m_fetcher);
 
   m_rootScrollerController = RootScrollerController::create(*this);
 
@@ -4100,10 +4102,21 @@
     m_cssTarget->pseudoStateChanged(CSSSelector::PseudoTarget);
 }
 
+static void liveNodeListBaseWriteBarrier(void* parent,
+                                         const LiveNodeListBase* list) {
+  if (isHTMLCollectionType(list->type())) {
+    ScriptWrappableVisitor::writeBarrier(
+        parent, static_cast<const HTMLCollection*>(list));
+  } else {
+    ScriptWrappableVisitor::writeBarrier(
+        parent, static_cast<const LiveNodeList*>(list));
+  }
+}
+
 void Document::registerNodeList(const LiveNodeListBase* list) {
   DCHECK(!m_nodeLists[list->invalidationType()].contains(list));
   m_nodeLists[list->invalidationType()].add(list);
-  ScriptWrappableVisitor::writeBarrier(this, list);
+  liveNodeListBaseWriteBarrier(this, list);
   if (list->isRootedAtTreeScope())
     m_listsInvalidatedAtDocument.add(list);
 }
@@ -4120,7 +4133,7 @@
 void Document::registerNodeListWithIdNameCache(const LiveNodeListBase* list) {
   DCHECK(!m_nodeLists[InvalidateOnIdNameAttrChange].contains(list));
   m_nodeLists[InvalidateOnIdNameAttrChange].add(list);
-  ScriptWrappableVisitor::writeBarrier(this, list);
+  liveNodeListBaseWriteBarrier(this, list);
 }
 
 void Document::unregisterNodeListWithIdNameCache(const LiveNodeListBase* list) {
@@ -6520,13 +6533,20 @@
   visitor->traceWrappers(m_styleEngine);
   for (int i = 0; i < numNodeListInvalidationTypes; ++i) {
     for (auto list : m_nodeLists[i]) {
-      visitor->traceWrappersWithManualWriteBarrier(list);
+      if (isHTMLCollectionType(list->type())) {
+        visitor->traceWrappersWithManualWriteBarrier(
+            static_cast<const HTMLCollection*>(list.get()));
+      } else {
+        visitor->traceWrappersWithManualWriteBarrier(
+            static_cast<const LiveNodeList*>(list.get()));
+      }
     }
   }
   // Cannot trace in Supplementable<Document> as it is part of platform/ and
   // thus cannot refer to ScriptWrappableVisitor.
-  visitor->traceWrappers(Supplementable<Document>::m_supplements.get(
-      FontFaceSet::supplementName()));
+  visitor->traceWrappers(
+      static_cast<FontFaceSet*>(Supplementable<Document>::m_supplements.get(
+          FontFaceSet::supplementName())));
   ContainerNode::traceWrappers(visitor);
 }
 
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
index 442f994..b190dd70 100644
--- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
+++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
@@ -250,7 +250,6 @@
   Member<MarkerList>& list = markers->at(markerListIndex);
   RenderedDocumentMarker* newRenderedMarker =
       RenderedDocumentMarker::create(newMarker);
-  updateMarkerRenderedRect(*node, *newRenderedMarker);
   if (list->isEmpty() || list->back()->endOffset() < newMarker.startOffset()) {
     list->append(newRenderedMarker);
   } else {
diff --git a/third_party/WebKit/Source/core/html/BUILD.gn b/third_party/WebKit/Source/core/html/BUILD.gn
index dda1279..3f45c048 100644
--- a/third_party/WebKit/Source/core/html/BUILD.gn
+++ b/third_party/WebKit/Source/core/html/BUILD.gn
@@ -17,6 +17,7 @@
     "CrossOriginAttribute.h",
     "DocumentNameCollection.cpp",
     "DocumentNameCollection.h",
+    "FormAssociated.h",
     "FormData.cpp",
     "FormData.h",
     "HTMLAllCollection.cpp",
diff --git a/third_party/WebKit/Source/core/html/FormAssociated.h b/third_party/WebKit/Source/core/html/FormAssociated.h
new file mode 100644
index 0000000..a10c5154
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/FormAssociated.h
@@ -0,0 +1,22 @@
+// Copyright 2016 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.
+
+#ifndef FormAssociated_h
+#define FormAssociated_h
+
+namespace blink {
+
+class HTMLFormElement;
+
+// Contains code to associate form with a form associated element
+// https://html.spec.whatwg.org/multipage/forms.html#form-associated-element
+class FormAssociated {
+ public:
+  // HTMLFormElement can be null
+  virtual void associateWith(HTMLFormElement*) = 0;
+};
+
+}  // namespace blink
+
+#endif  // FormAssociated_h
diff --git a/third_party/WebKit/Source/core/html/HTMLElement.h b/third_party/WebKit/Source/core/html/HTMLElement.h
index 9ad60ed..6c5d7e1 100644
--- a/third_party/WebKit/Source/core/html/HTMLElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLElement.h
@@ -29,9 +29,10 @@
 namespace blink {
 
 class DocumentFragment;
+class ExceptionState;
+class FormAssociated;
 class HTMLFormElement;
 class HTMLMenuElement;
-class ExceptionState;
 class KeyboardEvent;
 
 enum TranslateAttributeMode {
@@ -119,6 +120,8 @@
 
   Element* unclosedOffsetParent();
 
+  virtual FormAssociated* toFormAssociatedOrNull() { return nullptr; };
+
  protected:
   HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
 
diff --git a/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp b/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
index cc31336..6cfd1bb 100644
--- a/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
@@ -28,9 +28,7 @@
 #include "core/dom/ElementTraversal.h"
 #include "core/dom/NodeListsNodeData.h"
 #include "core/html/HTMLCollection.h"
-#include "core/html/HTMLFormControlsCollection.h"
 #include "core/html/HTMLLegendElement.h"
-#include "core/html/HTMLObjectElement.h"
 #include "core/layout/LayoutFieldset.h"
 #include "wtf/StdLibExtras.h"
 
@@ -40,30 +38,23 @@
 
 inline HTMLFieldSetElement::HTMLFieldSetElement(Document& document,
                                                 HTMLFormElement* form)
-    : HTMLFormControlElement(fieldsetTag, document, form),
-      m_documentVersion(0) {}
+    : HTMLFormControlElement(fieldsetTag, document, form) {}
 
 HTMLFieldSetElement* HTMLFieldSetElement::create(Document& document,
                                                  HTMLFormElement* form) {
   return new HTMLFieldSetElement(document, form);
 }
 
-DEFINE_TRACE(HTMLFieldSetElement) {
-  visitor->trace(m_listedElements);
-  HTMLFormControlElement::trace(visitor);
-}
-
 bool HTMLFieldSetElement::matchesValidityPseudoClasses() const {
   return true;
 }
 
 bool HTMLFieldSetElement::isValidElement() {
-  const ListedElement::List& elements = listedElements();
-  for (unsigned i = 0; i < elements.size(); ++i) {
-    if (elements[i]->isFormControlElement()) {
-      HTMLFormControlElement* control =
-          toHTMLFormControlElement(elements[i].get());
-      if (!control->checkValidity(0, CheckValidityDispatchNoEvent))
+  HTMLCollection* elements = this->elements();
+  for (unsigned i = 0; i < elements->length(); ++i) {
+    if (elements->item(i)->isFormControlElement()) {
+      if (!toHTMLFormControlElement(elements->item(i))
+               ->checkValidity(nullptr, CheckValidityDispatchNoEvent))
         return false;
     }
   }
@@ -115,33 +106,6 @@
   return ensureCachedCollection<HTMLCollection>(FormControls);
 }
 
-void HTMLFieldSetElement::refreshElementsIfNeeded() const {
-  uint64_t docVersion = document().domTreeVersion();
-  if (m_documentVersion == docVersion)
-    return;
-
-  m_documentVersion = docVersion;
-
-  m_listedElements.clear();
-
-  for (HTMLElement& element : Traversal<HTMLElement>::descendantsOf(*this)) {
-    if (isHTMLObjectElement(element)) {
-      m_listedElements.append(toHTMLObjectElement(&element));
-      continue;
-    }
-
-    if (!element.isFormControlElement())
-      continue;
-
-    m_listedElements.append(toHTMLFormControlElement(&element));
-  }
-}
-
-const ListedElement::List& HTMLFieldSetElement::listedElements() const {
-  refreshElementsIfNeeded();
-  return m_listedElements;
-}
-
 int HTMLFieldSetElement::tabIndex() const {
   return HTMLElement::tabIndex();
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h b/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
index 1a91b80..9c1a497 100644
--- a/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
@@ -36,7 +36,6 @@
 
  public:
   static HTMLFieldSetElement* create(Document&, HTMLFormElement*);
-  DECLARE_VIRTUAL_TRACE();
   HTMLLegendElement* legend() const;
   HTMLCollection* elements();
 
@@ -60,14 +59,6 @@
   bool alwaysCreateUserAgentShadowRoot() const override { return false; }
 
   static void invalidateDisabledStateUnder(Element&);
-  void refreshElementsIfNeeded() const;
-  const ListedElement::List& listedElements() const;
-
-  // TODO(tkent): Remove m_listedElements.
-  mutable ListedElement::List m_listedElements;
-  // When dom tree is modified, we have to refresh the m_listedElements
-  // array.
-  mutable uint64_t m_documentVersion;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp b/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
index dfcfd44c..5f6d4e1 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
@@ -627,4 +627,6 @@
   setNeedsValidityCheck();
 }
 
+void HTMLFormControlElement::associateWith(HTMLFormElement*){};
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLFormControlElement.h b/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
index 0d2a9a1..79334a57 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
@@ -26,6 +26,7 @@
 #define HTMLFormControlElement_h
 
 #include "core/CoreExport.h"
+#include "core/html/FormAssociated.h"
 #include "core/html/LabelableElement.h"
 #include "core/html/ListedElement.h"
 
@@ -43,7 +44,8 @@
 // ListedElement, and listed element implementations should use
 // HTMLFormControlElement unless there is a special reason.
 class CORE_EXPORT HTMLFormControlElement : public LabelableElement,
-                                           public ListedElement {
+                                           public ListedElement,
+                                           public FormAssociated {
   USING_GARBAGE_COLLECTED_MIXIN(HTMLFormControlElement);
 
  public:
@@ -127,6 +129,9 @@
 
   void copyNonAttributePropertiesFromElement(const Element&) override;
 
+  FormAssociated* toFormAssociatedOrNull() override { return this; };
+  void associateWith(HTMLFormElement*) override;
+
  protected:
   HTMLFormControlElement(const QualifiedName& tagName,
                          Document&,
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index 01fc2ac..e5c5aae 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -37,6 +37,7 @@
 #include "core/frame/Deprecation.h"
 #include "core/frame/ImageBitmap.h"
 #include "core/frame/LocalDOMWindow.h"
+#include "core/html/FormAssociated.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLFormElement.h"
@@ -891,4 +892,6 @@
   return IntSize(lSize.width().toInt(), lSize.height().toInt());
 }
 
+void HTMLImageElement::associateWith(HTMLFormElement*){};
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.h b/third_party/WebKit/Source/core/html/HTMLImageElement.h
index 1bc5c0cd..884a8b3e 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.h
@@ -27,6 +27,7 @@
 #include "bindings/core/v8/ActiveScriptWrappable.h"
 #include "core/CoreExport.h"
 #include "core/fetch/FetchRequest.h"
+#include "core/html/FormAssociated.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLImageLoader.h"
 #include "core/html/canvas/CanvasImageSource.h"
@@ -44,7 +45,8 @@
 class CORE_EXPORT HTMLImageElement final : public HTMLElement,
                                            public CanvasImageSource,
                                            public ImageBitmapSource,
-                                           public ActiveScriptWrappable {
+                                           public ActiveScriptWrappable,
+                                           public FormAssociated {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(HTMLImageElement);
 
@@ -140,6 +142,9 @@
                                   const ImageBitmapOptions&,
                                   ExceptionState&) override;
 
+  FormAssociated* toFormAssociatedOrNull() override { return this; };
+  void associateWith(HTMLFormElement*) override;
+
  protected:
   explicit HTMLImageElement(Document&,
                             HTMLFormElement* = 0,
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp b/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
index 5e10a70..abd237c 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
@@ -465,4 +465,6 @@
   return !hasValidClassId() && hasFallbackContent();
 }
 
+void HTMLObjectElement::associateWith(HTMLFormElement*){};
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.h b/third_party/WebKit/Source/core/html/HTMLObjectElement.h
index fea5c46..818329e 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.h
@@ -24,6 +24,7 @@
 #define HTMLObjectElement_h
 
 #include "core/CoreExport.h"
+#include "core/html/FormAssociated.h"
 #include "core/html/HTMLPlugInElement.h"
 #include "core/html/ListedElement.h"
 
@@ -36,7 +37,8 @@
 // working according to the spec.  See:
 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-object-element
 class CORE_EXPORT HTMLObjectElement final : public HTMLPlugInElement,
-                                            public ListedElement {
+                                            public ListedElement,
+                                            public FormAssociated {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(HTMLObjectElement);
 
@@ -76,6 +78,9 @@
 
   bool willUseFallbackContentAtLayout() const;
 
+  FormAssociated* toFormAssociatedOrNull() override { return this; };
+  void associateWith(HTMLFormElement*) override;
+
  private:
   HTMLObjectElement(Document&, HTMLFormElement*, bool createdByParser);
 
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
index 1954a69..c14205ed 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -46,6 +46,7 @@
 #include "core/dom/custom/CustomElementRegistry.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
+#include "core/html/FormAssociated.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLHtmlElement.h"
 #include "core/html/HTMLPlugInElement.h"
@@ -871,7 +872,7 @@
 }
 
 // "create an element for a token"
-// https://html.spec.whatwg.org/#create-an-element-for-the-token
+// https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token
 // TODO(dominicc): When form association is separate from creation, unify this
 // with foreign element creation. Add a namespace parameter and check for HTML
 // namespace to lookupCustomElementDefinition.
@@ -937,6 +938,10 @@
     // occur after construction to allow better code sharing here.
     element = HTMLElementFactory::createHTMLElement(
         token->name(), document, form, getCreateElementFlags());
+    if (FormAssociated* formAssociatedElement =
+            element->toFormAssociatedOrNull()) {
+      formAssociatedElement->associateWith(form);
+    }
     // Definition for the created element does not exist here and it cannot be
     // custom or failed.
     DCHECK_NE(element->getCustomElementState(), CustomElementState::Custom);
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 5542392..cb63f2c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -99,8 +99,7 @@
 
   // If border was changed, invalidate collapsed borders cache.
   if (!needsLayout() && oldStyle && oldStyle->border() != style()->border())
-    invalidateCollapsedBorders(PaintInvalidationStyleChange);
-
+    invalidateCollapsedBorders();
   if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *this, diff,
                                                      *oldStyle))
     markAllCellsWidthsDirtyAndOrNeedsLayout(MarkDirtyAndNeedsLayout);
@@ -733,7 +732,7 @@
     updateLayerTransformAfterLayout();
 
     // Layout was changed, so probably borders too.
-    invalidateCollapsedBorders(PaintInvalidationForcedByLayout);
+    invalidateCollapsedBorders();
 
     computeOverflow(clientLogicalBottom());
     updateAfterLayout();
@@ -752,19 +751,13 @@
   clearNeedsLayout();
 }
 
-void LayoutTable::invalidateCollapsedBorders(PaintInvalidationReason reason) {
-  DCHECK(reason == PaintInvalidationStyleChange ||
-         reason == PaintInvalidationForcedByLayout);
-
-  m_collapsedBordersInfo = nullptr;
+void LayoutTable::invalidateCollapsedBorders() {
+  m_collapsedBorders.clear();
   if (!collapseBorders())
     return;
 
   m_collapsedBordersValid = false;
-  if (reason == PaintInvalidationForcedByLayout)
-    setShouldDoFullPaintInvalidation(reason);
-  else
-    setMayNeedPaintInvalidation();
+  setMayNeedPaintInvalidation();
 }
 
 // Collect all the unique border values that we want to paint in a sorted list.
@@ -772,15 +765,10 @@
 // cache of its containing section, and invalidates itself if any border
 // changes. This method doesn't affect layout.
 void LayoutTable::recalcCollapsedBordersIfNeeded() {
-  if (m_collapsedBordersValid)
+  if (m_collapsedBordersValid || !collapseBorders())
     return;
   m_collapsedBordersValid = true;
-  m_collapsedBordersInfo = nullptr;
-  if (!collapseBorders())
-    return;
-
-  LayoutRect boundsOfChangedCells;
-  Vector<CollapsedBorderValue> values;
+  m_collapsedBorders.clear();
   for (LayoutObject* section = firstChild(); section;
        section = section->nextSibling()) {
     if (!section->isTableSection())
@@ -789,23 +777,12 @@
          row = row->nextRow()) {
       for (LayoutTableCell* cell = row->firstCell(); cell;
            cell = cell->nextCell()) {
-        DCHECK(cell->table() == this);
-        bool cellChanged = cell->collectBorderValues(values);
-        if (cellChanged && !shouldDoFullPaintInvalidation()) {
-          LayoutRect cellRect = cell->localVisualRect();
-          cell->mapToVisualRectInAncestorSpace(this, cellRect);
-          boundsOfChangedCells.unite(cellRect);
-        }
+        ASSERT(cell->table() == this);
+        cell->collectBorderValues(m_collapsedBorders);
       }
     }
   }
-  if (!values.isEmpty()) {
-    LayoutTableCell::sortBorderValues(values);
-    m_collapsedBordersInfo =
-        wrapUnique(new CollapsedBordersInfo(std::move(values)));
-  }
-
-  invalidatePaintRectangle(boundsOfChangedCells);
+  LayoutTableCell::sortBorderValues(m_collapsedBorders);
 }
 
 void LayoutTable::addOverflowFromChildren() {
@@ -1685,10 +1662,10 @@
 
 PaintInvalidationReason LayoutTable::invalidatePaintIfNeeded(
     const PaintInvalidationState& paintInvalidationState) {
-  if (hasCollapsedBorders()) {
+  if (collapseBorders() && !m_collapsedBorders.isEmpty())
     paintInvalidationState.paintingLayer()
         .setNeedsPaintPhaseDescendantBlockBackgrounds();
-  }
+
   return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState);
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.h b/third_party/WebKit/Source/core/layout/LayoutTable.h
index 2148c78..09ac5911 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.h
@@ -29,9 +29,7 @@
 #include "core/CSSPropertyNames.h"
 #include "core/CoreExport.h"
 #include "core/layout/LayoutBlock.h"
-#include "core/paint/PaintResult.h"
 #include "core/style/CollapsedBorderValue.h"
-#include "platform/graphics/paint/CullRect.h"
 #include "wtf/Vector.h"
 #include <memory>
 
@@ -379,7 +377,8 @@
   LayoutTableCell* cellBefore(const LayoutTableCell*) const;
   LayoutTableCell* cellAfter(const LayoutTableCell*) const;
 
-  void invalidateCollapsedBorders(PaintInvalidationReason);
+  typedef Vector<CollapsedBorderValue> CollapsedBorderValues;
+  void invalidateCollapsedBorders();
 
   bool hasSections() const { return m_head || m_foot || m_firstBody; }
 
@@ -408,23 +407,9 @@
 
   void paintMask(const PaintInfo&, const LayoutPoint&) const final;
 
-  struct CollapsedBordersInfo {
-    explicit CollapsedBordersInfo(const Vector<CollapsedBorderValue>& values)
-        : values(std::move(values)) {}
-
-    PaintResult lastPaintResult = FullyPainted;
-    CullRect lastPaintRect;
-    const Vector<CollapsedBorderValue> values;
-  };
-
-  bool hasCollapsedBorders() const {
-    DCHECK(m_collapsedBordersValid);
-    DCHECK(!m_collapsedBordersInfo || collapseBorders());
-    return !!m_collapsedBordersInfo;
-  }
-  CollapsedBordersInfo& getCollapsedBordersInfo() const {
-    DCHECK(hasCollapsedBorders());
-    return *m_collapsedBordersInfo;
+  const CollapsedBorderValues& collapsedBorders() const {
+    ASSERT(m_collapsedBordersValid);
+    return m_collapsedBorders;
   }
 
   void subtractCaptionRect(LayoutRect&) const;
@@ -567,7 +552,7 @@
   // need to compare a cells border against all the adjoining cells, rows,
   // row groups, column, column groups and table. Thus we cache them in this
   // field.
-  std::unique_ptr<CollapsedBordersInfo> m_collapsedBordersInfo;
+  CollapsedBorderValues m_collapsedBorders;
   bool m_collapsedBordersValid : 1;
 
   mutable bool m_hasColElements : 1;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
index 24d98a15..e8195e9 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
@@ -67,6 +67,34 @@
   updateColAndRowSpanFlags();
 }
 
+LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues(
+    const LayoutTable& layoutTable,
+    const CollapsedBorderValue& startBorder,
+    const CollapsedBorderValue& endBorder,
+    const CollapsedBorderValue& beforeBorder,
+    const CollapsedBorderValue& afterBorder)
+    : m_layoutTable(layoutTable),
+      m_startBorder(startBorder),
+      m_endBorder(endBorder),
+      m_beforeBorder(beforeBorder),
+      m_afterBorder(afterBorder) {}
+
+void LayoutTableCell::CollapsedBorderValues::setCollapsedBorderValues(
+    const CollapsedBorderValues& other) {
+  m_startBorder = other.startBorder();
+  m_endBorder = other.endBorder();
+  m_beforeBorder = other.beforeBorder();
+  m_afterBorder = other.afterBorder();
+}
+
+String LayoutTableCell::CollapsedBorderValues::debugName() const {
+  return "CollapsedBorderValues";
+}
+
+LayoutRect LayoutTableCell::CollapsedBorderValues::visualRect() const {
+  return m_layoutTable.visualRect();
+}
+
 void LayoutTableCell::willBeRemovedFromTree() {
   LayoutBlockFlow::willBeRemovedFromTree();
 
@@ -472,7 +500,7 @@
     return;
   if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() &&
       oldStyle && oldStyle->border() != style()->border())
-    table->invalidateCollapsedBorders(PaintInvalidationStyleChange);
+    table->invalidateCollapsedBorders();
 
   if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff,
                                                      *oldStyle)) {
@@ -1275,7 +1303,7 @@
   TableCellPainter(*this).paint(paintInfo, paintOffset);
 }
 
-static void addBorderStyle(Vector<CollapsedBorderValue>& borderValues,
+static void addBorderStyle(LayoutTable::CollapsedBorderValues& borderValues,
                            CollapsedBorderValue borderValue) {
   if (!borderValue.isVisible())
     return;
@@ -1287,34 +1315,56 @@
   borderValues.append(borderValue);
 }
 
-bool LayoutTableCell::collectBorderValues(
-    Vector<CollapsedBorderValue>& borderValues) {
-  CollapsedBorderValues newValues = {
-      computeCollapsedStartBorder(), computeCollapsedEndBorder(),
-      computeCollapsedBeforeBorder(), computeCollapsedAfterBorder()};
+void LayoutTableCell::collectBorderValues(
+    LayoutTable::CollapsedBorderValues& borderValues) {
+  CollapsedBorderValues newValues(
+      *table(), computeCollapsedStartBorder(), computeCollapsedEndBorder(),
+      computeCollapsedBeforeBorder(), computeCollapsedAfterBorder());
 
   bool changed = false;
-  if (newValues.allBordersAreInvisible()) {
+  if (!newValues.startBorder().isVisible() &&
+      !newValues.endBorder().isVisible() &&
+      !newValues.beforeBorder().isVisible() &&
+      !newValues.afterBorder().isVisible()) {
     changed = !!m_collapsedBorderValues;
     m_collapsedBorderValues = nullptr;
   } else if (!m_collapsedBorderValues) {
     changed = true;
-    m_collapsedBorderValues = wrapUnique(new CollapsedBorderValues(newValues));
+    m_collapsedBorderValues = wrapUnique(new CollapsedBorderValues(
+        *table(), newValues.startBorder(), newValues.endBorder(),
+        newValues.beforeBorder(), newValues.afterBorder()));
   } else {
-    changed = !m_collapsedBorderValues->bordersVisuallyEqual(newValues);
+    // We check visuallyEquals so that the table cell is invalidated only if a
+    // changed collapsed border is visible in the first place.
+    changed = !m_collapsedBorderValues->startBorder().visuallyEquals(
+                  newValues.startBorder()) ||
+              !m_collapsedBorderValues->endBorder().visuallyEquals(
+                  newValues.endBorder()) ||
+              !m_collapsedBorderValues->beforeBorder().visuallyEquals(
+                  newValues.beforeBorder()) ||
+              !m_collapsedBorderValues->afterBorder().visuallyEquals(
+                  newValues.afterBorder());
     if (changed)
-      *m_collapsedBorderValues = newValues;
+      m_collapsedBorderValues->setCollapsedBorderValues(newValues);
   }
 
-  addBorderStyle(borderValues, newValues.startBorder);
-  addBorderStyle(borderValues, newValues.endBorder);
-  addBorderStyle(borderValues, newValues.beforeBorder);
-  addBorderStyle(borderValues, newValues.afterBorder);
-  return changed;
+  // If collapsed borders changed, invalidate the cell's display item client on
+  // the table's backing.
+  // TODO(crbug.com/451090#c5): Need a way to invalidate/repaint the borders
+  // only.
+  if (changed)
+    ObjectPaintInvalidator(*table())
+        .slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(
+            *this, PaintInvalidationStyleChange);
+
+  addBorderStyle(borderValues, newValues.startBorder());
+  addBorderStyle(borderValues, newValues.endBorder());
+  addBorderStyle(borderValues, newValues.beforeBorder());
+  addBorderStyle(borderValues, newValues.afterBorder());
 }
 
 void LayoutTableCell::sortBorderValues(
-    Vector<CollapsedBorderValue>& borderValues) {
+    LayoutTable::CollapsedBorderValues& borderValues) {
   std::sort(borderValues.begin(), borderValues.end(), compareBorders);
 }
 
@@ -1409,6 +1459,8 @@
     return;
 
   ObjectPaintInvalidator invalidator(*this);
+  if (m_collapsedBorderValues)
+    invalidator.invalidateDisplayItemClient(*m_collapsedBorderValues, reason);
   if (m_rowBackgroundDisplayItemClient) {
     invalidator.invalidateDisplayItemClient(*m_rowBackgroundDisplayItemClient,
                                             reason);
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.h b/third_party/WebKit/Source/core/layout/LayoutTableCell.h
index e9a9716..12f5210 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCell.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.h
@@ -185,9 +185,8 @@
   int borderBefore() const override;
   int borderAfter() const override;
 
-  // Returns true if any collapsed borders related to this cell changed.
-  bool collectBorderValues(Vector<CollapsedBorderValue>&);
-  static void sortBorderValues(Vector<CollapsedBorderValue>&);
+  void collectBorderValues(LayoutTable::CollapsedBorderValues&);
+  static void sortBorderValues(LayoutTable::CollapsedBorderValues&);
 
   void layout() override;
 
@@ -290,22 +289,33 @@
   bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const override;
   void invalidateDisplayItemClients(PaintInvalidationReason) const override;
 
-  struct CollapsedBorderValues {
-    CollapsedBorderValue startBorder;
-    CollapsedBorderValue endBorder;
-    CollapsedBorderValue beforeBorder;
-    CollapsedBorderValue afterBorder;
+  // TODO(wkorman): Consider renaming to more clearly differentiate from
+  // CollapsedBorderValue.
+  class CollapsedBorderValues : public DisplayItemClient {
+   public:
+    CollapsedBorderValues(const LayoutTable&,
+                          const CollapsedBorderValue& startBorder,
+                          const CollapsedBorderValue& endBorder,
+                          const CollapsedBorderValue& beforeBorder,
+                          const CollapsedBorderValue& afterBorder);
 
-    bool allBordersAreInvisible() const {
-      return !startBorder.isVisible() && !endBorder.isVisible() &&
-             !beforeBorder.isVisible() && !afterBorder.isVisible();
-    }
-    bool bordersVisuallyEqual(const CollapsedBorderValues& other) const {
-      return startBorder.visuallyEquals(other.startBorder) &&
-             endBorder.visuallyEquals(other.endBorder) &&
-             beforeBorder.visuallyEquals(other.beforeBorder) &&
-             afterBorder.visuallyEquals(other.afterBorder);
-    }
+    const CollapsedBorderValue& startBorder() const { return m_startBorder; }
+    const CollapsedBorderValue& endBorder() const { return m_endBorder; }
+    const CollapsedBorderValue& beforeBorder() const { return m_beforeBorder; }
+    const CollapsedBorderValue& afterBorder() const { return m_afterBorder; }
+
+    void setCollapsedBorderValues(const CollapsedBorderValues& other);
+
+    // DisplayItemClient methods.
+    String debugName() const;
+    LayoutRect visualRect() const;
+
+   private:
+    const LayoutTable& m_layoutTable;
+    CollapsedBorderValue m_startBorder;
+    CollapsedBorderValue m_endBorder;
+    CollapsedBorderValue m_beforeBorder;
+    CollapsedBorderValue m_afterBorder;
   };
 
   class RowBackgroundDisplayItemClient : public DisplayItemClient {
@@ -321,7 +331,6 @@
   };
 
   bool usesCompositedCellDisplayItemClients() const;
-
   const CollapsedBorderValues* collapsedBorderValues() const {
     return m_collapsedBorderValues.get();
   }
@@ -341,8 +350,6 @@
 
   void ensureIsReadyForPaintInvalidation() override;
 
-  LayoutRect localVisualRect() const override;
-
  protected:
   void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override;
   void computePreferredLogicalWidths() override;
@@ -366,6 +373,7 @@
   void paintMask(const PaintInfo&, const LayoutPoint&) const override;
 
   LayoutSize offsetFromContainer(const LayoutObject*) const override;
+  LayoutRect localVisualRect() const override;
 
   int borderHalfLeft(bool outer) const;
   int borderHalfRight(bool outer) const;
@@ -403,8 +411,8 @@
   // See also https://code.google.com/p/chromium/issues/detail?id=128227 for
   // some history.
   //
-  // Those functions are called before paint invalidation if the collapsed
-  // borders cache is invalidated on LayoutTable.
+  // Those functions are called when the cache (m_collapsedBorders) is
+  // invalidated on LayoutTable.
   CollapsedBorderValue computeCollapsedStartBorder(
       IncludeBorderColorOrNot = IncludeBorderColor) const;
   CollapsedBorderValue computeCollapsedEndBorder(
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp
index b136ac8..ba923455 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp
@@ -60,7 +60,7 @@
   // the next one can't be, so don't even check its condition.
   if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() &&
       oldStyle->border() != style()->border()) {
-    table->invalidateCollapsedBorders(PaintInvalidationStyleChange);
+    table->invalidateCollapsedBorders();
   } else if ((oldStyle->logicalWidth() != style()->logicalWidth()) ||
              LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff,
                                                             *oldStyle)) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
index 41d43d6..03d700d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
@@ -74,7 +74,7 @@
 
   if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() &&
       oldStyle->border() != style()->border())
-    table->invalidateCollapsedBorders(PaintInvalidationStyleChange);
+    table->invalidateCollapsedBorders();
 
   if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff,
                                                      *oldStyle)) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
index 79f4c10..572ded7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
@@ -132,7 +132,7 @@
 
   if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() &&
       oldStyle->border() != style()->border())
-    table->invalidateCollapsedBorders(PaintInvalidationStyleChange);
+    table->invalidateCollapsedBorders();
 
   if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff,
                                                      *oldStyle))
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.h b/third_party/WebKit/Source/core/layout/LayoutTableSection.h
index 6c82c3ad..5c0b9f70 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.h
@@ -57,13 +57,6 @@
   unsigned m_end;
 };
 
-inline bool operator==(const CellSpan& a, const CellSpan& b) {
-  return a.start() == b.start() && a.end() == b.end();
-}
-inline bool operator!=(const CellSpan& a, const CellSpan& b) {
-  return !(a == b);
-}
-
 class LayoutTableCell;
 class LayoutTableRow;
 
@@ -303,13 +296,8 @@
   // columnPos vectors.
   LayoutRect logicalRectForWritingModeAndDirection(const LayoutRect&) const;
 
-  CellSpan fullTableRowSpan() const { return CellSpan(0, m_grid.size()); }
-  CellSpan fullTableEffectiveColumnSpan() const {
-    return CellSpan(0, table()->numEffectiveColumns());
-  }
   CellSpan dirtiedRows(const LayoutRect& visualRect) const;
   CellSpan dirtiedEffectiveColumns(const LayoutRect& visualRect) const;
-
   const HashSet<LayoutTableCell*>& overflowingCells() const {
     return m_overflowingCells;
   }
@@ -413,6 +401,11 @@
 
   void computeOverflowFromCells(unsigned totalRows, unsigned nEffCols);
 
+  CellSpan fullTableRowSpan() const { return CellSpan(0, m_grid.size()); }
+  CellSpan fullTableEffectiveColumnSpan() const {
+    return CellSpan(0, table()->numEffectiveColumns());
+  }
+
   // These two functions take a rectangle as input that has been flipped by
   // logicalRectForWritingModeAndDirection.
   // The returned span of rows or columns is end-exclusive, and empty if
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index 043e2e7e..04bb0c42 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -99,7 +99,7 @@
                                const SubstituteData& substituteData,
                                ClientRedirectPolicy clientRedirectPolicy)
     : m_frame(frame),
-      m_fetcher(FrameFetchContext::createContextAndFetcher(this, nullptr)),
+      m_fetcher(FrameFetchContext::createFetcherFromDocumentLoader(this)),
       m_originalRequest(req),
       m_substituteData(substituteData),
       m_request(req),
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 049c2e2..d5787a3 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -203,12 +203,20 @@
   m_documentLoader = nullptr;
 }
 
+LocalFrame* FrameFetchContext::frameOfImportsController() const {
+  DCHECK(m_document);
+  HTMLImportsController* importsController = m_document->importsController();
+  DCHECK(importsController);
+  LocalFrame* frame = importsController->master()->frame();
+  DCHECK(frame);
+  return frame;
+}
+
 LocalFrame* FrameFetchContext::frame() const {
-  LocalFrame* frame = nullptr;
-  if (m_documentLoader)
-    frame = m_documentLoader->frame();
-  else if (m_document && m_document->importsController())
-    frame = m_document->importsController()->master()->frame();
+  if (!m_documentLoader)
+    return frameOfImportsController();
+
+  LocalFrame* frame = m_documentLoader->frame();
   DCHECK(frame);
   return frame;
 }
@@ -357,8 +365,10 @@
 // FIXME(http://crbug.com/274173): This means Inspector, which uses
 // DocumentLoader as a grouping entity, cannot see imported documents.
 inline DocumentLoader* FrameFetchContext::masterDocumentLoader() const {
-  return m_documentLoader ? m_documentLoader.get()
-                          : frame()->loader().documentLoader();
+  if (m_documentLoader)
+    return m_documentLoader.get();
+
+  return frameOfImportsController()->loader().documentLoader();
 }
 
 void FrameFetchContext::dispatchDidChangeResourcePriority(
@@ -491,9 +501,11 @@
 bool FrameFetchContext::shouldLoadNewResource(Resource::Type type) const {
   if (!m_documentLoader)
     return true;
+
+  FrameLoader& loader = m_documentLoader->frame()->loader();
   if (type == Resource::MainResource)
-    return m_documentLoader == frame()->loader().provisionalDocumentLoader();
-  return m_documentLoader == frame()->loader().documentLoader();
+    return m_documentLoader == loader.provisionalDocumentLoader();
+  return m_documentLoader == loader.documentLoader();
 }
 
 static std::unique_ptr<TracedValue>
@@ -767,8 +779,10 @@
     return false;
 
   if (m_documentLoader) {
-    return frame()->loader().client()->isControlledByServiceWorker(
-        *m_documentLoader);
+    return m_documentLoader->frame()
+        ->loader()
+        .client()
+        ->isControlledByServiceWorker(*m_documentLoader);
   }
   // m_documentLoader is null while loading resources from an HTML import. In
   // such cases whether the request is controlled by ServiceWorker or not is
@@ -779,8 +793,10 @@
 
 int64_t FrameFetchContext::serviceWorkerID() const {
   DCHECK(m_documentLoader || frame()->loader().documentLoader());
-  if (m_documentLoader)
-    return frame()->loader().client()->serviceWorkerID(*m_documentLoader);
+  if (m_documentLoader) {
+    return m_documentLoader->frame()->loader().client()->serviceWorkerID(
+        *m_documentLoader);
+  }
   // m_documentLoader is null while loading resources from an HTML import.
   // In such cases a service worker ID could be retrieved from the document
   // loader of the frame.
@@ -975,7 +991,8 @@
   MixedContentChecker::checkMixedPrivatePublic(frame(),
                                                response.remoteIPAddress());
   if (m_documentLoader &&
-      m_documentLoader == frame()->loader().provisionalDocumentLoader()) {
+      m_documentLoader ==
+          m_documentLoader->frame()->loader().provisionalDocumentLoader()) {
     ResourceFetcher* fetcher = nullptr;
     if (frame()->document())
       fetcher = frame()->document()->fetcher();
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.h b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
index e65e7028..b35a7fb 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.h
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
@@ -50,9 +50,12 @@
 
 class CORE_EXPORT FrameFetchContext final : public FetchContext {
  public:
-  static ResourceFetcher* createContextAndFetcher(DocumentLoader* loader,
-                                                  Document* document) {
-    return ResourceFetcher::create(new FrameFetchContext(loader, document));
+  static ResourceFetcher* createFetcherFromDocumentLoader(
+      DocumentLoader* loader) {
+    return ResourceFetcher::create(new FrameFetchContext(loader, nullptr));
+  }
+  static ResourceFetcher* createFetcherFromDocument(Document* document) {
+    return ResourceFetcher::create(new FrameFetchContext(nullptr, document));
   }
 
   static void provideDocumentToContext(FetchContext& context,
@@ -155,10 +158,11 @@
   DECLARE_VIRTUAL_TRACE();
 
  private:
-  explicit FrameFetchContext(DocumentLoader*, Document*);
+  FrameFetchContext(DocumentLoader*, Document*);
   inline DocumentLoader* masterDocumentLoader() const;
 
-  LocalFrame* frame() const;  // Can be null
+  LocalFrame* frameOfImportsController() const;
+  LocalFrame* frame() const;
   void printAccessDeniedMessage(const KURL&) const;
   ResourceRequestBlockedReason canRequestInternal(
       Resource::Type,
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index 213982d..4cbd51b 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -193,6 +193,7 @@
       m_dispatchingDidClearWindowObjectInMainWorld(false),
       m_protectProvisionalLoader(false),
       m_isNavigationHandledByClient(false) {
+  DCHECK(m_frame);
   TRACE_EVENT_OBJECT_CREATED_WITH_ID("loading", "FrameLoader", this);
   takeObjectSnapshot();
 }
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
index 8756306e..9982e8a0 100644
--- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
@@ -214,8 +214,11 @@
     context.paintingLayer->setNeedsPaintPhaseDescendantBlockBackgrounds();
   }
 
-  if (object.isTable() && toLayoutTable(object).hasCollapsedBorders())
-    context.paintingLayer->setNeedsPaintPhaseDescendantBlockBackgrounds();
+  if (object.isTable()) {
+    const LayoutTable& table = toLayoutTable(object);
+    if (table.collapseBorders() && !table.collapsedBorders().isEmpty())
+      context.paintingLayer->setNeedsPaintPhaseDescendantBlockBackgrounds();
+  }
 }
 
 namespace {
diff --git a/third_party/WebKit/Source/core/paint/TableCellPainter.cpp b/third_party/WebKit/Source/core/paint/TableCellPainter.cpp
index f3102f6..856d8ecc 100644
--- a/third_party/WebKit/Source/core/paint/TableCellPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/TableCellPainter.cpp
@@ -19,40 +19,40 @@
     const ComputedStyle& styleForCellFlow,
     const LayoutTableCell::CollapsedBorderValues& values) {
   if (styleForCellFlow.isHorizontalWritingMode()) {
-    return styleForCellFlow.isLeftToRightDirection() ? values.startBorder
-                                                     : values.endBorder;
+    return styleForCellFlow.isLeftToRightDirection() ? values.startBorder()
+                                                     : values.endBorder();
   }
-  return styleForCellFlow.isFlippedBlocksWritingMode() ? values.afterBorder
-                                                       : values.beforeBorder;
+  return styleForCellFlow.isFlippedBlocksWritingMode() ? values.afterBorder()
+                                                       : values.beforeBorder();
 }
 
 static const CollapsedBorderValue& collapsedRightBorder(
     const ComputedStyle& styleForCellFlow,
     const LayoutTableCell::CollapsedBorderValues& values) {
   if (styleForCellFlow.isHorizontalWritingMode()) {
-    return styleForCellFlow.isLeftToRightDirection() ? values.endBorder
-                                                     : values.startBorder;
+    return styleForCellFlow.isLeftToRightDirection() ? values.endBorder()
+                                                     : values.startBorder();
   }
-  return styleForCellFlow.isFlippedBlocksWritingMode() ? values.beforeBorder
-                                                       : values.afterBorder;
+  return styleForCellFlow.isFlippedBlocksWritingMode() ? values.beforeBorder()
+                                                       : values.afterBorder();
 }
 
 static const CollapsedBorderValue& collapsedTopBorder(
     const ComputedStyle& styleForCellFlow,
     const LayoutTableCell::CollapsedBorderValues& values) {
   if (styleForCellFlow.isHorizontalWritingMode())
-    return values.beforeBorder;
-  return styleForCellFlow.isLeftToRightDirection() ? values.startBorder
-                                                   : values.endBorder;
+    return values.beforeBorder();
+  return styleForCellFlow.isLeftToRightDirection() ? values.startBorder()
+                                                   : values.endBorder();
 }
 
 static const CollapsedBorderValue& collapsedBottomBorder(
     const ComputedStyle& styleForCellFlow,
     const LayoutTableCell::CollapsedBorderValues& values) {
   if (styleForCellFlow.isHorizontalWritingMode())
-    return values.afterBorder;
-  return styleForCellFlow.isLeftToRightDirection() ? values.endBorder
-                                                   : values.startBorder;
+    return values.afterBorder();
+  return styleForCellFlow.isLeftToRightDirection() ? values.endBorder()
+                                                   : values.startBorder();
 }
 
 void TableCellPainter::paint(const PaintInfo& paintInfo,
@@ -68,6 +68,15 @@
   return style;
 }
 
+const DisplayItemClient& TableCellPainter::displayItemClientForBorders() const {
+  // TODO(wkorman): We may need to handle PaintInvalidationDelayedFull.
+  // http://crbug.com/657186
+  return m_layoutTableCell.usesCompositedCellDisplayItemClients()
+             ? static_cast<const DisplayItemClient&>(
+                   *m_layoutTableCell.collapsedBorderValues())
+             : m_layoutTableCell;
+}
+
 void TableCellPainter::paintCollapsedBorders(
     const PaintInfo& paintInfo,
     const LayoutPoint& paintOffset,
@@ -95,6 +104,18 @@
   const CollapsedBorderValue& bottomBorderValue =
       collapsedBottomBorder(styleForCellFlow, *values);
 
+  int displayItemType = DisplayItem::kTableCollapsedBorderBase;
+  if (topBorderValue.shouldPaint(currentBorderValue))
+    displayItemType |= DisplayItem::TableCollapsedBorderTop;
+  if (bottomBorderValue.shouldPaint(currentBorderValue))
+    displayItemType |= DisplayItem::TableCollapsedBorderBottom;
+  if (leftBorderValue.shouldPaint(currentBorderValue))
+    displayItemType |= DisplayItem::TableCollapsedBorderLeft;
+  if (rightBorderValue.shouldPaint(currentBorderValue))
+    displayItemType |= DisplayItem::TableCollapsedBorderRight;
+  if (displayItemType == DisplayItem::kTableCollapsedBorderBase)
+    return;
+
   int topWidth = topBorderValue.width();
   int bottomWidth = bottomBorderValue.width();
   int leftWidth = leftBorderValue.width();
@@ -110,32 +131,41 @@
       paintRect.height() + topWidth / 2 + (bottomWidth + 1) / 2);
 
   GraphicsContext& graphicsContext = paintInfo.context;
+  const DisplayItemClient& client = displayItemClientForBorders();
+  if (DrawingRecorder::useCachedDrawingIfPossible(
+          graphicsContext, client,
+          static_cast<DisplayItem::Type>(displayItemType)))
+    return;
+
+  DrawingRecorder recorder(graphicsContext, client,
+                           static_cast<DisplayItem::Type>(displayItemType),
+                           borderRect);
   Color cellColor = m_layoutTableCell.resolveColor(CSSPropertyColor);
 
   // We never paint diagonals at the joins.  We simply let the border with the
   // highest precedence paint on top of borders with lower precedence.
-  if (topBorderValue.shouldPaint(currentBorderValue)) {
+  if (displayItemType & DisplayItem::TableCollapsedBorderTop) {
     ObjectPainter::drawLineForBoxSide(
         graphicsContext, borderRect.x(), borderRect.y(), borderRect.maxX(),
         borderRect.y() + topWidth, BSTop,
         topBorderValue.color().resolve(cellColor),
         collapsedBorderStyle(topBorderValue.style()), 0, 0, true);
   }
-  if (bottomBorderValue.shouldPaint(currentBorderValue)) {
+  if (displayItemType & DisplayItem::TableCollapsedBorderBottom) {
     ObjectPainter::drawLineForBoxSide(
         graphicsContext, borderRect.x(), borderRect.maxY() - bottomWidth,
         borderRect.maxX(), borderRect.maxY(), BSBottom,
         bottomBorderValue.color().resolve(cellColor),
         collapsedBorderStyle(bottomBorderValue.style()), 0, 0, true);
   }
-  if (leftBorderValue.shouldPaint(currentBorderValue)) {
+  if (displayItemType & DisplayItem::TableCollapsedBorderLeft) {
     ObjectPainter::drawLineForBoxSide(
         graphicsContext, borderRect.x(), borderRect.y(),
         borderRect.x() + leftWidth, borderRect.maxY(), BSLeft,
         leftBorderValue.color().resolve(cellColor),
         collapsedBorderStyle(leftBorderValue.style()), 0, 0, true);
   }
-  if (rightBorderValue.shouldPaint(currentBorderValue)) {
+  if (displayItemType & DisplayItem::TableCollapsedBorderRight) {
     ObjectPainter::drawLineForBoxSide(
         graphicsContext, borderRect.maxX() - rightWidth, borderRect.y(),
         borderRect.maxX(), borderRect.maxY(), BSRight,
diff --git a/third_party/WebKit/Source/core/paint/TableCellPainter.h b/third_party/WebKit/Source/core/paint/TableCellPainter.h
index 749915c..a87c4b59 100644
--- a/third_party/WebKit/Source/core/paint/TableCellPainter.h
+++ b/third_party/WebKit/Source/core/paint/TableCellPainter.h
@@ -39,6 +39,7 @@
   void paintMask(const PaintInfo&, const LayoutPoint& paintOffset);
 
  private:
+  const DisplayItemClient& displayItemClientForBorders() const;
   LayoutRect paintRectNotIncludingVisualOverflow(
       const LayoutPoint& paintOffset);
   void paintBackground(const PaintInfo&,
diff --git a/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp b/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
index adce65d..1cd5830 100644
--- a/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
@@ -170,12 +170,11 @@
       "100px solid yellow; background: green; }"
       "  table { margin: 100px; border-collapse: collapse; }"
       "</style>"
-      "<table id='table'>"
+      "<table>"
       "  <tr><td id='cell'></td></tr>"
       "</table>");
 
   LayoutView& layoutView = *document().layoutView();
-  LayoutObject& table = *getLayoutObjectByElementId("table");
   LayoutObject& cell = *getLayoutObjectByElementId("cell");
 
   rootPaintController().invalidateAll();
@@ -189,7 +188,7 @@
       rootPaintController().getDisplayItemList(), 4,
       TestDisplayItem(layoutView, DisplayItem::kDocumentBackground),
       TestDisplayItem(cell, DisplayItem::kBoxDecorationBackground),
-      TestDisplayItem(table, DisplayItem::kTableCollapsedBorders),
+      TestDisplayItem(cell, DisplayItem::kTableCollapsedBorderLast),
       TestDisplayItem(cell, DisplayItem::paintPhaseToDrawingType(
                                 PaintPhaseSelfOutlineOnly)));
 }
diff --git a/third_party/WebKit/Source/core/paint/TablePainter.cpp b/third_party/WebKit/Source/core/paint/TablePainter.cpp
index 65a069c..16f910484 100644
--- a/third_party/WebKit/Source/core/paint/TablePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/TablePainter.cpp
@@ -44,61 +44,31 @@
       }
     }
 
-    if (shouldPaintDescendantBlockBackgrounds(paintPhase))
-      paintCollapsedBorders(paintInfoForDescendants, paintOffset);
+    if (m_layoutTable.collapseBorders() &&
+        shouldPaintDescendantBlockBackgrounds(paintPhase) &&
+        m_layoutTable.style()->visibility() == EVisibility::Visible) {
+      // Using our cached sorted styles, we then do individual passes,
+      // painting each style of border from lowest precedence to highest
+      // precedence.
+      LayoutTable::CollapsedBorderValues collapsedBorders =
+          m_layoutTable.collapsedBorders();
+      size_t count = collapsedBorders.size();
+      for (size_t i = 0; i < count; ++i) {
+        for (LayoutTableSection* section = m_layoutTable.bottomSection();
+             section; section = m_layoutTable.sectionAbove(section)) {
+          LayoutPoint childPoint =
+              m_layoutTable.flipForWritingModeForChild(section, paintOffset);
+          TableSectionPainter(*section).paintCollapsedBorders(
+              paintInfoForDescendants, childPoint, collapsedBorders[i]);
+        }
+      }
+    }
   }
 
   if (shouldPaintSelfOutline(paintPhase))
     ObjectPainter(m_layoutTable).paintOutline(paintInfo, paintOffset);
 }
 
-void TablePainter::paintCollapsedBorders(const PaintInfo& paintInfo,
-                                         const LayoutPoint& paintOffset) {
-  if (!m_layoutTable.hasCollapsedBorders() ||
-      m_layoutTable.style()->visibility() != EVisibility::Visible)
-    return;
-
-  LayoutTable::CollapsedBordersInfo& collapsedBorders =
-      m_layoutTable.getCollapsedBordersInfo();
-
-  // Normally we don't clip individual display items by paint dirty rect
-  // (aka interest rect), to keep display items independent with paint dirty
-  // rect so we can just depend on paint invalidation status to repaint them.
-  // However, the collapsed border display item may be too big to contain all
-  // collapsed borders in a huge table, so we clip it to paint dirty rect.
-  // We need to invalidate the display item if the previous paint is clipped
-  // and the paint dirty rect changed.
-  if (collapsedBorders.lastPaintResult != FullyPainted &&
-      collapsedBorders.lastPaintRect != paintInfo.cullRect())
-    m_layoutTable.setDisplayItemsUncached();
-
-  if (DrawingRecorder::useCachedDrawingIfPossible(
-          paintInfo.context, m_layoutTable,
-          DisplayItem::kTableCollapsedBorders))
-    return;
-
-  DrawingRecorder recorder(
-      paintInfo.context, m_layoutTable, DisplayItem::kTableCollapsedBorders,
-      FloatRect(LayoutRect(paintOffset, m_layoutTable.size())));
-
-  // Using our cached sorted styles, we then do individual passes, painting
-  // each style of border from lowest precedence to highest precedence.
-  PaintResult paintResult = FullyPainted;
-  for (const auto& borderValue : collapsedBorders.values) {
-    for (LayoutTableSection* section = m_layoutTable.bottomSection(); section;
-         section = m_layoutTable.sectionAbove(section)) {
-      LayoutPoint childPoint =
-          m_layoutTable.flipForWritingModeForChild(section, paintOffset);
-      if (TableSectionPainter(*section).paintCollapsedBorders(
-              paintInfo, childPoint, borderValue) ==
-          MayBeClippedByPaintDirtyRect)
-        paintResult = MayBeClippedByPaintDirtyRect;
-    }
-  }
-  collapsedBorders.lastPaintResult = paintResult;
-  collapsedBorders.lastPaintRect = paintInfo.cullRect();
-}
-
 void TablePainter::paintBoxDecorationBackground(
     const PaintInfo& paintInfo,
     const LayoutPoint& paintOffset) {
diff --git a/third_party/WebKit/Source/core/paint/TablePainter.h b/third_party/WebKit/Source/core/paint/TablePainter.h
index ac57899..d3de8e0e 100644
--- a/third_party/WebKit/Source/core/paint/TablePainter.h
+++ b/third_party/WebKit/Source/core/paint/TablePainter.h
@@ -24,8 +24,6 @@
   void paintMask(const PaintInfo&, const LayoutPoint&);
 
  private:
-  void paintCollapsedBorders(const PaintInfo&, const LayoutPoint&);
-
   const LayoutTable& m_layoutTable;
 };
 
diff --git a/third_party/WebKit/Source/core/paint/TablePainterTest.cpp b/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
deleted file mode 100644
index 7ebcdff1..0000000
--- a/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2015 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/paint/PaintControllerPaintTest.h"
-#include "platform/graphics/paint/DrawingDisplayItem.h"
-
-namespace blink {
-
-using TablePainterTest = PaintControllerPaintTest;
-
-TEST_F(TablePainterTest, CollapsedBorderInterestRectChange) {
-  setBodyInnerHTML(
-      "<style>"
-      "  table { border-collapse: collapse; position: absolute; }"
-      "  td { width: 100px; height: 100px; border: 2px solid blue; }"
-      "</style>"
-      "<table id='table'>"
-      "  <tr><td></td><td></td><td></td><td></td></tr>"
-      "  <tr><td></td><td></td><td></td><td></td></tr>"
-      "  <tr><td></td><td></td><td></td><td></td></tr>"
-      "  <tr><td></td><td></td><td></td><td></td></tr>"
-      "</table>");
-
-  PaintLayer& htmlLayer =
-      *toLayoutBoxModelObject(document().documentElement()->layoutObject())
-           ->layer();
-  LayoutObject& table = *getLayoutObjectByElementId("table");
-
-  rootPaintController().invalidateAll();
-  document().view()->updateAllLifecyclePhasesExceptPaint();
-  IntRect interestRect(300, 300, 300, 300);
-  paint(&interestRect);
-
-  EXPECT_DISPLAY_LIST(
-      rootPaintController().getDisplayItemList(), 4,
-      TestDisplayItem(layoutView(), documentBackgroundType),
-      TestDisplayItem(htmlLayer, DisplayItem::kSubsequence),
-      TestDisplayItem(table, DisplayItem::kTableCollapsedBorders),
-      TestDisplayItem(htmlLayer, DisplayItem::kEndSubsequence));
-  // Painted collapsed borders of the central 4 cells, each 4 operations.
-  EXPECT_EQ(16, static_cast<const DrawingDisplayItem&>(
-                    rootPaintController().getDisplayItemList()[2])
-                    .picture()
-                    ->approximateOpCount());
-
-  // Should repaint collapsed borders if the previous paint didn't fully paint
-  // and interest rect changes.
-  document().view()->updateAllLifecyclePhasesExceptPaint();
-  interestRect = IntRect(0, 0, 1000, 1000);
-  EXPECT_TRUE(paintWithoutCommit(&interestRect));
-  EXPECT_EQ(1, numCachedNewItems());
-  commit();
-  EXPECT_DISPLAY_LIST(
-      rootPaintController().getDisplayItemList(), 4,
-      TestDisplayItem(layoutView(), documentBackgroundType),
-      TestDisplayItem(htmlLayer, DisplayItem::kSubsequence),
-      TestDisplayItem(table, DisplayItem::kTableCollapsedBorders),
-      TestDisplayItem(htmlLayer, DisplayItem::kEndSubsequence));
-  // Painted collapsed borders of all 16 cells, each 4 operations.
-  EXPECT_EQ(64, static_cast<const DrawingDisplayItem&>(
-                    rootPaintController().getDisplayItemList()[2])
-                    .picture()
-                    ->approximateOpCount());
-
-  // Should not repaint collapsed borders if the previous paint fully painted
-  // and interest rect changes.
-  document().view()->updateAllLifecyclePhasesExceptPaint();
-  interestRect = IntRect(0, 0, 400, 400);
-  EXPECT_TRUE(paintWithoutCommit(&interestRect));
-  EXPECT_EQ(4, numCachedNewItems());
-  commit();
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
index 44e1d61..685ba682 100644
--- a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
@@ -149,27 +149,24 @@
   return elem1->absoluteColumnIndex() < elem2->absoluteColumnIndex();
 }
 
-PaintResult TableSectionPainter::paintCollapsedBorders(
+void TableSectionPainter::paintCollapsedBorders(
     const PaintInfo& paintInfo,
     const LayoutPoint& paintOffset,
     const CollapsedBorderValue& currentBorderValue) {
-  PaintResult result =
-      paintCollapsedSectionBorders(paintInfo, paintOffset, currentBorderValue);
+  paintCollapsedSectionBorders(paintInfo, paintOffset, currentBorderValue);
   LayoutTable* table = m_layoutTableSection.table();
-  if (table->header() == m_layoutTableSection) {
+  if (table->header() == m_layoutTableSection)
     paintRepeatingHeaderGroup(paintInfo, paintOffset, currentBorderValue,
                               PaintCollapsedBorders);
-  }
-  return result;
 }
 
-PaintResult TableSectionPainter::paintCollapsedSectionBorders(
+void TableSectionPainter::paintCollapsedSectionBorders(
     const PaintInfo& paintInfo,
     const LayoutPoint& paintOffset,
     const CollapsedBorderValue& currentBorderValue) {
   if (!m_layoutTableSection.numRows() ||
       !m_layoutTableSection.table()->effectiveColumns().size())
-    return FullyPainted;
+    return;
 
   LayoutPoint adjustedPaintOffset =
       paintOffset + m_layoutTableSection.location();
@@ -188,7 +185,7 @@
       m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect);
 
   if (dirtiedColumns.start() >= dirtiedColumns.end())
-    return MayBeClippedByPaintDirtyRect;
+    return;
 
   // Collapsed borders are painted from the bottom right to the top left so that
   // precedence due to cell position is respected.
@@ -210,11 +207,6 @@
                                                     currentBorderValue);
     }
   }
-
-  if (dirtiedRows == m_layoutTableSection.fullTableRowSpan() &&
-      dirtiedColumns == m_layoutTableSection.fullTableEffectiveColumnSpan())
-    return FullyPainted;
-  return MayBeClippedByPaintDirtyRect;
 }
 
 void TableSectionPainter::paintObject(const PaintInfo& paintInfo,
diff --git a/third_party/WebKit/Source/core/paint/TableSectionPainter.h b/third_party/WebKit/Source/core/paint/TableSectionPainter.h
index 9e33c022..d6ff986f 100644
--- a/third_party/WebKit/Source/core/paint/TableSectionPainter.h
+++ b/third_party/WebKit/Source/core/paint/TableSectionPainter.h
@@ -6,7 +6,6 @@
 #define TableSectionPainter_h
 
 #include "core/paint/PaintPhase.h"
-#include "core/paint/PaintResult.h"
 #include "core/style/ShadowData.h"
 #include "wtf/Allocator.h"
 
@@ -27,10 +26,9 @@
       : m_layoutTableSection(layoutTableSection) {}
 
   void paint(const PaintInfo&, const LayoutPoint&);
-
-  PaintResult paintCollapsedBorders(const PaintInfo&,
-                                    const LayoutPoint&,
-                                    const CollapsedBorderValue&);
+  void paintCollapsedBorders(const PaintInfo&,
+                             const LayoutPoint&,
+                             const CollapsedBorderValue&);
 
  private:
   void paintObject(const PaintInfo&, const LayoutPoint&);
@@ -58,9 +56,9 @@
                                  const CollapsedBorderValue& currentBorderValue,
                                  ItemToPaint);
   void paintSection(const PaintInfo&, const LayoutPoint&);
-  PaintResult paintCollapsedSectionBorders(const PaintInfo&,
-                                           const LayoutPoint&,
-                                           const CollapsedBorderValue&);
+  void paintCollapsedSectionBorders(const PaintInfo&,
+                                    const LayoutPoint&,
+                                    const CollapsedBorderValue&);
 
   const LayoutTableSection& m_layoutTableSection;
 };
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
index b63eb6f..3e35ff5 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
@@ -80,50 +80,53 @@
   }
 
   ~InProcessWorkerMessagingProxyForTest() override {
-    EXPECT_EQ(WaitUntilMode::DontWait, m_waitUntilMode);
+    EXPECT_FALSE(m_blocking);
     m_workerThread->workerLoaderProxy()->detachProvider(
         m_mockWorkerLoaderProxyProvider.get());
   }
 
-  enum class WaitUntilMode {
-    DontWait,
+  enum class Notification {
     MessageConfirmed,
     PendingActivityReported,
     ThreadTerminated,
   };
 
-  // Blocks the main thread until a specified event happens.
-  void waitUntil(WaitUntilMode mode) {
+  // Blocks the main thread until some event is notified.
+  Notification waitForNotification() {
     EXPECT_TRUE(isMainThread());
-    EXPECT_EQ(WaitUntilMode::DontWait, m_waitUntilMode);
-    m_waitUntilMode = mode;
-    testing::enterRunLoop();
+    DCHECK(!m_blocking);
+    if (m_events.isEmpty()) {
+      m_blocking = true;
+      testing::enterRunLoop();
+      DCHECK(!m_blocking);
+    }
+    return m_events.takeFirst();
   }
 
   void confirmMessageFromWorkerObject() override {
     EXPECT_TRUE(isMainThread());
     InProcessWorkerMessagingProxy::confirmMessageFromWorkerObject();
-    if (m_waitUntilMode != WaitUntilMode::MessageConfirmed)
-      return;
-    m_waitUntilMode = WaitUntilMode::DontWait;
-    testing::exitRunLoop();
+    m_events.append(Notification::MessageConfirmed);
+    if (m_blocking)
+      testing::exitRunLoop();
+    m_blocking = false;
   }
 
   void pendingActivityFinished() override {
     EXPECT_TRUE(isMainThread());
     InProcessWorkerMessagingProxy::pendingActivityFinished();
-    if (m_waitUntilMode != WaitUntilMode::PendingActivityReported)
-      return;
-    m_waitUntilMode = WaitUntilMode::DontWait;
-    testing::exitRunLoop();
+    m_events.append(Notification::PendingActivityReported);
+    if (m_blocking)
+      testing::exitRunLoop();
+    m_blocking = false;
   }
 
   void workerThreadTerminated() override {
     EXPECT_TRUE(isMainThread());
-    if (m_waitUntilMode != WaitUntilMode::ThreadTerminated)
-      return;
-    m_waitUntilMode = WaitUntilMode::DontWait;
-    testing::exitRunLoop();
+    m_events.append(Notification::ThreadTerminated);
+    if (m_blocking)
+      testing::exitRunLoop();
+    m_blocking = false;
   }
 
   std::unique_ptr<WorkerThread> createWorkerThread(double originTime) override {
@@ -135,9 +138,6 @@
     return static_cast<DedicatedWorkerThreadForTest*>(m_workerThread.get());
   }
 
-  bool workerGlobalScopeMayHavePendingActivity() const {
-    return m_workerGlobalScopeMayHavePendingActivity;
-  }
   unsigned unconfirmedMessageCount() const { return m_unconfirmedMessageCount; }
 
  private:
@@ -146,10 +146,11 @@
   Persistent<MockWorkerThreadLifecycleObserver>
       m_mockWorkerThreadLifecycleObserver;
 
-  WaitUntilMode m_waitUntilMode = WaitUntilMode::DontWait;
+  WTF::Deque<Notification> m_events;
+  bool m_blocking = false;
 };
 
-using WaitUntilMode = InProcessWorkerMessagingProxyForTest::WaitUntilMode;
+using Notification = InProcessWorkerMessagingProxyForTest::Notification;
 
 class DedicatedWorkerTest
     : public ::testing::TestWithParam<BlinkGC::ThreadHeapMode> {
@@ -167,7 +168,8 @@
 
   void TearDown() override {
     workerThread()->terminate();
-    workerMessagingProxy()->waitUntil(WaitUntilMode::ThreadTerminated);
+    EXPECT_EQ(Notification::ThreadTerminated,
+              workerMessagingProxy()->waitForNotification());
   }
 
   void startWithSourceCode(const String& source) {
@@ -218,11 +220,11 @@
   startWithSourceCode(sourceCode);
 
   // Worker initialization should be counted as a pending activity.
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
 
   // There should be no pending activities after the initialization.
-  workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
+  EXPECT_EQ(Notification::PendingActivityReported,
+            workerMessagingProxy()->waitForNotification());
   EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
 }
 
@@ -232,12 +234,12 @@
   startWithSourceCode(sourceCode);
 
   // Worker initialization should be counted as a pending activity.
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
 
   // The timer is fired soon and there should be no pending activities after
   // that.
-  workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
+  EXPECT_EQ(Notification::PendingActivityReported,
+            workerMessagingProxy()->waitForNotification());
   EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
 }
 
@@ -251,23 +253,21 @@
   startWithSourceCode(sourceCode);
 
   // Worker initialization should be counted as a pending activity.
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
 
   // Stop the timer.
   dispatchMessageEvent();
   EXPECT_EQ(1u, workerMessagingProxy()->unconfirmedMessageCount());
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
-  workerMessagingProxy()->waitUntil(WaitUntilMode::MessageConfirmed);
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
+  EXPECT_EQ(Notification::MessageConfirmed,
+            workerMessagingProxy()->waitForNotification());
   EXPECT_EQ(0u, workerMessagingProxy()->unconfirmedMessageCount());
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
 
   // There should be no pending activities after the timer is stopped.
-  workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
-  EXPECT_FALSE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_EQ(Notification::PendingActivityReported,
+            workerMessagingProxy()->waitForNotification());
+  EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
 }
 
 TEST_P(DedicatedWorkerTest, PendingActivity_SetTimeoutOnMessageEvent) {
@@ -279,27 +279,25 @@
   startWithSourceCode(sourceCode);
 
   // Worker initialization should be counted as a pending activity.
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
-  workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
-  EXPECT_FALSE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
+  EXPECT_EQ(Notification::PendingActivityReported,
+            workerMessagingProxy()->waitForNotification());
+  EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
 
   // A message starts the oneshot timer that is counted as a pending activity.
   dispatchMessageEvent();
   EXPECT_EQ(1u, workerMessagingProxy()->unconfirmedMessageCount());
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
-  workerMessagingProxy()->waitUntil(WaitUntilMode::MessageConfirmed);
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
+  EXPECT_EQ(Notification::MessageConfirmed,
+            workerMessagingProxy()->waitForNotification());
   EXPECT_EQ(0u, workerMessagingProxy()->unconfirmedMessageCount());
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
 
   // The timer is fired soon and there should be no pending activities after
   // that.
-  workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
-  EXPECT_FALSE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_EQ(Notification::PendingActivityReported,
+            workerMessagingProxy()->waitForNotification());
+  EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
 }
 
 TEST_P(DedicatedWorkerTest, PendingActivity_SetIntervalOnMessageEvent) {
@@ -319,22 +317,20 @@
   startWithSourceCode(sourceCode);
 
   // Worker initialization should be counted as a pending activity.
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
-  workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
-  EXPECT_FALSE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
+  EXPECT_EQ(Notification::PendingActivityReported,
+            workerMessagingProxy()->waitForNotification());
+  EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
 
   // The first message event sets the active timer that is counted as a
   // pending activity.
   dispatchMessageEvent();
   EXPECT_EQ(1u, workerMessagingProxy()->unconfirmedMessageCount());
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
-  workerMessagingProxy()->waitUntil(WaitUntilMode::MessageConfirmed);
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
+  EXPECT_EQ(Notification::MessageConfirmed,
+            workerMessagingProxy()->waitForNotification());
   EXPECT_EQ(0u, workerMessagingProxy()->unconfirmedMessageCount());
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
 
   // Run the message loop for a while to make sure the timer is counted as a
   // pending activity until it's stopped. The delay is equal to the max
@@ -342,23 +338,20 @@
   // to run before the next expectation check.
   const double kDelayInMs = kMaxIntervalInSec * 1000;
   testing::runDelayedTasks(kDelayInMs);
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
 
   // Stop the timer.
   dispatchMessageEvent();
   EXPECT_EQ(1u, workerMessagingProxy()->unconfirmedMessageCount());
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
-  workerMessagingProxy()->waitUntil(WaitUntilMode::MessageConfirmed);
+  EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
+  EXPECT_EQ(Notification::MessageConfirmed,
+            workerMessagingProxy()->waitForNotification());
   EXPECT_EQ(0u, workerMessagingProxy()->unconfirmedMessageCount());
-  EXPECT_TRUE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
 
   // There should be no pending activities after the timer is stopped.
-  workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
-  EXPECT_FALSE(
-      workerMessagingProxy()->workerGlobalScopeMayHavePendingActivity());
+  EXPECT_EQ(Notification::PendingActivityReported,
+            workerMessagingProxy()->waitForNotification());
+  EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
index ea5c21f..51171c0 100644
--- a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
+++ b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
@@ -89,8 +89,6 @@
     : ThreadedMessagingProxyBase(executionContext),
       m_workerObject(workerObject),
       m_workerClients(workerClients),
-      m_unconfirmedMessageCount(0),
-      m_workerGlobalScopeMayHavePendingActivity(false),
       m_weakPtrFactory(this) {
   m_workerObjectProxy =
       InProcessWorkerObjectProxy::create(m_weakPtrFactory.createWeakPtr());
@@ -163,7 +161,7 @@
       passed(std::move(channels)), crossThreadUnretained(&workerObjectProxy()));
   if (workerThread()) {
     // A message event is an activity and may initiate another activity.
-    m_workerGlobalScopeMayHavePendingActivity = true;
+    m_workerGlobalScopeHasPendingActivity = true;
     ++m_unconfirmedMessageCount;
     workerThread()->postTask(BLINK_FROM_HERE, std::move(task));
   } else {
@@ -195,16 +193,14 @@
 }
 
 void InProcessWorkerMessagingProxy::workerThreadCreated() {
+  DCHECK(isParentContextThread());
   ThreadedMessagingProxyBase::workerThreadCreated();
 
-  DCHECK(isParentContextThread());
-
-  DCHECK(!m_unconfirmedMessageCount);
-  m_unconfirmedMessageCount = m_queuedEarlyTasks.size();
-
   // Worker initialization means a pending activity.
-  m_workerGlobalScopeMayHavePendingActivity = true;
+  m_workerGlobalScopeHasPendingActivity = true;
 
+  DCHECK_EQ(0u, m_unconfirmedMessageCount);
+  m_unconfirmedMessageCount = m_queuedEarlyTasks.size();
   for (auto& earlyTask : m_queuedEarlyTasks)
     workerThread()->postTask(BLINK_FROM_HERE, std::move(earlyTask));
   m_queuedEarlyTasks.clear();
@@ -225,26 +221,27 @@
   DCHECK(isParentContextThread());
   if (askedToTerminate())
     return;
-  DCHECK(m_unconfirmedMessageCount);
+  DCHECK(m_workerGlobalScopeHasPendingActivity);
+  DCHECK_GT(m_unconfirmedMessageCount, 0u);
   --m_unconfirmedMessageCount;
 }
 
 void InProcessWorkerMessagingProxy::pendingActivityFinished() {
   DCHECK(isParentContextThread());
-  DCHECK(m_workerGlobalScopeMayHavePendingActivity);
+  DCHECK(m_workerGlobalScopeHasPendingActivity);
   if (m_unconfirmedMessageCount > 0) {
     // Ignore the report because an inflight message event may initiate a
     // new activity.
     return;
   }
-  m_workerGlobalScopeMayHavePendingActivity = false;
+  m_workerGlobalScopeHasPendingActivity = false;
 }
 
 bool InProcessWorkerMessagingProxy::hasPendingActivity() const {
   DCHECK(isParentContextThread());
   if (askedToTerminate())
     return false;
-  return m_unconfirmedMessageCount || m_workerGlobalScopeMayHavePendingActivity;
+  return m_workerGlobalScopeHasPendingActivity;
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.h b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.h
index 9720acc..8fa70ecc 100644
--- a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.h
+++ b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.h
@@ -45,9 +45,6 @@
 class SerializedScriptValue;
 class WorkerClients;
 
-// TODO(nhiroki): "MessagingProxy" is not well-defined term among worker
-// components. Probably we should rename this to something more suitable.
-// (http://crbug.com/603785)
 class CORE_EXPORT InProcessWorkerMessagingProxy
     : public ThreadedMessagingProxyBase {
   WTF_MAKE_NONCOPYABLE(InProcessWorkerMessagingProxy);
@@ -77,6 +74,9 @@
 
   // 'virtual' for testing.
   virtual void confirmMessageFromWorkerObject();
+
+  // Called from InProcessWorkerObjectProxy when all pending activities on the
+  // worker context are finished. See InProcessWorkerObjectProxy.h for details.
   virtual void pendingActivityFinished();
 
  protected:
@@ -101,9 +101,13 @@
   Vector<std::unique_ptr<ExecutionContextTask>> m_queuedEarlyTasks;
 
   // Unconfirmed messages from the parent context thread to the worker thread.
-  unsigned m_unconfirmedMessageCount;
+  // When this is greater than 0, |m_workerGlobalScopeHasPendingActivity| should
+  // be true.
+  unsigned m_unconfirmedMessageCount = 0;
 
-  bool m_workerGlobalScopeMayHavePendingActivity;
+  // Indicates whether there are pending activities (e.g, MessageEvent,
+  // setTimeout) on the worker context.
+  bool m_workerGlobalScopeHasPendingActivity = false;
 
   WeakPtrFactory<InProcessWorkerMessagingProxy> m_weakPtrFactory;
 };
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index ddc5aa7b..10f067a 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -238,7 +238,7 @@
 // touchscreen) in ApplyWebPreferences. "Touch events" themselves are always
 // enabled since they're a feature always supported by Chrome.
 TouchEventAPI status=stable
-TraceWrappables
+TraceWrappables status=stable
 TrueColorRendering status=experimental, settable_from_internals=True
 TrustedEventsDefaultAction status=stable
 UserSelectAll status=stable
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.cpp
index f37ca39..ecaa5b61 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.cpp
@@ -68,6 +68,23 @@
     return "Unknown"
 
 static WTF::String specialDrawingTypeAsDebugString(DisplayItem::Type type) {
+  if (type >= DisplayItem::kTableCollapsedBorderUnalignedBase) {
+    if (type <= DisplayItem::kTableCollapsedBorderBase)
+      return "TableCollapsedBorderAlignment";
+    if (type <= DisplayItem::kTableCollapsedBorderLast) {
+      StringBuilder sb;
+      sb.append("TableCollapsedBorder");
+      if (type & DisplayItem::TableCollapsedBorderTop)
+        sb.append("Top");
+      if (type & DisplayItem::TableCollapsedBorderRight)
+        sb.append("Right");
+      if (type & DisplayItem::TableCollapsedBorderBottom)
+        sb.append("Bottom");
+      if (type & DisplayItem::TableCollapsedBorderLeft)
+        sb.append("Left");
+      return sb.toString();
+    }
+  }
   switch (type) {
     DEBUG_STRING_CASE(BoxDecorationBackground);
     DEBUG_STRING_CASE(Caret);
@@ -109,7 +126,6 @@
     DEBUG_STRING_CASE(TableCellBackgroundFromColumn);
     DEBUG_STRING_CASE(TableCellBackgroundFromSection);
     DEBUG_STRING_CASE(TableCellBackgroundFromRow);
-    DEBUG_STRING_CASE(TableCollapsedBorders);
     DEBUG_STRING_CASE(TableSectionBoxShadowInset);
     DEBUG_STRING_CASE(TableSectionBoxShadowNormal);
     DEBUG_STRING_CASE(TableRowBoxShadowInset);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
index efdf25d..90d9449 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
@@ -110,7 +110,15 @@
     kTableCellBackgroundFromColumn,
     kTableCellBackgroundFromSection,
     kTableCellBackgroundFromRow,
-    kTableCollapsedBorders,
+    // Table collapsed borders can be painted together (e.g., left & top) but
+    // there are at most 4 phases of collapsed border painting for a single
+    // cell. To disambiguate these phases of collapsed border painting, a mask
+    // is used. TableCollapsedBorderBase can be larger than
+    // TableCollapsedBorderUnalignedBase to ensure the base lower bits are 0's.
+    kTableCollapsedBorderUnalignedBase,
+    kTableCollapsedBorderBase =
+        (((kTableCollapsedBorderUnalignedBase - 1) >> 4) + 1) << 4,
+    kTableCollapsedBorderLast = kTableCollapsedBorderBase + 0x0f,
     kTableSectionBoxShadowInset,
     kTableSectionBoxShadowNormal,
     kTableRowBoxShadowInset,
@@ -194,6 +202,19 @@
     kTypeLast = kUninitializedType
   };
 
+  static_assert(kTableCollapsedBorderBase >= kTableCollapsedBorderUnalignedBase,
+                "TableCollapsedBorder types overlap with other types");
+  static_assert((kTableCollapsedBorderBase & 0xf) == 0,
+                "The lowest 4 bits of TableCollapsedBorderBase should be zero");
+  // Bits or'ed onto TableCollapsedBorderBase to generate a real table collapsed
+  // border type.
+  enum TableCollapsedBorderSides {
+    TableCollapsedBorderTop = 1 << 0,
+    TableCollapsedBorderRight = 1 << 1,
+    TableCollapsedBorderBottom = 1 << 2,
+    TableCollapsedBorderLeft = 1 << 3,
+  };
+
   DisplayItem(const DisplayItemClient& client, Type type, size_t derivedSize)
       : m_client(&client),
         m_type(type),
diff --git a/third_party/WebKit/Source/platform/heap/GarbageCollected.h b/third_party/WebKit/Source/platform/heap/GarbageCollected.h
index 4d8a415a..42f78a3 100644
--- a/third_party/WebKit/Source/platform/heap/GarbageCollected.h
+++ b/third_party/WebKit/Source/platform/heap/GarbageCollected.h
@@ -16,6 +16,7 @@
 class GarbageCollected;
 class HeapObjectHeader;
 class InlinedGlobalMarkingVisitor;
+class TraceWrapperBase;
 class WrapperVisitor;
 
 // GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or
@@ -101,27 +102,29 @@
                                                                               \
  private:
 
-#define DEFINE_GARBAGE_COLLECTED_MIXIN_WRAPPER_METHODS(TYPE)                   \
- public:                                                                       \
-  void adjustAndMarkWrapper(const WrapperVisitor* visitor) const override {    \
-    typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type,  \
-                                      blink::GarbageCollected>                 \
-        IsSubclassOfGarbageCollected;                                          \
-    static_assert(                                                             \
-        IsSubclassOfGarbageCollected::value,                                   \
-        "only garbage collected objects can have garbage collected mixins");   \
-    TraceTrait<TYPE>::markWrapper(visitor, static_cast<const TYPE*>(this));    \
-  }                                                                            \
-  HeapObjectHeader* adjustAndGetHeapObjectHeader() const override {            \
-    typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type,  \
-                                      blink::GarbageCollected>                 \
-        IsSubclassOfGarbageCollected;                                          \
-    static_assert(                                                             \
-        IsSubclassOfGarbageCollected::value,                                   \
-        "only garbage collected objects can have garbage collected mixins");   \
-    return TraceTrait<TYPE>::heapObjectHeader(static_cast<const TYPE*>(this)); \
-  }                                                                            \
-                                                                               \
+#define DEFINE_GARBAGE_COLLECTED_MIXIN_WRAPPER_METHODS(TYPE)                  \
+ public:                                                                      \
+  void adjustAndMarkWrapper(const WrapperVisitor* visitor) const override {   \
+    typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \
+                                      blink::GarbageCollected>                \
+        IsSubclassOfGarbageCollected;                                         \
+    static_assert(                                                            \
+        IsSubclassOfGarbageCollected::value,                                  \
+        "only garbage collected objects can have garbage collected mixins");  \
+    AdjustAndMarkTrait<TYPE>::markWrapper(visitor,                            \
+                                          static_cast<const TYPE*>(this));    \
+  }                                                                           \
+  HeapObjectHeader* adjustAndGetHeapObjectHeader() const override {           \
+    typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \
+                                      blink::GarbageCollected>                \
+        IsSubclassOfGarbageCollected;                                         \
+    static_assert(                                                            \
+        IsSubclassOfGarbageCollected::value,                                  \
+        "only garbage collected objects can have garbage collected mixins");  \
+    return AdjustAndMarkTrait<TYPE>::heapObjectHeader(                        \
+        static_cast<const TYPE*>(this));                                      \
+  }                                                                           \
+                                                                              \
  private:
 
 // A C++ object's vptr will be initialized to its leftmost base's vtable after
@@ -283,6 +286,31 @@
 template <typename T>
 const bool NeedsAdjustAndMark<T, false>::value;
 
+template <typename T,
+          bool = std::is_base_of<TraceWrapperBase,
+                                 typename std::remove_const<T>::type>::value>
+class CanTraceWrappers;
+
+template <typename T>
+class CanTraceWrappers<T, true> {
+  static_assert(sizeof(T), "T must be fully defined");
+
+ public:
+  static const bool value = true;
+};
+template <typename T>
+const bool CanTraceWrappers<T, true>::value;
+
+template <typename T>
+class CanTraceWrappers<T, false> {
+  static_assert(sizeof(T), "T must be fully defined");
+
+ public:
+  static const bool value = false;
+};
+template <typename T>
+const bool CanTraceWrappers<T, false>::value;
+
 // TODO(sof): migrate to wtf/TypeTraits.h
 template <typename T>
 class IsFullyDefined {
diff --git a/third_party/WebKit/Source/platform/heap/TraceTraits.h b/third_party/WebKit/Source/platform/heap/TraceTraits.h
index 168f5f6..fca21397 100644
--- a/third_party/WebKit/Source/platform/heap/TraceTraits.h
+++ b/third_party/WebKit/Source/platform/heap/TraceTraits.h
@@ -206,9 +206,15 @@
   static void trace(InlinedGlobalMarkingVisitor, void* self);
 
   static void markWrapper(const WrapperVisitor* visitor, const void* t) {
+    static_assert(CanTraceWrappers<T>::value,
+                  "T should be able to trace wrappers. See "
+                  "dispatchTraceWrappers in WrapperVisitor.h");
     AdjustAndMarkTrait<T>::markWrapper(visitor, reinterpret_cast<const T*>(t));
   }
   static HeapObjectHeader* heapObjectHeader(const void* t) {
+    static_assert(CanTraceWrappers<T>::value,
+                  "T should be able to trace wrappers. See "
+                  "dispatchTraceWrappers in WrapperVisitor.h");
     return AdjustAndMarkTrait<T>::heapObjectHeader(
         reinterpret_cast<const T*>(t));
   }
diff --git a/third_party/WebKit/Source/platform/heap/WrapperVisitor.h b/third_party/WebKit/Source/platform/heap/WrapperVisitor.h
index 5a0b92d..b999d30 100644
--- a/third_party/WebKit/Source/platform/heap/WrapperVisitor.h
+++ b/third_party/WebKit/Source/platform/heap/WrapperVisitor.h
@@ -137,6 +137,10 @@
   void traceWrappersWithManualWriteBarrier(const WeakMember<T>& t) const {
     traceWrappers(t.get());
   }
+  template <typename T>
+  void traceWrappersWithManualWriteBarrier(const T* traceable) const {
+    traceWrappers(traceable);
+  }
 
   virtual void traceWrappers(
       const TraceWrapperV8Reference<v8::Value>&) const = 0;
@@ -149,7 +153,14 @@
   WRAPPER_VISITOR_SPECIAL_CLASSES(DECLARE_DISPATCH_TRACE_WRAPPERS);
 
 #undef DECLARE_DISPATCH_TRACE_WRAPPERS
-  virtual void dispatchTraceWrappers(const void*) const = 0;
+
+  void dispatchTraceWrappers(const void*) const {
+    // This call should never be reached as we access all tracing through
+    // TraceTraits, which will check that we can dispatch at compile time.
+    // This handler is merely here to make adjustAndMarkWrapper compile
+    // for GarbageCollectedMixin objects.
+    NOTREACHED();
+  }
 
   virtual bool markWrapperHeader(HeapObjectHeader*) const = 0;
   virtual void markWrappersInAllWorlds(const ScriptWrappable*) const = 0;
@@ -160,6 +171,17 @@
       const void*) const = 0;
 };
 
+#define SPECIALIZE_WRAPPER_TRACING_MARK_TRAIT(ClassName) \
+  template <>                                            \
+  class CanTraceWrappers<ClassName, false> {             \
+   public:                                               \
+    static const bool value = true;                      \
+  };
+
+WRAPPER_VISITOR_SPECIAL_CLASSES(SPECIALIZE_WRAPPER_TRACING_MARK_TRAIT)
+
+#undef SPECIALIZE_WRAPPER_TRACING_MARK_TRAIT
+
 }  // namespace blink
 
 #endif  // WrapperVisitor_h