diff --git a/DEPS b/DEPS
index 4f309fb..1c50fed2 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '92ce5946855aa8d55bb4a0dd0a47d58746d67d0a',
+  'skia_revision': '412a86d014783be99a7a9a0fae407791b95806e8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '15dfb254cdaa106f2f751335668e279d30e7725d',
+  'v8_revision': 'bba58654c340fe4404a7ce694e8b333b1f7c3b76',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'e507dc5004184ae3f8fd1cd19b723b4be69a46da',
+  'pdfium_revision': 'e6cf01356e3336dc4f0717a391d9067693a418c1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -72,7 +72,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': '8b8d22c961413c1ae465719d8252bea50587ed3f',
+  'boringssl_revision': '1252f8758ab1c4c4a14db25f9fa53e5950e4bcda',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -201,7 +201,7 @@
     Var('chromium_git') + '/webm/libvpx.git' + '@' +  '5b1a8ca5e846f838062becaec9ed6b5ecef306e5',
 
   'src/third_party/ffmpeg':
-    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'f309edd7828e3ea500c2891187d15926690ddd27',
+    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '28e7fbe8891639aa53088c3e728a66a09b967ab1',
 
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '8679f2b0bf063ac894dc473debefd61dbbebf622',
diff --git a/WATCHLISTS b/WATCHLISTS
index 08624bf..fd2f47b6 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1618,6 +1618,7 @@
     'blink_layout_ng': ['ojan+watch@chromium.org',
                         'cbiesinger@chromium.org',
                         'glebl+reviews@chromium.org',
+                        'dgrogan+ng@chromium.org',
                         'atotic+reviews@chromium.org'],
     'blink_loader': ['gavinp+loader@chromium.org',
                      'japhet@chromium.org',
diff --git a/ash/DEPS b/ash/DEPS
index 9fe5345..528f4fcd 100644
--- a/ash/DEPS
+++ b/ash/DEPS
@@ -18,7 +18,6 @@
   "+third_party/skia",
   "+net",
   "+ui",
-  "+win8",
   "-ash/host",
   "-content",
   "+content/public/common/service_names.mojom.h",
diff --git a/ash/system/chromeos/power/tablet_power_button_controller.cc b/ash/system/chromeos/power/tablet_power_button_controller.cc
index aba3b6c..7017674 100644
--- a/ash/system/chromeos/power/tablet_power_button_controller.cc
+++ b/ash/system/chromeos/power/tablet_power_button_controller.cc
@@ -87,7 +87,10 @@
   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
       this);
   WmShell::Get()->AddShellObserver(this);
-  ui::InputDeviceManager::GetInstance()->AddObserver(this);
+  // TODO(mash): Provide a way for this class to observe stylus events:
+  // http://crbug.com/682460
+  if (ui::InputDeviceManager::HasInstance())
+    ui::InputDeviceManager::GetInstance()->AddObserver(this);
   Shell::GetInstance()->PrependPreTargetHandler(this);
 
   GetInitialBacklightsForcedOff();
@@ -95,7 +98,8 @@
 
 TabletPowerButtonController::~TabletPowerButtonController() {
   Shell::GetInstance()->RemovePreTargetHandler(this);
-  ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
+  if (ui::InputDeviceManager::HasInstance())
+    ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
   WmShell::Get()->RemoveShellObserver(this);
   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
       this);
diff --git a/ash/test/DEPS b/ash/test/DEPS
index 71b63fb..caa60c0 100644
--- a/ash/test/DEPS
+++ b/ash/test/DEPS
@@ -1,7 +1,6 @@
 include_rules = [
   # In general files in this directory should not depend upon content.
   "+mojo/edk",
-  "+win8/viewer",
 ]
 
 specific_include_rules = {
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc
index f3a03fe9..31c3fd41 100644
--- a/base/trace_event/heap_profiler_allocation_context_tracker.cc
+++ b/base/trace_event/heap_profiler_allocation_context_tracker.cc
@@ -29,7 +29,6 @@
 const size_t kMaxTaskDepth = 16u;
 AllocationContextTracker* const kInitializingSentinel =
     reinterpret_cast<AllocationContextTracker*>(-1);
-const char kTracingOverhead[] = "tracing_overhead";
 
 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER;
 
@@ -157,21 +156,15 @@
 }
 
 // static
-AllocationContext AllocationContextTracker::GetContextSnapshot() {
-  AllocationContext ctx;
-
-  if (ignore_scope_depth_) {
-    ctx.backtrace.frames[0] = StackFrame::FromTraceEventName(kTracingOverhead);
-    ctx.type_name = kTracingOverhead;
-    ctx.backtrace.frame_count = 1;
-    return ctx;
-  }
+bool AllocationContextTracker::GetContextSnapshot(AllocationContext* ctx) {
+  if (ignore_scope_depth_)
+    return false;
 
   CaptureMode mode = static_cast<CaptureMode>(
       subtle::NoBarrier_Load(&capture_mode_));
 
-  auto* backtrace = std::begin(ctx.backtrace.frames);
-  auto* backtrace_end = std::end(ctx.backtrace.frames);
+  auto* backtrace = std::begin(ctx->backtrace.frames);
+  auto* backtrace_end = std::end(ctx->backtrace.frames);
 
   if (!thread_name_) {
     // Ignore the string allocation made by GetAndLeakThreadName to avoid
@@ -236,19 +229,21 @@
       }
   }
 
-  ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames);
+  ctx->backtrace.frame_count = backtrace - std::begin(ctx->backtrace.frames);
 
   // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension
   // (component name) in the heap profiler and not piggy back on the type name.
   if (!task_contexts_.empty()) {
-    ctx.type_name = task_contexts_.back();
+    ctx->type_name = task_contexts_.back();
   } else if (!pseudo_stack_.empty()) {
     // If task context was unavailable, then the category names are taken from
     // trace events.
-    ctx.type_name = pseudo_stack_.back().trace_event_category;
+    ctx->type_name = pseudo_stack_.back().trace_event_category;
+  } else {
+    ctx->type_name = nullptr;
   }
 
-  return ctx;
+  return true;
 }
 
 }  // namespace trace_event
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.h b/base/trace_event/heap_profiler_allocation_context_tracker.h
index ae5f73af..4f2a8c9 100644
--- a/base/trace_event/heap_profiler_allocation_context_tracker.h
+++ b/base/trace_event/heap_profiler_allocation_context_tracker.h
@@ -70,8 +70,8 @@
   static void SetCurrentThreadName(const char* name);
 
   // Starts and ends a new ignore scope between which the allocations are
-  // ignored in the heap profiler. A dummy context that short circuits to
-  // "tracing_overhead" is returned for these allocations.
+  // ignored by the heap profiler. GetContextSnapshot() returns false when
+  // allocations are ignored.
   void begin_ignore_scope() { ignore_scope_depth_++; }
   void end_ignore_scope() {
     if (ignore_scope_depth_)
@@ -89,8 +89,9 @@
   void PushCurrentTaskContext(const char* context);
   void PopCurrentTaskContext(const char* context);
 
-  // Returns a snapshot of the current thread-local context.
-  AllocationContext GetContextSnapshot();
+  // Fills a snapshot of the current thread-local context. Doesn't fill and
+  // returns false if allocations are being ignored.
+  bool GetContextSnapshot(AllocationContext* snapshot);
 
   ~AllocationContextTracker();
 
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
index 056aa2c..577f50043 100644
--- a/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
+++ b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
@@ -43,9 +43,9 @@
 // in |AllocationContextTracker::GetContextSnapshot|.
 template <size_t N>
 void AssertBacktraceEquals(const StackFrame(&expected_backtrace)[N]) {
-  AllocationContext ctx =
-      AllocationContextTracker::GetInstanceForCurrentThread()
-          ->GetContextSnapshot();
+  AllocationContext ctx;
+  ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                  ->GetContextSnapshot(&ctx));
 
   auto* actual = std::begin(ctx.backtrace.frames);
   auto* actual_bottom = actual + ctx.backtrace.frame_count;
@@ -65,9 +65,9 @@
 
 void AssertBacktraceContainsOnlyThreadName() {
   StackFrame t = StackFrame::FromThreadName(kThreadName);
-  AllocationContext ctx =
-      AllocationContextTracker::GetInstanceForCurrentThread()
-          ->GetContextSnapshot();
+  AllocationContext ctx;
+  ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                  ->GetContextSnapshot(&ctx));
 
   ASSERT_EQ(1u, ctx.backtrace.frame_count);
   ASSERT_EQ(t, ctx.backtrace.frames[0]);
@@ -243,9 +243,9 @@
 
   {
     TRACE_EVENT0("Testing", kGingerbread);
-    AllocationContext ctx =
-        AllocationContextTracker::GetInstanceForCurrentThread()
-            ->GetContextSnapshot();
+    AllocationContext ctx;
+    ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                    ->GetContextSnapshot(&ctx));
 
     // The pseudo stack relies on pointer equality, not deep string comparisons.
     ASSERT_EQ(t, ctx.backtrace.frames[0]);
@@ -254,9 +254,9 @@
   }
 
   {
-    AllocationContext ctx =
-        AllocationContextTracker::GetInstanceForCurrentThread()
-            ->GetContextSnapshot();
+    AllocationContext ctx;
+    ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                    ->GetContextSnapshot(&ctx));
     ASSERT_EQ(t, ctx.backtrace.frames[0]);
     ASSERT_EQ(c, ctx.backtrace.frames[1]);
     ASSERT_EQ(f, ctx.backtrace.frames[11]);
@@ -269,39 +269,39 @@
   {
     // The context from the scoped task event should be used as type name.
     TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION event1(kContext1);
-    AllocationContext ctx1 =
-        AllocationContextTracker::GetInstanceForCurrentThread()
-            ->GetContextSnapshot();
+    AllocationContext ctx1;
+    ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                    ->GetContextSnapshot(&ctx1));
     ASSERT_EQ(kContext1, ctx1.type_name);
 
     // In case of nested events, the last event's context should be used.
     TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION event2(kContext2);
-    AllocationContext ctx2 =
-        AllocationContextTracker::GetInstanceForCurrentThread()
-            ->GetContextSnapshot();
+    AllocationContext ctx2;
+    ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                    ->GetContextSnapshot(&ctx2));
     ASSERT_EQ(kContext2, ctx2.type_name);
   }
 
   {
     // Type should be category name of the last seen trace event.
     TRACE_EVENT0("Testing", kCupcake);
-    AllocationContext ctx1 =
-        AllocationContextTracker::GetInstanceForCurrentThread()
-            ->GetContextSnapshot();
+    AllocationContext ctx1;
+    ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                    ->GetContextSnapshot(&ctx1));
     ASSERT_EQ("Testing", std::string(ctx1.type_name));
 
     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("Testing"), kCupcake);
-    AllocationContext ctx2 =
-        AllocationContextTracker::GetInstanceForCurrentThread()
-            ->GetContextSnapshot();
+    AllocationContext ctx2;
+    ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                    ->GetContextSnapshot(&ctx2));
     ASSERT_EQ(TRACE_DISABLED_BY_DEFAULT("Testing"),
               std::string(ctx2.type_name));
   }
 
   // Type should be nullptr without task event.
-  AllocationContext ctx =
-      AllocationContextTracker::GetInstanceForCurrentThread()
-          ->GetContextSnapshot();
+  AllocationContext ctx;
+  ASSERT_TRUE(AllocationContextTracker::GetInstanceForCurrentThread()
+                  ->GetContextSnapshot(&ctx));
   ASSERT_FALSE(ctx.type_name);
 }
 
@@ -309,13 +309,9 @@
   TRACE_EVENT0("Testing", kCupcake);
   TRACE_EVENT0("Testing", kDonut);
   HEAP_PROFILER_SCOPED_IGNORE;
-  AllocationContext ctx =
-      AllocationContextTracker::GetInstanceForCurrentThread()
-          ->GetContextSnapshot();
-  const StringPiece kTracingOverhead("tracing_overhead");
-  ASSERT_EQ(kTracingOverhead,
-            static_cast<const char*>(ctx.backtrace.frames[0].value));
-  ASSERT_EQ(1u, ctx.backtrace.frame_count);
+  AllocationContext ctx;
+  ASSERT_FALSE(AllocationContextTracker::GetInstanceForCurrentThread()
+                   ->GetContextSnapshot(&ctx));
 }
 
 }  // namespace trace_event
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc
index c09470be..4683694d 100644
--- a/base/trace_event/malloc_dump_provider.cc
+++ b/base/trace_event/malloc_dump_provider.cc
@@ -297,7 +297,10 @@
   auto* tracker = AllocationContextTracker::GetInstanceForCurrentThread();
   if (!tracker)
     return;
-  AllocationContext context = tracker->GetContextSnapshot();
+
+  AllocationContext context;
+  if (!tracker->GetContextSnapshot(&context))
+    return;
 
   AutoLock lock(allocation_register_lock_);
   if (!allocation_register_)
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py
index 926f275f..ce140e1 100755
--- a/build/android/gyp/javac.py
+++ b/build/android/gyp/javac.py
@@ -382,10 +382,11 @@
       # Chromium only allows UTF8 source files.  Being explicit avoids
       # javac pulling a default encoding from the user's environment.
       '-encoding', 'UTF-8',
-      '-classpath', ':'.join(options.classpath),
+      # Make sure we do not pass an empty string to -classpath and -sourcepath.
+      '-classpath', ':'.join(options.classpath) or ':',
       # Prevent compiler from compiling .java files not listed as inputs.
       # See: http://blog.ltgt.net/most-build-tools-misuse-javac/
-      '-sourcepath', ''
+      '-sourcepath', ':',
   ))
 
   if options.bootclasspath:
diff --git a/build/nocompile.gni b/build/nocompile.gni
index f93ac94..7c91c67 100644
--- a/build/nocompile.gni
+++ b/build/nocompile.gni
@@ -85,7 +85,7 @@
         "{{source}}",
         "-Wall -Werror -Wfatal-errors " + "-I" +
             rebase_path("//", root_build_dir) + sysroot_args,
-        "{{output}}",
+        rebase_path(result_path, root_build_dir),
       ]
     }
 
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc
index 1a3845b..921cf25 100644
--- a/cc/layers/render_surface_impl.cc
+++ b/cc/layers/render_surface_impl.cc
@@ -50,7 +50,7 @@
   EffectTree& effect_tree = layer_tree_impl_->property_trees()->effect_tree;
   EffectNode* node = effect_tree.Node(EffectTreeIndex());
   EffectNode* target_node = effect_tree.Node(node->target_id);
-  if (target_node->id != 0)
+  if (target_node->id != EffectTree::kRootNodeId)
     return target_node->render_surface;
   else
     return this;
@@ -61,7 +61,7 @@
       layer_tree_impl_->property_trees()->effect_tree;
   const EffectNode* node = effect_tree.Node(EffectTreeIndex());
   const EffectNode* target_node = effect_tree.Node(node->target_id);
-  if (target_node->id != 0)
+  if (target_node->id != EffectTree::kRootNodeId)
     return target_node->render_surface;
   else
     return this;
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 4bcac305..af6f8e6 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -420,7 +420,7 @@
 
     int effect_ancestor_with_copy_request =
         effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index());
-    if (effect_ancestor_with_copy_request > 1) {
+    if (effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId) {
       // Non root copy request.
       bool include_viewport_clip = false;
       bool include_expanding_clips = true;
@@ -821,10 +821,11 @@
   ClipTree* clip_tree = &property_trees->clip_tree;
   if (!clip_tree->needs_update())
     return;
-  for (int i = 1; i < static_cast<int>(clip_tree->size()); ++i) {
+  for (int i = ClipTree::kViewportNodeId;
+       i < static_cast<int>(clip_tree->size()); ++i) {
     ClipNode* clip_node = clip_tree->Node(i);
 
-    if (clip_node->id == 1) {
+    if (clip_node->id == ClipTree::kViewportNodeId) {
       ResetIfHasNanCoordinate(&clip_node->clip);
       clip_node->clip_in_target_space = clip_node->clip;
       clip_node->combined_clip_in_target_space = clip_node->clip;
@@ -975,20 +976,22 @@
 void ComputeTransforms(TransformTree* transform_tree) {
   if (!transform_tree->needs_update())
     return;
-  for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i)
+  for (int i = TransformTree::kContentsRootNodeId;
+       i < static_cast<int>(transform_tree->size()); ++i)
     transform_tree->UpdateTransforms(i);
   transform_tree->set_needs_update(false);
 }
 
 void UpdateRenderTarget(EffectTree* effect_tree,
                         bool can_render_to_separate_surface) {
-  for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) {
+  for (int i = EffectTree::kContentsRootNodeId;
+       i < static_cast<int>(effect_tree->size()); ++i) {
     EffectNode* node = effect_tree->Node(i);
-    if (i == 1) {
+    if (i == EffectTree::kContentsRootNodeId) {
       // Render target of the node corresponding to root is itself.
-      node->target_id = 1;
+      node->target_id = EffectTree::kContentsRootNodeId;
     } else if (!can_render_to_separate_surface) {
-      node->target_id = 1;
+      node->target_id = EffectTree::kContentsRootNodeId;
     } else if (effect_tree->parent(node)->has_render_surface) {
       node->target_id = node->parent_id;
     } else {
@@ -1000,7 +1003,8 @@
 void ComputeEffects(EffectTree* effect_tree) {
   if (!effect_tree->needs_update())
     return;
-  for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i)
+  for (int i = EffectTree::kContentsRootNodeId;
+       i < static_cast<int>(effect_tree->size()); ++i)
     effect_tree->UpdateEffects(i);
   effect_tree->set_needs_update(false);
 }
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 4cd9aae..fa637e2 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -1793,7 +1793,8 @@
     return true;
 
   for (const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
-       clip_node->id > 1; clip_node = clip_tree.parent(clip_node)) {
+       clip_node->id > ClipTree::kViewportNodeId;
+       clip_node = clip_tree.parent(clip_node)) {
     if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) {
       const TransformNode* transform_node =
           transform_tree.Node(clip_node->target_transform_id);
@@ -1802,10 +1803,11 @@
 
       const LayerImpl* target_layer =
           layer->layer_tree_impl()->LayerById(transform_node->owning_layer_id);
-      DCHECK(transform_node->id == 0 || target_layer->render_surface() ||
+      DCHECK(transform_node->id == TransformTree::kRootNodeId ||
+             target_layer->render_surface() ||
              layer->layer_tree_impl()->is_in_resourceless_software_draw_mode());
       gfx::Transform surface_screen_space_transform =
-          transform_node->id == 0 ||
+          transform_node->id == TransformTree::kRootNodeId ||
                   (layer->layer_tree_impl()
                        ->is_in_resourceless_software_draw_mode())
               ? gfx::Transform()
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 2e9ed3e..45679f9 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -200,7 +200,8 @@
 }
 
 void TransformTree::ResetChangeTracking() {
-  for (int id = 1; id < static_cast<int>(size()); ++id) {
+  for (int id = TransformTree::kContentsRootNodeId;
+       id < static_cast<int>(size()); ++id) {
     TransformNode* node = Node(id);
     node->transform_changed = false;
   }
@@ -958,9 +959,9 @@
 }
 
 int EffectTree::ClosestAncestorWithCopyRequest(int id) const {
-  DCHECK_GE(id, 0);
+  DCHECK_GE(id, EffectTree::kRootNodeId);
   const EffectNode* node = Node(id);
-  while (node->id > 1) {
+  while (node->id > EffectTree::kContentsRootNodeId) {
     if (node->has_copy_request)
       return node->id;
 
@@ -987,7 +988,8 @@
 }
 
 void EffectTree::ResetChangeTracking() {
-  for (int id = 1; id < static_cast<int>(size()); ++id) {
+  for (int id = EffectTree::kContentsRootNodeId; id < static_cast<int>(size());
+       ++id) {
     EffectNode* node = Node(id);
     node->effect_changed = false;
   }
@@ -1722,12 +1724,14 @@
 }
 
 void PropertyTrees::UpdateChangeTracking() {
-  for (int id = 1; id < static_cast<int>(effect_tree.size()); ++id) {
+  for (int id = EffectTree::kContentsRootNodeId;
+       id < static_cast<int>(effect_tree.size()); ++id) {
     EffectNode* node = effect_tree.Node(id);
     EffectNode* parent_node = effect_tree.parent(node);
     effect_tree.UpdateEffectChanged(node, parent_node);
   }
-  for (int i = 1; i < static_cast<int>(transform_tree.size()); ++i) {
+  for (int i = TransformTree::kContentsRootNodeId;
+       i < static_cast<int>(transform_tree.size()); ++i) {
     TransformNode* node = transform_tree.Node(i);
     TransformNode* parent_node = transform_tree.parent(node);
     TransformNode* source_node = transform_tree.Node(node->source_node_id);
@@ -1736,14 +1740,16 @@
 }
 
 void PropertyTrees::PushChangeTrackingTo(PropertyTrees* tree) {
-  for (int id = 1; id < static_cast<int>(effect_tree.size()); ++id) {
+  for (int id = EffectTree::kContentsRootNodeId;
+       id < static_cast<int>(effect_tree.size()); ++id) {
     EffectNode* node = effect_tree.Node(id);
     if (node->effect_changed) {
       EffectNode* target_node = tree->effect_tree.Node(node->id);
       target_node->effect_changed = true;
     }
   }
-  for (int id = 1; id < static_cast<int>(transform_tree.size()); ++id) {
+  for (int id = TransformTree::kContentsRootNodeId;
+       id < static_cast<int>(transform_tree.size()); ++id) {
     TransformNode* node = transform_tree.Node(id);
     if (node->transform_changed) {
       TransformNode* target_node = tree->transform_tree.Node(node->id);
@@ -2007,7 +2013,7 @@
       FetchDrawTransformsDataFromCache(transform_id, dest_id);
 
   DCHECK(data.update_number != cached_data_.property_tree_update_number ||
-         data.target_id != -1);
+         data.target_id != EffectTree::kInvalidNodeId);
   if (data.update_number == cached_data_.property_tree_update_number)
     return data.transforms;
 
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index bcf5615b..f259664 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -30,9 +30,6 @@
 
 namespace {
 
-static const int kRootPropertyTreeNodeId = 0;
-static const int kViewportClipTreeNodeId = 1;
-
 template <typename LayerType>
 struct DataForRecursion {
   PropertyTrees* property_trees;
@@ -571,7 +568,7 @@
   LayerType* transform_parent = GetTransformParent(data_from_ancestor, layer);
   DCHECK(is_root || transform_parent);
 
-  int parent_index = kRootPropertyTreeNodeId;
+  int parent_index = TransformTree::kRootNodeId;
   if (transform_parent)
     parent_index = transform_parent->transform_tree_index();
 
@@ -1099,8 +1096,8 @@
     // into. Transform node created from root layer (includes device scale
     // factor) and clip node created from root layer (include viewports) applies
     // to root render surface's content, but not root render surface itself.
-    node.transform_id = kRootPropertyTreeNodeId;
-    node.clip_id = kViewportClipTreeNodeId;
+    node.transform_id = TransformTree::kRootNodeId;
+    node.clip_id = ClipTree::kViewportNodeId;
   }
   int node_id = effect_tree.Insert(node, parent_id);
   data_for_children->effect_tree_parent = node_id;
@@ -1424,10 +1421,10 @@
   data_for_recursion.property_trees = property_trees;
   data_for_recursion.transform_tree_parent = nullptr;
   data_for_recursion.transform_fixed_parent = nullptr;
-  data_for_recursion.render_target = kRootPropertyTreeNodeId;
-  data_for_recursion.clip_tree_parent = kRootPropertyTreeNodeId;
+  data_for_recursion.render_target = EffectTree::kRootNodeId;
+  data_for_recursion.clip_tree_parent = ClipTree::kRootNodeId;
   data_for_recursion.effect_tree_parent = EffectTree::kInvalidNodeId;
-  data_for_recursion.scroll_tree_parent = kRootPropertyTreeNodeId;
+  data_for_recursion.scroll_tree_parent = ScrollTree::kRootNodeId;
   data_for_recursion.page_scale_layer = page_scale_layer;
   data_for_recursion.inner_viewport_scroll_layer = inner_viewport_scroll_layer;
   data_for_recursion.outer_viewport_scroll_layer = outer_viewport_scroll_layer;
@@ -1458,11 +1455,11 @@
   root_clip.resets_clip = true;
   root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP;
   root_clip.clip = gfx::RectF(viewport);
-  root_clip.transform_id = kRootPropertyTreeNodeId;
-  root_clip.target_transform_id = kRootPropertyTreeNodeId;
+  root_clip.transform_id = TransformTree::kRootNodeId;
+  root_clip.target_transform_id = TransformTree::kRootNodeId;
   data_for_recursion.clip_tree_parent =
       data_for_recursion.property_trees->clip_tree.Insert(
-          root_clip, kRootPropertyTreeNodeId);
+          root_clip, ClipTree::kRootNodeId);
 
   DataForRecursionFromChild<LayerType> data_from_child;
   BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child);
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index a4044b8..7a92deb 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -183,6 +183,7 @@
         "//chrome/chrome_watcher:client",
         "//chrome/common:constants",
         "//chrome/common:metrics_constants_util_win",
+        "//chrome/install_static:secondary_module",
         "//chrome/installer/util:with_no_strings",
         "//chrome_elf",
         "//components/browser_watcher:browser_watcher_client",
@@ -327,6 +328,7 @@
       "//chrome/app/theme:chrome_unscaled_resources",
       "//chrome/common:features",
       "//chrome/install_static:install_static_util",
+      "//chrome/install_static:secondary_module",
       "//chrome_elf",
       "//components/crash/content/app",
       "//components/policy:generated",
@@ -412,6 +414,8 @@
         "//chrome/browser/policy:path_parser",
         "//chrome/common:features",
         "//chrome/install_static:install_static_util",
+        "//chrome/install_static:secondary_module",
+        "//chrome_elf",
         "//components/browser_watcher:browser_watcher_client",
         "//components/crash/content/app",
         "//content/public/app:child",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java
index 9bee553b..cbbcd4b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java
@@ -6,6 +6,7 @@
 
 import android.Manifest;
 import android.app.Activity;
+import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -15,6 +16,7 @@
 import android.text.TextUtils;
 import android.view.View;
 
+import org.chromium.base.Log;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.chrome.R;
@@ -35,6 +37,8 @@
  */
 public class BluetoothChooserDialog
         implements ItemChooserDialog.ItemSelectedCallback, WindowAndroid.PermissionCallback {
+    private static final String TAG = "Bluetooth";
+
     // These constants match BluetoothChooserAndroid::ShowDiscoveryState, and are used in
     // notifyDiscoveryState().
     static final int DISCOVERY_FAILED_TO_START = 0;
@@ -69,6 +73,12 @@
     // Used to keep track of when the Mode Changed Receiver is registered.
     boolean mIsLocationModeChangedReceiverRegistered;
 
+    // The local device Bluetooth adapter.
+    private final BluetoothAdapter mAdapter;
+
+    // The status message to show when the bluetooth adapter is turned off.
+    private final SpannableString mAdapterOffStatus;
+
     @VisibleForTesting
     final BroadcastReceiver mLocationModeBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -106,6 +116,14 @@
         mOrigin = origin;
         mSecurityLevel = securityLevel;
         mNativeBluetoothChooserDialogPtr = nativeBluetoothChooserDialogPtr;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (mAdapter == null) {
+            Log.i(TAG, "BluetoothChooserDialog: Default Bluetooth adapter not found.");
+        }
+        mAdapterOffStatus =
+                SpanApplier.applySpans(mActivity.getString(R.string.bluetooth_adapter_off_help),
+                        new SpanInfo("<link>", "</link>",
+                                new BluetoothClickableSpan(LinkType.ADAPTER_OFF_HELP, mActivity)));
     }
 
     /**
@@ -275,9 +293,13 @@
                     break;
                 }
                 case ADAPTER_OFF: {
-                    Intent intent = new Intent();
-                    intent.setAction(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
-                    mContext.startActivity(intent);
+                    if (mAdapter != null && mAdapter.enable()) {
+                        mItemChooserDialog.signalInitializingAdapter();
+                    } else {
+                        String unableToTurnOnAdapter =
+                                mActivity.getString(R.string.bluetooth_unable_to_turn_on_adapter);
+                        mItemChooserDialog.setErrorState(unableToTurnOnAdapter, mAdapterOffStatus);
+                    }
                     break;
                 }
                 case ADAPTER_OFF_HELP: {
@@ -357,12 +379,8 @@
                 mActivity.getString(R.string.bluetooth_adapter_off),
                 new SpanInfo("<link>", "</link>",
                         new BluetoothClickableSpan(LinkType.ADAPTER_OFF, mActivity)));
-        SpannableString adapterOffStatus = SpanApplier.applySpans(
-                mActivity.getString(R.string.bluetooth_adapter_off_help),
-                new SpanInfo("<link>", "</link>",
-                        new BluetoothClickableSpan(LinkType.ADAPTER_OFF_HELP, mActivity)));
 
-        mItemChooserDialog.setErrorState(adapterOffMessage, adapterOffStatus);
+        mItemChooserDialog.setErrorState(adapterOffMessage, mAdapterOffStatus);
     }
 
     @CalledByNative
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ItemChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/ItemChooserDialog.java
index b71813a..3ddfb79 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ItemChooserDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ItemChooserDialog.java
@@ -10,7 +10,6 @@
 import android.content.DialogInterface;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
-import android.text.SpannableString;
 import android.text.TextUtils;
 import android.text.method.LinkMovementMethod;
 import android.view.Gravity;
@@ -133,7 +132,7 @@
     /**
      * The various states the dialog can represent.
      */
-    private enum State { STARTING, PROGRESS_UPDATE_AVAILABLE, DISCOVERY_IDLE }
+    private enum State { INITIALIZING_ADAPTER, STARTING, PROGRESS_UPDATE_AVAILABLE, DISCOVERY_IDLE }
 
     /**
      * An adapter for keeping track of which items to show in the dialog.
@@ -518,6 +517,13 @@
     }
 
     /**
+     * Indicates the adapter is being initialized.
+     */
+    public void signalInitializingAdapter() {
+        setState(State.INITIALIZING_ADAPTER);
+    }
+
+    /**
      * Clear all items from the dialog.
      */
     public void clear() {
@@ -528,7 +534,7 @@
     /**
      * Shows an error message in the dialog.
      */
-    public void setErrorState(SpannableString errorMessage, SpannableString errorStatus) {
+    public void setErrorState(CharSequence errorMessage, CharSequence errorStatus) {
         mListView.setVisibility(View.GONE);
         mProgressBar.setVisibility(View.GONE);
         mEmptyMessage.setText(errorMessage);
@@ -538,6 +544,11 @@
 
     private void setState(State state) {
         switch (state) {
+            case INITIALIZING_ADAPTER:
+                mListView.setVisibility(View.GONE);
+                mProgressBar.setVisibility(View.VISIBLE);
+                mEmptyMessage.setVisibility(View.GONE);
+                break;
             case STARTING:
                 mStatus.setText(mLabels.searching);
                 mListView.setVisibility(View.GONE);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java
index 9cfb7983..0a41375 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java
@@ -243,7 +243,11 @@
     }
 
     static int getMediaType(Uri uri) {
-        String path = uri.getPath().toLowerCase(Locale.US);
+        String path = uri.getPath();
+
+        if (path == null) return MEDIA_TYPE_UNKNOWN;
+
+        path = path.toLowerCase(Locale.US);
         if (path.endsWith(".m3u8")) return MEDIA_TYPE_HLS;
         if (path.endsWith(".mp4")) return MEDIA_TYPE_MPEG4;
         if (path.endsWith(".mpd")) return MEDIA_TYPE_DASH;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
index b9dca9d..ff0529e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -30,10 +30,9 @@
 import android.support.v7.media.MediaRouter;
 import android.text.TextUtils;
 import android.util.SparseArray;
-import android.util.TypedValue;
 import android.view.KeyEvent;
 
-import org.chromium.base.ContextUtils;
+import org.chromium.base.SysUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.blink.mojom.MediaSessionAction;
 import org.chromium.chrome.R;
@@ -59,12 +58,11 @@
     @VisibleForTesting
     static final int CUSTOM_MEDIA_SESSION_ACTION_STOP = MediaSessionAction.LAST + 1;
 
-    // MediaStyle large icon size for pre-N.
-    private static final int PRE_N_LARGE_ICON_SIZE_DP = 128;
-    // MediaStyle large icon size for N.
-    // TODO(zqzhang): use android.R.dimen.media_notification_expanded_image_max_size when Android
-    // SDK is rolled to level 24. See https://crbug.com/645059
-    private static final int N_LARGE_ICON_SIZE_DP = 94;
+    // The media artwork image resolution on high-end devices.
+    private static final int HIGH_IMAGE_SIZE_PX = 512;
+
+    // The media artwork image resolution on high-end devices.
+    private static final int LOW_IMAGE_SIZE_PX = 256;
 
     // The maximum number of actions in CompactView media notification.
     private static final int COMPACT_VIEW_ACTIONS_COUNT = 3;
@@ -485,25 +483,16 @@
     }
 
     /**
-     * Scale a given bitmap to a proper size for display.
-     * @param icon The bitmap to be resized, can be null.
-     * @return A scaled icon to be used in media notification. Returns null if |icon| is null.
+     * Scales |icon| to the size returned by {@link getIdealMediaImageSize()}. Returns null if
+     * |icon| is null.
+     * @param icon The icon to be scaled.
      */
     @Nullable
-    public static Bitmap scaleIconForDisplay(@Nullable Bitmap icon) {
+    public static Bitmap scaleIconToIdealSize(Bitmap icon) {
         if (icon == null) return null;
 
-        int largeIconSizePx = getMaximumLargeIconSize();
+        int targetSize = getIdealMediaImageSize();
 
-        if (icon.getWidth() > largeIconSizePx || icon.getHeight() > largeIconSizePx
-                || icon.getWidth() != icon.getHeight()) {
-            return scaleIconInternal(icon, largeIconSizePx);
-        }
-
-        return icon;
-    }
-
-    private static Bitmap scaleIconInternal(Bitmap icon, int targetSize) {
         Matrix m = new Matrix();
         int dominantLength = Math.max(icon.getWidth(), icon.getHeight());
         // Move the center to (0,0).
@@ -523,21 +512,13 @@
     }
 
     /**
-     * @return Prefered maximum large icon size. If the large icon is larger than this size, then it
-     * needs to be scaled.
+     * @returns The ideal size of the media image.
      */
-    public static int getMaximumLargeIconSize() {
-        int maxLargeIconSizePx;
-        if (isRunningN()) {
-            maxLargeIconSizePx = (int) TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP, N_LARGE_ICON_SIZE_DP,
-                ContextUtils.getApplicationContext().getResources().getDisplayMetrics());
-        } else {
-            maxLargeIconSizePx = (int) TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP, PRE_N_LARGE_ICON_SIZE_DP,
-                ContextUtils.getApplicationContext().getResources().getDisplayMetrics());
+    public static int getIdealMediaImageSize() {
+        if (SysUtils.isLowEndDevice()) {
+            return LOW_IMAGE_SIZE_PX;
         }
-        return maxLargeIconSizePx;
+        return HIGH_IMAGE_SIZE_PX;
     }
 
     private static MediaNotificationManager getManager(int notificationId) {
@@ -862,8 +843,8 @@
                 int resourceId = (mMediaNotificationInfo.defaultNotificationLargeIcon != 0)
                         ? mMediaNotificationInfo.defaultNotificationLargeIcon
                         : R.drawable.audio_playing_square;
-                mDefaultNotificationLargeIcon = scaleIconForDisplay(
-                        BitmapFactory.decodeResource(mContext.getResources(), resourceId));
+                mDefaultNotificationLargeIcon = scaleIconToIdealSize(
+                    BitmapFactory.decodeResource(mContext.getResources(), resourceId));
             }
             builder.setLargeIcon(mDefaultNotificationLargeIcon);
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
index 48decea..157afb1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
@@ -341,7 +341,7 @@
         mTab = tab;
         mTab.addObserver(mTabObserver);
         mMediaImageManager = new MediaImageManager(
-            MINIMAL_FAVICON_SIZE, MediaNotificationManager.getMaximumLargeIconSize());
+                MINIMAL_FAVICON_SIZE, MediaNotificationManager.getIdealMediaImageSize());
         if (mTab.getWebContents() != null) setWebContents(tab.getWebContents());
 
         Activity activity = getActivityFromTab(mTab);
@@ -412,7 +412,7 @@
                                         || icon.getHeight() < mFavicon.getHeight())) {
             return false;
         }
-        mFavicon = MediaNotificationManager.scaleIconForDisplay(icon);
+        mFavicon = MediaNotificationManager.scaleIconToIdealSize(icon);
         return true;
     }
 
@@ -465,7 +465,7 @@
 
     @Override
     public void onImageDownloaded(Bitmap image) {
-        mPageMediaImage = MediaNotificationManager.scaleIconForDisplay(image);
+        mPageMediaImage = MediaNotificationManager.scaleIconToIdealSize(image);
         updateNotificationImage();
     }
 
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 3312e83..3aa1d0b 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1228,7 +1228,10 @@
         No Bluetooth devices found
       </message>
       <message name="IDS_BLUETOOTH_ADAPTER_OFF" desc="The message to show when scanning cannot start because the bluetooth adapter is turned off.">
-        Turn on Bluetooth in <ph name="BEGIN_LINK">&lt;link&gt;</ph>device settings<ph name="END_LINK">&lt;/link&gt;</ph> to allow pairing
+        <ph name="BEGIN_LINK">&lt;link&gt;</ph>Turn on Bluetooth<ph name="END_LINK">&lt;/link&gt;</ph> to allow pairing
+      </message>
+      <message name="IDS_BLUETOOTH_UNABLE_TO_TURN_ON_ADAPTER" desc="The message to show when Chrome is unable to turn on the Bluetooth adapter.">
+          Chrome is unable to turn on Bluetooth adapter
       </message>
       <message name="IDS_BLUETOOTH_ADAPTER_OFF_HELP" desc="The status message to show along with the message when the bluetooth adapter is turned off (to get Help).">
         <ph name="BEGIN_LINK">&lt;link&gt;</ph>Get help<ph name="END_LINK">&lt;/link&gt;</ph>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java
index a69d8cd..cc56e2f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java
@@ -378,6 +378,52 @@
 
     // TODO(jyasskin): Test when the user denies Chrome the ability to ask for permission.
 
+    @LargeTest
+    public void testTurnOnAdapter() {
+        final ItemChooserDialog itemChooser = mChooserDialog.mItemChooserDialog;
+        Dialog dialog = itemChooser.getDialogForTesting();
+        assertTrue(dialog.isShowing());
+
+        final TextViewWithClickableSpans statusView =
+                (TextViewWithClickableSpans) dialog.findViewById(R.id.status);
+        final TextViewWithClickableSpans errorView =
+                (TextViewWithClickableSpans) dialog.findViewById(R.id.not_found_message);
+        final View items = dialog.findViewById(R.id.items);
+        final Button button = (Button) dialog.findViewById(R.id.positive);
+        final View progress = dialog.findViewById(R.id.progress);
+
+        // Turn off adapter.
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mChooserDialog.notifyAdapterTurnedOff();
+            }
+        });
+
+        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_adapter_off)),
+                errorView.getText().toString());
+        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_adapter_off_help)),
+                statusView.getText().toString());
+        assertFalse(button.isEnabled());
+        assertEquals(View.VISIBLE, errorView.getVisibility());
+        assertEquals(View.GONE, items.getVisibility());
+        assertEquals(View.GONE, progress.getVisibility());
+
+        // Turn on adapter.
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                itemChooser.signalInitializingAdapter();
+            }
+        });
+
+        assertEquals(View.GONE, errorView.getVisibility());
+        assertEquals(View.GONE, items.getVisibility());
+        assertEquals(View.VISIBLE, progress.getVisibility());
+
+        mChooserDialog.closeDialog();
+    }
+
     private static class TestAndroidPermissionDelegate implements AndroidPermissionDelegate {
         Dialog mDialog = null;
         PermissionCallback mCallback = null;
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc
index 9d135f0..7bac0755 100644
--- a/chrome/app/chrome_exe_main_win.cc
+++ b/chrome/app/chrome_exe_main_win.cc
@@ -26,10 +26,9 @@
 #include "chrome/app/main_dll_loader_win.h"
 #include "chrome/browser/policy/policy_path_parser.h"
 #include "chrome/browser/win/chrome_process_finder.h"
-#include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths_internal.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/install_static/install_details.h"
+#include "chrome/install_static/initialize_from_primary_module.h"
 #include "chrome/install_static/install_util.h"
 #include "chrome_elf/chrome_elf_main.h"
 #include "components/crash/content/app/crash_switches.h"
@@ -230,8 +229,7 @@
 int main() {
   HINSTANCE instance = GetModuleHandle(nullptr);
 #endif
-  install_static::InstallDetails::InitializeFromPrimaryModule(
-      chrome::kChromeElfDllName);
+  install_static::InitializeFromPrimaryModule();
 
   // Initialize the CommandLine singleton from the environment.
   base::CommandLine::Init(0, nullptr);
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc
index 5d63c3b6..c35dd61d 100644
--- a/chrome/app/chrome_main.cc
+++ b/chrome/app/chrome_main.cc
@@ -25,6 +25,7 @@
 #include "base/debug/dump_without_crashing.h"
 #include "base/win/win_util.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/install_static/initialize_from_primary_module.h"
 #include "chrome/install_static/install_details.h"
 
 #define DLLEXPORT __declspec(dllexport)
@@ -52,8 +53,7 @@
 #endif
 
 #if defined(OS_WIN)
-  install_static::InstallDetails::InitializeFromPrimaryModule(
-      chrome::kChromeElfDllName);
+  install_static::InitializeFromPrimaryModule();
 #endif
 
   ChromeMainDelegate chrome_main_delegate(
diff --git a/chrome/browser/chrome_browser_field_trials_desktop.cc b/chrome/browser/chrome_browser_field_trials_desktop.cc
index 5eb97f5..40386d9e 100644
--- a/chrome/browser/chrome_browser_field_trials_desktop.cc
+++ b/chrome/browser/chrome_browser_field_trials_desktop.cc
@@ -20,6 +20,7 @@
 #include "base/path_service.h"
 #include "chrome/browser/features.h"
 #include "chrome/browser/prerender/prerender_field_trial.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/browser_watcher/features.h"
@@ -165,6 +166,7 @@
   SetupStunProbeTrial();
 #if defined(OS_WIN)
   SetupStabilityDebugging();
+  base::FeatureList::IsEnabled(features::kModuleDatabase);
 #endif  // defined(OS_WIN)
   // Activate the experiment as early as possible to increase its visibility
   // (e.g. the likelihood of its presence in the serialized system profile).
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 1c782da..dd3a9b6 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -6,6 +6,7 @@
 
 #include <shellapi.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <windows.h>
 
 #include <algorithm>
@@ -25,10 +26,13 @@
 #include "base/scoped_native_library.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/win/pe_image.h"
 #include "base/win/registry.h"
 #include "base/win/win_util.h"
 #include "base/win/windows_version.h"
 #include "base/win/wrapped_window_proc.h"
+#include "chrome/browser/conflicts/module_database_win.h"
+#include "chrome/browser/conflicts/module_event_sink_impl_win.h"
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/install_verification/win/install_verification.h"
 #include "chrome/browser/profiles/profile_shortcut_manager.h"
@@ -39,10 +43,12 @@
 #include "chrome/browser/win/chrome_elf_init.h"
 #include "chrome/chrome_watcher/chrome_watcher_main_api.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_utility_messages.h"
+#include "chrome/common/conflicts/module_watcher_win.h"
 #include "chrome/common/crash_keys.h"
 #include "chrome/common/env_vars.h"
 #include "chrome/grit/chromium_strings.h"
@@ -202,6 +208,60 @@
   UMA_HISTOGRAM_ENUMERATION("FaultTolerantHeap", detected, FTH_FLAGS_COUNT);
 }
 
+// Helper function for getting the time date stamp associated with a module in
+// this process.
+uint32_t GetModuleTimeDateStamp(const void* module_load_address) {
+  base::win::PEImage pe_image(module_load_address);
+  return pe_image.GetNTHeaders()->FileHeader.TimeDateStamp;
+}
+
+// Used as the callback for ModuleWatcher events in this process. Dispatches
+// them to the ModuleDatabase.
+void OnModuleEvent(uint32_t process_id,
+                   uint64_t creation_time,
+                   const ModuleWatcher::ModuleEvent& event) {
+  auto* module_database = ModuleDatabase::GetInstance();
+  uintptr_t load_address =
+      reinterpret_cast<uintptr_t>(event.module_load_address);
+
+  switch (event.event_type) {
+    case mojom::ModuleEventType::MODULE_ALREADY_LOADED:
+    case mojom::ModuleEventType::MODULE_LOADED: {
+      module_database->OnModuleLoad(
+          process_id, creation_time, event.module_path, event.module_size,
+          GetModuleTimeDateStamp(event.module_load_address), load_address);
+      return;
+    }
+
+    case mojom::ModuleEventType::MODULE_UNLOADED: {
+      module_database->OnModuleUnload(process_id, creation_time, load_address);
+      return;
+    }
+  }
+}
+
+// Helper function for initializing the module database subsystem. Populates
+// the provided |module_watcher|.
+void SetupModuleDatabase(std::unique_ptr<ModuleWatcher>* module_watcher) {
+  uint64_t creation_time = 0;
+  ModuleEventSinkImpl::GetProcessCreationTime(::GetCurrentProcess(),
+                                              &creation_time);
+  ModuleDatabase::SetInstance(base::MakeUnique<ModuleDatabase>(
+      content::BrowserThread::GetTaskRunnerForThread(
+          content::BrowserThread::UI)));
+  auto* module_database = ModuleDatabase::GetInstance();
+  uint32_t process_id = ::GetCurrentProcessId();
+
+  // The ModuleWatcher will immediately start emitting module events, but the
+  // ModuleDatabase expects an OnProcessStarted event prior to that. For child
+  // processes this is handled via the ModuleEventSinkImpl. For the browser
+  // process a manual notification is sent before wiring up the ModuleWatcher.
+  module_database->OnProcessStarted(process_id, creation_time,
+                                    content::PROCESS_TYPE_BROWSER);
+  *module_watcher = ModuleWatcher::Create(
+      base::Bind(&OnModuleEvent, process_id, creation_time));
+}
+
 }  // namespace
 
 void ShowCloseBrowserFirstMessageBox() {
@@ -326,6 +386,12 @@
       FROM_HERE, content::BrowserThread::GetTaskRunnerForThread(
                      content::BrowserThread::FILE),
       base::Bind(base::IgnoreResult(&base::DeleteFile), path, false));
+
+  // Create the module database and hook up the in-process module watcher. This
+  // needs to be done before any child processes are initialized as the
+  // ModuleDatabase is an endpoint for IPC from child processes.
+  if (base::FeatureList::IsEnabled(features::kModuleDatabase))
+    SetupModuleDatabase(&module_watcher_);
 }
 
 void ChromeBrowserMainPartsWin::PostBrowserStart() {
diff --git a/chrome/browser/chrome_browser_main_win.h b/chrome/browser/chrome_browser_main_win.h
index 35165b00..68ad182 100644
--- a/chrome/browser/chrome_browser_main_win.h
+++ b/chrome/browser/chrome_browser_main_win.h
@@ -13,6 +13,7 @@
 #include "third_party/kasko/kasko_features.h"
 
 class DidRunUpdater;
+class ModuleWatcher;
 
 namespace base {
 class CommandLine;
@@ -78,6 +79,8 @@
   base::FilePathWatcher failed_kasko_crash_report_watcher_;
 #endif
 
+  std::unique_ptr<ModuleWatcher> module_watcher_;
+
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsWin);
 };
 
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index dec1278..0e25e8ef 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -101,6 +101,7 @@
 #include "chrome/browser/webshare/share_service_impl.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/env_vars.h"
@@ -214,6 +215,8 @@
 #if defined(OS_WIN)
 #include "base/strings/string_tokenizer.h"
 #include "chrome/browser/chrome_browser_main_win.h"
+#include "chrome/browser/conflicts/module_database_win.h"
+#include "chrome/browser/conflicts/module_event_sink_impl_win.h"
 #include "sandbox/win/src/sandbox_policy.h"
 #elif defined(OS_MACOSX)
 #include "chrome/browser/chrome_browser_main_mac.h"
@@ -2925,6 +2928,28 @@
     registry->AddInterface(
         base::Bind(&NetBenchmarking::Create, profile, context));
   }
+#if defined(OS_WIN)
+  if (base::FeatureList::IsEnabled(features::kModuleDatabase)) {
+    // Add the ModuleDatabase interface. This is the interface used by renderer
+    // processes to notify the browser of modules in their address space. It
+    // ultimately drives the chrome://conflicts UI. The process handle is not
+    // yet available at this point so pass in a callback to allow it to be
+    // retrieved at the time the interface is actually created. It is safe to
+    // pass a raw pointer to |render_process_host|: the callback will be invoked
+    // in the context of ModuleDatabase::GetInstance, which is invoked by Mojo
+    // initialization, which occurs while the |render_process_host| is alive.
+    auto get_process = base::Bind(&content::RenderProcessHost::GetHandle,
+                                  base::Unretained(render_process_host));
+    // The ModuleDatabase is a global singleton so passing an unretained pointer
+    // is safe.
+    registry->AddInterface(
+        base::Bind(&ModuleEventSinkImpl::Create, std::move(get_process),
+                   content::PROCESS_TYPE_RENDERER,
+                   base::Unretained(ModuleDatabase::GetInstance())),
+        ui_task_runner);
+  }
+#endif
+
 #if defined(OS_CHROMEOS)
   registry->AddInterface<metrics::mojom::LeakDetector>(
       base::Bind(&metrics::LeakDetectorRemoteController::Create),
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json
index 30087f5..dc94551 100644
--- a/chrome/browser/chrome_content_browser_manifest_overlay.json
+++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -11,6 +11,7 @@
           "chrome::mojom::FieldTrialRecorder",
           "extensions::StashService",
           "metrics::mojom::LeakDetector",
+          "mojom::ModuleEventSink",
           "rappor::mojom::RapporRecorder",
           "startup_metric_utils::mojom::StartupMetricHost",
           "translate::mojom::ContentTranslateDriver"
diff --git a/chrome/browser/chromeos/arc/process/arc_process_service.cc b/chrome/browser/chromeos/arc/process/arc_process_service.cc
index aa8cebbd..9de7760 100644
--- a/chrome/browser/chromeos/arc/process/arc_process_service.cc
+++ b/chrome/browser/chromeos/arc/process/arc_process_service.cc
@@ -30,7 +30,6 @@
 using base::kNullProcessId;
 using base::Process;
 using base::ProcessId;
-using base::SequencedWorkerPool;
 using std::vector;
 
 namespace {
@@ -204,19 +203,20 @@
 
 ArcProcessService::ArcProcessService(ArcBridgeService* bridge_service)
     : ArcService(bridge_service),
-      heavy_task_thread_("ArcProcessServiceThread"),
       nspid_to_pid_(new NSPidToPidMap()),
       weak_ptr_factory_(this) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  auto* blocking_pool = content::BrowserThread::GetBlockingPool();
+  task_runner_ = blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior(
+      blocking_pool->GetSequenceToken(),
+      base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
   arc_bridge_service()->process()->AddObserver(this);
   DCHECK(!g_arc_process_service);
   g_arc_process_service = this;
-  heavy_task_thread_.Start();
 }
 
 ArcProcessService::~ArcProcessService() {
   DCHECK(g_arc_process_service == this);
-  heavy_task_thread_.Stop();
   g_arc_process_service = nullptr;
   arc_bridge_service()->process()->RemoveObserver(this);
 }
@@ -231,7 +231,7 @@
     RequestProcessListCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  base::PostTaskAndReplyWithResult(GetTaskRunner().get(), FROM_HERE,
+  base::PostTaskAndReplyWithResult(task_runner_.get(), FROM_HERE,
                                    base::Bind(&GetArcSystemProcessList),
                                    callback);
 }
@@ -264,19 +264,15 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   base::PostTaskAndReplyWithResult(
-      GetTaskRunner().get(), FROM_HERE,
+      task_runner_.get(), FROM_HERE,
       base::Bind(&UpdateAndReturnProcessList, nspid_to_pid_,
                  base::Passed(&instance_processes)),
       callback);
 }
 
-scoped_refptr<base::SingleThreadTaskRunner> ArcProcessService::GetTaskRunner() {
-  return heavy_task_thread_.task_runner();
-}
-
 void ArcProcessService::OnInstanceReady() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  GetTaskRunner()->PostTask(FROM_HERE, base::Bind(&Reset, nspid_to_pid_));
+  task_runner_->PostTask(FROM_HERE, base::Bind(&Reset, nspid_to_pid_));
   instance_ready_ = true;
 }
 
diff --git a/chrome/browser/chromeos/arc/process/arc_process_service.h b/chrome/browser/chromeos/arc/process/arc_process_service.h
index b88343d..a3720cc 100644
--- a/chrome/browser/chromeos/arc/process/arc_process_service.h
+++ b/chrome/browser/chromeos/arc/process/arc_process_service.h
@@ -13,8 +13,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/process/process_iterator.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread.h"
+#include "base/sequenced_task_runner.h"
 #include "chrome/browser/chromeos/arc/process/arc_process.h"
 #include "components/arc/arc_service.h"
 #include "components/arc/common/process.mojom.h"
@@ -98,8 +97,6 @@
       const RequestProcessListCallback& callback,
       std::vector<mojom::RunningAppProcessInfoPtr> instance_processes);
 
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
-
   // InstanceHolder<mojom::ProcessInstance>::Observer overrides.
   void OnInstanceReady() override;
   void OnInstanceClosed() override;
@@ -108,14 +105,12 @@
   bool instance_ready_ = false;
 
   // There are some expensive tasks such as traverse whole process tree that
-  // we can't do it on the UI thread. Thus we need an additional thread to
-  // handle
-  // such tasks.
-  base::Thread heavy_task_thread_;
+  // we can't do it on the UI thread.
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   // Keep a cache pid mapping of all arc processes so to minimize the number of
   // nspid lookup from /proc/<PID>/status.
-  // To play safe, always modify |nspid_to_pid_| on the |heavy_task_thread_|.
+  // To play safe, always modify |nspid_to_pid_| on the blocking pool.
   scoped_refptr<NSPidToPidMap> nspid_to_pid_;
 
   // Always keep this the last member of this class to make sure it's the
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 3c520466..e4a0cb8 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1117,10 +1117,11 @@
   }
 
   if (user_context_.GetAuthFlow() == UserContext::AUTH_FLOW_ACTIVE_DIRECTORY) {
+    // Call FinalizePrepareProfile directly and skip RestoreAuthSessionImpl
+    // because there is no need to merge session for Active Directory users.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(&UserSessionManager::CompleteProfileCreateAfterAuthTransfer,
-                   AsWeakPtr(), profile));
+        FROM_HERE, base::Bind(&UserSessionManager::FinalizePrepareProfile,
+                              AsWeakPtr(), profile));
     return;
   }
 
diff --git a/chrome/browser/conflicts/module_database_win.cc b/chrome/browser/conflicts/module_database_win.cc
index 22c1d790..af71f6ee 100644
--- a/chrome/browser/conflicts/module_database_win.cc
+++ b/chrome/browser/conflicts/module_database_win.cc
@@ -19,13 +19,32 @@
               "assumes browser process type has value 2");
 constexpr uint32_t kFirstValidProcessType = content::PROCESS_TYPE_BROWSER;
 
+ModuleDatabase* g_instance = nullptr;
+
 }  // namespace
 
 ModuleDatabase::ModuleDatabase(
     scoped_refptr<base::SequencedTaskRunner> task_runner)
     : task_runner_(std::move(task_runner)), weak_ptr_factory_(this) {}
 
-ModuleDatabase::~ModuleDatabase() = default;
+ModuleDatabase::~ModuleDatabase() {
+  if (this == g_instance)
+    g_instance = nullptr;
+}
+
+// static
+ModuleDatabase* ModuleDatabase::GetInstance() {
+  return g_instance;
+}
+
+// static
+void ModuleDatabase::SetInstance(
+    std::unique_ptr<ModuleDatabase> module_database) {
+  DCHECK_EQ(nullptr, g_instance);
+  // This is deliberately leaked. It can be cleaned up by manually deleting the
+  // ModuleDatabase
+  g_instance = module_database.release();
+}
 
 void ModuleDatabase::OnProcessStarted(uint32_t process_id,
                                       uint64_t creation_time,
diff --git a/chrome/browser/conflicts/module_database_win.h b/chrome/browser/conflicts/module_database_win.h
index 8172082..73725556 100644
--- a/chrome/browser/conflicts/module_database_win.h
+++ b/chrome/browser/conflicts/module_database_win.h
@@ -16,6 +16,10 @@
 
 // A class that keeps track of all modules loaded across Chrome processes.
 // Drives the chrome://conflicts UI.
+//
+// This is effectively a singleton, but doesn't use base::Singleton. The intent
+// is for the object to be created when Chrome is single-threaded, and for it
+// be set as the process-wide singleton via SetInstance.
 class ModuleDatabase {
  public:
   // A ModuleDatabase is by default bound to a provided sequenced task runner.
@@ -25,6 +29,14 @@
   explicit ModuleDatabase(scoped_refptr<base::SequencedTaskRunner> task_runner);
   ~ModuleDatabase();
 
+  // Retrieves the singleton global instance of the ModuleDatabase.
+  static ModuleDatabase* GetInstance();
+
+  // Sets the global instance of the ModuleDatabase. Ownership is passed to the
+  // global instance and deliberately leaked, unless manually cleaned up. This
+  // has no locking and should be called when Chrome is single threaded.
+  static void SetInstance(std::unique_ptr<ModuleDatabase> module_database);
+
   // Indicates that process with the given type has started. This must be called
   // before any calls to OnModuleEvent or OnModuleUnload. Must be called in the
   // same sequence as |task_runner_|.
diff --git a/chrome/browser/conflicts/module_event_sink_impl_win.cc b/chrome/browser/conflicts/module_event_sink_impl_win.cc
index 428b382..808940332 100644
--- a/chrome/browser/conflicts/module_event_sink_impl_win.cc
+++ b/chrome/browser/conflicts/module_event_sink_impl_win.cc
@@ -22,22 +22,6 @@
 
 namespace {
 
-// Gets the process creation time associated with the given process.
-bool GetProcessCreationTime(base::ProcessHandle process,
-                            uint64_t* creation_time) {
-  FILETIME creation_ft = {};
-  FILETIME exit_ft = {};
-  FILETIME kernel_ft = {};
-  FILETIME user_ft = {};
-  if (!::GetProcessTimes(process, &creation_ft, &exit_ft, &kernel_ft,
-                         &user_ft)) {
-    return false;
-  }
-  *creation_time = (static_cast<uint64_t>(creation_ft.dwHighDateTime) << 32) |
-                   static_cast<uint64_t>(creation_ft.dwLowDateTime);
-  return true;
-}
-
 // Gets the path of the module in the provided remote process. Returns true on
 // success, false otherwise.
 bool GetModulePath(base::ProcessHandle process,
@@ -132,11 +116,12 @@
 ModuleEventSinkImpl::~ModuleEventSinkImpl() = default;
 
 // static
-void ModuleEventSinkImpl::Create(base::ProcessHandle process,
+void ModuleEventSinkImpl::Create(GetProcessHandleCallback get_process_handle,
                                  content::ProcessType process_type,
                                  ModuleDatabase* module_database,
                                  mojom::ModuleEventSinkRequest request) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  base::ProcessHandle process = get_process_handle.Run();
   auto module_event_sink_impl = base::MakeUnique<ModuleEventSinkImpl>(
       process, process_type, module_database);
   base::Closure error_handler = base::Bind(
@@ -169,6 +154,22 @@
   }
 }
 
+// static
+bool ModuleEventSinkImpl::GetProcessCreationTime(base::ProcessHandle process,
+                                                 uint64_t* creation_time) {
+  FILETIME creation_ft = {};
+  FILETIME exit_ft = {};
+  FILETIME kernel_ft = {};
+  FILETIME user_ft = {};
+  if (!::GetProcessTimes(process, &creation_ft, &exit_ft, &kernel_ft,
+                         &user_ft)) {
+    return false;
+  }
+  *creation_time = (static_cast<uint64_t>(creation_ft.dwHighDateTime) << 32) |
+                   static_cast<uint64_t>(creation_ft.dwLowDateTime);
+  return true;
+}
+
 void ModuleEventSinkImpl::OnModuleLoad(uint64_t load_address) {
   if (in_error_)
     return;
diff --git a/chrome/browser/conflicts/module_event_sink_impl_win.h b/chrome/browser/conflicts/module_event_sink_impl_win.h
index 5f5b7ce..7abe5124 100644
--- a/chrome/browser/conflicts/module_event_sink_impl_win.h
+++ b/chrome/browser/conflicts/module_event_sink_impl_win.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include "base/callback_forward.h"
 #include "base/process/process_handle.h"
 #include "chrome/common/conflicts/module_event_sink_win.mojom.h"
 #include "content/public/common/process_type.h"
@@ -18,6 +19,10 @@
 // object.
 class ModuleEventSinkImpl : public mojom::ModuleEventSink {
  public:
+  // Callback for retrieving the handle associated with a process. This is used
+  // by "Create" to get a handle to the remote process.
+  using GetProcessHandleCallback = base::Callback<base::ProcessHandle()>;
+
   // Creates a service endpoint that forwards notifications from the remote
   // |process| of the provided |process_type| to the provided |module_database|.
   // The |module_database| must outlive this object.
@@ -30,7 +35,7 @@
   // creates a concrete implementation of mojom::ModuleDatabase interface in the
   // current process, for the remote process represented by the provided
   // |request|. This should only be called on the UI thread.
-  static void Create(base::ProcessHandle process,
+  static void Create(GetProcessHandleCallback get_process_handle,
                      content::ProcessType process_type,
                      ModuleDatabase* module_database,
                      mojom::ModuleEventSinkRequest request);
@@ -41,6 +46,10 @@
 
   bool in_error() const { return in_error_; }
 
+  // Gets the process creation time associated with the given process.
+  static bool GetProcessCreationTime(base::ProcessHandle process,
+                                     uint64_t* creation_time);
+
  private:
   friend class ModuleEventSinkImplTest;
 
diff --git a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
index dbb8ac05..2c543d1e 100644
--- a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
@@ -67,14 +67,13 @@
 const char kBackgroundHistogramDocWriteBlockParseDuration[] =
     "PageLoad.Clients.DocWrite.Block.ParseTiming.ParseDuration.Background";
 
+const char kHistogramDocWriteBlockCount[] =
+    "PageLoad.Clients.DocWrite.Block.Count";
 const char kHistogramDocWriteBlockReloadCount[] =
     "PageLoad.Clients.DocWrite.Block.ReloadCount";
 
 }  // namespace internal
 
-DocumentWritePageLoadMetricsObserver::DocumentWritePageLoadMetricsObserver()
-    : doc_write_block_reload_observed_(false) {}
-
 void DocumentWritePageLoadMetricsObserver::OnFirstContentfulPaint(
     const page_load_metrics::PageLoadTiming& timing,
     const page_load_metrics::PageLoadExtraInfo& info) {
@@ -126,6 +125,12 @@
     UMA_HISTOGRAM_COUNTS(internal::kHistogramDocWriteBlockReloadCount, 1);
     doc_write_block_reload_observed_ = true;
   }
+  if ((info.metadata.behavior_flags &
+       blink::WebLoadingBehaviorFlag::WebLoadingBehaviorDocumentWriteBlock) &&
+      !doc_write_block_observed_) {
+    UMA_HISTOGRAM_BOOLEAN(internal::kHistogramDocWriteBlockCount, true);
+    doc_write_block_observed_ = true;
+  }
 }
 
 void DocumentWritePageLoadMetricsObserver::
diff --git a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.h
index 0261f1d..a4358a64 100644
--- a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.h
@@ -13,6 +13,7 @@
 // Expose metrics for tests.
 extern const char kHistogramDocWriteParseStartToFirstContentfulPaint[];
 extern const char kHistogramDocWriteBlockParseStartToFirstContentfulPaint[];
+extern const char kHistogramDocWriteBlockCount[];
 extern const char kHistogramDocWriteBlockReloadCount[];
 
 }  // namespace internal
@@ -20,7 +21,8 @@
 class DocumentWritePageLoadMetricsObserver
     : public page_load_metrics::PageLoadMetricsObserver {
  public:
-  DocumentWritePageLoadMetricsObserver();
+  DocumentWritePageLoadMetricsObserver() = default;
+
   // page_load_metrics::PageLoadMetricsObserver implementation:
   void OnFirstContentfulPaint(
       const page_load_metrics::PageLoadTiming& timing,
@@ -62,7 +64,8 @@
       const page_load_metrics::PageLoadTiming& timing,
       const page_load_metrics::PageLoadExtraInfo& info);
 
-  bool doc_write_block_reload_observed_;
+  bool doc_write_block_observed_ = false;
+  bool doc_write_block_reload_observed_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(DocumentWritePageLoadMetricsObserver);
 };
diff --git a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer_unittest.cc
index 4b9c2640..52726c58 100644
--- a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer_unittest.cc
@@ -89,6 +89,8 @@
   NavigateAndCommit(GURL("https://www.google.com"));
   SimulateTimingAndMetadataUpdate(timing, metadata);
 
+  histogram_tester().ExpectTotalCount(internal::kHistogramDocWriteBlockCount,
+                                      1);
   histogram_tester().ExpectTotalCount(
       internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1);
   histogram_tester().ExpectBucketCount(
@@ -134,6 +136,9 @@
   SimulateTimingAndMetadataUpdate(timing, metadata);
   histogram_tester().ExpectTotalCount(
       internal::kHistogramDocWriteBlockReloadCount, 2);
+
+  histogram_tester().ExpectTotalCount(internal::kHistogramDocWriteBlockCount,
+                                      0);
 }
 
 TEST_F(DocumentWritePageLoadMetricsObserverTest, NoPossibleBlock) {
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
index 1586b63..d72610d 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -229,6 +229,7 @@
       internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 0);
   histogram_tester_.ExpectTotalCount(
       internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
+  histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
 }
 
 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteBlock) {
@@ -241,6 +242,7 @@
 
   histogram_tester_.ExpectTotalCount(
       internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1);
+  histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteReload) {
@@ -269,6 +271,7 @@
 
   histogram_tester_.ExpectTotalCount(
       internal::kHistogramDocWriteBlockReloadCount, 2);
+  histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteAsync) {
@@ -281,6 +284,7 @@
 
   histogram_tester_.ExpectTotalCount(
       internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
+  histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
 }
 
 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteSameDomain) {
@@ -293,6 +297,7 @@
 
   histogram_tester_.ExpectTotalCount(
       internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
+  histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
 }
 
 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoDocumentWriteScript) {
@@ -305,6 +310,7 @@
 
   histogram_tester_.ExpectTotalCount(
       internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
+  histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
 }
 
 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, BadXhtml) {
diff --git a/chrome/chrome_watcher/BUILD.gn b/chrome/chrome_watcher/BUILD.gn
index 88fe846..4a5d77e 100644
--- a/chrome/chrome_watcher/BUILD.gn
+++ b/chrome/chrome_watcher/BUILD.gn
@@ -69,6 +69,8 @@
     "//base:base_static",
     "//build/config/sanitizers:deps",
     "//chrome/common:metrics_constants_util_win",
+    "//chrome/install_static:secondary_module",
+    "//chrome_elf",
     "//components/browser_watcher",
   ]
   ldflags = [ "/DEF:" + rebase_path("chrome_watcher.def", root_build_dir) ]
diff --git a/chrome/chrome_watcher/chrome_watcher_main.cc b/chrome/chrome_watcher/chrome_watcher_main.cc
index 47efb29..180ec3c 100644
--- a/chrome/chrome_watcher/chrome_watcher_main.cc
+++ b/chrome/chrome_watcher/chrome_watcher_main.cc
@@ -34,8 +34,7 @@
 #include "base/win/scoped_handle.h"
 #include "base/win/win_util.h"
 #include "chrome/chrome_watcher/chrome_watcher_main_api.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/install_static/install_details.h"
+#include "chrome/install_static/initialize_from_primary_module.h"
 #include "components/browser_watcher/endsession_watcher_window_win.h"
 #include "components/browser_watcher/exit_code_watcher_win.h"
 #include "components/browser_watcher/window_hang_monitor_win.h"
@@ -188,8 +187,7 @@
                            DWORD main_thread_id,
                            HANDLE on_initialized_event_handle,
                            const base::char16* browser_data_directory) {
-  install_static::InstallDetails::InitializeFromPrimaryModule(
-      chrome::kChromeElfDllName);
+  install_static::InitializeFromPrimaryModule();
   base::Process process(process_handle);
   base::win::ScopedHandle on_initialized_event(on_initialized_event_handle);
 
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 0c2394d..809f2f5 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -145,6 +145,12 @@
 const base::Feature kModalPermissionPrompts{"ModalPermissionPrompts",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
+#if defined(OS_WIN)
+// Enables or disables the ModuleDatabase backend for the conflicts UI.
+const base::Feature kModuleDatabase{"ModuleDatabase",
+                                    base::FEATURE_DISABLED_BY_DEFAULT};
+#endif
+
 // Enables the use of native notification centers instead of using the Message
 // Center for displaying the toasts.
 #if defined(OS_MACOSX)
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 298f6b0..430dd0d6 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -87,6 +87,10 @@
 
 extern const base::Feature kModalPermissionPrompts;
 
+#if defined(OS_WIN)
+extern const base::Feature kModuleDatabase;
+#endif
+
 #if defined(OS_MACOSX)
 extern const base::Feature kNativeNotifications;
 #endif  // defined(OS_MACOSX)
diff --git a/chrome/common/extensions/api/_manifest_features.json b/chrome/common/extensions/api/_manifest_features.json
index 55bd040..370e7d6 100644
--- a/chrome/common/extensions/api/_manifest_features.json
+++ b/chrome/common/extensions/api/_manifest_features.json
@@ -145,10 +145,18 @@
       "location": "component"
     }
   ],
-  "file_system_provider_capabilities": {
+  "file_system_provider_capabilities": [{
     "channel": "stable",
     "extension_types": ["extension", "platform_app"]
-  },
+  }, {
+    "channel": "stable",
+    "extension_types": ["legacy_packaged_app"],
+    "platforms": ["chromeos"],
+    "whitelist": [
+      "0EA6B717932AD64C469C1CCB6911457733295907",  // http://crbug.com/673004
+      "58B0C2968C335964D5433E89CA4D86628A0E3D4B"   // http://crbug.com/673004
+    ]
+  }],
   "homepage_url": {
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"]
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 7f8a14c..1a040bf 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -402,11 +402,19 @@
     "extension_types": ["platform_app"],
     "platforms": ["chromeos"]
   }],
-  "fileSystemProvider": {
+  "fileSystemProvider": [{
     "channel": "stable",
     "extension_types": ["extension", "platform_app"],
     "platforms": ["chromeos"]
-  },
+  }, {
+    "channel": "stable",
+    "extension_types": ["legacy_packaged_app"],
+    "platforms": ["chromeos"],
+    "whitelist": [
+      "0EA6B717932AD64C469C1CCB6911457733295907",  // http://crbug.com/673004
+      "58B0C2968C335964D5433E89CA4D86628A0E3D4B"   // http://crbug.com/673004
+    ]
+  }],
   "firstRunPrivate": {
     "channel": "stable",
     "extension_types": ["platform_app"],
diff --git a/chrome/install_static/BUILD.gn b/chrome/install_static/BUILD.gn
index 3fff4aa..3687901 100644
--- a/chrome/install_static/BUILD.gn
+++ b/chrome/install_static/BUILD.gn
@@ -54,6 +54,28 @@
   ]
 }
 
+# A source set for use by the module in a process that creates the process-wide
+# InstallDetails instance (i.e., chrome_elf.dll).
+source_set("primary_module") {
+  sources = [
+    "get_install_details_payload.cc",
+  ]
+}
+
+# A source set for use by modules in a process that fetch the process-wide
+# InstallDetails instance from the primary module by way of
+# GetInstallDetailsPayload (i.e., chrome.exe, chrome.dll, chrome_child.dll, and
+# chrome_watcher.dll).
+source_set("secondary_module") {
+  sources = [
+    "initialize_from_primary_module.cc",
+    "initialize_from_primary_module.h",
+  ]
+  deps = [
+    ":install_static_util",
+  ]
+}
+
 test("install_static_unittests") {
   output_name = "install_static_unittests"
   sources = [
diff --git a/chrome/install_static/get_install_details_payload.cc b/chrome/install_static/get_install_details_payload.cc
new file mode 100644
index 0000000..9a4ed35
--- /dev/null
+++ b/chrome/install_static/get_install_details_payload.cc
@@ -0,0 +1,14 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/install_static/install_details.h"
+
+// Returns the payload of the module's details. This should be linked into the
+// primary module (i.e., chrome_elf) via the "primary_module" source set and
+// exported for use by other modules in the process; see
+// install_static::InitializeFromPrimaryModule.
+extern "C" const install_static::InstallDetails::Payload*
+GetInstallDetailsPayload() {
+  return install_static::InstallDetails::Get().GetPayload();
+}
diff --git a/chrome/install_static/initialize_from_primary_module.cc b/chrome/install_static/initialize_from_primary_module.cc
new file mode 100644
index 0000000..58584ac7
--- /dev/null
+++ b/chrome/install_static/initialize_from_primary_module.cc
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/install_static/initialize_from_primary_module.h"
+
+#include "chrome/install_static/install_details.h"
+
+// A function exported by the primary module, which is expected to be built with
+// the "primary_module" source set.
+extern "C" const install_static::InstallDetails::Payload __declspec(dllimport) *
+    GetInstallDetailsPayload();
+
+namespace install_static {
+
+void InitializeFromPrimaryModule() {
+  InstallDetails::InitializeFromPayload(GetInstallDetailsPayload());
+}
+
+}  // namespace install_static
diff --git a/chrome/install_static/initialize_from_primary_module.h b/chrome/install_static/initialize_from_primary_module.h
new file mode 100644
index 0000000..e66e2057
--- /dev/null
+++ b/chrome/install_static/initialize_from_primary_module.h
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_INSTALL_STATIC_INITIALIZE_FROM_PRIMARY_MODULE_H_
+#define CHROME_INSTALL_STATIC_INITIALIZE_FROM_PRIMARY_MODULE_H_
+
+namespace install_static {
+
+// Initializes an InstallDetails instance for this module with the payload from
+// the process's primary module (which exports an "GetInstallDetailsPayload"
+// function for this express purpose).
+void InitializeFromPrimaryModule();
+
+}  // namespace install_static
+
+#endif  // CHROME_INSTALL_STATIC_INITIALIZE_FROM_PRIMARY_MODULE_H_
diff --git a/chrome/install_static/install_details.cc b/chrome/install_static/install_details.cc
index b0fda62..688b079 100644
--- a/chrome/install_static/install_details.cc
+++ b/chrome/install_static/install_details.cc
@@ -67,16 +67,11 @@
 }
 
 // static
-void InstallDetails::InitializeFromPrimaryModule(
-    const wchar_t* primary_module_name) {
+void InstallDetails::InitializeFromPayload(
+    const InstallDetails::Payload* payload) {
   assert(!g_module_details);
-  using GetInstallDetailsPayloadFunction = const Payload*(__cdecl*)();
-  GetInstallDetailsPayloadFunction payload_getter =
-      reinterpret_cast<GetInstallDetailsPayloadFunction>(::GetProcAddress(
-          ::GetModuleHandle(primary_module_name), "GetInstallDetailsPayload"));
-  assert(payload_getter);
   // Intentionally leaked at shutdown.
-  g_module_details = new InstallDetails(payload_getter());
+  g_module_details = new InstallDetails(payload);
 }
 
 PrimaryInstallDetails::PrimaryInstallDetails() : InstallDetails(&payload_) {
diff --git a/chrome/install_static/install_details.h b/chrome/install_static/install_details.h
index f9c0a13b..aefdbb8 100644
--- a/chrome/install_static/install_details.h
+++ b/chrome/install_static/install_details.h
@@ -122,12 +122,9 @@
   // other modules in the process.
   static const Payload* GetPayload();
 
-  // Initializes this module's instance with the payload owned by the process's
-  // primary module (the one that used SetForProcess). Said primary module must
-  // export the function:
-  // extern "C" const install_static::InstallDetails::Payload*
-  // GetInstallDetailsPayload();
-  static void InitializeFromPrimaryModule(const wchar_t* primary_module_name);
+  // Initializes this module's instance with the payload from the process's
+  // primary module (the one that used SetForProcess).
+  static void InitializeFromPayload(const Payload* payload);
 
  protected:
   explicit InstallDetails(const Payload* payload) : payload_(payload) {}
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 6728fc9..be3f1393 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -297,6 +297,37 @@
   DISALLOW_COPY_AND_ASSIGN(MediaLoadDeferrer);
 };
 
+#if defined(OS_WIN)
+// Dispatches a module |event| to the provided |module_event_sink| interface.
+// It is expected that this only be called from the IO thread. This is only
+// safe because the underlying |module_event_sink| object is never deleted,
+// being owned by the leaked ChromeContentRendererClient object. If this ever
+// changes then a WeakPtr mechanism would have to be used.
+void HandleModuleEventOnIOThread(mojom::ModuleEventSinkPtr* module_event_sink,
+                                 const ModuleWatcher::ModuleEvent& event) {
+  // Simply send the module load address. The browser can validate this and look
+  // up the module details on its own.
+  (*module_event_sink)
+      ->OnModuleEvent(event.event_type,
+                      reinterpret_cast<uintptr_t>(event.module_load_address));
+}
+
+// Receives notifications from the ModuleWatcher on any thread. Bounces these
+// over to the provided |io_task_runner| where they are subsequently dispatched
+// to the |module_event_sink| interface.
+void OnModuleEvent(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+                   mojom::ModuleEventSinkPtr* module_event_sink,
+                   const ModuleWatcher::ModuleEvent& event) {
+  // The Mojo interface can only be used from a single thread. Bounce tasks
+  // over to it. It is safe to pass an unretained pointer to
+  // |module_event_sink|: it is owned by a ChromeContentRendererClient, which is
+  // a leaked singleton in the process.
+  io_task_runner->PostTask(
+      FROM_HERE, base::Bind(&HandleModuleEventOnIOThread,
+                            base::Unretained(module_event_sink), event));
+}
+#endif
+
 }  // namespace
 
 ChromeContentRendererClient::ChromeContentRendererClient()
@@ -331,6 +362,19 @@
     startup_metric_host->RecordRendererMainEntryTime(main_entry_time_);
   }
 
+#if defined(OS_WIN)
+  if (base::FeatureList::IsEnabled(features::kModuleDatabase)) {
+    thread->GetRemoteInterfaces()->GetInterface(&module_event_sink_);
+
+    // It is safe to pass an unretained pointer to |module_event_sink_|, as it
+    // is owned by the process singleton ChromeContentRendererClient, which is
+    // leaked.
+    module_watcher_ = ModuleWatcher::Create(
+        base::Bind(&OnModuleEvent, thread->GetIOTaskRunner(),
+                   base::Unretained(&module_event_sink_)));
+  }
+#endif
+
   chrome_observer_.reset(new ChromeRenderThreadObserver());
   web_cache_impl_.reset(new web_cache::WebCacheImpl());
 
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 8d58406..4aae7bc 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -30,6 +30,11 @@
 #include "chrome/renderer/leak_detector/leak_detector_remote_client.h"
 #endif
 
+#if defined(OS_WIN)
+#include "chrome/common/conflicts/module_event_sink_win.mojom.h"
+#include "chrome/common/conflicts/module_watcher_win.h"
+#endif
+
 class ChromeRenderThreadObserver;
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 class ChromePDFPrintClient;
@@ -258,6 +263,13 @@
   std::unique_ptr<LeakDetectorRemoteClient> leak_detector_remote_client_;
 #endif
 
+#if defined(OS_WIN)
+  // Observes module load and unload events and notifies the ModuleDatabase in
+  // the browser process.
+  std::unique_ptr<ModuleWatcher> module_watcher_;
+  mojom::ModuleEventSinkPtr module_event_sink_;
+#endif
+
   DISALLOW_COPY_AND_ASSIGN(ChromeContentRendererClient);
 };
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 60093e5..bd701a7 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -929,9 +929,15 @@
     test_type = "webui"
 
     sources = [
+      "data/webui/cr_elements/cr_elements_focus_test.js",
       "data/webui/md_history/md_history_focus_test.js",
     ]
 
+    gen_include_files = [
+      "data/webui/polymer_browser_test_base.js",
+      "data/webui/polymer_interactive_ui_test.js",
+    ]
+
     deps = [
       "//chrome/browser/ui",
     ]
diff --git a/chrome/test/base/web_ui_browser_test.cc b/chrome/test/base/web_ui_browser_test.cc
index c50a434..4c8d5bc7 100644
--- a/chrome/test/base/web_ui_browser_test.cc
+++ b/chrome/test/base/web_ui_browser_test.cc
@@ -224,16 +224,6 @@
       browser(), GURL(browse_to), ui::PAGE_TRANSITION_TYPED);
   params.disposition = WindowOpenDisposition::CURRENT_TAB;
 
-  // This is needed to make the test
-  // MaterialHistoryBrowserTest.HistoryToolbarFocusTest pass on macOS. The test
-  // is fundamentally flawed, since it expects a particular widget to be
-  // focused. Chrome focus semantics are based on the Windows platform, where a
-  // widget cannot be focused without window activation. browser_tests can be
-  // sharded, so there is no way to enforce that a given window is activated.
-  // Focus tests should be interactive_ui_tests, and they should explicitly
-  // activate the window. https://crbug.com/642467.
-  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
-
   chrome::Navigate(&params);
   navigation_observer.Wait();
 }
diff --git a/chrome/test/data/webui/cr_elements/cr_action_menu_test.js b/chrome/test/data/webui/cr_elements/cr_action_menu_test.js
index 233b3ec1..6cfa650 100644
--- a/chrome/test/data/webui/cr_elements/cr_action_menu_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_action_menu_test.js
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/** @fileoverview Tests for cr-action-menu element. */
+/**
+ * @fileoverview Tests for cr-action-menu element. Runs as an interactive UI
+ * test, since many of these tests check focus behavior.
+ */
 suite('CrActionMenu', function() {
   /** @type {?CrActionMenuElement} */
   var menu = null;
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
index 31e9fa7..1fcc2225f 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
+++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -74,7 +74,7 @@
 
 TEST_F('CrElementsProfileAvatarSelectorTest', 'All', function() {
   cr_profile_avatar_selector.registerTests();
-  mocha.run();
+  mocha.grep(cr_profile_avatar_selector.TestNames.Basic).run();
 });
 
 function CrElementsToolbarSearchFieldTest() {}
@@ -116,24 +116,6 @@
   mocha.run();
 });
 
-function CrElementsActionMenuTest() {}
-
-CrElementsActionMenuTest.prototype = {
-  __proto__: CrElementsBrowserTest.prototype,
-
-  /** @override */
-  browsePreload:
-      'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html',
-
-  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
-    'cr_action_menu_test.js',
-  ]),
-};
-
-TEST_F('CrElementsActionMenuTest', 'All', function() {
-  mocha.run();
-});
-
 function CrElementsDrawerTest() {}
 
 CrElementsDrawerTest.prototype = {
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js b/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js
new file mode 100644
index 0000000..1a3469c
--- /dev/null
+++ b/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js
@@ -0,0 +1,58 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/** @fileoverview Tests for shared Polymer elements which rely on focus. */
+
+/** @const {string} Path to source root. */
+var ROOT_PATH = '../../../../../';
+
+// Polymer BrowserTest fixture.
+GEN_INCLUDE(
+    [ROOT_PATH + 'chrome/test/data/webui/polymer_interactive_ui_test.js']);
+
+function CrElementsFocusTest() {}
+
+CrElementsFocusTest.prototype = {
+  __proto__: PolymerInteractiveUITest.prototype,
+
+  extraLibraries: PolymerTest.getLibraries(ROOT_PATH),
+};
+
+function CrElementsActionMenuTest() {}
+
+CrElementsActionMenuTest.prototype = {
+  __proto__: CrElementsFocusTest.prototype,
+
+  /** @override */
+  browsePreload:
+      'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html',
+
+  extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([
+    'cr_action_menu_test.js',
+  ]),
+};
+
+TEST_F('CrElementsActionMenuTest', 'All', function() {
+  mocha.run();
+});
+
+function CrElementsProfileAvatarSelectorFocusTest() {}
+
+CrElementsProfileAvatarSelectorFocusTest.prototype = {
+  __proto__: CrElementsFocusTest.prototype,
+
+  /** @override */
+  browsePreload:
+      'chrome://resources/cr_elements/cr_profile_avatar_selector/' +
+      'cr_profile_avatar_selector.html',
+
+  extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([
+    'cr_profile_avatar_selector_tests.js',
+  ]),
+};
+
+TEST_F('CrElementsProfileAvatarSelectorFocusTest', 'All', function() {
+  cr_profile_avatar_selector.registerTests();
+  mocha.grep(cr_profile_avatar_selector.TestNames.Focus).run();
+});
diff --git a/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js b/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js
index f7666137..b01b697e 100644
--- a/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js
@@ -4,6 +4,11 @@
 
 /** @fileoverview Suite of tests for cr-profile-avatar-selector. */
 cr.define('cr_profile_avatar_selector', function() {
+  var TestNames = {
+    Basic: 'basic',
+    Focus: 'Ignores modified key events',
+  };
+
   function registerTests() {
     suite('cr-profile-avatar-selector', function() {
       /** @type {CrProfileAvatarSelectorElement} */
@@ -30,66 +35,73 @@
         avatarSelector.remove();
       });
 
-      test('Displays avatars', function() {
-        assertEquals(3, avatarSelector.$['avatar-grid'].items.length);
-      });
+      // Run in CrElementsProfileAvatarSelectorTest.All as a browser_test.
+      suite(TestNames.Basic, function() {
 
-      test('Can update avatars', function() {
-        avatarSelector.pop('avatars');
-        Polymer.dom.flush();
-        assertEquals(2, avatarSelector.$['avatar-grid'].items.length);
-      });
-
-      test('No avatar is initially selected', function() {
-        var selector = avatarSelector.$['avatar-grid'];
-
-        assertFalse(!!avatarSelector.selectedAvatarUrl);
-        assertFalse(selector.items[0].classList.contains('iron-selected'));
-        assertFalse(selector.items[1].classList.contains('iron-selected'));
-        assertFalse(selector.items[2].classList.contains('iron-selected'));
-      });
-
-      test('An avatar is initially selected if selectedAvatarUrl is set',
-           function() {
-        var anotherAvatarSelector = createElement();
-        anotherAvatarSelector.selectedAvatarUrl =
-            anotherAvatarSelector.avatars[0].url;
-        document.body.appendChild(anotherAvatarSelector);
-        Polymer.dom.flush();
-
-        var selector = anotherAvatarSelector.$['avatar-grid'];
-
-        assertEquals('chrome://avatar1.png',
-                     anotherAvatarSelector.selectedAvatarUrl);
-        assertTrue(selector.items[0].classList.contains('iron-selected'));
-        assertFalse(selector.items[1].classList.contains('iron-selected'));
-        assertFalse(selector.items[2].classList.contains('iron-selected'));
-      });
-
-      test('Can select avatar', function() {
-        var selector = avatarSelector.$['avatar-grid'];
-
-        // Simulate tapping the third avatar.
-        MockInteractions.tap(selector.items[2]);
-        assertEquals('chrome://avatar3.png', avatarSelector.selectedAvatarUrl);
-        assertFalse(selector.items[0].classList.contains('iron-selected'));
-        assertFalse(selector.items[1].classList.contains('iron-selected'));
-        assertTrue(selector.items[2].classList.contains('iron-selected'));
-      });
-
-      test('Fires iron-activate event when an avatar is activated',
-           function(done) {
-        avatarSelector.addEventListener('iron-activate',
-                                        function(event) {
-          assertEquals(event.detail.selected, 'chrome://avatar2.png');
-          done();
+        test('Displays avatars', function() {
+          assertEquals(3, avatarSelector.$['avatar-grid'].items.length);
         });
 
-        // Simulate tapping the second avatar.
-        MockInteractions.tap(avatarSelector.$['avatar-grid'].items[1]);
+        test('Can update avatars', function() {
+          avatarSelector.pop('avatars');
+          Polymer.dom.flush();
+          assertEquals(2, avatarSelector.$['avatar-grid'].items.length);
+        });
+
+        test('No avatar is initially selected', function() {
+          var selector = avatarSelector.$['avatar-grid'];
+
+          assertFalse(!!avatarSelector.selectedAvatarUrl);
+          assertFalse(selector.items[0].classList.contains('iron-selected'));
+          assertFalse(selector.items[1].classList.contains('iron-selected'));
+          assertFalse(selector.items[2].classList.contains('iron-selected'));
+        });
+
+        test('An avatar is initially selected if selectedAvatarUrl is set',
+             function() {
+          var anotherAvatarSelector = createElement();
+          anotherAvatarSelector.selectedAvatarUrl =
+              anotherAvatarSelector.avatars[0].url;
+          document.body.appendChild(anotherAvatarSelector);
+          Polymer.dom.flush();
+
+          var selector = anotherAvatarSelector.$['avatar-grid'];
+
+          assertEquals('chrome://avatar1.png',
+                       anotherAvatarSelector.selectedAvatarUrl);
+          assertTrue(selector.items[0].classList.contains('iron-selected'));
+          assertFalse(selector.items[1].classList.contains('iron-selected'));
+          assertFalse(selector.items[2].classList.contains('iron-selected'));
+        });
+
+        test('Can select avatar', function() {
+          var selector = avatarSelector.$['avatar-grid'];
+
+          // Simulate tapping the third avatar.
+          MockInteractions.tap(selector.items[2]);
+          assertEquals(
+              'chrome://avatar3.png', avatarSelector.selectedAvatarUrl);
+          assertFalse(selector.items[0].classList.contains('iron-selected'));
+          assertFalse(selector.items[1].classList.contains('iron-selected'));
+          assertTrue(selector.items[2].classList.contains('iron-selected'));
+        });
+
+        test('Fires iron-activate event when an avatar is activated',
+             function(done) {
+          avatarSelector.addEventListener('iron-activate',
+                                          function(event) {
+            assertEquals(event.detail.selected, 'chrome://avatar2.png');
+            done();
+          });
+
+          // Simulate tapping the second avatar.
+          MockInteractions.tap(avatarSelector.$['avatar-grid'].items[1]);
+        });
       });
 
-      test('Ignores modified key events', function() {
+      // Run in CrElementsProfileAvatarSelectorFocusTest.All as an
+      // interactive_ui_test.
+      test(TestNames.Focus, function() {
         var selector = avatarSelector.$['avatar-grid'];
         var items = selector.items;
 
@@ -121,5 +133,6 @@
 
   return {
     registerTests: registerTests,
+    TestNames: TestNames,
   };
 });
diff --git a/chrome/test/data/webui/md_history/md_history_focus_test.js b/chrome/test/data/webui/md_history/md_history_focus_test.js
index 522a45a..12de3903 100644
--- a/chrome/test/data/webui/md_history/md_history_focus_test.js
+++ b/chrome/test/data/webui/md_history/md_history_focus_test.js
@@ -10,15 +10,12 @@
 var ROOT_PATH = '../../../../../';
 
 GEN_INCLUDE(
-    [ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
-GEN('#include "chrome/browser/ui/browser.h"');
-GEN('#include "chrome/browser/ui/tabs/tab_strip_model.h"');
-GEN('#include "content/public/browser/web_contents.h"');
+    [ROOT_PATH + 'chrome/test/data/webui/polymer_interactive_ui_test.js']);
 
 function MaterialHistoryFocusTest() {}
 
 MaterialHistoryFocusTest.prototype = {
-  __proto__: PolymerTest.prototype,
+  __proto__: PolymerInteractiveUITest.prototype,
 
   browsePreload: 'chrome://history',
 
diff --git a/chrome/test/data/webui/polymer_interactive_ui_test.js b/chrome/test/data/webui/polymer_interactive_ui_test.js
new file mode 100644
index 0000000..8737533
--- /dev/null
+++ b/chrome/test/data/webui/polymer_interactive_ui_test.js
@@ -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.
+
+GEN_INCLUDE(['polymer_browser_test_base.js']);
+
+GEN('#include "chrome/browser/ui/browser.h"');
+GEN('#include "chrome/browser/ui/tabs/tab_strip_model.h"');
+GEN('#include "content/public/browser/web_contents.h"');
+
+function PolymerInteractiveUITest() {}
+
+PolymerInteractiveUITest.prototype = {
+  __proto__: PolymerTest.prototype,
+
+  testGenPreamble: function() {
+    // Must explicitly focus the web contents before running the test on Mac.
+    // See: https://crbug.com/642467.
+    GEN('  browser()->tab_strip_model()->GetActiveWebContents()->Focus();');
+  },
+
+};
diff --git a/chrome_elf/BUILD.gn b/chrome_elf/BUILD.gn
index 0629b6f..c2861e0f6 100644
--- a/chrome_elf/BUILD.gn
+++ b/chrome_elf/BUILD.gn
@@ -48,6 +48,7 @@
     ":security",
     "//build/config/sanitizers:deps",
     "//chrome/install_static:install_static_util",
+    "//chrome/install_static:primary_module",
   ]
   configs += [ "//build/config/win:windowed" ]
   configs -= [ "//build/config/win:console" ]
diff --git a/chrome_elf/chrome_elf_main.cc b/chrome_elf/chrome_elf_main.cc
index cbb9a00e..23edaaf 100644
--- a/chrome_elf/chrome_elf_main.cc
+++ b/chrome_elf/chrome_elf_main.cc
@@ -33,13 +33,6 @@
             invalid_user_data_dir_str.c_str(), _TRUNCATE);
 }
 
-// Returns the payload for the ELF's InstallDetails instance. For use by
-// install_static::InstallDetails::InitializeFromPrimaryModule.
-extern "C" const install_static::InstallDetails::Payload*
-GetInstallDetailsPayload() {
-  return install_static::InstallDetails::Get().GetPayload();
-}
-
 BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
   if (reason == DLL_PROCESS_ATTACH) {
     install_static::InitializeProductDetailsForPrimaryModule();
diff --git a/components/cronet/android/cronet_data_reduction_proxy.cc b/components/cronet/android/cronet_data_reduction_proxy.cc
index fa5a3cbf..a0303e4 100644
--- a/components/cronet/android/cronet_data_reduction_proxy.cc
+++ b/components/cronet/android/cronet_data_reduction_proxy.cc
@@ -89,10 +89,8 @@
   settings_.reset(
       new data_reduction_proxy::DataReductionProxySettings());
   io_data_.reset(new data_reduction_proxy::DataReductionProxyIOData(
-      data_reduction_proxy::Client::CRONET_ANDROID,
-      data_reduction_proxy::DataReductionProxyParams::kAllowed |
-          data_reduction_proxy::DataReductionProxyParams::kFallbackAllowed,
-      net_log, task_runner, task_runner, false, user_agent, std::string()));
+      data_reduction_proxy::Client::CRONET_ANDROID, 0, net_log, task_runner,
+      task_runner, false, user_agent, std::string()));
   io_data_->request_options()->SetKeyOnIO(key);
 }
 
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_decider.cc b/components/data_reduction_proxy/content/browser/content_lofi_decider.cc
index addf63b..fdecf63 100644
--- a/components/data_reduction_proxy/content/browser/content_lofi_decider.cc
+++ b/components/data_reduction_proxy/content/browser/content_lofi_decider.cc
@@ -86,6 +86,11 @@
   if (is_previews_disabled)
     return;
 
+  // Do not add the Chrome-Proxy-Accept-Transform header when the page load
+  // explicitly forbids previews transformations.
+  if (request_info->GetPreviewsState() & content::PREVIEWS_NO_TRANSFORM)
+    return;
+
   // LoFi is not allowed on the main frame, stylesheet, script, font resource,
   // media, service worker, or CSP report.
   bool resource_type_supports_empty_image =
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc b/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
index 09a1e1fa..8c806f1 100644
--- a/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
+++ b/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
@@ -97,14 +97,14 @@
 
   void AllocateRequestInfoForTesting(net::URLRequest* request,
                                      content::ResourceType resource_type,
-                                     bool is_using_lofi) {
+                                     content::PreviewsState previews_state) {
     content::ResourceRequestInfo::AllocateForTesting(
         request, resource_type, NULL, -1, -1, -1,
         resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
         false,  // parent_is_main_frame
         false,  // allow_download
         false,  // is_async
-        is_using_lofi ? content::SERVER_LOFI_ON : content::PREVIEWS_OFF);
+        previews_state);
   }
 
   std::unique_ptr<net::URLRequest> CreateRequest(bool is_main_frame,
@@ -114,7 +114,7 @@
     AllocateRequestInfoForTesting(
         request.get(), (is_main_frame ? content::RESOURCE_TYPE_MAIN_FRAME
                                       : content::RESOURCE_TYPE_SUB_FRAME),
-        is_using_lofi);
+        is_using_lofi ? content::SERVER_LOFI_ON : content::PREVIEWS_OFF);
     return request;
   }
 
@@ -126,7 +126,20 @@
         context_.CreateRequest(GURL(scheme_is_https ? "https://www.google.com/"
                                                     : "http://www.google.com/"),
                                net::IDLE, &delegate_);
-    AllocateRequestInfoForTesting(request.get(), resource_type, is_using_lofi);
+    AllocateRequestInfoForTesting(
+        request.get(), resource_type,
+        is_using_lofi ? content::SERVER_LOFI_ON : content::PREVIEWS_OFF);
+    return request;
+  }
+
+  std::unique_ptr<net::URLRequest> CreateNoTransformRequest(
+      bool is_main_frame) {
+    std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
+        GURL("http://www.google.com/"), net::IDLE, &delegate_);
+    AllocateRequestInfoForTesting(
+        request.get(), (is_main_frame ? content::RESOURCE_TYPE_MAIN_FRAME
+                                      : content::RESOURCE_TYPE_SUB_FRAME),
+        content::PREVIEWS_NO_TRANSFORM);
     return request;
   }
 
@@ -278,9 +291,10 @@
 
     // The Lo-Fi flag is "always-on" and Lo-Fi is being used. Lo-Fi header
     // should be added.
-    AllocateRequestInfoForTesting(request.get(),
-                                  content::RESOURCE_TYPE_SUB_FRAME,
-                                  tests[i].is_using_lofi);
+    AllocateRequestInfoForTesting(
+        request.get(), content::RESOURCE_TYPE_SUB_FRAME,
+        tests[i].is_using_lofi ? content::SERVER_LOFI_ON
+                               : content::PREVIEWS_OFF);
     headers.Clear();
     NotifyBeforeSendHeaders(&headers, request.get(), true);
     VerifyLoFiHeader(!tests[i].is_using_lite_page, !tests[i].is_using_lofi,
@@ -684,4 +698,14 @@
   EXPECT_EQ("Foo, exp=ignore_preview_blacklist", header_value);
 }
 
+TEST_F(ContentLoFiDeciderTest, NoTransformDoesNotAddHeader) {
+  base::FieldTrialList field_trial_list(nullptr);
+  base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
+                                         "Enabled");
+  std::unique_ptr<net::URLRequest> request = CreateNoTransformRequest(false);
+  net::HttpRequestHeaders headers;
+  NotifyBeforeSendHeaders(&headers, request.get(), true);
+  EXPECT_FALSE(headers.HasHeader(chrome_proxy_accept_transform_header()));
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/sync/model_impl/shared_model_type_processor.cc b/components/sync/model_impl/shared_model_type_processor.cc
index c3226ff..ef29ab96 100644
--- a/components/sync/model_impl/shared_model_type_processor.cc
+++ b/components/sync/model_impl/shared_model_type_processor.cc
@@ -28,18 +28,18 @@
   DCHECK(bridge);
 }
 
-SharedModelTypeProcessor::~SharedModelTypeProcessor() {}
+SharedModelTypeProcessor::~SharedModelTypeProcessor() = default;
 
 void SharedModelTypeProcessor::OnSyncStarting(
     const ModelErrorHandler& error_handler,
     const StartCallback& start_callback) {
   DCHECK(CalledOnValidThread());
-  DCHECK(start_callback_.is_null());
   DCHECK(!IsConnected());
   DCHECK(error_handler);
+  DCHECK(start_callback);
   DVLOG(1) << "Sync is starting for " << ModelTypeToString(type_);
 
-  error_handler_ = std::move(error_handler);
+  error_handler_ = error_handler;
   start_callback_ = start_callback;
   ConnectIfReady();
 }
@@ -47,15 +47,14 @@
 void SharedModelTypeProcessor::OnMetadataLoaded(
     std::unique_ptr<MetadataBatch> batch) {
   DCHECK(CalledOnValidThread());
+  DCHECK(waiting_for_metadata_);
   DCHECK(entities_.empty());
 
-  // An error occurred earlier in the model.
-  if (is_metadata_loaded_)
+  // The model already experienced an error; abort;
+  if (model_error_)
     return;
 
-  is_metadata_loaded_ = true;
-  // Flip this flag here to cover all cases where we don't need to load data.
-  is_initial_pending_data_loaded_ = true;
+  waiting_for_metadata_ = false;
 
   if (batch->GetModelTypeState().initial_sync_done()) {
     EntityMetadataMap metadata_map(batch->TakeAllMetadata());
@@ -73,9 +72,9 @@
     }
     model_type_state_ = batch->GetModelTypeState();
     if (!entities_to_commit.empty()) {
-      is_initial_pending_data_loaded_ = false;
+      waiting_for_pending_data_ = true;
       bridge_->GetData(
-          entities_to_commit,
+          std::move(entities_to_commit),
           base::Bind(&SharedModelTypeProcessor::OnInitialPendingDataLoaded,
                      weak_ptr_factory_.GetWeakPtr()));
     }
@@ -88,21 +87,17 @@
   ConnectIfReady();
 }
 
-bool SharedModelTypeProcessor::ConnectPreconditionsMet() const {
-  return is_metadata_loaded_ && is_initial_pending_data_loaded_ &&
-         !error_handler_.is_null();
+bool SharedModelTypeProcessor::IsModelReadyOrError() const {
+  return model_error_ || (!waiting_for_metadata_ && !waiting_for_pending_data_);
 }
 
 void SharedModelTypeProcessor::ConnectIfReady() {
-  DCHECK(CalledOnValidThread());
-  if (!ConnectPreconditionsMet()) {
+  if (!IsModelReadyOrError() || !start_callback_)
     return;
-  }
 
-  if (start_error_) {
-    error_handler_.Run(start_error_.value());
-    start_error_.reset();
-  } else if (start_callback_) {
+  if (model_error_) {
+    error_handler_.Run(model_error_.value());
+  } else {
     auto activation_context = base::MakeUnique<ActivationContext>();
     activation_context->model_type_state = model_type_state_;
     activation_context->type_processor =
@@ -111,11 +106,14 @@
             base::ThreadTaskRunnerHandle::Get());
     start_callback_.Run(std::move(activation_context));
   }
+
   start_callback_.Reset();
 }
 
 bool SharedModelTypeProcessor::IsAllowingChanges() const {
-  return is_metadata_loaded_;
+  DCHECK(CalledOnValidThread());
+  // Changes can be handled correctly even before pending data is loaded.
+  return !waiting_for_metadata_;
 }
 
 bool SharedModelTypeProcessor::IsConnected() const {
@@ -125,7 +123,6 @@
 
 void SharedModelTypeProcessor::DisableSync() {
   DCHECK(CalledOnValidThread());
-  DCHECK(is_metadata_loaded_);
   std::unique_ptr<MetadataChangeList> change_list =
       bridge_->CreateMetadataChangeList();
   for (auto it = entities_.begin(); it != entities_.end(); ++it) {
@@ -141,18 +138,21 @@
 }
 
 void SharedModelTypeProcessor::ReportError(const ModelError& error) {
-  if (ConnectPreconditionsMet()) {
-    // If both model and sync are ready, then |start_callback_| was already
-    // called and this can't be treated as a start error.
-    DCHECK(!error_handler_.is_null());
-    error_handler_.Run(error);
-  } else if (!start_error_) {
-    start_error_ = error;
-    // An early model error means we're no longer expecting OnMetadataLoaded to
-    // be called.
-    is_metadata_loaded_ = true;
-    is_initial_pending_data_loaded_ = true;
+  DCHECK(CalledOnValidThread());
+
+  // Ignore all errors after the first.
+  if (model_error_)
+    return;
+
+  model_error_ = error;
+
+  if (start_callback_) {
+    // Tell sync about the error instead of connecting.
     ConnectIfReady();
+  } else if (error_handler_) {
+    // Connecting was already initiated; just tell sync about the error instead
+    // of going through ConnectIfReady().
+    error_handler_.Run(error);
   }
 }
 
@@ -188,8 +188,9 @@
 void SharedModelTypeProcessor::Put(const std::string& storage_key,
                                    std::unique_ptr<EntityData> data,
                                    MetadataChangeList* metadata_change_list) {
+  DCHECK(CalledOnValidThread());
   DCHECK(IsAllowingChanges());
-  DCHECK(data.get());
+  DCHECK(data);
   DCHECK(!data->is_deleted());
   DCHECK(!data->non_unique_name.empty());
   DCHECK_EQ(type_, GetModelTypeFromSpecifics(data->specifics));
@@ -227,6 +228,7 @@
 void SharedModelTypeProcessor::Delete(
     const std::string& storage_key,
     MetadataChangeList* metadata_change_list) {
+  DCHECK(CalledOnValidThread());
   DCHECK(IsAllowingChanges());
 
   if (!model_type_state_.initial_sync_done()) {
@@ -277,6 +279,7 @@
 void SharedModelTypeProcessor::OnCommitCompleted(
     const sync_pb::ModelTypeState& type_state,
     const CommitResponseDataList& response_list) {
+  DCHECK(CalledOnValidThread());
   std::unique_ptr<MetadataChangeList> change_list =
       bridge_->CreateMetadataChangeList();
 
@@ -313,6 +316,7 @@
 void SharedModelTypeProcessor::OnUpdateReceived(
     const sync_pb::ModelTypeState& model_type_state,
     const UpdateResponseDataList& updates) {
+  DCHECK(CalledOnValidThread());
   if (!model_type_state_.initial_sync_done()) {
     OnInitialUpdateReceived(model_type_state, updates);
     return;
@@ -522,7 +526,7 @@
 
   if (!entities_needing_data.empty()) {
     bridge_->GetData(
-        entities_needing_data,
+        std::move(entities_needing_data),
         base::Bind(&SharedModelTypeProcessor::OnDataLoadedForReEncryption,
                    weak_ptr_factory_.GetWeakPtr()));
   }
@@ -571,19 +575,23 @@
 
 void SharedModelTypeProcessor::OnInitialPendingDataLoaded(
     std::unique_ptr<DataBatch> data_batch) {
-  // An error occurred before this callback.
-  if (is_initial_pending_data_loaded_)
+  DCHECK(CalledOnValidThread());
+  DCHECK(waiting_for_pending_data_);
+
+  // The model already experienced an error; abort;
+  if (model_error_)
     return;
 
   ConsumeDataBatch(std::move(data_batch));
-  is_initial_pending_data_loaded_ = true;
+  waiting_for_pending_data_ = false;
 
   ConnectIfReady();
 }
 
 void SharedModelTypeProcessor::OnDataLoadedForReEncryption(
     std::unique_ptr<DataBatch> data_batch) {
-  DCHECK(is_initial_pending_data_loaded_);
+  DCHECK(CalledOnValidThread());
+  DCHECK(!waiting_for_pending_data_);
 
   ConsumeDataBatch(std::move(data_batch));
   FlushPendingCommitRequests();
diff --git a/components/sync/model_impl/shared_model_type_processor.h b/components/sync/model_impl/shared_model_type_processor.h
index b0e7de77..68c8bcd 100644
--- a/components/sync/model_impl/shared_model_type_processor.h
+++ b/components/sync/model_impl/shared_model_type_processor.h
@@ -27,6 +27,7 @@
 #include "components/sync/protocol/sync.pb.h"
 
 namespace syncer {
+
 class CommitQueue;
 class ProcessorEntityTracker;
 
@@ -73,13 +74,8 @@
   friend class ModelTypeDebugInfo;
   friend class SharedModelTypeProcessorTest;
 
-  using EntityMap =
-      std::map<std::string, std::unique_ptr<ProcessorEntityTracker>>;
-  using UpdateMap = std::map<std::string, std::unique_ptr<UpdateResponseData>>;
-
-  // Whether the preconditions to connect are met. Note: returns true if we have
-  // already connected.
-  bool ConnectPreconditionsMet() const;
+  // Returns true if the model is ready or encountered an error.
+  bool IsModelReadyOrError() const;
 
   // If preconditions are met, inform sync that we are ready to connect.
   void ConnectIfReady();
@@ -146,15 +142,16 @@
   // Stores the start callback in between OnSyncStarting() and ReadyToConnect().
   StartCallback start_callback_;
 
-  // A cache for any error that may occur during startup and should be passed
-  // into the |start_callback_|.
-  base::Optional<ModelError> start_error_;
+  // The first model error that occurred, if any. Stored to track model state
+  // and so it can be passed to sync if it happened prior to sync being ready.
+  base::Optional<ModelError> model_error_;
 
-  // Indicates whether the metadata has finished loading.
-  bool is_metadata_loaded_ = false;
+  // Whether we're waiting for the model to provide metadata.
+  bool waiting_for_metadata_ = true;
 
-  // Indicates whether data for any initial pending commits has been loaded.
-  bool is_initial_pending_data_loaded_ = false;
+  // Whether we're waiting for the model to provide initial commit data. Starts
+  // as false but will be set to true if we detect it's necessary to load data.
+  bool waiting_for_pending_data_ = false;
 
   // Reference to the CommitQueue.
   //
@@ -166,7 +163,7 @@
   // A map of client tag hash to sync entities known to this processor. This
   // should contain entries and metadata for most everything, although the
   // entities may not always contain model type data/specifics.
-  EntityMap entities_;
+  std::map<std::string, std::unique_ptr<ProcessorEntityTracker>> entities_;
 
   // The bridge wants to communicate entirely via storage keys that is free to
   // define and can understand more easily. All of the sync machinery wants to
diff --git a/components/sync/model_impl/shared_model_type_processor_unittest.cc b/components/sync/model_impl/shared_model_type_processor_unittest.cc
index 76b4065..118c4d4 100644
--- a/components/sync/model_impl/shared_model_type_processor_unittest.cc
+++ b/components/sync/model_impl/shared_model_type_processor_unittest.cc
@@ -71,7 +71,7 @@
   }
 
   void OnPendingCommitDataLoaded() {
-    DCHECK(!data_callback_.is_null());
+    ASSERT_TRUE(data_callback_);
     data_callback_.Run();
     data_callback_.Reset();
   }
@@ -88,6 +88,9 @@
     db_->set_model_type_state(model_type_state);
   }
 
+  // Expect a GetData call in the future and return its data immediately.
+  void ExpectSynchronousDataCallback() { synchronous_data_callback_ = true; }
+
   int merge_call_count() const { return merge_call_count_; }
 
   // FakeModelTypeSyncBridge overrides.
@@ -101,14 +104,20 @@
   }
 
   void GetData(StorageKeyList keys, DataCallback callback) override {
-    FakeModelTypeSyncBridge::GetData(
-        keys, base::Bind(&TestModelTypeSyncBridge::CaptureDataCallback,
-                         base::Unretained(this), callback));
+    if (synchronous_data_callback_) {
+      synchronous_data_callback_ = false;
+      FakeModelTypeSyncBridge::GetData(keys, callback);
+    } else {
+      FakeModelTypeSyncBridge::GetData(
+          keys, base::Bind(&TestModelTypeSyncBridge::CaptureDataCallback,
+                           base::Unretained(this), callback));
+    }
   }
 
   void CheckPostConditions() override {
     FakeModelTypeSyncBridge::CheckPostConditions();
-    DCHECK(data_callback_.is_null());
+    EXPECT_FALSE(synchronous_data_callback_);
+    EXPECT_FALSE(data_callback_);
   }
 
  private:
@@ -122,6 +131,10 @@
 
   // Stores the data callback between GetData() and OnPendingCommitDataLoaded().
   base::Closure data_callback_;
+
+  // Whether to return GetData results synchronously. Overrides the default
+  // callback capture behavior if set to true.
+  bool synchronous_data_callback_ = false;
 };
 
 }  // namespace
@@ -531,6 +544,25 @@
   worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics);
 }
 
+// Tests cases where pending data loads synchronously.
+TEST_F(SharedModelTypeProcessorTest, LoadPendingSynchronous) {
+  // Model, sync.
+  EntitySpecifics specifics1 = ResetStateWriteItem(kKey1, kValue1);
+  bridge()->ExpectSynchronousDataCallback();
+  InitializeToMetadataLoaded();
+  OnSyncStarting();
+  EXPECT_EQ(1U, worker()->GetNumPendingCommits());
+  worker()->ExpectNthPendingCommit(0, kHash1, specifics1);
+
+  // Sync, model.
+  EntitySpecifics specifics2 = ResetStateWriteItem(kKey1, kValue1);
+  OnSyncStarting();
+  bridge()->ExpectSynchronousDataCallback();
+  InitializeToMetadataLoaded();
+  EXPECT_EQ(1U, worker()->GetNumPendingCommits());
+  worker()->ExpectNthPendingCommit(0, kHash1, specifics2);
+}
+
 // This test covers race conditions during loading a pending delete. All cases
 // start with no processor and one item with a pending delete. There are two
 // different events that can occur in any order once metadata is loaded, since
diff --git a/components/user_manager/user.cc b/components/user_manager/user.cc
index 19fe85c..11aba12 100644
--- a/components/user_manager/user.cc
+++ b/components/user_manager/user.cc
@@ -59,6 +59,7 @@
   ~ActiveDirectoryUser() override;
   // Overridden from User:
   UserType GetType() const override;
+  bool CanSyncImage() const override;
 };
 
 class GuestUser : public User {
@@ -289,6 +290,10 @@
   return user_manager::USER_TYPE_ACTIVE_DIRECTORY;
 }
 
+bool ActiveDirectoryUser::CanSyncImage() const {
+  return false;
+}
+
 RegularUser::RegularUser(const AccountId& account_id) : User(account_id) {
   set_can_lock(true);
   set_display_email(account_id.GetUserEmail());
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
index 49c4809..611d3d1 100644
--- a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
+++ b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
@@ -79,8 +79,11 @@
 bool BluetoothDeviceChooserController::use_test_scan_duration_ = false;
 
 namespace {
-constexpr size_t kMaxLengthForDeviceName =
-    29;  // max length of device name in filter.
+// Max length of device name in filter. A name coming from an adv packet
+// is max 29 bytes (adv packet max size 31 bytes - 2 byte length field),
+// but the name can also be acquired via gap.device_name, so it is limited
+// to the max EIR packet size of 240 bytes. See Core Spec 5.0, vol 3, C, 8.1.2.
+constexpr size_t kMaxLengthForDeviceName = 240;
 
 // The duration of a Bluetooth Scan in seconds.
 constexpr int kScanDuration = 60;
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 7a80a112..4483572 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -341,7 +341,7 @@
                      ->last_navigation_previews_state();
   } else if (reload_type == ReloadType::DISABLE_LOFI_MODE) {
     // Disable LoFi when asked for it explicitly.
-    previews_state = PREVIEWS_OFF;
+    previews_state = PREVIEWS_NO_TRANSFORM;
   }
 
   // PlzNavigate: the RenderFrameHosts are no longer asked to navigate.
diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc
index f7268195..a3a707d 100644
--- a/content/browser/indexed_db/indexed_db_callbacks.cc
+++ b/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -76,15 +76,6 @@
   return mojo_value;
 }
 
-// Destructively converts an IndexedDBValue to a Mojo Value.
-::indexed_db::mojom::ValuePtr ConvertValue(IndexedDBValue* value) {
-  auto mojo_value = ::indexed_db::mojom::Value::New();
-  if (!value->empty())
-    swap(mojo_value->bits, value->bits);
-  ConvertBlobInfo(value->blob_info, &mojo_value->blob_or_file_info);
-  return mojo_value;
-}
-
 }  // namespace
 
 class IndexedDBCallbacks::IOThreadHelper {
@@ -140,6 +131,16 @@
   DISALLOW_COPY_AND_ASSIGN(IOThreadHelper);
 };
 
+// static
+::indexed_db::mojom::ValuePtr IndexedDBCallbacks::ConvertAndEraseValue(
+    IndexedDBValue* value) {
+  auto mojo_value = ::indexed_db::mojom::Value::New();
+  if (!value->empty())
+    swap(mojo_value->bits, value->bits);
+  ConvertBlobInfo(value->blob_info, &mojo_value->blob_or_file_info);
+  return mojo_value;
+}
+
 IndexedDBCallbacks::IndexedDBCallbacks(
     scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
     const url::Origin& origin,
@@ -291,7 +292,7 @@
   ::indexed_db::mojom::ValuePtr mojo_value;
   std::vector<IndexedDBBlobInfo> blob_info;
   if (value) {
-    mojo_value = ConvertValue(value);
+    mojo_value = ConvertAndEraseValue(value);
     blob_info.swap(value->blob_info);
   }
 
@@ -316,7 +317,7 @@
   ::indexed_db::mojom::ValuePtr mojo_value;
   std::vector<IndexedDBBlobInfo> blob_info;
   if (value) {
-    mojo_value = ConvertValue(value);
+    mojo_value = ConvertAndEraseValue(value);
     blob_info.swap(value->blob_info);
   }
 
@@ -343,7 +344,7 @@
   std::vector<::indexed_db::mojom::ValuePtr> mojo_values;
   mojo_values.reserve(values->size());
   for (size_t i = 0; i < values->size(); ++i)
-    mojo_values.push_back(ConvertValue(&(*values)[i]));
+    mojo_values.push_back(ConvertAndEraseValue(&(*values)[i]));
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
diff --git a/content/browser/indexed_db/indexed_db_callbacks.h b/content/browser/indexed_db/indexed_db_callbacks.h
index aa3cc0c3..b72fc60 100644
--- a/content/browser/indexed_db/indexed_db_callbacks.h
+++ b/content/browser/indexed_db/indexed_db_callbacks.h
@@ -35,6 +35,10 @@
 class CONTENT_EXPORT IndexedDBCallbacks
     : public base::RefCounted<IndexedDBCallbacks> {
  public:
+  // Destructively converts an IndexedDBValue to a Mojo Value.
+  static ::indexed_db::mojom::ValuePtr ConvertAndEraseValue(
+      IndexedDBValue* value);
+
   IndexedDBCallbacks(
       scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
       const url::Origin& origin,
diff --git a/content/browser/indexed_db/indexed_db_connection.cc b/content/browser/indexed_db/indexed_db_connection.cc
index 216786a..6e72e36 100644
--- a/content/browser/indexed_db/indexed_db_connection.cc
+++ b/content/browser/indexed_db/indexed_db_connection.cc
@@ -158,4 +158,12 @@
   transactions_.erase(id);
 }
 
+int64_t IndexedDBConnection::NewObserverTransactionId() {
+  // When we overflow to 0, reset the ID to 1 (id of 0 is reserved for upgrade
+  // transactions).
+  if (next_observer_transaction_id_ == 0)
+    next_observer_transaction_id_ = 1;
+  return static_cast<int64_t>(next_observer_transaction_id_++) << 32;
+}
+
 }  // namespace content
diff --git a/content/browser/indexed_db/indexed_db_connection.h b/content/browser/indexed_db/indexed_db_connection.h
index 20acb7b..e69119557 100644
--- a/content/browser/indexed_db/indexed_db_connection.h
+++ b/content/browser/indexed_db/indexed_db_connection.h
@@ -77,9 +77,19 @@
   // TODO(dmurph): Change that so this doesn't need to ignore unknown ids.
   void RemoveTransaction(int64_t id);
 
+  // Returns a new transaction id for an observer transaction.
+  // Unique per connection.
+  int64_t NewObserverTransactionId();
+
  private:
   const int32_t id_;
 
+  // The renderer-created transactions are in the right 32 bits of the
+  // transaction id, and the observer (browser-created) transactions are in the
+  // left 32 bits.
+  // This keeps track of the left 32 bits. Unsigned for defined overflow.
+  uint32_t next_observer_transaction_id_ = 1;
+
   // The process id of the child process this connection is associated with.
   // Tracked for IndexedDBContextImpl::GetAllOriginsDetails and debugging.
   const int child_process_id_;
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index 84d3a89d..1b266ef 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -800,12 +800,11 @@
   transaction->AddPendingObserver(observer_id, options);
 }
 
-// TODO(palakj): Augment the function with IDBValue later. Issue
-// crbug.com/609934.
 void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction,
                                           int64_t object_store_id,
                                           blink::WebIDBOperationType type,
-                                          const IndexedDBKeyRange& key_range) {
+                                          const IndexedDBKeyRange& key_range,
+                                          const IndexedDBValue* value) {
   for (auto* connection : connections_) {
     bool recorded = false;
     for (const auto& observer : connection->active_observers()) {
@@ -821,8 +820,28 @@
         transaction->AddObservation(connection->id(), std::move(observation));
         recorded = true;
       }
-      transaction->RecordObserverForLastObservation(connection->id(),
-                                                    observer->id());
+      ::indexed_db::mojom::ObserverChangesPtr& changes =
+          *transaction->GetPendingChangesForConnection(connection->id());
+
+      changes->observation_index_map[observer->id()].push_back(
+          changes->observations.size() - 1);
+      if (observer->include_transaction() &&
+          !base::ContainsKey(changes->transaction_map, observer->id())) {
+        auto mojo_transaction = ::indexed_db::mojom::ObserverTransaction::New();
+        mojo_transaction->id = connection->NewObserverTransactionId();
+        mojo_transaction->scope.insert(mojo_transaction->scope.end(),
+                                       observer->object_store_ids().begin(),
+                                       observer->object_store_ids().end());
+        changes->transaction_map[observer->id()] = std::move(mojo_transaction);
+      }
+      if (value && observer->values() && !changes->observations.back()->value) {
+        // TODO(dmurph): Avoid any and all IndexedDBValue copies. Perhaps defer
+        // this until the end of the transaction, where we can safely erase the
+        // indexeddb value. crbug.com/682363
+        IndexedDBValue copy = *value;
+        changes->observations.back()->value =
+            IndexedDBCallbacks::ConvertAndEraseValue(&copy);
+      }
     }
   }
 }
@@ -831,8 +850,25 @@
     std::map<int32_t, ::indexed_db::mojom::ObserverChangesPtr> changes_map) {
   for (auto* conn : connections_) {
     auto it = changes_map.find(conn->id());
-    if (it != changes_map.end())
-      conn->callbacks()->OnDatabaseChange(std::move(it->second));
+    if (it == changes_map.end())
+      continue;
+
+    // Start all of the transactions.
+    ::indexed_db::mojom::ObserverChangesPtr& changes = it->second;
+    for (const auto& transaction_pair : changes->transaction_map) {
+      std::set<int64_t> scope(transaction_pair.second->scope.begin(),
+                              transaction_pair.second->scope.end());
+      IndexedDBTransaction* transaction = conn->CreateTransaction(
+          transaction_pair.second->id, scope,
+          blink::WebIDBTransactionModeReadOnly,
+          new IndexedDBBackingStore::Transaction(backing_store_.get()));
+      DCHECK(transaction);
+      transaction_coordinator_.DidCreateObserverTransaction(transaction);
+      transaction_count_++;
+      transaction->GrabSnapshotThenStart();
+    }
+
+    conn->callbacks()->OnDatabaseChange(std::move(it->second));
   }
 }
 
@@ -1336,7 +1372,7 @@
                     params->put_mode == blink::WebIDBPutModeAddOnly
                         ? blink::WebIDBAdd
                         : blink::WebIDBPut,
-                    IndexedDBKeyRange(*key));
+                    IndexedDBKeyRange(*key), &params->value);
   return s;
 }
 
@@ -1650,7 +1686,7 @@
     return s;
   callbacks->OnSuccess();
   FilterObservation(transaction, object_store_id, blink::WebIDBDelete,
-                    *key_range);
+                    *key_range, nullptr);
   return s;
 }
 
@@ -1680,7 +1716,7 @@
   callbacks->OnSuccess();
 
   FilterObservation(transaction, object_store_id, blink::WebIDBClear,
-                    IndexedDBKeyRange());
+                    IndexedDBKeyRange(), nullptr);
   return s;
 }
 
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index df26126..3a40282a 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -139,10 +139,12 @@
                           int32_t observer_id,
                           const IndexedDBObserver::Options& options);
 
+  // |value| can be null for delete and clear operations.
   void FilterObservation(IndexedDBTransaction*,
                          int64_t object_store_id,
                          blink::WebIDBOperationType type,
-                         const IndexedDBKeyRange& key_range);
+                         const IndexedDBKeyRange& key_range,
+                         const IndexedDBValue* value);
   void SendObservations(
       std::map<int32_t, ::indexed_db::mojom::ObserverChangesPtr> change_map);
 
diff --git a/content/browser/indexed_db/indexed_db_observer.h b/content/browser/indexed_db/indexed_db_observer.h
index 2d8f23b7..f183884 100644
--- a/content/browser/indexed_db/indexed_db_observer.h
+++ b/content/browser/indexed_db/indexed_db_observer.h
@@ -44,6 +44,10 @@
     return object_store_ids_;
   }
 
+  void set_object_store_ids(std::set<int64_t> ids) {
+    object_store_ids_ = std::move(ids);
+  }
+
   bool IsRecordingType(blink::WebIDBOperationType type) const {
     DCHECK_NE(type, blink::WebIDBOperationTypeCount);
     return options_.operation_types[type];
diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc
index 975a14e..6c6d4c7 100644
--- a/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -226,6 +226,13 @@
   RunTasksIfStarted();
 }
 
+void IndexedDBTransaction::GrabSnapshotThenStart() {
+  DCHECK(!backing_store_transaction_begun_);
+  transaction_->Begin();
+  backing_store_transaction_begun_ = true;
+  Start();
+}
+
 class BlobWriteCallbackImpl : public IndexedDBBackingStore::BlobWriteCallback {
  public:
   explicit BlobWriteCallbackImpl(
@@ -363,10 +370,8 @@
           "txn.id", id());
       callbacks_->OnComplete(*this);
     }
-    if (!pending_observers_.empty() && connection_) {
+    if (!pending_observers_.empty() && connection_)
       connection_->ActivatePendingObservers(std::move(pending_observers_));
-      pending_observers_.clear();
-    }
 
     database_->TransactionFinished(this, true);
     // RemoveTransaction will delete |this|.
@@ -481,6 +486,7 @@
 void IndexedDBTransaction::AddPendingObserver(
     int32_t observer_id,
     const IndexedDBObserver::Options& options) {
+  DCHECK_NE(mode(), blink::WebIDBTransactionModeVersionChange);
   pending_observers_.push_back(base::MakeUnique<IndexedDBObserver>(
       observer_id, object_store_ids_, options));
 }
@@ -509,13 +515,12 @@
   it->second->observations.push_back(std::move(observation));
 }
 
-void IndexedDBTransaction::RecordObserverForLastObservation(
-    int32_t connection_id,
-    int32_t observer_id) {
+::indexed_db::mojom::ObserverChangesPtr*
+IndexedDBTransaction::GetPendingChangesForConnection(int32_t connection_id) {
   auto it = connection_changes_map_.find(connection_id);
-  DCHECK(it != connection_changes_map_.end());
-  it->second->observation_index_map[observer_id].push_back(
-      it->second->observations.size() - 1);
+  if (it != connection_changes_map_.end())
+    return &it->second;
+  return nullptr;
 }
 
 }  // namespace content
diff --git a/content/browser/indexed_db/indexed_db_transaction.h b/content/browser/indexed_db/indexed_db_transaction.h
index 8315eb2..7155b4e 100644
--- a/content/browser/indexed_db/indexed_db_transaction.h
+++ b/content/browser/indexed_db/indexed_db_transaction.h
@@ -23,6 +23,7 @@
 #include "content/browser/indexed_db/indexed_db_database.h"
 #include "content/browser/indexed_db/indexed_db_database_error.h"
 #include "content/browser/indexed_db/indexed_db_observer.h"
+#include "content/common/indexed_db/indexed_db.mojom.h"
 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h"
 
 namespace content {
@@ -55,6 +56,10 @@
   // Called by the transaction coordinator when this transaction is unblocked.
   void Start();
 
+  // Grabs a snapshot from the database immediately, then starts the
+  // transaction.
+  void GrabSnapshotThenStart();
+
   blink::WebIDBTransactionMode mode() const { return mode_; }
   const std::set<int64_t>& scope() const { return object_store_ids_; }
 
@@ -79,10 +84,9 @@
   // Adds observation for the connection.
   void AddObservation(int32_t connection_id,
                       ::indexed_db::mojom::ObservationPtr observation);
-  // Adds the last observation index to observer_id's list of recorded
-  // observation indices.
-  void RecordObserverForLastObservation(int32_t connection_id,
-                                        int32_t observer_id);
+
+  ::indexed_db::mojom::ObserverChangesPtr* GetPendingChangesForConnection(
+      int32_t connection_id);
 
   IndexedDBBackingStore::Transaction* BackingStoreTransaction() {
     return transaction_.get();
diff --git a/content/browser/indexed_db/indexed_db_transaction_coordinator.cc b/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
index 68e0172..8034530 100644
--- a/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
+++ b/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
@@ -27,6 +27,17 @@
   ProcessQueuedTransactions();
 }
 
+// Observer transactions jump to the front of the queue.
+void IndexedDBTransactionCoordinator::DidCreateObserverTransaction(
+    IndexedDBTransaction* transaction) {
+  DCHECK(!queued_transactions_.count(transaction));
+  DCHECK(!started_transactions_.count(transaction));
+  DCHECK_EQ(IndexedDBTransaction::CREATED, transaction->state());
+
+  started_transactions_.insert_front(transaction);
+  ProcessQueuedTransactions();
+}
+
 void IndexedDBTransactionCoordinator::DidFinishTransaction(
     IndexedDBTransaction* transaction) {
   if (queued_transactions_.count(transaction)) {
diff --git a/content/browser/indexed_db/indexed_db_transaction_coordinator.h b/content/browser/indexed_db/indexed_db_transaction_coordinator.h
index 865ddc7c..357b464e 100644
--- a/content/browser/indexed_db/indexed_db_transaction_coordinator.h
+++ b/content/browser/indexed_db/indexed_db_transaction_coordinator.h
@@ -14,19 +14,21 @@
 
 #include "base/macros.h"
 #include "content/browser/indexed_db/list_set.h"
+#include "content/common/content_export.h"
 
 namespace content {
 
 class IndexedDBTransaction;
 
 // Transactions are executed in the order the were created.
-class IndexedDBTransactionCoordinator {
+class CONTENT_EXPORT IndexedDBTransactionCoordinator {
  public:
   IndexedDBTransactionCoordinator();
   ~IndexedDBTransactionCoordinator();
 
   // Called by transactions as they start and finish.
   void DidCreateTransaction(IndexedDBTransaction* transaction);
+  void DidCreateObserverTransaction(IndexedDBTransaction* transaction);
   void DidFinishTransaction(IndexedDBTransaction* transaction);
 
   bool IsRunningVersionChangeTransaction() const;
@@ -39,6 +41,8 @@
   std::vector<const IndexedDBTransaction*> GetTransactions() const;
 
  private:
+  friend class IndexedDBTransactionCoordinatorTest;
+
   void ProcessQueuedTransactions();
   bool CanStartTransaction(IndexedDBTransaction* const transaction,
                            const std::set<int64_t>& locked_scope) const;
diff --git a/content/browser/indexed_db/list_set.h b/content/browser/indexed_db/list_set.h
index ab46af20..3bbd34d 100644
--- a/content/browser/indexed_db/list_set.h
+++ b/content/browser/indexed_db/list_set.h
@@ -33,6 +33,13 @@
     return *this;
   }
 
+  void insert_front(const T& elem) {
+    if (set_.find(elem) != set_.end())
+      return;
+    set_.insert(elem);
+    list_.push_front(elem);
+  }
+
   void insert(const T& elem) {
     if (set_.find(elem) != set_.end())
       return;
diff --git a/content/browser/indexed_db/list_set_unittest.cc b/content/browser/indexed_db/list_set_unittest.cc
index 64248664..b5b7145 100644
--- a/content/browser/indexed_db/list_set_unittest.cc
+++ b/content/browser/indexed_db/list_set_unittest.cc
@@ -50,6 +50,23 @@
   EXPECT_EQ(ref.end(), it);
 }
 
+TEST(ListSetTest, ListSetInsertFront) {
+  list_set<int> set;
+  for (int i = 5; i > 0; --i)
+    set.insert(i);
+  for (int i = 6; i <= 10; ++i)
+    set.insert_front(i);
+
+  const list_set<int>& ref = set;
+
+  list_set<int>::const_iterator it = ref.begin();
+  for (int i = 10; i > 0; --i) {
+    EXPECT_EQ(i, *it);
+    ++it;
+  }
+  EXPECT_EQ(ref.end(), it);
+}
+
 TEST(ListSetTest, ListSetPrimitive) {
   list_set<int> set;
   EXPECT_TRUE(set.empty());
diff --git a/content/browser/loader/resource_dispatcher_host_browsertest.cc b/content/browser/loader/resource_dispatcher_host_browsertest.cc
index d8b5847..729e82e 100644
--- a/content/browser/loader/resource_dispatcher_host_browsertest.cc
+++ b/content/browser/loader/resource_dispatcher_host_browsertest.cc
@@ -800,7 +800,7 @@
   CheckResourcesRequested(true);
 
   // Reload with Lo-Fi disabled.
-  Reset(PREVIEWS_OFF);
+  Reset(PREVIEWS_NO_TRANSFORM);
   TestNavigationObserver tab_observer(shell()->web_contents(), 1);
   shell()->web_contents()->GetController().Reload(ReloadType::DISABLE_LOFI_MODE,
                                                   true);
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc
index 18a0934..5476991 100644
--- a/content/browser/media/capture/desktop_capture_device.cc
+++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -201,6 +201,7 @@
     webrtc::DesktopCapturer::Result result,
     std::unique_ptr<webrtc::DesktopFrame> frame) {
   DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(client_);
   DCHECK(capture_in_progress_);
   capture_in_progress_ = false;
 
@@ -224,9 +225,6 @@
   }
   DCHECK(frame);
 
-  if (!client_)
-    return;
-
   base::TimeDelta capture_time(
       base::TimeDelta::FromMilliseconds(frame->capture_time_ms()));
 
diff --git a/content/child/indexed_db/indexed_db_callbacks_impl.cc b/content/child/indexed_db/indexed_db_callbacks_impl.cc
index 845dc54..35c0dc1 100644
--- a/content/child/indexed_db/indexed_db_callbacks_impl.cc
+++ b/content/child/indexed_db/indexed_db_callbacks_impl.cc
@@ -65,8 +65,19 @@
     ConvertObjectStoreMetadata(iter.second, &output->objectStores[i++]);
 }
 
-void ConvertValue(const indexed_db::mojom::ValuePtr& value,
-                  WebIDBValue* web_value) {
+void ConvertReturnValue(const indexed_db::mojom::ReturnValuePtr& value,
+                        WebIDBValue* web_value) {
+  IndexedDBCallbacksImpl::ConvertValue(value->value, web_value);
+  web_value->primaryKey = WebIDBKeyBuilder::Build(value->primary_key);
+  web_value->keyPath = WebIDBKeyPathBuilder::Build(value->key_path);
+}
+
+}  // namespace
+
+// static
+void IndexedDBCallbacksImpl::ConvertValue(
+    const indexed_db::mojom::ValuePtr& value,
+    WebIDBValue* web_value) {
   if (value->bits.empty())
     return;
 
@@ -92,14 +103,6 @@
   web_value->webBlobInfo.swap(local_blob_info);
 }
 
-void ConvertReturnValue(const indexed_db::mojom::ReturnValuePtr& value,
-                        WebIDBValue* web_value) {
-  ConvertValue(value->value, web_value);
-  web_value->primaryKey = WebIDBKeyBuilder::Build(value->primary_key);
-  web_value->keyPath = WebIDBKeyPathBuilder::Build(value->key_path);
-}
-
-}  // namespace
 
 IndexedDBCallbacksImpl::IndexedDBCallbacksImpl(
     std::unique_ptr<WebIDBCallbacks> callbacks,
@@ -301,7 +304,7 @@
     indexed_db::mojom::ValuePtr value) {
   WebIDBValue web_value;
   if (value)
-    ConvertValue(value, &web_value);
+    IndexedDBCallbacksImpl::ConvertValue(value, &web_value);
 
   WebIDBCursorImpl* cursor =
       new WebIDBCursorImpl(std::move(cursor_info), transaction_id_, io_runner_);
diff --git a/content/child/indexed_db/indexed_db_callbacks_impl.h b/content/child/indexed_db/indexed_db_callbacks_impl.h
index 7b98c65f..6d695e73 100644
--- a/content/child/indexed_db/indexed_db_callbacks_impl.h
+++ b/content/child/indexed_db/indexed_db_callbacks_impl.h
@@ -10,6 +10,7 @@
 
 namespace blink {
 class WebIDBCallbacks;
+struct WebIDBValue;
 }
 
 namespace content {
@@ -68,6 +69,9 @@
     DISALLOW_COPY_AND_ASSIGN(InternalState);
   };
 
+  static void ConvertValue(const indexed_db::mojom::ValuePtr& value,
+                           blink::WebIDBValue* web_value);
+
   IndexedDBCallbacksImpl(std::unique_ptr<blink::WebIDBCallbacks> callbacks,
                          int64_t transaction_id,
                          const base::WeakPtr<WebIDBCursorImpl>& cursor,
diff --git a/content/child/indexed_db/indexed_db_database_callbacks_impl.cc b/content/child/indexed_db/indexed_db_database_callbacks_impl.cc
index 24b8f694..0d5edee 100644
--- a/content/child/indexed_db/indexed_db_database_callbacks_impl.cc
+++ b/content/child/indexed_db/indexed_db_database_callbacks_impl.cc
@@ -4,7 +4,11 @@
 
 #include "content/child/indexed_db/indexed_db_database_callbacks_impl.h"
 
+#include <unordered_map>
+#include <utility>
+
 #include "base/threading/thread_task_runner_handle.h"
+#include "content/child/indexed_db/indexed_db_callbacks_impl.h"
 #include "content/child/indexed_db/indexed_db_dispatcher.h"
 #include "content/child/indexed_db/indexed_db_key_builders.h"
 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h"
@@ -41,10 +45,26 @@
     web_observation.type = observation->type;
     web_observation.keyRange =
         WebIDBKeyRangeBuilder::Build(observation->key_range);
-    // TODO(palakj): Assign value to web_observation.
+    if (observation->value) {
+      IndexedDBCallbacksImpl::ConvertValue(observation->value,
+                                           &web_observation.value);
+    }
     web_observations.push_back(std::move(web_observation));
   }
-  callbacks->onChanges(changes->observation_index_map, web_observations);
+  std::unordered_map<int32_t, std::pair<int64_t, std::vector<int64_t>>>
+      observer_transactions;
+
+  for (const auto& transaction_pair : changes->transaction_map) {
+    std::pair<int64_t, std::vector<int64_t>>& obs_txn =
+        observer_transactions[transaction_pair.first];
+    obs_txn.first = transaction_pair.second->id;
+    for (int64_t scope : transaction_pair.second->scope) {
+      obs_txn.second.push_back(scope);
+    }
+  }
+
+  callbacks->onChanges(changes->observation_index_map, web_observations,
+                       observer_transactions);
 }
 
 }  // namespace
diff --git a/content/common/indexed_db/indexed_db.mojom b/content/common/indexed_db/indexed_db.mojom
index 89f3bda..60d02d9 100644
--- a/content/common/indexed_db/indexed_db.mojom
+++ b/content/common/indexed_db/indexed_db.mojom
@@ -148,10 +148,17 @@
   int64 object_store_id;
   OperationType type;
   KeyRange key_range;
+  Value? value;
+};
+
+struct ObserverTransaction {
+  int64 id;
+  array<int64> scope;
 };
 
 struct ObserverChanges {
   map<int32, array<int32>> observation_index_map;
+  map<int32, ObserverTransaction> transaction_map;
   array<Observation> observations;
 };
 
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 0fd4428..6fc00c0 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -177,8 +177,14 @@
 
 // If Pepper 3D Image Chromium is allowed, this feature controls whether it is
 // enabled.
-const base::Feature kPepper3DImageChromium{"Pepper3DImageChromium",
-                                           base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kPepper3DImageChromium {
+  "Pepper3DImageChromium",
+#if defined(OS_MACOSX)
+      base::FEATURE_ENABLED_BY_DEFAULT
+#else
+      base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
 
 // Throttle Blink's rendering pipeline based on frame visibility.
 const base::Feature kRenderingPipelineThrottling{
diff --git a/content/public/common/previews_state.h b/content/public/common/previews_state.h
index ea839e3..5c887448 100644
--- a/content/public/common/previews_state.h
+++ b/content/public/common/previews_state.h
@@ -19,14 +19,17 @@
 // content of web pages to improve data savings and / or performance. This enum
 // determines which Previews types to request.
 enum PreviewsState {
-  PREVIEWS_UNSPECIFIED = 0,  // Let the browser process decide whether or
-                             // not to request Preview types.
-  SERVER_LOFI_ON = 1 << 0,   // Request a Lo-Fi version of the resource
-                             // from the server.
-  CLIENT_LOFI_ON = 1 << 1,   // Request a Lo-Fi version of the resource
-                             // from the client.
-  PREVIEWS_OFF = 1 << 2,     // Request a normal (non-Preview) version of
-                             // the resource.
+  PREVIEWS_UNSPECIFIED = 0,        // Let the browser process decide whether or
+                                   // not to request Preview types.
+  SERVER_LOFI_ON = 1 << 0,         // Request a Lo-Fi version of the resource
+                                   // from the server.
+  CLIENT_LOFI_ON = 1 << 1,         // Request a Lo-Fi version of the resource
+                                   // from the client.
+  PREVIEWS_NO_TRANSFORM = 1 << 2,  // Explicitly forbid Previews
+                                   // transformations.
+  PREVIEWS_OFF = 1 << 3,           // Request a normal (non-Preview) version of
+                                   // the resource. Server transformations may
+                                   // still happen if the page is heavy.
   PREVIEWS_STATE_LAST = PREVIEWS_OFF
 };
 
@@ -36,6 +39,8 @@
                             blink::WebURLRequest::PreviewsUnspecified);
 STATIC_ASSERT_PREVIEWS_ENUM(SERVER_LOFI_ON, blink::WebURLRequest::ServerLoFiOn);
 STATIC_ASSERT_PREVIEWS_ENUM(CLIENT_LOFI_ON, blink::WebURLRequest::ClientLoFiOn);
+STATIC_ASSERT_PREVIEWS_ENUM(PREVIEWS_NO_TRANSFORM,
+                            blink::WebURLRequest::PreviewsNoTransform);
 STATIC_ASSERT_PREVIEWS_ENUM(PREVIEWS_OFF, blink::WebURLRequest::PreviewsOff);
 STATIC_ASSERT_PREVIEWS_ENUM(PREVIEWS_STATE_LAST,
                             blink::WebURLRequest::PreviewsStateLast);
diff --git a/content/renderer/dom_storage/dom_storage_cached_area.cc b/content/renderer/dom_storage/dom_storage_cached_area.cc
index 092dcf3..b2686d9 100644
--- a/content/renderer/dom_storage/dom_storage_cached_area.cc
+++ b/content/renderer/dom_storage/dom_storage_cached_area.cc
@@ -48,7 +48,8 @@
                                    const GURL& page_url) {
   // A quick check to reject obviously overbudget items to avoid
   // the priming the cache.
-  if (key.length() + value.length() > kPerStorageAreaQuota)
+  if ((key.length() + value.length()) * sizeof(base::char16) >
+      kPerStorageAreaQuota)
     return false;
 
   PrimeIfNeeded(connection_id);
diff --git a/content/renderer/dom_storage/local_storage_cached_area.cc b/content/renderer/dom_storage/local_storage_cached_area.cc
index f258064..a7ba25ed 100644
--- a/content/renderer/dom_storage/local_storage_cached_area.cc
+++ b/content/renderer/dom_storage/local_storage_cached_area.cc
@@ -114,7 +114,8 @@
                                      const std::string& storage_area_id) {
   // A quick check to reject obviously overbudget items to avoid priming the
   // cache.
-  if (key.length() + value.length() > kPerStorageAreaQuota)
+  if ((key.length() + value.length()) * sizeof(base::char16) >
+      kPerStorageAreaQuota)
     return false;
 
   EnsureLoaded();
diff --git a/content/renderer/media/rtc_peer_connection_handler.h b/content/renderer/media/rtc_peer_connection_handler.h
index cc179dc..0ad099fe 100644
--- a/content/renderer/media/rtc_peer_connection_handler.h
+++ b/content/renderer/media/rtc_peer_connection_handler.h
@@ -262,9 +262,10 @@
   int num_local_candidates_ipv4_ = 0;
   int num_local_candidates_ipv6_ = 0;
 
-  // To make sure the observer is released after the native_peer_connection_,
-  // it has to come first.
+  // To make sure the observers are released after native_peer_connection_,
+  // they have to come first.
   scoped_refptr<Observer> peer_connection_observer_;
+  scoped_refptr<webrtc::UMAObserver> uma_observer_;
 
   // |native_peer_connection_| is the libjingle native PeerConnection object.
   scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
@@ -284,7 +285,6 @@
   std::map<webrtc::MediaStreamInterface*,
            std::unique_ptr<content::RemoteMediaStreamImpl>>
       remote_streams_;
-  scoped_refptr<webrtc::UMAObserver> uma_observer_;
   base::TimeTicks ice_connection_checking_start_;
 
   // Track which ICE Connection state that this PeerConnection has gone through.
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.cc b/content/renderer/pepper/ppb_graphics_3d_impl.cc
index e9e17ff..8a89b72 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -48,20 +48,11 @@
       bound_to_instance_(false),
       commit_pending_(false),
       has_alpha_(false),
-      use_image_chromium_(false),
-      weak_ptr_factory_(this) {
-#if defined(OS_MACOSX)
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  bool use_image_chromium =
-      !command_line->HasSwitch(switches::kDisablePepper3DImageChromium);
-
-  if (use_image_chromium) {
-    use_image_chromium =
-        base::FeatureList::IsEnabled(features::kPepper3DImageChromium);
-  }
-  use_image_chromium_ = use_image_chromium;
-#endif
-}
+      use_image_chromium_(
+          !base::CommandLine::ForCurrentProcess()->HasSwitch(
+              switches::kDisablePepper3DImageChromium) &&
+          base::FeatureList::IsEnabled(features::kPepper3DImageChromium)),
+      weak_ptr_factory_(this) {}
 
 PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() {
   // Unset the client before the command_buffer_ is destroyed, similar to how
@@ -190,10 +181,15 @@
     // Don't need to check for NULL from GetPluginInstance since when we're
     // bound, we know our instance is valid.
     bool is_overlay_candidate = use_image_chromium_;
-    GLenum target =
-        is_overlay_candidate ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D;
-    cc::TextureMailbox texture_mailbox(taken_front_buffer_, sync_token, target,
-                                       size, is_overlay_candidate, false);
+    cc::TextureMailbox texture_mailbox(
+        taken_front_buffer_, sync_token,
+// TODO(reveman): Get texture target from browser process.
+#if defined(OS_MACOSX)
+        use_image_chromium_ ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D,
+#else
+        use_image_chromium_ ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D,
+#endif
+        size, is_overlay_candidate, false);
     taken_front_buffer_.SetZero();
     HostGlobals::Get()
         ->GetInstance(pp_instance())
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.h b/content/renderer/pepper/ppb_graphics_3d_impl.h
index dca5aaa..a15b48d 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.h
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.h
@@ -116,7 +116,7 @@
 #endif
 
   bool has_alpha_;
-  bool use_image_chromium_;
+  const bool use_image_chromium_;
   std::unique_ptr<gpu::CommandBufferProxyImpl> command_buffer_;
 
   base::WeakPtrFactory<PPB_Graphics3D_Impl> weak_ptr_factory_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index ce8f2725..823dbb8 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2256,7 +2256,7 @@
 }
 
 void RenderFrameImpl::OnReloadLoFiImages() {
-  previews_state_ = PREVIEWS_OFF;
+  previews_state_ = PREVIEWS_NO_TRANSFORM;
   GetWebFrame()->reloadLoFiImages();
 }
 
@@ -2684,7 +2684,7 @@
     return;
   }
 
-  engagement_levels_[origin] = level;
+  engagement_level_ = std::make_pair(origin, level);
 }
 
 // mojom::Frame implementation -------------------------------------------------
@@ -4826,13 +4826,12 @@
   InternalDocumentStateData* internal_data =
       InternalDocumentStateData::FromDocumentState(document_state);
 
-  // Set the correct engagement level on the frame.
-  EngagementLevels::iterator engagement_level =
-      engagement_levels_.find(url::Origin(frame_->getSecurityOrigin()));
-
-  if (engagement_level != engagement_levels_.end())
-    frame_->setEngagementLevel(engagement_level->second);
-  engagement_levels_.clear();
+  // Set the correct engagement level on the frame, and wipe the cached origin
+  // so this will not be reused accidentally.
+  if (url::Origin(frame_->getSecurityOrigin()) == engagement_level_.first) {
+    frame_->setEngagementLevel(engagement_level_.second);
+    engagement_level_.first = url::Origin();
+  }
 
   FrameHostMsg_DidCommitProvisionalLoad_Params params;
   params.http_status_code = response.httpStatusCode();
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index f415989..53041fd 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -767,7 +767,8 @@
   };
 
   typedef std::map<GURL, double> HostZoomLevels;
-  typedef std::map<url::Origin, blink::mojom::EngagementLevel> EngagementLevels;
+  typedef std::pair<url::Origin, blink::mojom::EngagementLevel>
+      EngagementOriginAndLevel;
 
   // Creates a new RenderFrame. |render_view| is the RenderView object that this
   // frame belongs to.
@@ -1356,7 +1357,7 @@
 #endif
 
   HostZoomLevels host_zoom_levels_;
-  EngagementLevels engagement_levels_;
+  EngagementOriginAndLevel engagement_level_;
 
   mojo::AssociatedBinding<blink::mojom::EngagementClient> engagement_binding_;
   mojo::Binding<mojom::Frame> frame_binding_;
diff --git a/content/renderer/shared_worker/shared_worker_repository.cc b/content/renderer/shared_worker/shared_worker_repository.cc
index 9aa746a..dfbcf70ad8 100644
--- a/content/renderer/shared_worker/shared_worker_repository.cc
+++ b/content/renderer/shared_worker/shared_worker_repository.cc
@@ -4,10 +4,10 @@
 
 #include "content/renderer/shared_worker/shared_worker_repository.h"
 
-#include "content/child/child_thread_impl.h"
 #include "content/common/view_messages.h"
 #include "content/renderer/render_frame_impl.h"
 #include "content/renderer/shared_worker/websharedworker_proxy.h"
+#include "third_party/WebKit/public/web/WebSharedWorkerConnectListener.h"
 
 namespace content {
 
@@ -16,8 +16,7 @@
 
 SharedWorkerRepository::~SharedWorkerRepository() = default;
 
-std::unique_ptr<blink::WebSharedWorkerConnector>
-SharedWorkerRepository::createSharedWorkerConnector(
+void SharedWorkerRepository::connect(
     const blink::WebURL& url,
     const blink::WebString& name,
     DocumentID document_id,
@@ -25,7 +24,10 @@
     blink::WebContentSecurityPolicyType security_policy_type,
     blink::WebAddressSpace creation_address_space,
     blink::WebSharedWorkerCreationContextType creation_context_type,
-    blink::WebWorkerCreationError* error) {
+    blink::WebMessagePortChannel* channel,
+    std::unique_ptr<blink::WebSharedWorkerConnectListener> listener) {
+  documents_with_workers_.insert(document_id);
+
   ViewHostMsg_CreateWorker_Params params;
   params.url = url;
   params.name = name.utf16();
@@ -36,11 +38,9 @@
   params.creation_address_space = creation_address_space;
   params.creation_context_type = creation_context_type;
   ViewHostMsg_CreateWorker_Reply reply;
-  render_frame_->Send(new ViewHostMsg_CreateWorker(params, &reply));
-  *error = reply.error;
-  documents_with_workers_.insert(document_id);
-  return base::MakeUnique<WebSharedWorkerProxy>(
-      ChildThreadImpl::current()->GetRouter(), reply.route_id);
+
+  // This proxy will self-destruct when a connection is established.
+  new WebSharedWorkerProxy(std::move(listener), params, channel);
 }
 
 void SharedWorkerRepository::documentDetached(DocumentID document) {
diff --git a/content/renderer/shared_worker/shared_worker_repository.h b/content/renderer/shared_worker/shared_worker_repository.h
index b6895911..1628382e 100644
--- a/content/renderer/shared_worker/shared_worker_repository.h
+++ b/content/renderer/shared_worker/shared_worker_repository.h
@@ -25,7 +25,7 @@
   ~SharedWorkerRepository();
 
   // WebSharedWorkerRepositoryClient overrides.
-  std::unique_ptr<blink::WebSharedWorkerConnector> createSharedWorkerConnector(
+  void connect(
       const blink::WebURL& url,
       const blink::WebString& name,
       DocumentID document_id,
@@ -33,7 +33,8 @@
       blink::WebContentSecurityPolicyType,
       blink::WebAddressSpace,
       blink::WebSharedWorkerCreationContextType,
-      blink::WebWorkerCreationError* error) override;
+      blink::WebMessagePortChannel* channel,
+      std::unique_ptr<blink::WebSharedWorkerConnectListener> listener) override;
   void documentDetached(DocumentID document_id) override;
 
  private:
diff --git a/content/renderer/shared_worker/websharedworker_proxy.cc b/content/renderer/shared_worker/websharedworker_proxy.cc
index 15d534d..628b14df 100644
--- a/content/renderer/shared_worker/websharedworker_proxy.cc
+++ b/content/renderer/shared_worker/websharedworker_proxy.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include "content/child/child_thread_impl.h"
 #include "content/child/webmessageportchannel_impl.h"
 #include "content/common/view_messages.h"
 #include "content/common/worker_messages.h"
@@ -13,29 +14,41 @@
 
 namespace content {
 
-WebSharedWorkerProxy::WebSharedWorkerProxy(IPC::MessageRouter* router,
-                                           int route_id)
-    : route_id_(route_id),
-      router_(router),
+WebSharedWorkerProxy::WebSharedWorkerProxy(
+    std::unique_ptr<blink::WebSharedWorkerConnectListener> listener,
+    ViewHostMsg_CreateWorker_Params params,
+    blink::WebMessagePortChannel* channel)
+    : route_id_(MSG_ROUTING_NONE),
+      router_(ChildThreadImpl::current()->GetRouter()),
       message_port_id_(MSG_ROUTING_NONE),
-      connect_listener_(nullptr) {
-  DCHECK_NE(MSG_ROUTING_NONE, route_id_);
-  router_->AddRoute(route_id_, this);
+      listener_(std::move(listener)) {
+  connect(params, channel);
 }
 
 WebSharedWorkerProxy::~WebSharedWorkerProxy() {
+  DCHECK_NE(MSG_ROUTING_NONE, route_id_);
   router_->RemoveRoute(route_id_);
 }
 
-void WebSharedWorkerProxy::connect(blink::WebMessagePortChannel* channel,
-                                   ConnectListener* listener) {
+void WebSharedWorkerProxy::connect(ViewHostMsg_CreateWorker_Params params,
+                                   blink::WebMessagePortChannel* channel) {
+  // Send synchronous IPC to get |route_id|.
+  // TODO(nhiroki): Stop using synchronous IPC (https://crbug.com/679654).
+  ViewHostMsg_CreateWorker_Reply reply;
+  router_->Send(new ViewHostMsg_CreateWorker(params, &reply));
+  route_id_ = reply.route_id;
+  router_->AddRoute(route_id_, this);
+  listener_->workerCreated(reply.error);
+
   DCHECK_EQ(MSG_ROUTING_NONE, message_port_id_);
   WebMessagePortChannelImpl* webchannel =
         static_cast<WebMessagePortChannelImpl*>(channel);
   message_port_id_ = webchannel->message_port_id();
   DCHECK_NE(MSG_ROUTING_NONE, message_port_id_);
   webchannel->QueueMessages();
-  connect_listener_ = listener;
+  // |webchannel| is intentionally leaked here: it'll be removed at
+  // WebMessagePortChannelImpl::OnMessagesQueued().
+
   // An actual connection request will be issued on OnWorkerCreated().
 }
 
@@ -53,26 +66,19 @@
 }
 
 void WebSharedWorkerProxy::OnWorkerCreated() {
-  // connect() should be called before.
-  DCHECK_NE(MSG_ROUTING_NONE, message_port_id_);
-
   // The worker is created - now send off the connection request.
   router_->Send(
       new ViewHostMsg_ConnectToWorker(route_id_, message_port_id_));
 }
 
 void WebSharedWorkerProxy::OnWorkerScriptLoadFailed() {
-  if (connect_listener_) {
-    // This can result in this object being freed.
-    connect_listener_->scriptLoadFailed();
-  }
+  listener_->scriptLoadFailed();
+  delete this;
 }
 
 void WebSharedWorkerProxy::OnWorkerConnected() {
-  if (connect_listener_) {
-    // This can result in this object being freed.
-    connect_listener_->connected();
-  }
+  listener_->connected();
+  delete this;
 }
 
 }  // namespace content
diff --git a/content/renderer/shared_worker/websharedworker_proxy.h b/content/renderer/shared_worker/websharedworker_proxy.h
index cb9a9c3c..78cd84c 100644
--- a/content/renderer/shared_worker/websharedworker_proxy.h
+++ b/content/renderer/shared_worker/websharedworker_proxy.h
@@ -5,13 +5,16 @@
 #ifndef CONTENT_RENDERER_SHARED_WORKER_WEBSHAREDWORKER_PROXY_H_
 #define CONTENT_RENDERER_SHARED_WORKER_WEBSHAREDWORKER_PROXY_H_
 
-#include <string>
-#include <vector>
-
-#include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "ipc/ipc_listener.h"
-#include "third_party/WebKit/public/web/WebSharedWorkerConnector.h"
+#include "third_party/WebKit/public/web/WebSharedWorkerConnectListener.h"
+#include "third_party/WebKit/public/web/WebSharedWorkerCreationErrors.h"
+
+struct ViewHostMsg_CreateWorker_Params;
+
+namespace blink {
+class WebMessagePortChannel;
+}
 
 namespace IPC {
 class MessageRouter;
@@ -22,19 +25,21 @@
 // Implementation of the WebSharedWorker APIs. This object is intended to only
 // live long enough to allow the caller to send a "connect" event to the worker
 // thread. Once the connect event has been sent, all future communication will
-// happen via the WebMessagePortChannel, and the WebSharedWorker instance will
-// be freed.
-class WebSharedWorkerProxy : public blink::WebSharedWorkerConnector,
-                             private IPC::Listener {
+// happen via the WebMessagePortChannel. This instance will self-destruct when a
+// connection is established.
+class WebSharedWorkerProxy : private IPC::Listener {
  public:
-  WebSharedWorkerProxy(IPC::MessageRouter* router, int route_id);
+  // |channel| should be passed with its ownership.
+  WebSharedWorkerProxy(
+      std::unique_ptr<blink::WebSharedWorkerConnectListener> listener,
+      ViewHostMsg_CreateWorker_Params params,
+      blink::WebMessagePortChannel* channel);
   ~WebSharedWorkerProxy() override;
 
-  // Implementations of WebSharedWorkerConnector APIs
-  void connect(blink::WebMessagePortChannel* channel,
-               ConnectListener* listener) override;
-
  private:
+  void connect(ViewHostMsg_CreateWorker_Params params,
+               blink::WebMessagePortChannel* channel);
+
   // IPC::Listener implementation.
   bool OnMessageReceived(const IPC::Message& message) override;
 
@@ -46,12 +51,12 @@
   // worker, and also to route messages to the worker (WorkerService contains
   // a map that maps between these renderer-side route IDs and worker-side
   // routing ids).
-  const int route_id_;
+  int route_id_;
 
   IPC::MessageRouter* const router_;
 
   int message_port_id_;
-  ConnectListener* connect_listener_;
+  std::unique_ptr<blink::WebSharedWorkerConnectListener> listener_;
 
   DISALLOW_COPY_AND_ASSIGN(WebSharedWorkerProxy);
 };
diff --git a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
index 968d0e8d..4fa8f075 100644
--- a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
+++ b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
@@ -195,6 +195,8 @@
     return GetGlucoseHeartRateAdapter();
   if (fake_adapter_name == "UnicodeDeviceAdapter")
     return GetUnicodeDeviceAdapter();
+  if (fake_adapter_name == "DeviceNameLongerThan29BytesAdapter")
+    return GetDeviceNameLongerThan29BytesAdapter();
   if (fake_adapter_name == "MissingServiceHeartRateAdapter")
     return GetMissingServiceHeartRateAdapter();
   if (fake_adapter_name == "MissingCharacteristicHeartRateAdapter")
@@ -414,6 +416,17 @@
   return adapter;
 }
 
+// static
+scoped_refptr<NiceMockBluetoothAdapter>
+LayoutTestBluetoothAdapterProvider::GetDeviceNameLongerThan29BytesAdapter() {
+  scoped_refptr<NiceMockBluetoothAdapter> adapter(GetEmptyAdapter());
+
+  adapter->AddMockDevice(GetBaseDevice(adapter.get(),
+                         "a_device_name_that_is_longer_than_29_bytes_but_shorter_than_240_bytes"));
+
+  return adapter;
+}
+
 // Adds a device to |adapter| and notifies all observers about that new device.
 // Mocks can call this asynchronously to cause changes in the middle of a test.
 static void AddDevice(scoped_refptr<NiceMockBluetoothAdapter> adapter,
diff --git a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
index 6b6342e..1b4f4fd8 100644
--- a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
+++ b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
@@ -134,6 +134,15 @@
   static scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
   GetUnicodeDeviceAdapter();
 
+  // |GetDeviceNameLongerThan29BytesAdapter|
+  // Inherits from |EmptyAdapter|
+  // Internal structure
+  //  - DeviceNameLongerThan29Bytes
+  //    - Mock Functions:
+  //      - GetName(): Returns "a_device_name_that_is_longer_than_29_bytes_but_shorter_than_240_bytes"
+  static scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
+  GetDeviceNameLongerThan29BytesAdapter();
+
   // |SecondDiscoveryFindsHeartRateAdapter|
   // Inherits from |PoweredAdapter|
   // Mock Functions:
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 6f39ea0..7f4dffd8 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -232,32 +232,6 @@
       'swarming': False,
       'os_type': 'win',
     },
-    'Win10 Release (New Intel)': {
-      'swarming_dimensions': [
-        {
-          'gpu': '8086:0412',
-          'os': 'Windows-10',
-        },
-      ],
-      'build_config': 'Release',
-      # This bot is a one-off and doesn't have similar slaves in the
-      # swarming pool.
-      'swarming': False,
-      'os_type': 'win',
-    },
-    'Win10 Debug (New Intel)': {
-      'swarming_dimensions': [
-        {
-          'gpu': '8086:0412',
-          'os': 'Windows-10',
-        },
-      ],
-      'build_config': 'Debug',
-      # This bot is a one-off and doesn't have similar slaves in the
-      # swarming pool.
-      'swarming': False,
-      'os_type': 'win',
-    },
     'Win10 Release (Intel HD 530)': {
       'swarming_dimensions': [
         {
@@ -428,6 +402,19 @@
       'swarming': False,
       'os_type': 'mac',
     },
+    'Mac Experimental Retina Release (NVIDIA)': {
+      'swarming_dimensions': [
+        {
+          'gpu': '10de:0fe9',
+          'hidpi': '1',
+          'os': 'Mac'
+        },
+      ],
+      'build_config': 'Release',
+      # This bot is a one-off for testing purposes.
+      'swarming': False,
+      'os_type': 'mac',
+    },
     'Mac GPU ASAN Release': {
       # This bot spawns jobs on multiple GPU types.
       'swarming_dimensions': [
@@ -507,32 +494,6 @@
       'swarming': True,
       'os_type': 'linux',
     },
-    'Linux Release (New Intel)': {
-      'swarming_dimensions': [
-        {
-          'gpu': '8086:0412',
-          'os': 'Linux'
-        },
-      ],
-      'build_config': 'Release',
-      # This bot is a one-off and doesn't have similar slaves in the
-      # swarming pool.
-      'swarming': False,
-      'os_type': 'linux',
-    },
-    'Linux Debug (New Intel)': {
-      'swarming_dimensions': [
-        {
-          'gpu': '8086:0412',
-          'os': 'Linux'
-        },
-      ],
-      'build_config': 'Debug',
-      # This bot is a one-off and doesn't have similar slaves in the
-      # swarming pool.
-      'swarming': False,
-      'os_type': 'linux',
-    },
     'Linux Release (Intel HD 530)': {
       'swarming_dimensions': [
         {
@@ -736,6 +697,107 @@
   }
 }
 
+V8_FYI_WATERFALL = {
+  'prologue': {
+    "V8 Android GN (dbg)": {
+      "additional_compile_targets": [
+        "chrome_public_apk"
+      ],
+      "gtest_tests": []
+    },
+    "V8 Linux GN": {
+      "additional_compile_targets": [
+        "accessibility_unittests",
+        "aura_unittests",
+        "browser_tests",
+        "cacheinvalidation_unittests",
+        "capture_unittests",
+        "cast_unittests",
+        "cc_unittests",
+        "chromedriver_unittests",
+        "components_browsertests",
+        "components_unittests",
+        "content_browsertests",
+        "content_unittests",
+        "crypto_unittests",
+        "dbus_unittests",
+        "device_unittests",
+        "display_unittests",
+        "events_unittests",
+        "extensions_browsertests",
+        "extensions_unittests",
+        "gcm_unit_tests",
+        "gfx_unittests",
+        "gn_unittests",
+        "google_apis_unittests",
+        "gpu_ipc_service_unittests",
+        "gpu_unittests",
+        "interactive_ui_tests",
+        "ipc_tests",
+        "jingle_unittests",
+        "media_unittests",
+        "media_blink_unittests",
+        "mojo_common_unittests",
+        "mojo_public_bindings_unittests",
+        "mojo_public_system_unittests",
+        "mojo_system_unittests",
+        "nacl_loader_unittests",
+        "net_unittests",
+        "pdf_unittests",
+        "ppapi_unittests",
+        "printing_unittests",
+        "remoting_unittests",
+        "sandbox_linux_unittests",
+        "skia_unittests",
+        "sql_unittests",
+        "storage_unittests",
+        "sync_integration_tests",
+        "ui_base_unittests",
+        "ui_touch_selection_unittests",
+        "unit_tests",
+        "url_unittests",
+        "views_unittests",
+        "wm_unittests"
+      ]
+    }
+  },
+  'testers': {
+    'Win Release (NVIDIA)': {
+      'swarming_dimensions': [
+        {
+          'gpu': '10de:104a',
+          'os': 'Windows-2008ServerR2-SP1'
+        },
+      ],
+      'build_config': 'Release',
+      'swarming': True,
+      'os_type': 'win',
+    },
+    'Mac Release (Intel)': {
+      'swarming_dimensions': [
+        {
+          'gpu': '8086:0a2e',
+          'os': 'Mac-10.12'
+        },
+      ],
+      'build_config': 'Release',
+      'swarming': True,
+      'os_type': 'mac',
+    },
+    'Linux Release (NVIDIA)': {
+      'swarming_dimensions': [
+        {
+          'gpu': '10de:104a',
+          'os': 'Linux'
+        },
+      ],
+      'build_config': 'Release',
+      'swarming': True,
+      'os_type': 'linux',
+    },
+  }
+}
+
 COMMON_GTESTS = {
   'angle_deqp_egl_tests': {
     'tester_configs': [
@@ -1168,6 +1230,7 @@
     'tester_configs': [
       {
         'allow_on_android': True,
+        'run_on_v8': True,
       },
     ]
   },
@@ -1175,21 +1238,24 @@
     'tester_configs': [
       {
         'allow_on_android': True,
+        'run_on_v8': True,
       },
     ]
   },
   'gpu_process_launch_tests': {
-      'target_name': 'gpu_process',
-      'tester_configs': [
-        {
-          'allow_on_android': True,
-        }
-      ],
+    'target_name': 'gpu_process',
+    'tester_configs': [
+      {
+        'allow_on_android': True,
+        'run_on_v8': True,
+      }
+    ],
   },
   'hardware_accelerated_feature': {
     'tester_configs': [
       {
         'allow_on_android': True,
+        'run_on_v8': True,
       },
     ],
   },
@@ -1206,6 +1272,7 @@
     'tester_configs': [
       {
         'allow_on_android': True,
+        'run_on_v8': True,
       },
     ],
   },
@@ -1230,6 +1297,7 @@
     'tester_configs': [
       {
         'allow_on_android': True,
+        'run_on_v8': True,
       },
     ],
   },
@@ -1237,6 +1305,7 @@
     'tester_configs': [
       {
         'allow_on_android': True,
+        'run_on_v8': True,
       },
     ],
   },
@@ -1244,6 +1313,7 @@
     'tester_configs': [
       {
         'allow_on_android': True,
+        'run_on_v8': True,
       },
     ],
   },
@@ -1251,6 +1321,7 @@
     'tester_configs': [
       {
         'allow_on_android': True,
+        'run_on_v8': True,
       },
     ],
     'asan_args': ['--is-asan'],
@@ -1354,6 +1425,7 @@
         'build_configs': ['Release', 'Release_x64'],
         'fyi_only': True,
         'run_on_optional': True,
+        'run_on_v8': True,
       },
     ],
     'disabled_tester_configs': [
@@ -1475,17 +1547,22 @@
 def is_asan(tester_config):
   return tester_config.get('is_asan', False)
 
-def tester_config_matches_tester(tester_name, tester_config, tc, is_fyi,
+def tester_config_matches_tester(tester_name, tester_config, tc, is_fyi, is_v8,
                                  check_waterfall):
   if check_waterfall:
     if tc.get('fyi_only', False) and not is_fyi:
       return False
+
     # Handle the optional tryservers with the 'run_on_optional' flag.
     # Only a subset of the tests run on these tryservers.
     if tester_name.startswith('Optional') and not tc.get(
         'run_on_optional', False):
       return False
 
+    # Handle the client.v8.fyi GPU bots with the 'run_on_v8' flag.
+    if (is_v8 and not tc.get('run_on_v8', False)):
+      return False
+
   if 'names' in tc:
     # Give priority to matching the tester_name.
     if tester_name in tc['names']:
@@ -1507,17 +1584,18 @@
       return False
   return True
 
-def should_run_on_tester(tester_name, tester_config, test_config, is_fyi):
+def should_run_on_tester(tester_name, tester_config, test_config,
+                         is_fyi, is_v8):
   # Check if this config is disabled on this tester
   if 'disabled_tester_configs' in test_config:
     for dtc in test_config['disabled_tester_configs']:
-      if tester_config_matches_tester(tester_name, tester_config, dtc, is_fyi,
-                                      False):
+      if tester_config_matches_tester(tester_name, tester_config, dtc,
+                                      is_fyi, is_v8, False):
         return False
   if 'tester_configs' in test_config:
     for tc in test_config['tester_configs']:
-      if tester_config_matches_tester(tester_name, tester_config, tc, is_fyi,
-                                      True):
+      if tester_config_matches_tester(tester_name, tester_config, tc,
+                                      is_fyi, is_v8, True):
         return True
     return False
   else:
@@ -1525,10 +1603,12 @@
     # but let tester_config_matches_tester filter out any undesired
     # tests, such as ones that should only run on the Optional bots.
     return tester_config_matches_tester(tester_name, tester_config, {},
-                                        is_fyi, True)
+                                        is_fyi, is_v8, True)
 
-def generate_gtest(tester_name, tester_config, test, test_config, is_fyi):
-  if not should_run_on_tester(tester_name, tester_config, test_config, is_fyi):
+def generate_gtest(tester_name, tester_config, test, test_config,
+                   is_fyi, is_v8):
+  if not should_run_on_tester(tester_name, tester_config, test_config,
+                              is_fyi, is_v8):
     return None
   result = copy.deepcopy(test_config)
   if 'tester_configs' in result:
@@ -1608,7 +1688,7 @@
   result['use_xvfb'] = False
   return result
 
-def generate_gtests(tester_name, tester_config, test_dictionary, is_fyi):
+def generate_gtests(tester_name, tester_config, test_dictionary, is_fyi, is_v8):
   # The relative ordering of some of the tests is important to
   # minimize differences compared to the handwritten JSON files, since
   # Python's sorts are stable and there are some tests with the same
@@ -1617,16 +1697,17 @@
   gtests = []
   for test_name, test_config in sorted(test_dictionary.iteritems()):
     test = generate_gtest(tester_name, tester_config,
-                          test_name, test_config, is_fyi)
+                          test_name, test_config, is_fyi, is_v8)
     if test:
       # generate_gtest may veto the test generation on this platform.
       gtests.append(test)
   return gtests
 
 def generate_isolated_test(tester_name, tester_config, test, test_config,
-                           is_fyi, extra_browser_args, isolate_name,
+                           is_fyi, is_v8, extra_browser_args, isolate_name,
                            override_compile_targets, prefix_args):
-  if not should_run_on_tester(tester_name, tester_config, test_config, is_fyi):
+  if not should_run_on_tester(tester_name, tester_config, test_config,
+                              is_fyi, is_v8):
     return None
   test_args = ['-v']
   extra_browser_args_string = ""
@@ -1679,7 +1760,7 @@
   return result
 
 def generate_telemetry_test(tester_name, tester_config,
-                            test, test_config, is_fyi):
+                            test, test_config, is_fyi, is_v8):
   extra_browser_args = ['--enable-logging=stderr', '--js-flags=--expose-gc']
   benchmark_name = test_config.get('target_name') or test
   prefix_args = [
@@ -1688,61 +1769,64 @@
     '--browser=%s' % tester_config['build_config'].lower()
   ]
   return generate_isolated_test(tester_name, tester_config, test,
-                                test_config, is_fyi, extra_browser_args,
+                                test_config, is_fyi, is_v8, extra_browser_args,
                                 'telemetry_gpu_integration_test',
                                 ['telemetry_gpu_integration_test_run'],
                                 prefix_args)
 
 def generate_telemetry_tests(tester_name, tester_config,
-                             test_dictionary, is_fyi):
+                             test_dictionary, is_fyi, is_v8):
   isolated_scripts = []
   for test_name, test_config in sorted(test_dictionary.iteritems()):
     test = generate_telemetry_test(
-      tester_name, tester_config, test_name, test_config, is_fyi)
+      tester_name, tester_config, test_name, test_config, is_fyi, is_v8)
     if test:
       isolated_scripts.append(test)
   return isolated_scripts
 
 def generate_non_telemetry_isolated_test(tester_name, tester_config,
-                                         test, test_config, is_fyi):
+                                         test, test_config, is_fyi, is_v8):
   return generate_isolated_test(tester_name, tester_config, test,
-                                test_config, is_fyi, None, test, None, [])
+                                test_config, is_fyi, is_v8,
+                                None, test, None, [])
 
 def generate_non_telemetry_isolated_tests(tester_name, tester_config,
-                                          test_dictionary, is_fyi):
+                                          test_dictionary, is_fyi, is_v8):
   isolated_scripts = []
   for test_name, test_config in sorted(test_dictionary.iteritems()):
     test = generate_non_telemetry_isolated_test(
-      tester_name, tester_config, test_name, test_config, is_fyi)
+      tester_name, tester_config, test_name, test_config, is_fyi, is_v8)
     if test:
       isolated_scripts.append(test)
   return isolated_scripts
 
-def generate_all_tests(waterfall, is_fyi):
+def generate_all_tests(waterfall, filename, is_fyi, is_v8):
   tests = {}
-  for builder, config in waterfall['builders'].iteritems():
+  for builder, config in waterfall.get('prologue', {}).iteritems():
+    tests[builder] = config
+  for builder, config in waterfall.get('builders', {}).iteritems():
     tests[builder] = config
   for name, config in waterfall['testers'].iteritems():
-    gtests = generate_gtests(name, config, COMMON_GTESTS, is_fyi)
+    gtests = generate_gtests(name, config, COMMON_GTESTS, is_fyi, is_v8)
     isolated_scripts = \
       generate_telemetry_tests(
-        name, config, TELEMETRY_GPU_INTEGRATION_TESTS, is_fyi) + \
+        name, config, TELEMETRY_GPU_INTEGRATION_TESTS, is_fyi, is_v8) + \
       generate_non_telemetry_isolated_tests(name, config,
-          NON_TELEMETRY_ISOLATED_SCRIPT_TESTS, is_fyi)
+        NON_TELEMETRY_ISOLATED_SCRIPT_TESTS, is_fyi, is_v8)
     tests[name] = {
       'gtest_tests': sorted(gtests, key=lambda x: x['test']),
       'isolated_scripts': sorted(isolated_scripts, key=lambda x: x['name'])
     }
   tests['AAAAA1 AUTOGENERATED FILE DO NOT EDIT'] = {}
   tests['AAAAA2 See generate_buildbot_json.py to make changes'] = {}
-  filename = 'chromium.gpu.fyi.json' if is_fyi else 'chromium.gpu.json'
   with open(os.path.join(SRC_DIR, 'testing', 'buildbot', filename), 'wb') as fp:
     json.dump(tests, fp, indent=2, separators=(',', ': '), sort_keys=True)
     fp.write('\n')
 
 def main():
-  generate_all_tests(FYI_WATERFALL, True)
-  generate_all_tests(WATERFALL, False)
+  generate_all_tests(FYI_WATERFALL, 'chromium.gpu.fyi.json', True, False)
+  generate_all_tests(WATERFALL, 'chromium.gpu.json', False, False)
+  generate_all_tests(V8_FYI_WATERFALL, 'client.v8.fyi.json', True, True)
   return 0
 
 if __name__ == "__main__":
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 07c27194..5d41505a 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -41,10 +41,6 @@
     self.Skip('deqp/functional/gles3/builtinprecision/*.html', bug=619403)
 
     # All platforms.
-
-    self.Fail('conformance/extensions/webgl-compressed-texture-etc.html',
-        bug=679678)
-
     self.Flaky('conformance2/query/occlusion-query.html', bug=603168)
     self.Fail('conformance2/glsl3/tricky-loop-conditions.html', bug=483282)
 
diff --git a/extensions/browser/api/async_api_function.h b/extensions/browser/api/async_api_function.h
index f109506..e260806 100644
--- a/extensions/browser/api/async_api_function.h
+++ b/extensions/browser/api/async_api_function.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_ASYNC_API_FUCTION_H_
-#define EXTENSIONS_BROWSER_API_ASYNC_API_FUCTION_H_
+#ifndef EXTENSIONS_BROWSER_API_ASYNC_API_FUNCTION_H_
+#define EXTENSIONS_BROWSER_API_ASYNC_API_FUNCTION_H_
 
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/extension_function.h"
@@ -58,4 +58,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_ASYNC_API_FUCTION_H_
+#endif  // EXTENSIONS_BROWSER_API_ASYNC_API_FUNCTION_H_
diff --git a/extensions/browser/api/device_permissions_manager.h b/extensions/browser/api/device_permissions_manager.h
index 299109b5..e57cd0e9 100644
--- a/extensions/browser/api/device_permissions_manager.h
+++ b/extensions/browser/api/device_permissions_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_DEVICE_PERMISSION_MANAGER_H_
-#define EXTENSIONS_DEVICE_PERMISSION_MANAGER_H_
+#ifndef EXTENSIONS_BROWSER_API_DEVICE_PERMISSIONS_MANAGER_H_
+#define EXTENSIONS_BROWSER_API_DEVICE_PERMISSIONS_MANAGER_H_
 
 #include <stdint.h>
 
@@ -227,4 +227,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_DEVICE_PERMISSION_MANAGER_H_
+#endif  // EXTENSIONS_BROWSER_API_DEVICE_PERMISSIONS_MANAGER_H_
diff --git a/extensions/browser/api/device_permissions_prompt.h b/extensions/browser/api/device_permissions_prompt.h
index 2d6b9194..40d29dc2 100644
--- a/extensions/browser/api/device_permissions_prompt.h
+++ b/extensions/browser/api/device_permissions_prompt.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_DEVICE_PERMISSIONS_PROMPT_H_
-#define EXTENSIONS_BROWSER_DEVICE_PERMISSIONS_PROMPT_H_
+#ifndef EXTENSIONS_BROWSER_API_DEVICE_PERMISSIONS_PROMPT_H_
+#define EXTENSIONS_BROWSER_API_DEVICE_PERMISSIONS_PROMPT_H_
 
 #include <stddef.h>
 
diff --git a/extensions/browser/api/guest_view/app_view/app_view_guest_internal_api.h b/extensions/browser/api/guest_view/app_view/app_view_guest_internal_api.h
index 0bcb7d85..ab210465 100644
--- a/extensions/browser/api/guest_view/app_view/app_view_guest_internal_api.h
+++ b/extensions/browser/api/guest_view/app_view/app_view_guest_internal_api.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_APP_VIEW_APP_VIEW_GUEST_INTERNAL_API_H_
-#define EXTENSIONS_BROWSER_API_APP_VIEW_APP_VIEW_GUEST_INTERNAL_API_H_
+#ifndef EXTENSIONS_BROWSER_API_GUEST_VIEW_APP_VIEW_APP_VIEW_GUEST_INTERNAL_API_H_
+#define EXTENSIONS_BROWSER_API_GUEST_VIEW_APP_VIEW_APP_VIEW_GUEST_INTERNAL_API_H_
 
 #include "base/macros.h"
 #include "extensions/browser/extension_function.h"
@@ -42,4 +42,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_APP_VIEW_APP_VIEW_GUEST_INTERNAL_API_H_
+#endif  // EXTENSIONS_BROWSER_API_GUEST_VIEW_APP_VIEW_APP_VIEW_GUEST_INTERNAL_API_H_
diff --git a/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h b/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h
index 1899d42..3758532 100644
--- a/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h
+++ b/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_
-#define EXTENSIONS_BROWSER_API_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_
+#ifndef EXTENSIONS_BROWSER_API_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_
+#define EXTENSIONS_BROWSER_API_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_
 
 #include "base/macros.h"
 #include "extensions/browser/api/execute_code_function.h"
@@ -66,4 +66,4 @@
 
 }  // namespace extensions
 
-#endif  // CHROME_BROWSER_EXTENSIONS_API_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_
+#endif  // EXTENSIONS_BROWSER_API_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
index e3bc9d2..3c5bf2aa 100644
--- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
+++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_WEB_VIEW_WEB_VIEW_INTERNAL_API_H_
-#define EXTENSIONS_BROWSER_API_WEB_VIEW_WEB_VIEW_INTERNAL_API_H_
+#ifndef EXTENSIONS_BROWSER_API_GUEST_VIEW_WEB_VIEW_WEB_VIEW_INTERNAL_API_H_
+#define EXTENSIONS_BROWSER_API_GUEST_VIEW_WEB_VIEW_WEB_VIEW_INTERNAL_API_H_
 
 #include <stdint.h>
 
@@ -461,4 +461,4 @@
 
 }  // namespace extensions
 
-#endif  // CHROME_BROWSER_EXTENSIONS_API_WEB_VIEW_WEB_VIEW_INTERNAL_API_H_
+#endif  // EXTENSIONS_BROWSER_API_GUEST_VIEW_WEB_VIEW_WEB_VIEW_INTERNAL_API_H_
diff --git a/extensions/browser/api/management/management_api_delegate.h b/extensions/browser/api/management/management_api_delegate.h
index f8e3def..b221907 100644
--- a/extensions/browser/api/management/management_api_delegate.h
+++ b/extensions/browser/api/management/management_api_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATER_H_
-#define EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATER_H_
+#ifndef EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATE_H_
+#define EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATE_H_
 
 #include "base/callback.h"
 #include "extensions/browser/uninstall_reason.h"
@@ -138,4 +138,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATER_H_
+#endif  // EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATE_H_
diff --git a/extensions/browser/api/runtime/runtime_api_delegate.h b/extensions/browser/api/runtime/runtime_api_delegate.h
index 21e9a6e..bd73f7a 100644
--- a/extensions/browser/api/runtime/runtime_api_delegate.h
+++ b/extensions/browser/api/runtime/runtime_api_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
-#define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
+#ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H_
+#define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H_
 
 #include "base/callback.h"
 #include "base/version.h"
@@ -79,4 +79,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
+#endif  // EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H_
diff --git a/extensions/browser/api/socket/tls_socket.h b/extensions/browser/api/socket/tls_socket.h
index d1fa232..0b43206 100644
--- a/extensions/browser/api/socket/tls_socket.h
+++ b/extensions/browser/api/socket/tls_socket.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_EXTENSIONS_API_SOCKET_TLS_SOCKET_H_
-#define CHROME_BROWSER_EXTENSIONS_API_SOCKET_TLS_SOCKET_H_
+#ifndef EXTENSIONS_BROWSER_API_SOCKET_TLS_SOCKET_H_
+#define EXTENSIONS_BROWSER_API_SOCKET_TLS_SOCKET_H_
 
 #include <stdint.h>
 
@@ -120,5 +120,5 @@
 
 }  // namespace extensions
 
-#endif  // CHROME_BROWSER_EXTENSIONS_API_SOCKET_TLS_SOCKET_H_
+#endif  // EXTENSIONS_BROWSER_API_SOCKET_TLS_SOCKET_H_
 
diff --git a/extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h b/extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h
index 4d1452e..62b54f3d 100644
--- a/extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h
+++ b/extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_VIRTUAL_KEYBOARD_VIRTUAL_KEYBOARD_DELEGATE_H_
-#define EXTENSIONS_BROWSER_API_VIRTUAL_KEYBOARD_VIRTUAL_KEYBOARD_DELEGATE_H_
+#ifndef EXTENSIONS_BROWSER_API_VIRTUAL_KEYBOARD_PRIVATE_VIRTUAL_KEYBOARD_DELEGATE_H_
+#define EXTENSIONS_BROWSER_API_VIRTUAL_KEYBOARD_PRIVATE_VIRTUAL_KEYBOARD_DELEGATE_H_
 
 #include "base/macros.h"
 #include "base/strings/string16.h"
@@ -68,4 +68,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_VIRTUAL_KEYBOARD_VIRTUAL_KEYBOARD_DELEGATE_H_
+#endif  // EXTENSIONS_BROWSER_API_VIRTUAL_KEYBOARD_PRIVATE_VIRTUAL_KEYBOARD_DELEGATE_H_
diff --git a/extensions/browser/api/vpn_provider/vpn_provider_api.h b/extensions/browser/api/vpn_provider/vpn_provider_api.h
index 3d3bb1d..94ce5ec4 100644
--- a/extensions/browser/api/vpn_provider/vpn_provider_api.h
+++ b/extensions/browser/api/vpn_provider/vpn_provider_api.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_EXTENSIONS_API_VPN_PROVIDER_VPN_PROVIDER_API_H_
-#define CHROME_BROWSER_EXTENSIONS_API_VPN_PROVIDER_VPN_PROVIDER_API_H_
+#ifndef EXTENSIONS_BROWSER_API_VPN_PROVIDER_VPN_PROVIDER_API_H_
+#define EXTENSIONS_BROWSER_API_VPN_PROVIDER_VPN_PROVIDER_API_H_
 
 #include <string>
 
@@ -81,4 +81,4 @@
 
 }  // namespace extensions
 
-#endif  // CHROME_BROWSER_EXTENSIONS_API_VPN_PROVIDER_VPN_PROVIDER_API_H_
+#endif  // EXTENSIONS_BROWSER_API_VPN_PROVIDER_VPN_PROVIDER_API_H_
diff --git a/extensions/browser/app_window/test_app_window_contents.h b/extensions/browser/app_window/test_app_window_contents.h
index 2bebf674..7e68b68e 100644
--- a/extensions/browser/app_window/test_app_window_contents.h
+++ b/extensions/browser/app_window/test_app_window_contents.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_APP_WINDOW_TEST_APP_WINDOW_CONTENTS_
-#define EXTENSIONS_BROWSER_APP_WINDOW_TEST_APP_WINDOW_CONTENTS_
+#ifndef EXTENSIONS_BROWSER_APP_WINDOW_TEST_APP_WINDOW_CONTENTS_H_
+#define EXTENSIONS_BROWSER_APP_WINDOW_TEST_APP_WINDOW_CONTENTS_H_
 
 #include <stdint.h>
 
@@ -42,4 +42,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_APP_WINDOW_TEST_APP_WINDOW_CONTENTS_
+#endif  // EXTENSIONS_BROWSER_APP_WINDOW_TEST_APP_WINDOW_CONTENTS_H_
diff --git a/extensions/browser/guest_view/extension_view/extension_view_constants.h b/extensions/browser/guest_view/extension_view/extension_view_constants.h
index e2e0780..cbfd7e20 100644
--- a/extensions/browser/guest_view/extension_view/extension_view_constants.h
+++ b/extensions/browser/guest_view/extension_view/extension_view_constants.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_OPTIONS_EXTENSION_VIEW_CONSTANTS_H_
-#define EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_OPTIONS_EXTENSION_VIEW_CONSTANTS_H_
+#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_CONSTANTS_H_
+#define EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_CONSTANTS_H_
 
 namespace extensionview {
 
@@ -19,4 +19,4 @@
 
 }  // namespace extensionview
 
-#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_OPTIONS_CONSTANTS_H_
+#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_CONSTANTS_H_
diff --git a/extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.h b/extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.h
index 517a1cb..1080c90 100644
--- a/extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.h
+++ b/extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_UI_URL_FETCHER_H
-#define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_UI_URL_FETCHER_H
+#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_UI_WEB_UI_URL_FETCHER_H_
+#define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_UI_WEB_UI_URL_FETCHER_H_
 
 #include <memory>
 
@@ -55,4 +55,4 @@
   DISALLOW_COPY_AND_ASSIGN(WebUIURLFetcher);
 };
 
-#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_UI_URL_FETCHER_H
+#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_UI_WEB_UI_URL_FETCHER_H_
diff --git a/extensions/browser/guest_view/web_view/web_view_content_script_manager.h b/extensions/browser/guest_view/web_view/web_view_content_script_manager.h
index 973995a..6e1d3a1 100644
--- a/extensions/browser/guest_view/web_view/web_view_content_script_manager.h
+++ b/extensions/browser/guest_view/web_view/web_view_content_script_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONTENT_SCRIPT_MANAGER_H
-#define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONTENT_SCRIPT_MANAGER_H
+#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONTENT_SCRIPT_MANAGER_H_
+#define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONTENT_SCRIPT_MANAGER_H_
 
 #include <map>
 #include <set>
@@ -105,4 +105,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONTENT_SCRIPT_MANAGER_H
+#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONTENT_SCRIPT_MANAGER_H_
diff --git a/extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h b/extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h
index 4f2bdd1..8bdec71 100644
--- a/extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h
+++ b/extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIWE_PERMISSION_HELPER_DELEGATE_H_
-#define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIWE_PERMISSION_HELPER_DELEGATE_H_
+#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_PERMISSION_HELPER_DELEGATE_H_
+#define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_PERMISSION_HELPER_DELEGATE_H_
 
 #include "base/macros.h"
 #include "content/public/browser/web_contents.h"
@@ -92,4 +92,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIWE_PERMISSION_HELPER_DELEGATE_H_
+#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_PERMISSION_HELPER_DELEGATE_H_
diff --git a/extensions/browser/requirements_checker.h b/extensions/browser/requirements_checker.h
index a5c16140..8844157e 100644
--- a/extensions/browser/requirements_checker.h
+++ b/extensions/browser/requirements_checker.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_EXTENSIONS_REQUIREMENTS_CHECKER_H_
-#define CHROME_BROWSER_EXTENSIONS_REQUIREMENTS_CHECKER_H_
+#ifndef EXTENSIONS_BROWSER_REQUIREMENTS_CHECKER_H_
+#define EXTENSIONS_BROWSER_REQUIREMENTS_CHECKER_H_
 
 #include <vector>
 
@@ -35,4 +35,4 @@
 
 }  // namespace extensions
 
-#endif  // CHROME_BROWSER_EXTENSIONS_REQUIREMENTS_CHECKER_H_
+#endif  // EXTENSIONS_BROWSER_REQUIREMENTS_CHECKER_H_
diff --git a/extensions/common/image_util.h b/extensions/common/image_util.h
index 2efdafd..a1ea706 100644
--- a/extensions/common/image_util.h
+++ b/extensions/common/image_util.h
@@ -29,4 +29,4 @@
 }  // namespace image_util
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_IMAGE_UTIL_H__
+#endif  // EXTENSIONS_COMMON_IMAGE_UTIL_H_
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_stream_packet_part.h b/extensions/renderer/api/display_source/wifi_display/wifi_display_stream_packet_part.h
index 152b4a7..6f094ae 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_stream_packet_part.h
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_stream_packet_part.h
@@ -40,4 +40,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_STREAM_PACKET_BASE_H_
+#endif  // EXTENSIONS_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_STREAM_PACKET_PART_H_
diff --git a/extensions/renderer/injection_host.h b/extensions/renderer/injection_host.h
index 21a4c0e..78015a4 100644
--- a/extensions/renderer/injection_host.h
+++ b/extensions/renderer/injection_host.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_RENDERER_INJECTION_HOST_H
-#define EXTENSIONS_RENDERER_INJECTION_HOST_H
+#ifndef EXTENSIONS_RENDERER_INJECTION_HOST_H_
+#define EXTENSIONS_RENDERER_INJECTION_HOST_H_
 
 #include "base/macros.h"
 #include "extensions/common/host_id.h"
@@ -44,4 +44,4 @@
   DISALLOW_COPY_AND_ASSIGN(InjectionHost);
 };
 
-#endif  // EXTENSIONS_RENDERER_INJECTION_HOST_H
+#endif  // EXTENSIONS_RENDERER_INJECTION_HOST_H_
diff --git a/extensions/renderer/scoped_web_frame.h b/extensions/renderer/scoped_web_frame.h
index ebcc877..18686ed 100644
--- a/extensions/renderer/scoped_web_frame.h
+++ b/extensions/renderer/scoped_web_frame.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef SCOPED_WEB_FRAME_H_
-#define SCOPED_WEB_FRAME_H_
+#ifndef EXTENSIONS_RENDERER_SCOPED_WEB_FRAME_H_
+#define EXTENSIONS_RENDERER_SCOPED_WEB_FRAME_H_
 
 #include "base/macros.h"
 #include "third_party/WebKit/public/web/WebFrameClient.h"
@@ -35,4 +35,4 @@
 
 }  // namespace extensions
 
-#endif  // SCOPED_WEB_FRAME_H_
+#endif  // EXTENSIONS_RENDERER_SCOPED_WEB_FRAME_H_
diff --git a/extensions/renderer/service_worker_data.h b/extensions/renderer/service_worker_data.h
index 8b356d1..e9bbabb 100644
--- a/extensions/renderer/service_worker_data.h
+++ b/extensions/renderer/service_worker_data.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_SERVICE_WORKER_DATA_H_
-#define EXTENSIONS_BROWSER_SERVICE_WORKER_DATA_H_
+#ifndef EXTENSIONS_RENDERER_SERVICE_WORKER_DATA_H_
+#define EXTENSIONS_RENDERER_SERVICE_WORKER_DATA_H_
 
 #include <memory>
 
@@ -40,4 +40,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_SERVICE_WORKER_DATA_H_
+#endif  // EXTENSIONS_RENDERER_SERVICE_WORKER_DATA_H_
diff --git a/extensions/renderer/web_ui_injection_host.h b/extensions/renderer/web_ui_injection_host.h
index a4df5f79..dfde94b4 100644
--- a/extensions/renderer/web_ui_injection_host.h
+++ b/extensions/renderer/web_ui_injection_host.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_RENDERER_WEBUI_INJECTION_HOST_H_
-#define EXTENSIONS_RENDERER_WEBUI_INJECTION_HOST_H_
+#ifndef EXTENSIONS_RENDERER_WEB_UI_INJECTION_HOST_H_
+#define EXTENSIONS_RENDERER_WEB_UI_INJECTION_HOST_H_
 
 #include "base/macros.h"
 #include "extensions/renderer/injection_host.h"
@@ -30,4 +30,4 @@
   DISALLOW_COPY_AND_ASSIGN(WebUIInjectionHost);
 };
 
-#endif  // EXTENSIONS_RENDERER_WEBUI_INJECTION_HOST_H_
+#endif  // EXTENSIONS_RENDERER_WEB_UI_INJECTION_HOST_H_
diff --git a/extensions/shell/browser/default_shell_browser_main_delegate.h b/extensions/shell/browser/default_shell_browser_main_delegate.h
index 64e643fb..05ce558f 100644
--- a/extensions/shell/browser/default_shell_browser_main_delegate.h
+++ b/extensions/shell/browser/default_shell_browser_main_delegate.h
@@ -29,4 +29,4 @@
 
 }  // namespace extensions
 
-#endif  // DEFAULT_SHELL_BROWSER_MAIN_DELEGATE_H_
+#endif  // EXTENSIONS_SHELL_BROWSER_DEFAULT_SHELL_BROWSER_MAIN_DELEGATE_H_
diff --git a/extensions/shell/browser/input_method_event_handler.h b/extensions/shell/browser/input_method_event_handler.h
index 4ecab33..b322cc1 100644
--- a/extensions/shell/browser/input_method_event_handler.h
+++ b/extensions/shell/browser/input_method_event_handler.h
@@ -39,4 +39,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_SHELL_BROWSER_METHOD_EVENT_HANDLER_H_
+#endif  // EXTENSIONS_SHELL_BROWSER_INPUT_METHOD_EVENT_HANDLER_H_
diff --git a/extensions/shell/browser/shell_browser_context_keyed_service_factories.h b/extensions/shell/browser/shell_browser_context_keyed_service_factories.h
index e252181..d626b78 100644
--- a/extensions/shell/browser/shell_browser_context_keyed_service_factories.h
+++ b/extensions/shell/browser/shell_browser_context_keyed_service_factories.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_SHELL_BROWSER_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
-#define EXTENSIONS_SHELL_BROWSER_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
+#ifndef EXTENSIONS_SHELL_BROWSER_SHELL_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
+#define EXTENSIONS_SHELL_BROWSER_SHELL_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
 
 namespace extensions {
 namespace shell {
@@ -15,4 +15,4 @@
 }  // namespace shell
 }  // namespace extensions
 
-#endif  // EXTENSIONS_SHELL_BROWSER_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
+#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
diff --git a/extensions/shell/browser/shell_network_delegate.h b/extensions/shell/browser/shell_network_delegate.h
index fc43d82..3936770 100644
--- a/extensions/shell/browser/shell_network_delegate.h
+++ b/extensions/shell/browser/shell_network_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_SHELL_BROWSER_SHELL_NETNETWORK_DELEGATE_H_
-#define EXTENSIONS_SHELL_BROWSER_SHELL_NETNETWORK_DELEGATE_H_
+#ifndef EXTENSIONS_SHELL_BROWSER_SHELL_NETWORK_DELEGATE_H_
+#define EXTENSIONS_SHELL_BROWSER_SHELL_NETWORK_DELEGATE_H_
 
 #include "base/macros.h"
 #include "extensions/browser/info_map.h"
@@ -58,4 +58,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_NETNETWORK_DELEGATE_H_
+#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_NETWORK_DELEGATE_H_
diff --git a/extensions/shell/browser/shell_oauth2_token_service_delegate.h b/extensions/shell/browser/shell_oauth2_token_service_delegate.h
index 2537092..3a87c07 100644
--- a/extensions/shell/browser/shell_oauth2_token_service_delegate.h
+++ b/extensions/shell/browser/shell_oauth2_token_service_delegate.h
@@ -52,4 +52,4 @@
 };
 
 }  // namespace extensions
-#endif
+#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_OAUTH2_TOKEN_SERVICE_DELEGATE_H_
diff --git a/extensions/shell/browser/shell_special_storage_policy.h b/extensions/shell/browser/shell_special_storage_policy.h
index dc78154..225d2d1 100644
--- a/extensions/shell/browser/shell_special_storage_policy.h
+++ b/extensions/shell/browser/shell_special_storage_policy.h
@@ -30,4 +30,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_SPECIAL_STORAGE_POLICY_H
+#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_SPECIAL_STORAGE_POLICY_H_
diff --git a/extensions/shell/browser/shell_speech_recognition_manager_delegate.h b/extensions/shell/browser/shell_speech_recognition_manager_delegate.h
index 3ee126c..7c05813a 100644
--- a/extensions/shell/browser/shell_speech_recognition_manager_delegate.h
+++ b/extensions/shell/browser/shell_speech_recognition_manager_delegate.h
@@ -56,4 +56,4 @@
 }  // namespace speech
 }  // namespace extensions
 
-#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_CONTENT_BROWSER_CLIENT_H_
+#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
diff --git a/extensions/utility/utility_handler.h b/extensions/utility/utility_handler.h
index b32707f92..2bc12f4 100644
--- a/extensions/utility/utility_handler.h
+++ b/extensions/utility/utility_handler.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_UTILITY_UTILITY_HANDLER_
-#define EXTENSIONS_UTILITY_UTILITY_HANDLER_
+#ifndef EXTENSIONS_UTILITY_UTILITY_HANDLER_H_
+#define EXTENSIONS_UTILITY_UTILITY_HANDLER_H_
 
 #include <string>
 
@@ -44,4 +44,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_UTILITY_UTILITY_HANDLER_
+#endif  // EXTENSIONS_UTILITY_UTILITY_HANDLER_H_
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 7f49bd2..0c1ac65 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -2418,7 +2418,7 @@
     helper_->CompressedTexSubImage2D(
         target, level, xoffset, yoffset, width, height, format, image_size,
         0, ToGLuint(data));
-  } else {
+  } else if (data) {
     SetBucketContents(kResultBucketId, data, image_size);
     helper_->CompressedTexSubImage2DBucket(
         target, level, xoffset, yoffset, width, height, format,
@@ -2427,6 +2427,9 @@
     // and we don't have to wait for the result so from the client's perspective
     // it's cheap.
     helper_->SetBucketSize(kResultBucketId, 0);
+  } else {
+    helper_->CompressedTexSubImage2D(target, level, xoffset, yoffset, width,
+                                     height, format, image_size, 0, 0);
   }
   CheckGLError();
 }
@@ -2521,7 +2524,7 @@
     helper_->CompressedTexSubImage3D(
         target, level, xoffset, yoffset, zoffset, width, height, depth, format,
         image_size, 0, ToGLuint(data));
-  } else {
+  } else if (data) {
     SetBucketContents(kResultBucketId, data, image_size);
     helper_->CompressedTexSubImage3DBucket(
         target, level, xoffset, yoffset, zoffset, width, height, depth, format,
@@ -2530,6 +2533,10 @@
     // and we don't have to wait for the result so from the client's perspective
     // it's cheap.
     helper_->SetBucketSize(kResultBucketId, 0);
+  } else {
+    helper_->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset,
+                                     width, height, depth, format, image_size,
+                                     0, 0);
   }
   CheckGLError();
 }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index e9fb769..068436bc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -3128,6 +3128,9 @@
         case GL_TEXTURE_RECTANGLE_ARB:
           supported = feature_info_->feature_flags().arb_texture_rectangle;
           break;
+        case GL_TEXTURE_EXTERNAL_OES:
+          supported = feature_info_->feature_flags().oes_egl_image_external;
+          break;
         case GL_TEXTURE_2D:
           supported = true;
           break;
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_ozone_native_pixmap.cc b/gpu/ipc/service/gpu_memory_buffer_factory_ozone_native_pixmap.cc
index e59f155c..8b266b8 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_ozone_native_pixmap.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_ozone_native_pixmap.cc
@@ -32,9 +32,9 @@
           ->GetSurfaceFactoryOzone()
           ->CreateNativePixmap(surface_handle, size, format, usage);
   if (!pixmap.get()) {
-    DLOG(ERROR) << "Failed to create pixmap " << size.width() << "x"
-                << size.height() << " format " << static_cast<int>(format)
-                << ", usage " << static_cast<int>(usage);
+    DLOG(ERROR) << "Failed to create pixmap " << size.ToString() << " format "
+                << static_cast<int>(format) << ", usage "
+                << static_cast<int>(usage);
     return gfx::GpuMemoryBufferHandle();
   }
 
@@ -109,10 +109,40 @@
   scoped_refptr<ui::GLImageOzoneNativePixmap> image(
       new ui::GLImageOzoneNativePixmap(size, internalformat));
   if (!image->Initialize(pixmap.get(), format)) {
-    LOG(ERROR) << "Failed to create GLImage";
+    LOG(ERROR) << "Failed to create GLImage " << size.ToString() << " format "
+               << static_cast<int>(format);
     return nullptr;
   }
   return image;
 }
 
+scoped_refptr<gl::GLImage>
+GpuMemoryBufferFactoryOzoneNativePixmap::CreateAnonymousImage(
+    const gfx::Size& size,
+    gfx::BufferFormat format,
+    unsigned internalformat) {
+  scoped_refptr<ui::NativePixmap> pixmap =
+      ui::OzonePlatform::GetInstance()
+          ->GetSurfaceFactoryOzone()
+          ->CreateNativePixmap(gpu::kNullSurfaceHandle, size, format,
+                               gfx::BufferUsage::SCANOUT);
+  if (!pixmap.get()) {
+    LOG(ERROR) << "Failed to create pixmap " << size.ToString() << " format "
+               << static_cast<int>(format);
+    return nullptr;
+  }
+  scoped_refptr<ui::GLImageOzoneNativePixmap> image(
+      new ui::GLImageOzoneNativePixmap(size, internalformat));
+  if (!image->Initialize(pixmap.get(), format)) {
+    LOG(ERROR) << "Failed to create GLImage " << size.ToString() << " format "
+               << static_cast<int>(format);
+    return nullptr;
+  }
+  return image;
+}
+
+unsigned GpuMemoryBufferFactoryOzoneNativePixmap::RequiredTextureType() {
+  return GL_TEXTURE_EXTERNAL_OES;
+}
+
 }  // namespace gpu
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_ozone_native_pixmap.h b/gpu/ipc/service/gpu_memory_buffer_factory_ozone_native_pixmap.h
index 5a132bbd..45be752 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_ozone_native_pixmap.h
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_ozone_native_pixmap.h
@@ -49,6 +49,11 @@
       unsigned internalformat,
       int client_id,
       SurfaceHandle surface_handle) override;
+  scoped_refptr<gl::GLImage> CreateAnonymousImage(
+      const gfx::Size& size,
+      gfx::BufferFormat format,
+      unsigned internalformat) override;
+  unsigned RequiredTextureType() override;
 
  private:
   using NativePixmapMapKey = std::pair<int, int>;
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS
index 6f78d48..5d7aca8 100644
--- a/ios/chrome/browser/DEPS
+++ b/ios/chrome/browser/DEPS
@@ -8,6 +8,7 @@
   "+components/bookmarks",
   "+components/browser_sync",
   "+components/browsing_data/core",
+  "+components/captive_portal",
   "+components/component_updater",
   "+components/content_settings/core",
   "+components/cookie_config",
diff --git a/ios/chrome/browser/ssl/BUILD.gn b/ios/chrome/browser/ssl/BUILD.gn
index 2691877d..29e125e 100644
--- a/ios/chrome/browser/ssl/BUILD.gn
+++ b/ios/chrome/browser/ssl/BUILD.gn
@@ -5,6 +5,8 @@
 source_set("ssl") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "captive_portal_detector_tab_helper.h",
+    "captive_portal_detector_tab_helper.mm",
     "ios_security_state_tab_helper.h",
     "ios_security_state_tab_helper.mm",
     "ios_ssl_blocking_page.h",
@@ -14,6 +16,7 @@
   ]
   deps = [
     "//base",
+    "//components/captive_portal",
     "//components/security_interstitials/core",
     "//components/security_state/core",
     "//components/strings",
diff --git a/ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h b/ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h
new file mode 100644
index 0000000..c7d9335d
--- /dev/null
+++ b/ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h
@@ -0,0 +1,35 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SSL_CAPTIVE_PORTAL_DETECTOR_TAB_HELPER_H_
+#define IOS_CHROME_BROWSER_SSL_CAPTIVE_PORTAL_DETECTOR_TAB_HELPER_H_
+
+#import "ios/web/public/web_state/web_state_user_data.h"
+
+namespace captive_portal {
+class CaptivePortalDetector;
+}
+
+namespace web {
+class WebState;
+}
+
+// Associates a Tab to a CaptivePortalDetector and manages its lifetime.
+class CaptivePortalDetectorTabHelper
+    : public web::WebStateUserData<CaptivePortalDetectorTabHelper> {
+ public:
+  explicit CaptivePortalDetectorTabHelper(web::WebState* web_state);
+
+  captive_portal::CaptivePortalDetector* detector();
+
+ private:
+  ~CaptivePortalDetectorTabHelper() override;
+
+  // The underlying CaptivePortalDetector.
+  std::unique_ptr<captive_portal::CaptivePortalDetector> detector_;
+
+  DISALLOW_COPY_AND_ASSIGN(CaptivePortalDetectorTabHelper);
+};
+
+#endif  // IOS_CHROME_BROWSER_SSL_CAPTIVE_PORTAL_DETECTOR_TAB_HELPER_H_
diff --git a/ios/chrome/browser/ssl/captive_portal_detector_tab_helper.mm b/ios/chrome/browser/ssl/captive_portal_detector_tab_helper.mm
new file mode 100644
index 0000000..e9555941
--- /dev/null
+++ b/ios/chrome/browser/ssl/captive_portal_detector_tab_helper.mm
@@ -0,0 +1,24 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h"
+
+#include "base/memory/ptr_util.h"
+#include "components/captive_portal/captive_portal_detector.h"
+#include "ios/web/public/browser_state.h"
+#import "ios/web/public/web_state/web_state.h"
+
+DEFINE_WEB_STATE_USER_DATA_KEY(CaptivePortalDetectorTabHelper);
+
+captive_portal::CaptivePortalDetector*
+CaptivePortalDetectorTabHelper::detector() {
+  return detector_.get();
+}
+
+CaptivePortalDetectorTabHelper::CaptivePortalDetectorTabHelper(
+    web::WebState* web_state)
+    : detector_(base::MakeUnique<captive_portal::CaptivePortalDetector>(
+          web_state->GetBrowserState()->GetRequestContext())) {}
+
+CaptivePortalDetectorTabHelper::~CaptivePortalDetectorTabHelper() = default;
diff --git a/ios/chrome/browser/ssl/ios_ssl_error_handler.h b/ios/chrome/browser/ssl/ios_ssl_error_handler.h
index 00dc12ea..d3237d6 100644
--- a/ios/chrome/browser/ssl/ios_ssl_error_handler.h
+++ b/ios/chrome/browser/ssl/ios_ssl_error_handler.h
@@ -35,6 +35,9 @@
       web::WebState* web_state,
       const base::Callback<void(bool)>& callback,
       bool proceed);
+  // Records a metric to classify if SSL errors are due to a Captive Portal
+  // state.
+  static void RecordCaptivePortalState(web::WebState* web_state);
   DISALLOW_IMPLICIT_CONSTRUCTORS(IOSSSLErrorHandler);
 };
 
diff --git a/ios/chrome/browser/ssl/ios_ssl_error_handler.mm b/ios/chrome/browser/ssl/ios_ssl_error_handler.mm
index 80a54dc..d856e38 100644
--- a/ios/chrome/browser/ssl/ios_ssl_error_handler.mm
+++ b/ios/chrome/browser/ssl/ios_ssl_error_handler.mm
@@ -6,8 +6,13 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/mac/bind_objc_block.h"
+#include "base/metrics/histogram.h"
+#include "components/captive_portal/captive_portal_detector.h"
 #include "components/security_interstitials/core/ssl_error_ui.h"
+#include "ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h"
 #include "ios/chrome/browser/ssl/ios_ssl_blocking_page.h"
+#include "ios/web/public/browser_state.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "net/ssl/ssl_info.h"
 
@@ -15,6 +20,21 @@
 #error "This file requires ARC support."
 #endif
 
+// Enum used to record the captive portal detection result.
+enum class CaptivePortalStatus {
+  UNKNOWN = 0,
+  OFFLINE = 1,
+  ONLINE = 2,
+  PORTAL = 3,
+  PROXY_AUTH_REQUIRED = 4,
+  COUNT
+};
+
+const char kSessionDetectionResultHistogram[] =
+    "CaptivePortal.Session.DetectionResult";
+
+using captive_portal::CaptivePortalDetector;
+
 // static
 void IOSSSLErrorHandler::HandleSSLError(
     web::WebState* web_state,
@@ -25,6 +45,8 @@
     const base::Callback<void(bool)>& callback) {
   DCHECK(!web_state->IsShowingWebInterstitial());
 
+  IOSSSLErrorHandler::RecordCaptivePortalState(web_state);
+
   int options_mask =
       overridable ? security_interstitials::SSLErrorUI::SOFT_OVERRIDE_ENABLED
                   : security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT;
@@ -39,6 +61,32 @@
 }
 
 // static
+void IOSSSLErrorHandler::RecordCaptivePortalState(web::WebState* web_state) {
+  CaptivePortalDetectorTabHelper::CreateForWebState(web_state);
+  CaptivePortalDetectorTabHelper* tab_helper =
+      CaptivePortalDetectorTabHelper::FromWebState(web_state);
+  tab_helper->detector()->DetectCaptivePortal(
+      GURL(CaptivePortalDetector::kDefaultURL),
+      base::BindBlockArc(^(const CaptivePortalDetector::Results& results) {
+        CaptivePortalStatus status;
+        switch (results.result) {
+          case captive_portal::RESULT_INTERNET_CONNECTED:
+            status = CaptivePortalStatus::ONLINE;
+            break;
+          case captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL:
+            status = CaptivePortalStatus::PORTAL;
+            break;
+          default:
+            status = CaptivePortalStatus::UNKNOWN;
+            break;
+        }
+        UMA_HISTOGRAM_ENUMERATION(kSessionDetectionResultHistogram,
+                                  static_cast<int>(status),
+                                  static_cast<int>(CaptivePortalStatus::COUNT));
+      }));
+}
+
+// static
 void IOSSSLErrorHandler::InterstitialWasDismissed(
     web::WebState* web_state,
     const base::Callback<void(bool)>& callback,
diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc
index 30c6162..83103be 100644
--- a/media/formats/mp4/box_definitions.cc
+++ b/media/formats/mp4/box_definitions.cc
@@ -9,6 +9,7 @@
 
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "base/numerics/safe_math.h"
 #include "base/strings/string_number_conversions.h"
 #include "media/base/media_switches.h"
 #include "media/base/video_types.h"
@@ -1122,16 +1123,31 @@
 
   int fields = sample_duration_present + sample_size_present +
       sample_flags_present + sample_composition_time_offsets_present;
-  RCHECK(reader->HasBytes(fields * sample_count));
 
-  if (sample_duration_present)
+  // |bytes_needed| is potentially 64-bit. Cast |sample_count| from uint32_t to
+  // size_t to avoid multiplication overflow.
+  base::CheckedNumeric<size_t> bytes_needed =
+      base::CheckMul(fields, static_cast<size_t>(sample_count));
+  RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
+                      "Extreme TRUN sample count exceeds system address space");
+  RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
+
+  if (sample_duration_present) {
+    RCHECK(sample_count <= sample_durations.max_size());
     sample_durations.resize(sample_count);
-  if (sample_size_present)
+  }
+  if (sample_size_present) {
+    RCHECK(sample_count <= sample_sizes.max_size());
     sample_sizes.resize(sample_count);
-  if (sample_flags_present)
+  }
+  if (sample_flags_present) {
+    RCHECK(sample_count <= sample_flags.max_size());
     sample_flags.resize(sample_count);
-  if (sample_composition_time_offsets_present)
+  }
+  if (sample_composition_time_offsets_present) {
+    RCHECK(sample_count <= sample_composition_time_offsets.max_size());
     sample_composition_time_offsets.resize(sample_count);
+  }
 
   for (uint32_t i = 0; i < sample_count; ++i) {
     if (sample_duration_present)
diff --git a/media/formats/mp4/box_reader_unittest.cc b/media/formats/mp4/box_reader_unittest.cc
index 09df3d7f..b416ab55 100644
--- a/media/formats/mp4/box_reader_unittest.cc
+++ b/media/formats/mp4/box_reader_unittest.cc
@@ -301,36 +301,6 @@
   EXPECT_FALSE(reader->ReadChild(&child));
 }
 
-TEST_F(BoxReaderTest, ReadAllChildrenWithInvalidChild) {
-  // This data is not a valid 'emsg' box. It is just used as a top-level box
-  // as ReadTopLevelBox() has a restricted set of boxes it allows.
-  // The nested 'trun' box is used as it includes a count of the number
-  // of samples. The data specifies a large number of samples, but only 1
-  // is actually included in the box. Verifying that the large count does not
-  // cause an int32_t overflow which would allow parsing of TrackFragmentRun
-  // to read past the end of the buffer.
-  static const uint8_t kData[] = {
-      0x00, 0x00, 0x00, 0x28, 'e',  'm',  's',  'g',  // outer box
-      0x00, 0x00, 0x00, 0x20, 't',  'r',  'u',  'n',  // nested box
-      0x00, 0x00, 0x0f, 0x00,  // version = 0, flags = samples present
-      0xff, 0xff, 0xff, 0xff,  // count = max, but only 1 actually included
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-  bool err;
-  std::unique_ptr<BoxReader> reader(
-      BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err));
-
-  EXPECT_FALSE(err);
-  EXPECT_TRUE(reader);
-  EXPECT_EQ(FOURCC_EMSG, reader->type());
-
-  // Reading the child should fail since the number of samples specified
-  // doesn't match what is in the box.
-  std::vector<TrackFragmentRun> children;
-  EXPECT_FALSE(reader->ReadAllChildrenAndCheckFourCC(&children));
-}
-
 TEST_F(BoxReaderTest, ReadAllChildrenWithChildLargerThanParent) {
   static const uint8_t kData[] = {
       0x00, 0x00, 0x00, 0x10, 's', 'k', 'i', 'p',  // outer box
@@ -349,5 +319,53 @@
   EXPECT_FALSE(reader->ReadAllChildren(&tmp));
 }
 
+TEST_F(BoxReaderTest, TrunSampleCount32bitOverflow) {
+  // This data is not a valid 'emsg' box. It is just used as a top-level box
+  // as ReadTopLevelBox() has a restricted set of boxes it allows.
+  // The nested 'trun' box specifies an unusually high number of samples, though
+  // only one sample is actually included in the box. The values for "sample
+  // count" and "flags" are chosen such that their 32-bit product will overflow
+  // to a very small number (4), leading to incorrect assumptions about bytes
+  // available and ultimately OOB reads. http://crbug.com/679640
+  static const uint8_t kData[] = {
+      0x00, 0x00, 0x00, 0x28,
+      'e',  'm',  's',  'g',  // outer box
+      0x00, 0x00, 0x00, 0x20,
+      't',  'r',  'u',  'n',  // nested box
+      0x00, 0x00,             // version = 0
+      0x03, 0x00,  // flags = 2 fields present (sample duration and sample size)
+      0x80, 0x00, 0x00, 0x02,  // sample count = 2147483650
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,  // only one sample present
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00};
+
+  bool err;
+  std::unique_ptr<BoxReader> reader(
+      BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err));
+
+  EXPECT_FALSE(err);
+  EXPECT_TRUE(reader);
+  EXPECT_EQ(FOURCC_EMSG, reader->type());
+
+// Overflow is only triggered/caught on 32-bit systems. 64-bit systems will
+// instead fail parsing because kData does not have enough bytes to describe
+// the large number of samples.
+#if defined(ARCH_CPU_32_BITS)
+  const int kOverflowLogCount = 1;
+#else
+  const int kOverflowLogCount = 0;
+#endif
+
+  EXPECT_MEDIA_LOG(
+      HasSubstr("Extreme TRUN sample count exceeds system address space"))
+      .Times(kOverflowLogCount);
+
+  // Reading the child should fail since the number of samples specified
+  // doesn't match what is in the box.
+  std::vector<TrackFragmentRun> children;
+  EXPECT_FALSE(reader->ReadAllChildrenAndCheckFourCC(&children));
+}
+
 }  // namespace mp4
 }  // namespace media
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h
index 9720575..8bb47cb 100644
--- a/net/base/net_error_list.h
+++ b/net/base/net_error_list.h
@@ -382,6 +382,10 @@
 // fallback will be removed.
 NET_ERROR(SSL_OBSOLETE_CIPHER, -172)
 
+// When a WebSocket handshake is done successfully, the URLRequest is cancelled
+// with this error code.
+NET_ERROR(WEBSOCKET_HANDSHAKE_SUCCESS, -173)
+
 // Certificate error codes
 //
 // The values of certificate error codes must be consecutive.
diff --git a/net/websockets/websocket_stream.cc b/net/websockets/websocket_stream.cc
index 5920826..ca73a53 100644
--- a/net/websockets/websocket_stream.cc
+++ b/net/websockets/websocket_stream.cc
@@ -148,9 +148,13 @@
 
     timer_->Stop();
 
+    std::unique_ptr<URLRequest> url_request = std::move(url_request_);
     WebSocketHandshakeStreamBase* handshake_stream = handshake_stream_;
     handshake_stream_ = nullptr;
     connect_delegate_->OnSuccess(handshake_stream->Upgrade());
+
+    // This is safe even if |this| has already been deleted.
+    url_request->CancelWithError(ERR_WEBSOCKET_HANDSHAKE_SUCCESS);
   }
 
   std::string FailureMessageFromNetError(int net_error) {
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc
index 091c28d..78bda66 100644
--- a/net/websockets/websocket_stream_test.cc
+++ b/net/websockets/websocket_stream_test.cc
@@ -337,6 +337,8 @@
   EXPECT_TRUE(stream_);
   EXPECT_TRUE(request_info_);
   EXPECT_TRUE(response_info_);
+  EXPECT_EQ(ERR_WEBSOCKET_HANDSHAKE_SUCCESS,
+            url_request_context_host_.network_delegate().last_error());
 }
 
 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) {
@@ -483,6 +485,8 @@
             "Response must not include 'Sec-WebSocket-Protocol' header "
             "if not present in request: chatv20.chromium.org",
             failure_message());
+  EXPECT_EQ(ERR_INVALID_RESPONSE,
+            url_request_context_host_.network_delegate().last_error());
 }
 
 // Missing sub-protocol response is rejected.
diff --git a/net/websockets/websocket_test_util.h b/net/websockets/websocket_test_util.h
index 6083146..23769404 100644
--- a/net/websockets/websocket_test_util.h
+++ b/net/websockets/websocket_test_util.h
@@ -126,6 +126,10 @@
   // returned pointer remains owned by this object.
   TestURLRequestContext* GetURLRequestContext();
 
+  const TestNetworkDelegate& network_delegate() const {
+    return network_delegate_;
+  }
+
  private:
   WebSocketMockClientSocketFactoryMaker maker_;
   TestURLRequestContext url_request_context_;
diff --git a/remoting/client/display/gl_renderer.h b/remoting/client/display/gl_renderer.h
index 72f04e4..46632187 100644
--- a/remoting/client/display/gl_renderer.h
+++ b/remoting/client/display/gl_renderer.h
@@ -98,6 +98,8 @@
   base::WeakPtr<GlRenderer> GetWeakPtr();
 
   // Convenience method to create a Renderer with standard desktop components.
+  // This function must be called on the display thread, or whatever thread that
+  // will be used after the renderer is created.
   static std::unique_ptr<GlRenderer> CreateGlRendererWithDesktop();
 
  private:
diff --git a/remoting/client/jni/jni_gl_display_handler.cc b/remoting/client/jni/jni_gl_display_handler.cc
index 85c0641..742c088 100644
--- a/remoting/client/jni/jni_gl_display_handler.cc
+++ b/remoting/client/jni/jni_gl_display_handler.cc
@@ -22,7 +22,8 @@
 
 namespace remoting {
 
-// The core that lives on the display thread.
+// The core that lives on the display thread. Must not be created on the display
+// thread.
 class JniGlDisplayHandler::Core : public protocol::CursorShapeStub,
                                   public GlRendererDelegate {
  public:
@@ -41,6 +42,9 @@
   // thread but no more than once.
   std::unique_ptr<protocol::FrameConsumer> GrabFrameConsumer();
 
+  void OnFrameReceived(std::unique_ptr<webrtc::DesktopFrame> frame,
+                       const base::Closure& done);
+
   void SurfaceCreated(base::android::ScopedJavaGlobalRef<jobject> surface);
   void SurfaceChanged(int width, int height);
   void SurfaceDestroyed();
@@ -53,6 +57,9 @@
   base::WeakPtr<Core> GetWeakPtr();
 
  private:
+  // Initializes the core on the display thread.
+  void Initialize();
+
   ChromotingJniRuntime* runtime_;
   base::WeakPtr<JniGlDisplayHandler> shell_;
 
@@ -75,11 +82,16 @@
 JniGlDisplayHandler::Core::Core(ChromotingJniRuntime* runtime,
                                 base::WeakPtr<JniGlDisplayHandler> shell)
     : runtime_(runtime), shell_(shell), weak_factory_(this) {
-  renderer_ = GlRenderer::CreateGlRendererWithDesktop();
+  DCHECK(!runtime_->display_task_runner()->BelongsToCurrentThread());
+  runtime_->display_task_runner()->PostTask(
+      FROM_HERE, base::Bind(&JniGlDisplayHandler::Core::Initialize,
+                            base::Unretained(this)));
+
   weak_ptr_ = weak_factory_.GetWeakPtr();
-  renderer_->SetDelegate(weak_ptr_);
+
+  // Do not bind GlRenderer::OnFrameReceived. |renderer_| is not ready yet.
   owned_frame_consumer_.reset(new DualBufferFrameConsumer(
-      base::Bind(&GlRenderer::OnFrameReceived, renderer_->GetWeakPtr()),
+      base::Bind(&JniGlDisplayHandler::Core::OnFrameReceived, weak_ptr_),
       runtime_->display_task_runner(),
       protocol::FrameConsumer::PixelFormat::FORMAT_RGBA));
   frame_consumer_ = owned_frame_consumer_->GetWeakPtr();
@@ -118,6 +130,13 @@
   return std::move(owned_frame_consumer_);
 }
 
+void JniGlDisplayHandler::Core::OnFrameReceived(
+    std::unique_ptr<webrtc::DesktopFrame> frame,
+    const base::Closure& done) {
+  DCHECK(runtime_->display_task_runner()->BelongsToCurrentThread());
+  renderer_->OnFrameReceived(std::move(frame), done);
+}
+
 void JniGlDisplayHandler::Core::SurfaceCreated(
     base::android::ScopedJavaGlobalRef<jobject> surface) {
   DCHECK(runtime_->display_task_runner()->BelongsToCurrentThread());
@@ -180,6 +199,13 @@
   return weak_ptr_;
 }
 
+void JniGlDisplayHandler::Core::Initialize() {
+  DCHECK(runtime_->display_task_runner()->BelongsToCurrentThread());
+
+  renderer_ = GlRenderer::CreateGlRendererWithDesktop();
+  renderer_->SetDelegate(weak_ptr_);
+}
+
 // Shell implementations.
 
 JniGlDisplayHandler::JniGlDisplayHandler(
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index a2d037a..a05f055 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -1,4 +1,26 @@
 {
+  "Android Tests (trial)(dbg)": {
+    "gtest_tests": [
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "blink_heap_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "blink_platform_unittests"
+      }
+    ],
+    "scripts": [
+      {
+        "name": "telemetry_unittests",
+        "script": "telemetry_unittests.py"
+      }
+    ]
+  },
   "Jelly Bean Tester": {
     "gtest_tests": [
       {
@@ -1746,5 +1768,1165 @@
         "script": "telemetry_perf_unittests.py"
       }
     ]
+  },
+  "x64 Device Tester": {
+    "gtest_tests": [
+      {
+        "override_compile_targets": [
+          "android_webview_test_apk"
+        ],
+        "override_isolate_target": "android_webview_test_apk",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "android_webview_test_apk"
+      },
+      {
+        "override_isolate_target": "angle_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "angle_unittests"
+      },
+      {
+        "override_isolate_target": "base_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "base_unittests"
+      },
+      {
+        "override_isolate_target": "blink_heap_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "blink_heap_unittests"
+      },
+      {
+        "override_isolate_target": "breakpad_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "breakpad_unittests"
+      },
+      {
+        "override_isolate_target": "cacheinvalidation_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "cacheinvalidation_unittests"
+      },
+      {
+        "override_isolate_target": "capture_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "capture_unittests"
+      },
+      {
+        "override_isolate_target": "cast_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "cast_unittests"
+      },
+      {
+        "override_isolate_target": "cc_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "cc_unittests"
+      },
+      {
+        "override_compile_targets": [
+          "chrome_public_test_apk"
+        ],
+        "override_isolate_target": "chrome_public_test_apk",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "chrome_public_test_apk"
+      },
+      {
+        "override_compile_targets": [
+          "chrome_sync_shell_test_apk"
+        ],
+        "override_isolate_target": "chrome_sync_shell_test_apk",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "chrome_sync_shell_test_apk"
+      },
+      {
+        "override_isolate_target": "components_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "components_browsertests"
+      },
+      {
+        "override_isolate_target": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "components_unittests"
+      },
+      {
+        "override_isolate_target": "content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "content_browsertests"
+      },
+      {
+        "override_compile_targets": [
+          "content_shell_test_apk"
+        ],
+        "override_isolate_target": "content_shell_test_apk",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "content_shell_test_apk"
+      },
+      {
+        "override_isolate_target": "content_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "content_unittests"
+      },
+      {
+        "override_isolate_target": "crypto_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "crypto_unittests"
+      },
+      {
+        "override_isolate_target": "device_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "device_unittests"
+      },
+      {
+        "override_isolate_target": "display_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "display_unittests"
+      },
+      {
+        "override_isolate_target": "events_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "events_unittests"
+      },
+      {
+        "override_isolate_target": "gcm_unit_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "gcm_unit_tests"
+      },
+      {
+        "override_isolate_target": "gfx_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "gfx_unittests"
+      },
+      {
+        "override_isolate_target": "gl_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "gl_tests"
+      },
+      {
+        "override_isolate_target": "gl_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "gl_unittests"
+      },
+      {
+        "override_isolate_target": "google_apis_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "google_apis_unittests"
+      },
+      {
+        "override_isolate_target": "gpu_ipc_service_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "gpu_ipc_service_unittests"
+      },
+      {
+        "override_isolate_target": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "gpu_unittests"
+      },
+      {
+        "override_isolate_target": "ipc_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "ipc_tests"
+      },
+      {
+        "override_isolate_target": "jingle_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "jingle_unittests"
+      },
+      {
+        "override_isolate_target": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "media_unittests"
+      },
+      {
+        "override_isolate_target": "midi_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "midi_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_common_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "mojo_common_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_public_application_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "mojo_public_application_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_public_bindings_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "mojo_public_bindings_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_public_system_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "mojo_public_system_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_system_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "mojo_system_unittests"
+      },
+      {
+        "override_isolate_target": "net_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "net_unittests"
+      },
+      {
+        "override_isolate_target": "remoting_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "remoting_unittests"
+      },
+      {
+        "override_isolate_target": "sandbox_linux_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "sandbox_linux_unittests"
+      },
+      {
+        "override_isolate_target": "skia_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "skia_unittests"
+      },
+      {
+        "override_isolate_target": "sql_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "sql_unittests"
+      },
+      {
+        "override_isolate_target": "storage_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "storage_unittests"
+      },
+      {
+        "override_isolate_target": "ui_android_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "ui_android_unittests"
+      },
+      {
+        "override_isolate_target": "ui_base_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "ui_base_unittests"
+      },
+      {
+        "override_isolate_target": "ui_touch_selection_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "ui_touch_selection_unittests"
+      },
+      {
+        "override_isolate_target": "unit_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "unit_tests"
+      },
+      {
+        "override_isolate_target": "url_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "url_unittests"
+      },
+      {
+        "override_isolate_target": "webkit_unit_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "webkit_unit_tests"
+      },
+      {
+        "override_isolate_target": "wtf_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "device_type": "coho"
+            }
+          ]
+        },
+        "test": "wtf_unittests"
+      }
+    ]
+  },
+  "x86 Cloud Tester": {
+    "gtest_tests": [
+      {
+        "override_compile_targets": [
+          "android_webview_test_apk"
+        ],
+        "override_isolate_target": "android_webview_test_apk",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 960
+        },
+        "test": "android_webview_test_apk"
+      },
+      {
+        "override_isolate_target": "android_webview_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "android_webview_unittests"
+      },
+      {
+        "override_isolate_target": "base_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "base_unittests"
+      },
+      {
+        "override_isolate_target": "blink_heap_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 120
+        },
+        "test": "blink_heap_unittests"
+      },
+      {
+        "override_isolate_target": "breakpad_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "breakpad_unittests"
+      },
+      {
+        "override_isolate_target": "capture_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "capture_unittests"
+      },
+      {
+        "override_isolate_target": "cc_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "cc_unittests"
+      },
+      {
+        "override_compile_targets": [
+          "chrome_public_test_apk"
+        ],
+        "override_isolate_target": "chrome_public_test_apk",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 1200
+        },
+        "test": "chrome_public_test_apk"
+      },
+      {
+        "override_compile_targets": [
+          "chrome_sync_shell_test_apk"
+        ],
+        "override_isolate_target": "chrome_sync_shell_test_apk",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 600
+        },
+        "test": "chrome_sync_shell_test_apk"
+      },
+      {
+        "override_isolate_target": "components_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "components_browsertests"
+      },
+      {
+        "override_isolate_target": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "components_unittests"
+      },
+      {
+        "override_isolate_target": "content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 960
+        },
+        "test": "content_browsertests"
+      },
+      {
+        "override_compile_targets": [
+          "content_shell_test_apk"
+        ],
+        "override_isolate_target": "content_shell_test_apk",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 1920
+        },
+        "test": "content_shell_test_apk"
+      },
+      {
+        "override_isolate_target": "content_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "content_unittests"
+      },
+      {
+        "override_isolate_target": "device_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "device_unittests"
+      },
+      {
+        "override_isolate_target": "events_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "events_unittests"
+      },
+      {
+        "override_isolate_target": "gl_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "gl_tests"
+      },
+      {
+        "override_isolate_target": "gl_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 60
+        },
+        "test": "gl_unittests"
+      },
+      {
+        "override_isolate_target": "gpu_ipc_service_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "gpu_ipc_service_unittests"
+      },
+      {
+        "override_isolate_target": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "gpu_unittests"
+      },
+      {
+        "override_isolate_target": "ipc_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "ipc_tests"
+      },
+      {
+        "override_isolate_target": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "media_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_common_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 60
+        },
+        "test": "mojo_common_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_public_application_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 60
+        },
+        "test": "mojo_public_application_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_public_bindings_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 60
+        },
+        "test": "mojo_public_bindings_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_public_system_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 60
+        },
+        "test": "mojo_public_system_unittests"
+      },
+      {
+        "override_isolate_target": "mojo_system_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 120
+        },
+        "test": "mojo_system_unittests"
+      },
+      {
+        "override_isolate_target": "net_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "net_unittests"
+      },
+      {
+        "override_isolate_target": "sandbox_linux_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "sandbox_linux_unittests"
+      },
+      {
+        "override_isolate_target": "sql_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "sql_unittests"
+      },
+      {
+        "override_isolate_target": "storage_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "storage_unittests"
+      },
+      {
+        "override_isolate_target": "ui_android_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "ui_android_unittests"
+      },
+      {
+        "override_isolate_target": "ui_base_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "ui_base_unittests"
+      },
+      {
+        "override_isolate_target": "ui_touch_selection_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "ui_touch_selection_unittests"
+      },
+      {
+        "override_isolate_target": "unit_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ]
+        },
+        "test": "unit_tests"
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "--browser=android-chromium",
+          "--device=android"
+        ],
+        "isolate_name": "telemetry_perf_unittests",
+        "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "4",
+              "device_type": "gce_x86"
+            }
+          ],
+          "hard_timeout": 960,
+          "shards": 1
+        }
+      }
+    ]
   }
 }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index c3cde1d0..c4b2361 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -219,629 +219,6 @@
       }
     ]
   },
-  "Android Cloud Tests": {
-    "gtest_tests": [
-      {
-        "override_compile_targets": [
-          "android_webview_test_apk"
-        ],
-        "override_isolate_target": "android_webview_test_apk",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 960
-        },
-        "test": "android_webview_test_apk"
-      },
-      {
-        "override_isolate_target": "android_webview_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "android_webview_unittests"
-      },
-      {
-        "override_isolate_target": "base_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "base_unittests"
-      },
-      {
-        "override_isolate_target": "blink_heap_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 120
-        },
-        "test": "blink_heap_unittests"
-      },
-      {
-        "override_isolate_target": "breakpad_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "breakpad_unittests"
-      },
-      {
-        "override_isolate_target": "capture_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "capture_unittests"
-      },
-      {
-        "override_isolate_target": "cc_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "cc_unittests"
-      },
-      {
-        "override_compile_targets": [
-          "chrome_public_test_apk"
-        ],
-        "override_isolate_target": "chrome_public_test_apk",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 1200
-        },
-        "test": "chrome_public_test_apk"
-      },
-      {
-        "override_compile_targets": [
-          "chrome_sync_shell_test_apk"
-        ],
-        "override_isolate_target": "chrome_sync_shell_test_apk",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 600
-        },
-        "test": "chrome_sync_shell_test_apk"
-      },
-      {
-        "override_isolate_target": "components_browsertests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "components_browsertests"
-      },
-      {
-        "override_isolate_target": "components_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "components_unittests"
-      },
-      {
-        "override_isolate_target": "content_browsertests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 960
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "override_compile_targets": [
-          "content_shell_test_apk"
-        ],
-        "override_isolate_target": "content_shell_test_apk",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 1920
-        },
-        "test": "content_shell_test_apk"
-      },
-      {
-        "override_isolate_target": "content_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "content_unittests"
-      },
-      {
-        "override_isolate_target": "device_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "device_unittests"
-      },
-      {
-        "override_isolate_target": "events_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "events_unittests"
-      },
-      {
-        "override_isolate_target": "gl_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "gl_tests"
-      },
-      {
-        "override_isolate_target": "gl_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 60
-        },
-        "test": "gl_unittests"
-      },
-      {
-        "override_isolate_target": "gpu_ipc_service_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "gpu_ipc_service_unittests"
-      },
-      {
-        "override_isolate_target": "gpu_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "gpu_unittests"
-      },
-      {
-        "override_isolate_target": "ipc_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "ipc_tests"
-      },
-      {
-        "override_isolate_target": "media_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "media_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_common_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 60
-        },
-        "test": "mojo_common_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_public_application_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 60
-        },
-        "test": "mojo_public_application_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_public_bindings_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 60
-        },
-        "test": "mojo_public_bindings_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_public_system_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 60
-        },
-        "test": "mojo_public_system_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_system_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 120
-        },
-        "test": "mojo_system_unittests"
-      },
-      {
-        "override_isolate_target": "net_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "net_unittests"
-      },
-      {
-        "override_isolate_target": "sandbox_linux_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "sandbox_linux_unittests"
-      },
-      {
-        "override_isolate_target": "sql_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "sql_unittests"
-      },
-      {
-        "override_isolate_target": "storage_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "storage_unittests"
-      },
-      {
-        "override_isolate_target": "ui_android_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "ui_android_unittests"
-      },
-      {
-        "override_isolate_target": "ui_base_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "ui_base_unittests"
-      },
-      {
-        "override_isolate_target": "ui_touch_selection_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "ui_touch_selection_unittests"
-      },
-      {
-        "override_isolate_target": "unit_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ]
-        },
-        "test": "unit_tests"
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "--browser=android-chromium",
-          "--device=android"
-        ],
-        "isolate_name": "telemetry_perf_unittests",
-        "name": "telemetry_perf_unittests",
-        "override_compile_targets": [
-          "telemetry_perf_unittests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "4",
-              "device_type": "gce_x86"
-            }
-          ],
-          "hard_timeout": 960,
-          "shards": 1
-        }
-      }
-    ]
-  },
-  "Android Tests (trial)(dbg)": {
-    "gtest_tests": [
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": false
-        },
-        "test": "blink_heap_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": false
-        },
-        "test": "blink_platform_unittests"
-      }
-    ],
-    "scripts": [
-      {
-        "name": "telemetry_unittests",
-        "script": "telemetry_unittests.py"
-      }
-    ]
-  },
-  "Android User Builder Tests": {
-    "gtest_tests": [
-      {
-        "test": "android_webview_unittests"
-      },
-      {
-        "test": "base_unittests"
-      },
-      {
-        "override_compile_targets": [
-          "breakpad_unittests_deps"
-        ],
-        "test": "breakpad_unittests"
-      },
-      {
-        "test": "capture_unittests"
-      },
-      {
-        "test": "cc_unittests"
-      },
-      {
-        "test": "components_browsertests"
-      },
-      {
-        "test": "components_unittests"
-      },
-      {
-        "test": "content_browsertests"
-      },
-      {
-        "test": "content_unittests"
-      },
-      {
-        "test": "device_unittests"
-      },
-      {
-        "test": "events_unittests"
-      },
-      {
-        "test": "gl_tests"
-      },
-      {
-        "test": "gl_unittests"
-      },
-      {
-        "test": "gpu_ipc_service_unittests"
-      },
-      {
-        "test": "gpu_unittests"
-      },
-      {
-        "test": "ipc_tests"
-      },
-      {
-        "test": "media_unittests"
-      },
-      {
-        "test": "midi_unittests"
-      },
-      {
-        "test": "net_unittests"
-      },
-      {
-        "override_compile_targets": [
-          "sandbox_linux_unittests_deps"
-        ],
-        "test": "sandbox_linux_unittests"
-      },
-      {
-        "test": "skia_unittests"
-      },
-      {
-        "test": "sql_unittests"
-      },
-      {
-        "test": "storage_unittests"
-      },
-      {
-        "test": "ui_android_unittests"
-      },
-      {
-        "test": "ui_base_unittests"
-      },
-      {
-        "test": "ui_touch_selection_unittests"
-      },
-      {
-        "test": "unit_tests"
-      },
-      {
-        "test": "webkit_unit_tests"
-      }
-    ]
-  },
   "Android VR Tests": {
     "gtest_tests": [
       {
@@ -861,659 +238,6 @@
       }
     ]
   },
-  "Android x64 Tests": {
-    "gtest_tests": [
-      {
-        "override_compile_targets": [
-          "android_webview_test_apk"
-        ],
-        "override_isolate_target": "android_webview_test_apk",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "android_webview_test_apk"
-      },
-      {
-        "override_isolate_target": "angle_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "angle_unittests"
-      },
-      {
-        "override_isolate_target": "base_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "base_unittests"
-      },
-      {
-        "override_isolate_target": "blink_heap_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "blink_heap_unittests"
-      },
-      {
-        "override_isolate_target": "breakpad_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "breakpad_unittests"
-      },
-      {
-        "override_isolate_target": "cacheinvalidation_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "cacheinvalidation_unittests"
-      },
-      {
-        "override_isolate_target": "capture_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "capture_unittests"
-      },
-      {
-        "override_isolate_target": "cast_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "cast_unittests"
-      },
-      {
-        "override_isolate_target": "cc_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "cc_unittests"
-      },
-      {
-        "override_compile_targets": [
-          "chrome_public_test_apk"
-        ],
-        "override_isolate_target": "chrome_public_test_apk",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "chrome_public_test_apk"
-      },
-      {
-        "override_compile_targets": [
-          "chrome_sync_shell_test_apk"
-        ],
-        "override_isolate_target": "chrome_sync_shell_test_apk",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "chrome_sync_shell_test_apk"
-      },
-      {
-        "override_isolate_target": "components_browsertests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "components_browsertests"
-      },
-      {
-        "override_isolate_target": "components_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "components_unittests"
-      },
-      {
-        "override_isolate_target": "content_browsertests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "override_compile_targets": [
-          "content_shell_test_apk"
-        ],
-        "override_isolate_target": "content_shell_test_apk",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "content_shell_test_apk"
-      },
-      {
-        "override_isolate_target": "content_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "content_unittests"
-      },
-      {
-        "override_isolate_target": "crypto_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "crypto_unittests"
-      },
-      {
-        "override_isolate_target": "device_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "device_unittests"
-      },
-      {
-        "override_isolate_target": "display_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "display_unittests"
-      },
-      {
-        "override_isolate_target": "events_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "events_unittests"
-      },
-      {
-        "override_isolate_target": "gcm_unit_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "gcm_unit_tests"
-      },
-      {
-        "override_isolate_target": "gfx_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "gfx_unittests"
-      },
-      {
-        "override_isolate_target": "gl_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "gl_tests"
-      },
-      {
-        "override_isolate_target": "gl_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "gl_unittests"
-      },
-      {
-        "override_isolate_target": "google_apis_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "google_apis_unittests"
-      },
-      {
-        "override_isolate_target": "gpu_ipc_service_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "gpu_ipc_service_unittests"
-      },
-      {
-        "override_isolate_target": "gpu_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "gpu_unittests"
-      },
-      {
-        "override_isolate_target": "ipc_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "ipc_tests"
-      },
-      {
-        "override_isolate_target": "jingle_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "jingle_unittests"
-      },
-      {
-        "override_isolate_target": "media_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "media_unittests"
-      },
-      {
-        "override_isolate_target": "midi_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "midi_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_common_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "mojo_common_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_public_application_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "mojo_public_application_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_public_bindings_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "mojo_public_bindings_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_public_system_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "mojo_public_system_unittests"
-      },
-      {
-        "override_isolate_target": "mojo_system_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "mojo_system_unittests"
-      },
-      {
-        "override_isolate_target": "net_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "net_unittests"
-      },
-      {
-        "override_isolate_target": "remoting_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "remoting_unittests"
-      },
-      {
-        "override_isolate_target": "sandbox_linux_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "sandbox_linux_unittests"
-      },
-      {
-        "override_isolate_target": "skia_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "skia_unittests"
-      },
-      {
-        "override_isolate_target": "sql_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "sql_unittests"
-      },
-      {
-        "override_isolate_target": "storage_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "storage_unittests"
-      },
-      {
-        "override_isolate_target": "ui_android_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "ui_android_unittests"
-      },
-      {
-        "override_isolate_target": "ui_base_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "ui_base_unittests"
-      },
-      {
-        "override_isolate_target": "ui_touch_selection_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "ui_touch_selection_unittests"
-      },
-      {
-        "override_isolate_target": "unit_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "unit_tests"
-      },
-      {
-        "override_isolate_target": "url_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "url_unittests"
-      },
-      {
-        "override_isolate_target": "webkit_unit_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "webkit_unit_tests"
-      },
-      {
-        "override_isolate_target": "wtf_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "device_type": "coho"
-            }
-          ]
-        },
-        "test": "wtf_unittests"
-      }
-    ]
-  },
   "Browser Side Navigation Linux": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 9c6307e..3572ec4 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -2820,373 +2820,6 @@
       }
     ]
   },
-  "Linux Debug (New Intel)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "angle_end2end_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "angle_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "audio_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "gl_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "gl_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "use_xvfb": false
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "swiftshader_unittests",
-        "use_xvfb": false
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "context_lost",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "context_lost_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "depth_capture",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "depth_capture_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "gpu_process",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "gpu_process_launch_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "hardware_accelerated_feature",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "hardware_accelerated_feature_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "maps",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--os-type",
-          "linux",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "maps_pixel_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "pixel",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--refimg-cloud-storage-bucket",
-          "chromium-gpu-archive/reference-images",
-          "--os-type",
-          "linux",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "pixel_test",
-        "non_precommit_args": [
-          "--upload-refimg-to-cloud-storage"
-        ],
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "precommit_args": [
-          "--download-refimg-from-cloud-storage"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "screenshot_sync",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "screenshot_sync_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "trace_test",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "trace_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_angle_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      }
-    ]
-  },
   "Linux Release (AMD R5 230)": {
     "gtest_tests": [
       {
@@ -5751,438 +5384,6 @@
       }
     ]
   },
-  "Linux Release (New Intel)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "angle_end2end_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "angle_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "audio_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--enable-gpu",
-          "--test-launcher-jobs=1",
-          "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*"
-        ],
-        "name": "tab_capture_end2end_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": false
-        },
-        "test": "browser_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "gl_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "gl_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "use_xvfb": false
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        },
-        "test": "swiftshader_unittests",
-        "use_xvfb": false
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "context_lost",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "context_lost_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "depth_capture",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "depth_capture_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "gpu_process",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "gpu_process_launch_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "hardware_accelerated_feature",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "hardware_accelerated_feature_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "maps",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--os-type",
-          "linux",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "maps_pixel_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "pixel",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--refimg-cloud-storage-bucket",
-          "chromium-gpu-archive/reference-images",
-          "--os-type",
-          "linux",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "pixel_test",
-        "non_precommit_args": [
-          "--upload-refimg-to-cloud-storage"
-        ],
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "precommit_args": [
-          "--download-refimg-from-cloud-storage"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "screenshot_sync",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "screenshot_sync_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "trace_test",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "trace_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle",
-          "--webgl-conformance-version=2.0.1",
-          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl2_conformance_angle_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ],
-          "shards": 15
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--webgl-conformance-version=2.0.1",
-          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl2_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ],
-          "shards": 15
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_angle_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Linux"
-            }
-          ]
-        }
-      }
-    ]
-  },
   "Mac 10.10 Debug (AMD)": {
     "gtest_tests": [
       {
@@ -8710,6 +7911,392 @@
       }
     ]
   },
+  "Mac Experimental Retina Release (NVIDIA)": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "angle_end2end_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "angle_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "audio_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--enable-gpu",
+          "--test-launcher-jobs=1",
+          "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*"
+        ],
+        "name": "tab_capture_end2end_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "browser_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gl_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gl_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gles2_conform_test",
+        "use_xvfb": false
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "depth_capture",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "depth_capture_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--os-type",
+          "mac",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "mac",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--webgl-conformance-version=2.0.1",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl2_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ],
+          "shards": 15
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        }
+      }
+    ]
+  },
   "Mac GPU ASAN Release": {
     "gtest_tests": [
       {
@@ -11590,472 +11177,6 @@
       }
     ]
   },
-  "Win10 Debug (New Intel)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "angle_end2end_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "angle_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "audio_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gl_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gl_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-angle=d3d9"
-        ],
-        "name": "gles2_conform_d3d9_test",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-angle=gl",
-          "--disable-gpu-sandbox"
-        ],
-        "name": "gles2_conform_gl_test",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "use_xvfb": false
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "swiftshader_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-test-data-path"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "video_decode_accelerator_unittest",
-        "use_xvfb": false
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "context_lost",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "context_lost_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "depth_capture",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "depth_capture_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "gpu_process",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "gpu_process_launch_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "hardware_accelerated_feature",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "hardware_accelerated_feature_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "maps",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--os-type",
-          "win",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "maps_pixel_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "pixel",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--refimg-cloud-storage-bucket",
-          "chromium-gpu-archive/reference-images",
-          "--os-type",
-          "win",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "pixel_test",
-        "non_precommit_args": [
-          "--upload-refimg-to-cloud-storage"
-        ],
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "precommit_args": [
-          "--download-refimg-from-cloud-storage"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "screenshot_sync",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "screenshot_sync_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "trace_test",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "trace_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-passthrough-cmd-decoder --disable-es3-apis --disable-es3-gl-context"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_d3d11_passthrough_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_d3d9_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=gl"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_gl_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=debug",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      }
-    ]
-  },
   "Win10 Release (Intel HD 530)": {
     "gtest_tests": [
       {
@@ -13069,511 +12190,6 @@
       }
     ]
   },
-  "Win10 Release (New Intel)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "angle_end2end_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "angle_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "audio_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--enable-gpu",
-          "--test-launcher-jobs=1",
-          "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*"
-        ],
-        "name": "tab_capture_end2end_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": false
-        },
-        "test": "browser_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gl_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gl_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-angle=d3d9"
-        ],
-        "name": "gles2_conform_d3d9_test",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-angle=gl",
-          "--disable-gpu-sandbox"
-        ],
-        "name": "gles2_conform_gl_test",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "use_xvfb": false
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "swiftshader_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-test-data-path"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        },
-        "test": "video_decode_accelerator_unittest",
-        "use_xvfb": false
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "context_lost",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "context_lost_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "depth_capture",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "depth_capture_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "gpu_process",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "gpu_process_launch_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "hardware_accelerated_feature",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "hardware_accelerated_feature_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "maps",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--os-type",
-          "win",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "maps_pixel_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "pixel",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--refimg-cloud-storage-bucket",
-          "chromium-gpu-archive/reference-images",
-          "--os-type",
-          "win",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "pixel_test",
-        "non_precommit_args": [
-          "--upload-refimg-to-cloud-storage"
-        ],
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "precommit_args": [
-          "--download-refimg-from-cloud-storage"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "screenshot_sync",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "screenshot_sync_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "trace_test",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "trace_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--webgl-conformance-version=2.0.1",
-          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl2_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ],
-          "shards": 15
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-passthrough-cmd-decoder --disable-es3-apis --disable-es3-gl-context"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_d3d11_passthrough_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_d3d9_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=gl"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_gl_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0412",
-              "os": "Windows-10"
-            }
-          ]
-        }
-      }
-    ]
-  },
   "Win7 Debug (AMD)": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/client.v8.fyi.json b/testing/buildbot/client.v8.fyi.json
index dcae224..29d35044 100644
--- a/testing/buildbot/client.v8.fyi.json
+++ b/testing/buildbot/client.v8.fyi.json
@@ -1,4 +1,522 @@
 {
+  "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
+  "AAAAA2 See generate_buildbot_json.py to make changes": {},
+  "Linux Release (NVIDIA)": {
+    "gtest_tests": [],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "depth_capture",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "depth_capture_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--os-type",
+          "linux",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "linux",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--webgl-conformance-version=2.0.1",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl2_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ],
+          "shards": 15
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Linux"
+            }
+          ]
+        }
+      }
+    ]
+  },
+  "Mac Release (Intel)": {
+    "gtest_tests": [],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "depth_capture",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "depth_capture_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--os-type",
+          "mac",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "mac",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--webgl-conformance-version=2.0.1",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl2_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ],
+          "shards": 15
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        }
+      }
+    ]
+  },
   "V8 Android GN (dbg)": {
     "additional_compile_targets": [
       "chrome_public_apk"
@@ -59,5 +577,263 @@
       "views_unittests",
       "wm_unittests"
     ]
+  },
+  "Win Release (NVIDIA)": {
+    "gtest_tests": [],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "depth_capture",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "depth_capture_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--os-type",
+          "win",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "win",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--webgl-conformance-version=2.0.1",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl2_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ],
+          "shards": 15
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      }
+    ]
   }
 }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index f78a59e..10649c6 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1679,6 +1679,21 @@
             ]
         }
     ],
+    "ProgressBarCompletion": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "progress-bar-completion-resources-before-domContentLoaded",
+                    "enable_features": [
+                        "progress-bar-completion-resources-before-domContentLoaded"
+                    ]
+                }
+            ]
+        }
+    ],
     "QUIC": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index e4bc085..98b8027 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -80,7 +80,6 @@
 Bug(none) webmidi/ [ Skip ]
 Bug(none) xmlviewer/ [ Skip ]
 
-Bug(none) broadcastchannel/blobs.html [ Pass Failure ]
 Bug(none) compositing/3d-cube.html [ Failure ]
 Bug(none) compositing/absolute-inside-out-of-view-fixed.html [ Failure ]
 Bug(none) compositing/animation/hidden-composited.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/device-name-longer-than-29-bytes.html b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/device-name-longer-than-29-bytes.html
new file mode 100644
index 0000000..ee8a4b34
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/device-name-longer-than-29-bytes.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../../resources/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+  const DEVICE_NAME = 'a_device_name_that_is_longer_than_29_bytes_but_shorter_than_240_bytes';
+
+  return setBluetoothFakeAdapter('DeviceNameLongerThan29BytesAdapter')
+    .then(() => requestDeviceWithKeyDown({ filters: [{name: DEVICE_NAME}]}))
+    .then(device => assert_equals(device.name, DEVICE_NAME));
+}, 'A device name between 29 and 240 bytes is valid.');
+</script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html
index 07474dc..7a8f843 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html
@@ -5,15 +5,15 @@
 <script>
 'use strict';
 promise_test(() => {
-  let name_too_long = generate_string(30, 'a');
+  const name_too_long = generate_string(241, 'a');
   return assert_promise_rejects_with_message(
     requestDeviceWithKeyDown({filters: [{name: name_too_long}]}),
     new DOMException(
       'Failed to execute \'requestDevice\' on \'Bluetooth\': ' +
-      'A \'name\' or \'namePrefix\' longer than 29 bytes ' +
+      'A \'name\' or \'namePrefix\' longer than 240 bytes ' +
       'results in no devices being found, because a device can\'t ' +
-      'advertise a name longer than 29 bytes.',
+      'acquire a name longer than 240 bytes.',
       'NotFoundError'),
-    'Device name longer than 29');
-}, 'A device name longer than 29 must reject.');
+    'Device name longer than 240');
+}, 'A device name longer than 240 bytes must reject.');
 </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html
index 0cefcb8..f227465 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html
@@ -5,15 +5,15 @@
 <script>
 'use strict';
 promise_test(() => {
-  let name_too_long = generate_string(30, 'a');
+  let name_too_long = generate_string(241, 'a');
   return assert_promise_rejects_with_message(
     requestDeviceWithKeyDown({filters: [{namePrefix: name_too_long}]}),
     new DOMException(
       'Failed to execute \'requestDevice\' on \'Bluetooth\': ' +
-      'A \'name\' or \'namePrefix\' longer than 29 bytes ' +
+      'A \'name\' or \'namePrefix\' longer than 240 bytes ' +
       'results in no devices being found, because a device can\'t ' +
-      'advertise a name longer than 29 bytes.',
+      'acquire a name longer than 240 bytes.',
       'NotFoundError'),
-    'Device name prefix longer than 29');
-}, 'A device name prefix longer than 29 must reject.');
+    'Device name prefix longer than 240');
+}, 'A device name prefix longer than 240 must reject.');
 </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html
index 9976d43..0ec1edba 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html
@@ -5,16 +5,16 @@
 <script>
 promise_test(() => {
   // \u2764's UTF-8 respresentation is 3 bytes long.
-  // 10 chars * 3 bytes/char = 30 bytes
-  let unicode_name = generate_string(10, '\u2764');
+  // 81 chars * 3 bytes/char = 243 bytes
+  const unicode_name = generate_string(81, '\u2764');
   return assert_promise_rejects_with_message(
     requestDeviceWithKeyDown({filters: [{name: unicode_name}]}),
     new DOMException(
       'Failed to execute \'requestDevice\' on \'Bluetooth\': ' +
-      'A \'name\' or \'namePrefix\' longer than 29 bytes ' +
+      'A \'name\' or \'namePrefix\' longer than 240 bytes ' +
       'results in no devices being found, because a device can\'t ' +
-      'advertise a name longer than 29 bytes.',
+      'acquire a name longer than 240 bytes.',
     'NotFoundError'));
-}, 'Unicode string with utf8 representation between (29, 248] bytes in ' +
+}, 'Unicode string with utf8 representation between (240, 248] bytes in ' +
    '\'name\' must throw NotFoundError.');
 </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html
index 488bf352..b366514 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html
@@ -5,16 +5,16 @@
 <script>
 promise_test(() => {
   // \u2764's UTF-8 respresentation is 3 bytes long.
-  // 10 chars * 3 bytes/char = 30 bytes
-  let unicode_name = generate_string(10, '\u2764');
+  // 81 chars * 3 bytes/char = 243 bytes
+  let unicode_name = generate_string(81, '\u2764');
   return assert_promise_rejects_with_message(
     requestDeviceWithKeyDown({filters: [{namePrefix: unicode_name}]}),
     new DOMException(
       'Failed to execute \'requestDevice\' on \'Bluetooth\': ' +
-      'A \'name\' or \'namePrefix\' longer than 29 bytes ' +
+      'A \'name\' or \'namePrefix\' longer than 240 bytes ' +
       'results in no devices being found, because a device can\'t ' +
-      'advertise a name longer than 29 bytes.',
+      'acquire a name longer than 240 bytes.',
     'NotFoundError'));
-}, 'Unicode string with utf8 representation between (29, 248] bytes in ' +
+}, 'Unicode string with utf8 representation between (240, 248] bytes in ' +
    '\'namePrefix\' must throw NotFoundError.');
 </script>
diff --git a/third_party/WebKit/LayoutTests/broadcastchannel/basics.html b/third_party/WebKit/LayoutTests/broadcastchannel/basics.html
deleted file mode 100644
index 810d731..0000000
--- a/third_party/WebKit/LayoutTests/broadcastchannel/basics.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-
-async_test(t => {
-    let c1 = new BroadcastChannel('eventType');
-    let c2 = new BroadcastChannel('eventType');
-
-    c2.onmessage = t.step_func(e => {
-        assert_true(e instanceof MessageEvent);
-        assert_equals(e.target, c2);
-        assert_equals(e.type, 'message');
-        assert_equals(e.origin, location.origin, 'origin');
-        assert_equals(e.data, 'hello world');
-        assert_equals(e.source, null, 'source');
-        t.done();
-      });
-    c1.postMessage('hello world');
-  }, 'postMessage results in correct event');
-
-async_test(t => {
-    let c1 = new BroadcastChannel('order');
-    let c2 = new BroadcastChannel('order');
-    let c3 = new BroadcastChannel('order');
-
-    let events = [];
-    let doneCount = 0;
-    let handler = t.step_func(e => {
-      events.push(e);
-      if (e.data == 'done') {
-        doneCount++;
-        if (doneCount == 2) {
-          assert_equals(events.length, 6);
-          assert_equals(events[0].target, c2, 'target for event 0');
-          assert_equals(events[0].data, 'from c1');
-          assert_equals(events[1].target, c3, 'target for event 1');
-          assert_equals(events[1].data, 'from c1');
-          assert_equals(events[2].target, c1, 'target for event 2');
-          assert_equals(events[2].data, 'from c3');
-          assert_equals(events[3].target, c2, 'target for event 3');
-          assert_equals(events[3].data, 'from c3');
-          assert_equals(events[4].target, c1, 'target for event 4');
-          assert_equals(events[4].data, 'done');
-          assert_equals(events[5].target, c3, 'target for event 5');
-          assert_equals(events[5].data, 'done');
-          t.done();
-        }
-      }
-    });
-    c1.onmessage = handler;
-    c2.onmessage = handler;
-    c3.onmessage = handler;
-
-    c1.postMessage('from c1');
-    c3.postMessage('from c3');
-    c2.postMessage('done');
-  }, 'messages are delivered in port creation order');
-
-async_test(t => {
-    let c1 = new BroadcastChannel('closed');
-    let c2 = new BroadcastChannel('closed');
-    let c3 = new BroadcastChannel('closed');
-
-    c2.onmessage = t.unreached_func();
-    c2.close();
-    c3.onmessage = t.step_func(() => t.done());
-    c1.postMessage('test');
-  }, 'messages aren\'t delivered to a closed port');
-
-async_test(t => {
-    let c1 = new BroadcastChannel('create-in-onmessage');
-    let c2 = new BroadcastChannel('create-in-onmessage');
-
-    c2.onmessage = t.step_func(e => {
-        assert_equals(e.data, 'first');
-        c2.close();
-        let c3 = new BroadcastChannel('create-in-onmessage');
-        c3.onmessage = t.step_func(event => {
-            assert_equals(event.data, 'done');
-            t.done();
-          });
-        c1.postMessage('done');
-      });
-    c1.postMessage('first');
-    c2.postMessage('second');
-  }, 'closing and creating channels during message delivery works correctly');
-
-// TODO(mek): Depending on https://github.com/whatwg/html/issues/1371 adjust
-// this test to match the correct behavior.
-async_test(t => {
-    let c1 = new BroadcastChannel('close-in-onmessage');
-    let c2 = new BroadcastChannel('close-in-onmessage');
-    let c3 = new BroadcastChannel('close-in-onmessage');
-    let events = [];
-    c1.onmessage = e => events.push('c1: ' + e.data);
-    c2.onmessage = e => events.push('c2: ' + e.data);
-    c3.onmessage = e => events.push('c3: ' + e.data);
-
-    // c2 closes itself when it receives the first message
-    c2.addEventListener('message', e => {
-        c2.close();
-      });
-
-    c3.addEventListener('message', t.step_func(e => {
-        if (e.data == 'done') {
-          assert_array_equals(events, [
-              'c2: first',
-              'c3: first',
-              'c2: done',
-              'c3: done']);
-          t.done();
-        }
-      }));
-    c1.postMessage('first');
-    c1.postMessage('done');
-  }, 'Closing a channel in onmessage doesn\'t cancel already queued events');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/broadcastchannel/blobs.html b/third_party/WebKit/LayoutTests/broadcastchannel/blobs.html
deleted file mode 100644
index 041d8022..0000000
--- a/third_party/WebKit/LayoutTests/broadcastchannel/blobs.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-
-async_test(t => {
-    const c1 = new BroadcastChannel('blob');
-    const c2 = new BroadcastChannel('blob');
-    const c3 = new BroadcastChannel('blob');
-
-    let readCount = 0;
-    c2.onmessage = t.step_func(e => {
-        // check blob
-        assert_true('blob' in e.data);
-        assert_true(e.data.blob instanceof Blob);
-        assert_equals(e.data.blob.size, 6);
-        const reader = new FileReader();
-        reader.onerror = t.unreached_func();
-        reader.onload = t.step_func(() => {
-            assert_equals(reader.result, 'foobar');
-            if (++readCount == 2)
-              t.done();
-          });
-        reader.readAsText(e.data.blob);
-      });
-    c3.onmessage = c2.onmessage;
-    c1.postMessage({blob: new Blob(['foo', 'bar'])});
-  }, 'Blobs work on BroadcastChannel');
-
-async_test(t => {
-    const c1 = new BroadcastChannel('blobworker');
-    const c2 = new BroadcastChannel('blobworker');
-    const events = [];
-
-    const verifyEvents = function() {
-        assert_equals(events.length, 5);
-        assert_equals(events[0], 'from worker');
-        assert_equals(events[1], 'from worker');
-        assert_true(events[2].blob instanceof Blob);
-        assert_equals(events[2].blob.size, 11);
-        assert_true(events[3].blob instanceof Blob);
-        assert_equals(events[3].blob.size, 11);
-        assert_equals(events[4], 'done');
-        const reader = new FileReader();
-        reader.onerror = t.unreached_func();
-        reader.onload = t.step_func(() => {
-            assert_equals(reader.result, 'hello-world');
-            t.done();
-          });
-        reader.readAsText(events[3].blob);
-    };
-
-    let receivedDone = false;
-    let receivedWorkerDone = false;
-
-    c1.onmessage = e => events.push(e.data);
-    c2.onmessage = e => events.push(e.data);
-    c2.addEventListener('message', t.step_func(e => {
-        if (e.data.blob)
-          c1.postMessage('done');
-        if (e.data === 'done')
-          receivedDone = true;
-        if (receivedDone && receivedWorkerDone)
-          verifyEvents();
-      }));
-
-    const worker = new Worker('resources/worker.js');
-    worker.onmessage = t.step_func(e => {
-        receivedWorkerDone = true;
-        if (receivedDone && receivedWorkerDone)
-          verifyEvents();
-      });
-    worker.postMessage({channel: 'blobworker'});
-    worker.postMessage({blob: ['hello-world']});
-
-  }, 'Blobs work with workers on BroadcastChannel');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/broadcastchannel/interface.html b/third_party/WebKit/LayoutTests/broadcastchannel/interface.html
deleted file mode 100644
index a928aed1..0000000
--- a/third_party/WebKit/LayoutTests/broadcastchannel/interface.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-
-test(() => assert_throws(new TypeError(), () => new BroadcastChannel()),
-  'Should throw if no name is provided');
-
-test(() => {
-    let c = new BroadcastChannel(null);
-    assert_equals(c.name, 'null');
-  }, 'Null name should not throw');
-
-test(() => {
-    let c = new BroadcastChannel(undefined);
-    assert_equals(c.name, 'undefined');
-  }, 'Undefined name should not throw');
-
-test(() => {
-    let c = new BroadcastChannel('fooBar');
-    assert_equals(c.name, 'fooBar');
-  }, 'Non-empty name should not throw');
-
-test(() => {
-    let c = new BroadcastChannel(123);
-    assert_equals(c.name, '123');
-  }, 'Non-string name should not throw');
-
-test(() => {
-    let c = new BroadcastChannel('');
-    assert_throws(new TypeError(), () => c.postMessage());
-  }, 'postMessage without parameters should throw');
-
-test(() => {
-    let c = new BroadcastChannel('');
-    c.postMessage(null);
-  }, 'postMessage with null should not throw');
-
-test(() => {
-    let c = new BroadcastChannel('');
-    c.close();
-  }, 'close should not throw');
-
-test(() => {
-    let c = new BroadcastChannel('');
-    c.close();
-    c.close();
-  }, 'close should not throw when called multiple times');
-
-test(() => {
-    let c = new BroadcastChannel('');
-    c.close();
-    assert_throws('InvalidStateError', () => c.postMessage(''));
-  }, 'postMessage after close should throw');
-
-test(() => {
-    let c = new BroadcastChannel('');
-    assert_not_equals(c.onmessage, undefined);
-  }, 'BroadcastChannel should have an onmessage event');
-
-test(() => {
-    let c = new BroadcastChannel('');
-    assert_throws('DataCloneError', () => c.postMessage(Symbol()));
-  }, 'postMessage should throw with uncloneable data');
-
-test(() => {
-    let c = new BroadcastChannel('');
-    c.close();
-    assert_throws('InvalidStateError', () => c.postMessage(Symbol()));
-  }, 'postMessage should throw InvalidStateError after close, even with uncloneable data');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/broadcastchannel/resources/sandboxed.html b/third_party/WebKit/LayoutTests/broadcastchannel/resources/sandboxed.html
deleted file mode 100644
index e32962c..0000000
--- a/third_party/WebKit/LayoutTests/broadcastchannel/resources/sandboxed.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<script>
-try {
-  let c = new BroadcastChannel('foo');
-  parent.postMessage('Created', '*');
-} catch (e) {
-  parent.postMessage('Exception: ' + e.name, '*');
-}
-</script>
diff --git a/third_party/WebKit/LayoutTests/broadcastchannel/resources/worker.js b/third_party/WebKit/LayoutTests/broadcastchannel/resources/worker.js
deleted file mode 100644
index 2f0e4ea..0000000
--- a/third_party/WebKit/LayoutTests/broadcastchannel/resources/worker.js
+++ /dev/null
@@ -1,26 +0,0 @@
-var c;
-
-function handler(e, reply) {
-  if (e.data.ping) {
-    c.postMessage(e.data.ping);
-    return;
-  }
-  if (e.data.blob) {
-    c.postMessage({blob: new Blob(e.data.blob)});
-  }
-  c = new BroadcastChannel(e.data.channel);
-  let messages = [];
-  c.onmessage = e => {
-      messages.push(e.data);
-      if (e.data == 'done')
-        reply(messages);
-    };
-  c.postMessage('from worker');
-}
-
-onmessage = e => handler(e, postMessage);
-
-onconnect = e => {
-  let port = e.ports[0];
-  port.onmessage = e => handler(e, msg => port.postMessage(msg));
-};
diff --git a/third_party/WebKit/LayoutTests/broadcastchannel/sandbox.html b/third_party/WebKit/LayoutTests/broadcastchannel/sandbox.html
deleted file mode 100644
index 88f47a1..0000000
--- a/third_party/WebKit/LayoutTests/broadcastchannel/sandbox.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<body>
-<script>
-async_test(t => {
-    self.onmessage = t.step_func(e => {
-        assert_equals(e.data, 'Exception: NotSupportedError');
-        t.done();
-      });
-  }, 'Creating BroadcastChannel in opaque origin should fail.');
-</script>
-<iframe sandbox="allow-scripts" src="resources/sandboxed.html"></iframe>
-</body>
diff --git a/third_party/WebKit/LayoutTests/broadcastchannel/workers.html b/third_party/WebKit/LayoutTests/broadcastchannel/workers.html
deleted file mode 100644
index 55e427a..0000000
--- a/third_party/WebKit/LayoutTests/broadcastchannel/workers.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-
-async_test(t => {
-    let c1 = new BroadcastChannel('worker');
-    let c2 = new BroadcastChannel('worker');
-    let events = [];
-
-    c1.onmessage = e => events.push(e);
-    c2.onmessage = e => events.push(e);
-
-    let doneCount = 0;
-    c2.addEventListener('message', t.step_func(e => {
-        if (e.data == 'from worker') {
-          c2.postMessage('from c2');
-          c1.postMessage('done');
-        } else if (e.data == 'done') {
-          assert_equals(events.length, 4);
-          assert_equals(events[0].data, 'from worker');
-          assert_equals(events[0].target, c1);
-          assert_equals(events[1].data, 'from worker');
-          assert_equals(events[1].target, c2);
-          assert_equals(events[2].data, 'from c2');
-          assert_equals(events[3].data, 'done');
-          if (++doneCount == 2) t.done();
-        }
-      }));
-
-    let worker = new Worker('resources/worker.js');
-    worker.onmessage = t.step_func(e => {
-        assert_array_equals(e.data, ['from c2', 'done']);
-        if (++doneCount == 2) t.done();
-      });
-    worker.postMessage({channel: 'worker'});
-
-  }, 'BroadcastChannel works in workers');
-
-async_test(t => {
-    let c1 = new BroadcastChannel('shared worker');
-    let c2 = new BroadcastChannel('shared worker');
-    let events = [];
-
-    c1.onmessage = e => events.push(e);
-    c2.onmessage = e => events.push(e);
-
-    let doneCount = 0;
-    c2.addEventListener('message', t.step_func(e => {
-        if (e.data == 'from worker') {
-          c2.postMessage('from c2');
-          c1.postMessage('done');
-        } else if (e.data == 'done') {
-          assert_equals(events.length, 4);
-          assert_equals(events[0].data, 'from worker');
-          assert_equals(events[0].target, c1);
-          assert_equals(events[1].data, 'from worker');
-          assert_equals(events[1].target, c2);
-          assert_equals(events[2].data, 'from c2');
-          assert_equals(events[3].data, 'done');
-          if (++doneCount == 2) t.done();
-        }
-      }));
-
-    let worker = new SharedWorker('resources/worker.js');
-    worker.port.onmessage = t.step_func(e => {
-        assert_array_equals(e.data, ['from c2', 'done']);
-        if (++doneCount == 2) t.done();
-      });
-    worker.port.postMessage({channel: 'shared worker'});
-
-  }, 'BroadcastChannel works in shared workers');
-
-async_test(t => {
-    let c = new BroadcastChannel('worker-close');
-    let events = [];
-
-    c.onmessage = e => events.push('c1: ' + e.data);
-
-    let worker = new Worker('resources/worker.js');
-    worker.onmessage = t.step_func(e => {
-        assert_array_equals(events, ['c1: from worker', 'c2: echo'],
-                            'messages in document');
-        assert_array_equals(e.data, ['done'], 'messages in worker');
-        t.done();
-      });
-
-    c.addEventListener('message', e => {
-        if (e.data == 'from worker') {
-          c.close();
-          if (self.gc) self.gc();
-          window.setTimeout(() => {
-              let c2 = new BroadcastChannel('worker-close');
-              c2.onmessage = e => {
-                  events.push('c2: ' + e.data);
-                  c2.postMessage('done');
-                };
-              worker.postMessage({ping: 'echo'});
-            }, 1);
-        }
-      });
-
-    worker.postMessage({channel: 'worker-close'});
-
-  }, 'Closing and re-opening a channel works.');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/testharnessreport.js b/third_party/WebKit/LayoutTests/external/wpt/resources/testharnessreport.js
index ec8af45..8086a62 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/resources/testharnessreport.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/resources/testharnessreport.js
@@ -201,7 +201,15 @@
         results.textContent = resultStr;
 
         function done() {
-            if (self.testRunner) {
+            // A temporary workaround since |window.self| property lookup starts
+            // failing if the frame is detached. |output_document| may be an
+            // ancestor of |self| so clearing |textContent| may detach |self|.
+            // To get around this, cache window.self now and use the cached
+            // value.
+            // TODO(dcheng): Remove this hack after fixing window/self/frames
+            // lookup in https://crbug.com/618672
+            var cachedSelf = window.self;
+            if (cachedSelf.testRunner) {
                 // The following DOM operations may show console messages.  We
                 // suppress them because they are not related to the running
                 // test.
@@ -223,7 +231,7 @@
             }
             output_document.body.appendChild(results);
 
-            if (self.testRunner)
+            if (cachedSelf.testRunner)
                 testRunner.notifyDone();
         }
 
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-in-closure-after-navigation-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-in-closure-after-navigation-expected.txt
index 0e0e6eb7..11d9d05 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-in-closure-after-navigation-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-in-closure-after-navigation-expected.txt
@@ -6,9 +6,9 @@
 PASS window is self
 PASS window is frames
 PASS parent is top
-PASS window is non-null.
-PASS self is non-null.
-PASS frames is non-null.
+FAIL window should be non-null. Was null
+FAIL self should be non-null. Was null
+FAIL frames should be non-null. Was null
 PASS parent is null.
 PASS top is null.
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 4bc15ac..f0fc9305 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -217,6 +217,11 @@
     method toString
     method transformPoint
     method translate
+interface DOMStringList
+    getter length
+    method constructor
+    method contains
+    method item
 interface DataView
     getter buffer
     getter byteLength
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/observer-exceptions-expected.txt b/third_party/WebKit/LayoutTests/intersection-observer/observer-exceptions-expected.txt
index 3c0faf22..6665dca 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/observer-exceptions-expected.txt
+++ b/third_party/WebKit/LayoutTests/intersection-observer/observer-exceptions-expected.txt
@@ -14,14 +14,7 @@
 PASS exc is an instance of DOMException
 PASS exc.code is DOMException.SYNTAX_ERR
 PASS exc is an instance of TypeError
-PASS exc is an instance of DOMException
-PASS exc.code is DOMException.INVALID_STATE_ERR
-PASS exc is an instance of DOMException
-PASS exc.code is DOMException.INVALID_STATE_ERR
-PASS exc is an instance of DOMException
-PASS exc.code is DOMException.INVALID_STATE_ERR
-PASS exc is an instance of DOMException
-PASS exc.code is DOMException.INVALID_STATE_ERR
+PASS 0 is 0
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/observer-exceptions.html b/third_party/WebKit/LayoutTests/intersection-observer/observer-exceptions.html
index a266655..e41569c 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/observer-exceptions.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/observer-exceptions.html
@@ -80,40 +80,8 @@
 
   observer = initializeObserverThenRemoveRootDiv();
   gc();
-
-  try {
-    observer.observe(target);
-    testFailed("IntersectionObserver.observe() with a deleted root did not throw.");
-  } catch(e) {
-    exc = e;
-    shouldBeType("exc", "DOMException");
-    shouldBe("exc.code", "DOMException.INVALID_STATE_ERR");
-  }
-
-  try {
-    observer.unobserve(target);
-    testFailed("IntersectionObserver.unobserve() with a deleted root did not throw.");
-  } catch(e) {
-    exc = e;
-    shouldBeType("exc", "DOMException");
-    shouldBe("exc.code", "DOMException.INVALID_STATE_ERR");
-  }
-
-  try {
-    observer.disconnect();
-    testFailed("IntersectionObserver.disconnect() with a deleted root did not throw.");
-  } catch(e) {
-    exc = e;
-    shouldBeType("exc", "DOMException");
-    shouldBe("exc.code", "DOMException.INVALID_STATE_ERR");
-  }
-
-  try {
-    observer.takeRecords();
-    testFailed("IntersectionObserver.takeRecords() with a deleted root did not throw.");
-  } catch(e) {
-    exc = e;
-    shouldBeType("exc", "DOMException");
-    shouldBe("exc.code", "DOMException.INVALID_STATE_ERR");
-  }
+  observer.observe(target);
+  observer.unobserve(target);
+  observer.disconnect();
+  shouldBeEqualToNumber("0", observer.takeRecords().length);
 </script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/number/number-appearance-spinbutton-layer-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
index 4e0849e..b9aa57a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
@@ -12,7 +12,7 @@
   LayoutBlockFlow {DIV} at (0,0) size 135x16
     LayoutText {#text} at (0,0) size 14x16
       text run at (0,0) width 14: "10"
-layer at (8,8) size 154x22 transparent
+layer at (8,8) size 154x22 clip at (10,10) size 150x18 transparent
   LayoutTextControl {INPUT} at (0,0) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
     LayoutFlexibleBox {DIV} at (2,3) size 150x16
       LayoutBlockFlow {DIV} at (0,0) size 135x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/placeholder-position-expected.png
index 7ff8ac7..0b9255ac 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/placeholder-position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/placeholder-position-expected.txt
index fcf3e37..b6ffe45 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/placeholder-position-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/placeholder-position-expected.txt
@@ -169,11 +169,11 @@
   LayoutBlockFlow {DIV} at (0,3.50) size 9x9
 layer at (149,81) size 9x9 transparent
   LayoutBlockFlow {DIV} at (138,3.50) size 9x9
-layer at (8,334) size 154x36
+layer at (8,334) size 154x36 clip at (10,336) size 150x32
   LayoutTextControl {INPUT} at (0,326) size 154x36 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (10,351) size 150x16
+layer at (10,351) size 150x16 backgroundClip at (29,351) size 131x11 clip at (29,351) size 131x11
   LayoutBlockFlow {DIV} at (2,17) size 150x16 [color=#757575]
     LayoutText {#text} at (0,0) size 66x16
       text run at (0,0) width 66: "placeholder"
-layer at (10,351) size 150x16
+layer at (10,351) size 150x16 backgroundClip at (29,351) size 131x11 clip at (29,351) size 131x11
   LayoutBlockFlow {DIV} at (2,17) size 150x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
index a5b10fa..c24f3e1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/input-appearance-preventDefault-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/input-appearance-preventDefault-expected.txt
index 399e9dbd..579d2ac 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/input-appearance-preventDefault-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/input-appearance-preventDefault-expected.txt
@@ -8,7 +8,7 @@
         text run at (0,20) width 630: "This tests that preventDefault called onmousedown will prevent a caret from being placed in the text field."
       LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
-layer at (10,50) size 154x22
+layer at (10,50) size 154x22 clip at (12,52) size 150x18
   LayoutTextControl (positioned) {INPUT} at (10,50) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
 layer at (12,53) size 150x16
   LayoutBlockFlow {DIV} at (2,3) size 150x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
index 90019287..b39b9ef 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
@@ -19,9 +19,9 @@
       text run at (63,60) width 317: "Filler Text Filler Text Filler Text Filler Text Filler Text"
       text run at (0,83) width 192: "Filler Text Filler Text Filler Text "
     LayoutText {#text} at (0,0) size 0x0
-layer at (202,90) size 154x22
+layer at (202,90) size 154x22 clip at (204,92) size 150x18
   LayoutTextControl (relative positioned) {INPUT} at (193.64,82) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (204,93) size 150x16
+layer at (204,93) size 150x16 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutBlockFlow {DIV} at (2,3) size 150x16
     LayoutText {#text} at (0,0) size 41x16
       text run at (0,0) width 41: "Testing"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png
index ca2116c..f6d5b3d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.txt
index 3ed3d88..57d03ef 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.txt
@@ -170,11 +170,11 @@
   LayoutBlockFlow {DIV} at (0,1) size 11x11
 layer at (126,69) size 11x11 transparent
   LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (8,283) size 131x33
+layer at (8,283) size 131x33 clip at (10,285) size 127x29
   LayoutTextControl {INPUT} at (0,275) size 131x33 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (11,300) size 125x13
+layer at (11,300) size 125x13 backgroundClip at (27,300) size 109x13 clip at (27,300) size 109x13
   LayoutBlockFlow {DIV} at (3,17) size 125x13 [color=#757575]
     LayoutText {#text} at (0,0) size 59x13
       text run at (0,0) width 59: "placeholder"
-layer at (11,300) size 125x13
+layer at (11,300) size 125x13 backgroundClip at (27,300) size 109x13 clip at (27,300) size 109x13
   LayoutBlockFlow {DIV} at (3,17) size 125x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/input-appearance-preventDefault-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/input-appearance-preventDefault-expected.txt
index 4b2d9c3e..33bbe59 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/input-appearance-preventDefault-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/input-appearance-preventDefault-expected.txt
@@ -8,7 +8,7 @@
         text run at (0,18) width 681: "This tests that preventDefault called onmousedown will prevent a caret from being placed in the text field."
       LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
-layer at (10,50) size 131x19
+layer at (10,50) size 131x19 clip at (12,52) size 127x15
   LayoutTextControl (positioned) {INPUT} at (10,50) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
 layer at (13,53) size 125x13
   LayoutBlockFlow {DIV} at (3,3) size 125x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
index 9c8605c8..e3f88f2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
@@ -20,9 +20,9 @@
       text run at (0,77) width 351: "Filler Text Filler Text Filler Text Filler Text Filler Text"
       text run at (0,97) width 142: "Filler Text Filler Text "
     LayoutText {#text} at (0,0) size 0x0
-layer at (152,105) size 131x19
+layer at (152,105) size 131x19 clip at (154,107) size 127x15
   LayoutTextControl (relative positioned) {INPUT} at (143.73,97) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (155,108) size 125x13
+layer at (155,108) size 125x13 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutBlockFlow {DIV} at (3,3) size 125x13
     LayoutText {#text} at (0,0) size 36x13
       text run at (0,0) width 36: "Testing"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/number/number-appearance-spinbutton-layer-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
index a24252b..428edf6ed 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
@@ -12,7 +12,7 @@
   LayoutBlockFlow {DIV} at (0,0) size 104x13
     LayoutText {#text} at (0,0) size 14x13
       text run at (0,0) width 14: "10"
-layer at (8,8) size 123x19 transparent
+layer at (8,8) size 123x19 clip at (10,10) size 119x15 transparent
   LayoutTextControl {INPUT} at (0,0) size 123x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
     LayoutFlexibleBox {DIV} at (3,2) size 117x15
       LayoutBlockFlow {DIV} at (0,1) size 104x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/placeholder-position-expected.png
index 7d87ecd..8d267ad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/placeholder-position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/placeholder-position-expected.txt
index 56868ef..92ea188 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/placeholder-position-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/placeholder-position-expected.txt
@@ -170,11 +170,11 @@
   LayoutBlockFlow {DIV} at (0,1) size 11x11
 layer at (118,69) size 11x11 transparent
   LayoutBlockFlow {DIV} at (106,1) size 11x11
-layer at (8,284) size 123x33
+layer at (8,284) size 123x33 clip at (10,286) size 119x29
   LayoutTextControl {INPUT} at (0,276) size 123x33 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (11,301) size 117x13
+layer at (11,301) size 117x13 backgroundClip at (26,301) size 102x13 clip at (26,301) size 102x13
   LayoutBlockFlow {DIV} at (3,17) size 117x13 [color=#757575]
     LayoutText {#text} at (0,0) size 63x13
       text run at (0,0) width 63: "placeholder"
-layer at (11,301) size 117x13
+layer at (11,301) size 117x13 backgroundClip at (26,301) size 102x13 clip at (26,301) size 102x13
   LayoutBlockFlow {DIV} at (3,17) size 117x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/input-appearance-preventDefault-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/input-appearance-preventDefault-expected.txt
index 4967ca9..59cbfff4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/input-appearance-preventDefault-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/input-appearance-preventDefault-expected.txt
@@ -8,7 +8,7 @@
         text run at (0,18) width 681: "This tests that preventDefault called onmousedown will prevent a caret from being placed in the text field."
       LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
-layer at (10,50) size 123x19
+layer at (10,50) size 123x19 clip at (12,52) size 119x15
   LayoutTextControl (positioned) {INPUT} at (10,50) size 123x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
 layer at (13,53) size 117x13 scrollWidth 129
   LayoutBlockFlow {DIV} at (3,3) size 117x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
index 5f35c74..b96fd3b9b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
@@ -20,9 +20,9 @@
       text run at (0,77) width 351: "Filler Text Filler Text Filler Text Filler Text Filler Text"
       text run at (0,97) width 142: "Filler Text Filler Text "
     LayoutText {#text} at (0,0) size 0x0
-layer at (152,105) size 123x19
+layer at (152,105) size 123x19 clip at (154,107) size 119x15
   LayoutTextControl (relative positioned) {INPUT} at (143.73,97) size 123x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (155,108) size 117x13
+layer at (155,108) size 117x13 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutBlockFlow {DIV} at (3,3) size 117x13
     LayoutText {#text} at (0,0) size 40x13
       text run at (0,0) width 40: "Testing"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/number/number-appearance-spinbutton-layer-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
index bb05c0a..6fafd1a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
@@ -12,7 +12,7 @@
   LayoutBlockFlow {DIV} at (0,0) size 112x13
     LayoutText {#text} at (0,0) size 13x13
       text run at (0,0) width 13: "10"
-layer at (8,8) size 131x19 transparent
+layer at (8,8) size 131x19 clip at (10,10) size 127x15 transparent
   LayoutTextControl {INPUT} at (0,0) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
     LayoutFlexibleBox {DIV} at (3,2) size 125x15
       LayoutBlockFlow {DIV} at (0,1) size 112x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png
index ebaf8fff..5254e24 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt
index 8a1a7e9a..5b3127a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt
@@ -170,11 +170,11 @@
   LayoutBlockFlow {DIV} at (0,1) size 11x11
 layer at (126,69) size 11x11 transparent
   LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (8,284) size 131x33
+layer at (8,284) size 131x33 clip at (10,286) size 127x29
   LayoutTextControl {INPUT} at (0,276) size 131x33 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (11,301) size 125x13
+layer at (11,301) size 125x13 backgroundClip at (27,301) size 109x13 clip at (27,301) size 109x13
   LayoutBlockFlow {DIV} at (3,17) size 125x13 [color=#757575]
     LayoutText {#text} at (0,0) size 62x13
       text run at (0,0) width 62: "placeholder"
-layer at (11,301) size 125x13
+layer at (11,301) size 125x13 backgroundClip at (27,301) size 109x13 clip at (27,301) size 109x13
   LayoutBlockFlow {DIV} at (3,17) size 125x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/input-appearance-preventDefault-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/input-appearance-preventDefault-expected.txt
index 6521b3b..eb3d9f7c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/input-appearance-preventDefault-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/input-appearance-preventDefault-expected.txt
@@ -8,7 +8,7 @@
         text run at (0,18) width 681: "This tests that preventDefault called onmousedown will prevent a caret from being placed in the text field."
       LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
-layer at (10,50) size 131x19
+layer at (10,50) size 131x19 clip at (12,52) size 127x15
   LayoutTextControl (positioned) {INPUT} at (10,50) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
 layer at (13,53) size 125x13 scrollWidth 126
   LayoutBlockFlow {DIV} at (3,3) size 125x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
index 8fcf34f..2a8707f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
@@ -20,9 +20,9 @@
       text run at (0,77) width 351: "Filler Text Filler Text Filler Text Filler Text Filler Text"
       text run at (0,97) width 142: "Filler Text Filler Text "
     LayoutText {#text} at (0,0) size 0x0
-layer at (152,105) size 131x19
+layer at (152,105) size 131x19 clip at (154,107) size 127x15
   LayoutTextControl (relative positioned) {INPUT} at (143.73,97) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (155,108) size 125x13
+layer at (155,108) size 125x13 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutBlockFlow {DIV} at (3,3) size 125x13
     LayoutText {#text} at (0,0) size 38x13
       text run at (0,0) width 38: "Testing"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/button-positioned-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/button-positioned-expected.txt
index 974427c..b75e78d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/button-positioned-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/button-positioned-expected.txt
@@ -8,7 +8,7 @@
     LayoutBlockFlow (anonymous) at (8,3) size 145x16
       LayoutText {#text} at (0,0) size 145x16
         text run at (0,0) width 145: "This button is positioned."
-layer at (8,8) size 185x22
+layer at (8,8) size 185x22 clip at (10,10) size 181x18
   LayoutButton (positioned) {INPUT} at (8,8) size 185x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
     LayoutBlockFlow (anonymous) at (8,3) size 169x16
       LayoutText {#text} at (0,0) size 169x16
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/number/number-appearance-spinbutton-layer-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
index 629a167..fc0b30e6 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/number/number-appearance-spinbutton-layer-expected.txt
@@ -12,7 +12,7 @@
   LayoutBlockFlow {DIV} at (0,0) size 154x16
     LayoutText {#text} at (0,0) size 14x16
       text run at (0,0) width 14: "10"
-layer at (8,8) size 173x22 transparent
+layer at (8,8) size 173x22 clip at (10,10) size 169x18 transparent
   LayoutTextControl {INPUT} at (0,0) size 173x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
     LayoutFlexibleBox {DIV} at (2,3) size 169x16
       LayoutBlockFlow {DIV} at (0,0) size 154x16
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/placeholder-position-expected.png
index adf5cd8..b872834 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/placeholder-position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/placeholder-position-expected.txt
index 0d36f75..814bf655 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/placeholder-position-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/placeholder-position-expected.txt
@@ -169,11 +169,11 @@
   LayoutBlockFlow {DIV} at (0,3.50) size 9x9
 layer at (168,81) size 9x9 transparent
   LayoutBlockFlow {DIV} at (157,3.50) size 9x9
-layer at (8,334) size 173x36
+layer at (8,334) size 173x36 clip at (10,336) size 169x32
   LayoutTextControl {INPUT} at (0,326) size 173x36 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (10,351) size 169x16
+layer at (10,351) size 169x16 backgroundClip at (31,351) size 148x6 clip at (31,351) size 148x6
   LayoutBlockFlow {DIV} at (2,17) size 169x16 [color=#757575]
     LayoutText {#text} at (0,0) size 66x16
       text run at (0,0) width 66: "placeholder"
-layer at (10,351) size 169x16
+layer at (10,351) size 169x16 backgroundClip at (31,351) size 148x6 clip at (31,351) size 148x6
   LayoutBlockFlow {DIV} at (2,17) size 169x16
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
index 5574224..f09bdf14 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/input-appearance-preventDefault-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/input-appearance-preventDefault-expected.txt
index 91e944ef..d3c48b7 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/input-appearance-preventDefault-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/input-appearance-preventDefault-expected.txt
@@ -8,7 +8,7 @@
         text run at (0,18) width 682: "This tests that preventDefault called onmousedown will prevent a caret from being placed in the text field."
       LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
-layer at (10,50) size 173x22
+layer at (10,50) size 173x22 clip at (12,52) size 169x18
   LayoutTextControl (positioned) {INPUT} at (10,50) size 173x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
 layer at (12,53) size 169x16
   LayoutBlockFlow {DIV} at (2,3) size 169x16
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
index 27a7966..4057ce3b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/multicol/multicol-with-child-renderLayer-for-input-expected.txt
@@ -20,9 +20,9 @@
       text run at (0,80) width 351: "Filler Text Filler Text Filler Text Filler Text Filler Text"
       text run at (0,102) width 142: "Filler Text Filler Text "
     LayoutText {#text} at (0,0) size 0x0
-layer at (152,108) size 173x22
+layer at (152,108) size 173x22 clip at (154,110) size 169x18
   LayoutTextControl (relative positioned) {INPUT} at (143.73,100) size 173x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (154,111) size 169x16
+layer at (154,111) size 169x16 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutBlockFlow {DIV} at (2,3) size 169x16
     LayoutText {#text} at (0,0) size 41x16
       text run at (0,0) width 41: "Testing"
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-navigation-multipleurls.html b/third_party/WebKit/LayoutTests/presentation/presentation-navigation-multipleurls.html
index 328755cf..706f16fc 100644
--- a/third_party/WebKit/LayoutTests/presentation/presentation-navigation-multipleurls.html
+++ b/third_party/WebKit/LayoutTests/presentation/presentation-navigation-multipleurls.html
@@ -3,19 +3,29 @@
 <body>
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
+<iframe></iframe>
 <script>
 
-// TODO(crbug.com/680298): use iframe to do presentation navigation layout tests
-if (location.href.endsWith('#after-reload')) {
-  test(function() {
-    assert_equals(navigator.presentation.defaultRequest, null);
-  }, "Test that navigator.defaultRequest with multiple URLs isn't kept alive after reload.")
-} else {
-  navigator.presentation.defaultRequest = new PresentationRequest(["https://example.org", "cast://google.com/app_id=deadbeef"]);
+var iframe = document.querySelector('iframe');
 
-  location.href += '#after-reload';
-  location.reload();
-}
+async_test(t => {
+  iframe.onload = t.step_func(() => {
+    var presentation = iframe.contentWindow.navigator.presentation;
+    if (iframe.src.endsWith('#after-reload')) {
+      assert_equals(presentation.defaultRequest, null);
+      t.done();
+    } else {
+      presentation.defaultRequest = new PresentationRequest(["https://example.org", "cast://google.com/app_id=deadbeef"]);
+      assert_not_equals(presentation.defaultRequest, null);
+
+      iframe.src += '#after-reload';
+      iframe.contentWindow.location.reload(true);
+    }
+  });
+
+  // Navigate the iframe
+  iframe.src = 'resources/blank.html';
+}, "Test that navigator.defaultRequest with multiple URLs isn't kept alive after reload.");
 
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-navigation.html b/third_party/WebKit/LayoutTests/presentation/presentation-navigation.html
index aca9aed..ba5e230 100644
--- a/third_party/WebKit/LayoutTests/presentation/presentation-navigation.html
+++ b/third_party/WebKit/LayoutTests/presentation/presentation-navigation.html
@@ -3,18 +3,29 @@
 <body>
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
+<iframe></iframe>
 <script>
 
-if (location.href.endsWith('#after-reload')) {
-  test(function() {
-    assert_equals(navigator.presentation.defaultRequest, null);
-  }, "Test that navigator.defaultRequest isn't kept alive after reload.")
-} else {
-  navigator.presentation.defaultRequest = new PresentationRequest("https://example.org");
+var iframe = document.querySelector('iframe');
 
-  location.href += '#after-reload';
-  location.reload();
-}
+async_test(t => {
+  iframe.onload = t.step_func(() => {
+    var presentation = iframe.contentWindow.navigator.presentation;
+    if (iframe.src.endsWith('#after-reload')) {
+      assert_equals(presentation.defaultRequest, null);
+      t.done();
+    } else {
+      presentation.defaultRequest = new PresentationRequest("https://example.org");
+      assert_not_equals(presentation.defaultRequest, null);
+
+      iframe.src += '#after-reload';
+      iframe.contentWindow.location.reload(true);
+    }
+  });
+
+  // Navigate the iframe
+  iframe.src = 'resources/blank.html';
+}, "Test that navigator.defaultRequest isn't kept alive after reload.");
 
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/presentation/resources/blank.html b/third_party/WebKit/LayoutTests/presentation/resources/blank.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/presentation/resources/blank.html
diff --git a/third_party/WebKit/LayoutTests/resources/testharnessreport.js b/third_party/WebKit/LayoutTests/resources/testharnessreport.js
index ec8af45..8086a62 100644
--- a/third_party/WebKit/LayoutTests/resources/testharnessreport.js
+++ b/third_party/WebKit/LayoutTests/resources/testharnessreport.js
@@ -201,7 +201,15 @@
         results.textContent = resultStr;
 
         function done() {
-            if (self.testRunner) {
+            // A temporary workaround since |window.self| property lookup starts
+            // failing if the frame is detached. |output_document| may be an
+            // ancestor of |self| so clearing |textContent| may detach |self|.
+            // To get around this, cache window.self now and use the cached
+            // value.
+            // TODO(dcheng): Remove this hack after fixing window/self/frames
+            // lookup in https://crbug.com/618672
+            var cachedSelf = window.self;
+            if (cachedSelf.testRunner) {
                 // The following DOM operations may show console messages.  We
                 // suppress them because they are not related to the running
                 // test.
@@ -223,7 +231,7 @@
             }
             output_document.body.appendChild(results);
 
-            if (self.testRunner)
+            if (cachedSelf.testRunner)
                 testRunner.notifyDone();
         }
 
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/observer-transaction-test.html b/third_party/WebKit/LayoutTests/storage/indexeddb/observer-transaction-test.html
new file mode 100644
index 0000000..7e21e960
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/storage/indexeddb/observer-transaction-test.html
@@ -0,0 +1,49 @@
+<html>
+<title>IndexedDB: Observer Constructor Tests</title>
+<meta name=timeout content=long>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script>
+
+indexeddb_test(function(t, db) {
+  db.createObjectStore("store");
+}, function(t, db) {
+  var kKey = 'key';
+  var kNumIters = 20;
+  var callback_number = 1;
+
+  var callbackFunction = function(changes) {
+    assert_true(changes.records.has('store'), "Store not in changes");
+    // Read the value using the transaction.
+    var os = changes.transaction.objectStore('store');
+    var req = os.get(kKey);
+    var expected_value = callback_number;
+    callback_number++;
+    req.onsuccess = t.step_func(function() {
+      assert_equals(req.result, expected_value);
+      if (req.result == kNumIters) {
+        t.done();
+      }
+    });
+  }
+
+  var obs = new IDBObserver(callbackFunction);
+  var txn = db.transaction(['store'], 'readonly');
+  obs.observe(db, txn, { transaction: true, operationTypes: ['put'] });
+
+  txn.oncomplete = t.step_func(function() {
+    var name_dict = {
+      db_name: db.name,
+      num_iters: kNumIters,
+      incrementing_actions: true,
+      key: kKey
+    };
+    var hash_string = encodeURIComponent(JSON.stringify(name_dict));
+    var url = 'resources/observer-actions.js#' + hash_string;
+    new Worker(url);
+  });
+}, 'IndexedDB Observers: Transaction data consistancy.');
+
+</script>
+</html>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/observer.html b/third_party/WebKit/LayoutTests/storage/indexeddb/observer.html
index b55e7882..3e46f40 100644
--- a/third_party/WebKit/LayoutTests/storage/indexeddb/observer.html
+++ b/third_party/WebKit/LayoutTests/storage/indexeddb/observer.html
@@ -1,7 +1,9 @@
+<!doctype html>
 <html>
 <title>IndexedDB: Observer Constructor Tests</title>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
-<script src="resources/observer.js"></script>
+<script src="resources/testharness-helpers.js"></script>
 <script src="resources/generic-idb-operations.js"></script>
+<script src="resources/observer.js"></script>
 </html>
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/resources/generic-idb-operations.js b/third_party/WebKit/LayoutTests/storage/indexeddb/resources/generic-idb-operations.js
index e1974e1..8b07672 100644
--- a/third_party/WebKit/LayoutTests/storage/indexeddb/resources/generic-idb-operations.js
+++ b/third_party/WebKit/LayoutTests/storage/indexeddb/resources/generic-idb-operations.js
@@ -2,31 +2,31 @@
     importScripts('../../../resources/testharness.js');
 }
 
-function compareChanges(actual, expected) {
+function assertChangesEqual(actual, expected) {
   assert_equals(actual.database.name, expected.dbName, 'The change record database should be the same as the database being acted on');
   var stores = Object.keys(expected.records);
   assert_equals(actual.records.size, stores.length, 'Incorrect number of objectStores recorded by observer');
 
+  var storeNamesString = Array.from(actual.records.keys()).join(", ");
   for (var i in stores) {
     var key = stores[i];
-    assert_true(actual.records.has(key));
-    var actual_obsv = actual.records.get(key);
-    var expected_obsv = expected.records[key];
-    assert_equals(actual_obsv.length, expected_obsv.length, 'Number of observations recorded for objectStore '+ key + ' should match observed operations');
-    for (var j in expected_obsv)
-      compareObservations(actual_obsv[j], expected_obsv[j]);
+    assert_true(actual.records.has(key), "Store '" + key + "' not found in changes. Stores: " + storeNamesString);
+    var actualObsv = actual.records.get(key);
+    var expectedObsv = expected.records[key];
+    assert_equals(actualObsv.length, expectedObsv.length, 'Number of observations recorded for objectStore '+ key + ' should match observed operations');
+    for (var j in expectedObsv)
+      assertObservationsEqual(actualObsv[j], expectedObsv[j]);
   }
 }
 
-function compareObservations(actual, expected) {
+function assertObservationsEqual(actual, expected) {
   assert_equals(actual.type, expected.type);
-  assert_not_equals(actual.type, 'kDelete');
-  if (actual.type == 'clear') {
+  if (actual.type === 'clear') {
     assert_equals(actual.key, undefined, 'clear operation has no key');
     assert_equals(actual.value, null, 'clear operation has no value');
     return;
   }
-  if (actual.type == 'delete') {
+  if (actual.type === 'delete') {
     assert_equals(actual.key.lower, expected.key.lower, 'Observed operation key lower bound should match operation performed');
     assert_equals(actual.key.upper, expected.key.upper, 'Observed operation key upper bound should match operation performed');
     assert_equals(actual.key.lower_open, expected.key.lower_open, 'Observed operation key lower open should match operation performed');
@@ -37,8 +37,11 @@
   }
   assert_equals(actual.key.lower, expected.key, 'Observed operation key lower bound should match operation performed');
   assert_equals(actual.key.upper, expected.key, 'Observed operation key upper bound should match operation performed');
-  // TODO(dmurph): Value needs to be updated, once returned correctly. Issue crbug.com/609934.
-  assert_equals(actual.value, null, 'Put/Add operation value does not match');
+  if (expected.value != undefined) {
+    assert_equals(actual.value, expected.value, 'Put/Add operation value does not match');
+  } else {
+    assert_equals(actual.value, null, 'Put/Add operation has unexpected value');
+  }
 }
 
 function countCallbacks(actual, expected) {
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer-actions.js b/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer-actions.js
index 5f88c1b..db44241 100644
--- a/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer-actions.js
+++ b/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer-actions.js
@@ -71,6 +71,25 @@
   perform_db2_actions_part1();
 }
 
+function increment_key_actions(db_name, num_iters, key) {
+  var open_request = indexedDB.open(db_name);
+  open_request.onsuccess = function() {
+    var db = open_request.result;
+
+    var increment_number = function(old_value, num_left) {
+      if (num_left == 0) return;
+      var txn = db.transaction(['store'], 'readwrite');
+      var os = txn.objectStore('store');
+      var new_value = old_value + 1;
+      os.put(new_value, key);
+      txn.oncomplete = function() {
+        increment_number(new_value, num_left - 1);
+      };
+    };
+    increment_number(0, num_iters);
+  };
+};
+
 if (isWorker && location.hash != "") {
   var hash = location.hash.split("#")[1];
   var names = JSON.parse(decodeURIComponent(hash));
@@ -78,6 +97,9 @@
   var errorCallback = function(event) {
     console.log('Error in actions: ' + event.target.error.message);
   }
-
-  indexeddb_observers_actions(names.db1_name, names.db2_name, errorCallback);
+  if (names.incrementing_actions) {
+    increment_key_actions(names.db_name, names.num_iters, names.key);
+  } else {
+    indexeddb_observers_actions(names.db1_name, names.db2_name, errorCallback);
+  }
 }
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer-tests.js b/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer-tests.js
index 8328c21..d1dbe66 100644
--- a/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer-tests.js
+++ b/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer-tests.js
@@ -26,9 +26,12 @@
     }
   };
   var connection = null;
+  var observedTimes = 0;
   var observeFunction = function(changes) {
-    compareChanges(changes, expectedChanges);
-    assert_true(connection != null);
+    assert_true(connection != null, "Observer called before db opened.");
+    observedTimes++;
+    assert_equals(1, observedTimes, "Observer was called after calling unobserve.");
+    assertChangesEqual(changes, expectedChanges);
     obs.unobserve(connection);
     t.done();
   };
@@ -68,9 +71,12 @@
   };
 
   var connection = null;
+  var observedTimes = 0;
   var observeFunction = function(changes) {
-    compareChanges(changes, expectedChanges);
-    assert_true(connection != null);
+    assert_true(connection != null, "Observer called before db opened.");
+    observedTimes++;
+    assert_equals(1, observedTimes, "Observer was called after calling unobserve.");
+    assertChangesEqual(changes, expectedChanges);
     obs.unobserve(connection);
     t.done();
   };
@@ -90,14 +96,84 @@
   var expectedChanges = {
     dbName: db1_name,
     records: {
+      'store2': [{type: 'add', key: 'z', value: 'z'}]
+    }
+  };
+
+  var connection = null;
+  var observedTimes = 0;
+  var observeFunction = function(changes) {
+    assert_true(connection != null, "Observer called before db opened.");
+    observedTimes++;
+    assert_equals(1, observedTimes, "Observer was called after calling unobserve.");
+    assertChangesEqual(changes, expectedChanges);
+    obs.unobserve(connection);
+    t.done();
+  };
+
+  var obs = new IDBObserver(t.step_func(observeFunction));
+
+  openDB(t, db1_name, t.step_func(function(db) {
+    connection = db;
+    var txn = db.transaction(['store2'], 'readonly');
+    obs.observe(db, txn, {operationTypes: ['add'], values: true});
+    txn.oncomplete = observers_added_callback;
+    txn.onerror = t.unreached_func('transaction should not fail')
+  }));
+}, 'IDB Observers: Values');
+
+
+indexeddb_observers_test(function(t, db1_name, db2_name, observers_added_callback) {
+  var expectedChanges = {
+    dbName: db1_name,
+    records: {
+      'store2': [{type: 'add', key: 'z'}],
+    }
+  };
+
+  var connection = null;
+  var observedTimes = 0;
+  var observeFunction = function(changes) {
+    assert_true(connection != null, "Observer called before db opened.");
+    observedTimes++;
+    assert_equals(1, observedTimes, "Observer was called after calling unobserve.");
+    assertChangesEqual(changes, expectedChanges);
+    obs.unobserve(connection);
+    assert_true(changes.transaction != null);
+    var store2 = changes.transaction.objectStore('store2');
+    var request = store2.get('z');
+    request.onsuccess = t.step_func(function() {
+      assert_equals(request.result, 'z');
+      t.done();
+    });
+  };
+
+  var obs = new IDBObserver(t.step_func(observeFunction));
+
+  openDB(t, db1_name, t.step_func(function(db) {
+    connection = db;
+    var txn = db.transaction(['store2'], 'readonly');
+    obs.observe(db, txn, {operationTypes: ['add'], transaction: true});
+    txn.oncomplete = observers_added_callback;
+    txn.onerror = t.unreached_func('transaction should not fail')
+  }));
+}, 'IDB Observers: Transaction');
+
+indexeddb_observers_test(function(t, db1_name, db2_name, observers_added_callback) {
+  var expectedChanges = {
+    dbName: db1_name,
+    records: {
       'store2': [{type: 'add', key: 'z'}]
     }
   };
 
   var connection = null;
+  var observedTimes = 0;
   var observeFunction = function(changes) {
-    compareChanges(changes, expectedChanges);
-    assert_true(connection != null);
+    assert_true(connection != null, "Observer called before db opened.");
+    observedTimes++;
+    assert_equals(1, observedTimes, "Observer was called after calling unobserve.");
+    assertChangesEqual(changes, expectedChanges);
     obs.unobserve(connection);
     t.done();
   };
@@ -139,11 +215,11 @@
   var observeFunction = function(changes) {
     pendingObserves = pendingObserves - 1;
     if (changes.database.name === db1_name) {
-      compareChanges(changes, expectedChanges1);
+      assertChangesEqual(changes, expectedChanges1);
       assert_true(connection1 != null);
       obs.unobserve(connection1);
     } else if (changes.database.name === db2_name) {
-      compareChanges(changes, expectedChanges2);
+      assertChangesEqual(changes, expectedChanges2);
       assert_true(connection2 != null);
       obs.unobserve(connection2);
     }
@@ -187,10 +263,10 @@
   var connection = null;
   var pendingObserves = 2;
   var observeFunction = function(changes) {
-    compareChanges(changes, expectedChanges);
+    assertChangesEqual(changes, expectedChanges);
     pendingObserves = pendingObserves - 1;
     if (pendingObserves === 0) {
-      assert_true(connection != null);
+      assert_true(connection != null, "Observer called before db opened.");
       obs.unobserve(connection);
       t.done();
     } else if (pendingObserves < 0) {
@@ -227,16 +303,18 @@
   var connection = null;
   var changeNumber = 0;
   var observeFunction = function(changes) {
-    assert_true(connection != null);
-    if (changeNumber === 0) {
-      compareChanges(changes, expectedChanges1);
-    } else if(changeNumber === 1) {
-      compareChanges(changes, expectedChanges2);
+    assert_true(connection != null, "Observer called before db opened.");
+    if (changes.records.has('store1')) {
+      assertChangesEqual(changes, expectedChanges1);
+    } else if(changes.records.has('store2')) {
+      assertChangesEqual(changes, expectedChanges2);
+    }
+    ++changeNumber;
+    assert_less_than_equal(changeNumber, 2, "incorrect pendingObserves");
+    if (changeNumber == 2) {
       obs.unobserve(connection);
       t.done();
     }
-    ++changeNumber;
-    assert_less_than_equal(changeNumber, 1, "incorrect pendingObserves");
   };
 
   var obs = new IDBObserver(t.step_func(observeFunction));
@@ -294,16 +372,16 @@
 
     if (changes.database === connection1) {
       assert_true(firstRound, "connection 1 should have been unobserved");
-      compareChanges(changes, partOneChanges1);
+      assertChangesEqual(changes, partOneChanges1);
       obs.unobserve(connection1);
     } else if (changes.database === connection2) {
       if (firstRound)
-        compareChanges(changes, partOneChanges2);
+        assertChangesEqual(changes, partOneChanges2);
       else
-        compareChanges(changes, partTwoChanges2);
+        assertChangesEqual(changes, partTwoChanges2);
     } else if (changes.database === connection3) {
       assert_true(firstRound, "connection 3 should have been unobserved ");
-      compareChanges(changes, partOneChanges3);
+      assertChangesEqual(changes, partOneChanges3);
       obs.unobserve(connection3);
     } else {
       assert_unreached('Unknown connection supplied with changes.');
@@ -347,7 +425,11 @@
   var connection1 = null;
   var connection2 = null;
 
+  var observedTimes = 0;
   var observeFunction = function(changes) {
+    assert_true(connection2 != null, "Observer called before db opened.");
+    observedTimes++;
+    assert_equals(1, observedTimes, "Observer was called after calling unobserve.");
     assert_equals(changes.database, connection2);
     obs.unobserve(connection2);
     t.done();
@@ -433,9 +515,9 @@
       connection1Observes = connection1Observes + 1;
       assert_true(connection1Observes <= 2);
       if (changes.records.has('store1')) {
-        compareChanges(changes, expectedChanges1);
+        assertChangesEqual(changes, expectedChanges1);
       } else if (changes.records.has('store2')) {
-        compareChanges(changes, expectedChanges2);
+        assertChangesEqual(changes, expectedChanges2);
       } else {
         assert_unreached("unknown changes");
       }
@@ -505,9 +587,9 @@
       connection1Observes = connection1Observes + 1;
       assert_true(connection1Observes <= 2);
       if (changes.records.has('store1')) {
-        compareChanges(changes, expectedChanges1);
+        assertChangesEqual(changes, expectedChanges1);
       } else if (changes.records.has('store2')) {
-        compareChanges(changes, expectedChanges2);
+        assertChangesEqual(changes, expectedChanges2);
       } else {
         assert_unreached("unknown changes");
       }
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer.js b/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer.js
index dfcf729..f5b08d68 100644
--- a/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer.js
+++ b/third_party/WebKit/LayoutTests/storage/indexeddb/resources/observer.js
@@ -1,146 +1,82 @@
 if (this.importScripts) {
     importScripts('../../../resources/testharness.js');
+    importScripts('testharness-helpers.js');
     importScripts('generic-idb-operations.js');
 }
 
 async_test(function(t) {
   var dbname = location.pathname + ' - ' + 'empty transaction';
-  var openRequest = indexedDB.open(dbname);
-  var callback_count = 0;
-  var obs = new IDBObserver(t.step_func(function() { callback_count++; }));
-
-  openRequest.onupgradeneeded = t.step_func(function() {
-      openRequest.result.createObjectStore('store');
-  });
-  openRequest.onsuccess = t.step_func(function() {
-    var db = openRequest.result;
+  var obs = new IDBObserver(t.step_func(() => { t.done(); }));
+  delete_then_open(t, dbname, function(t, db, request) {
+    db.createObjectStore('store');
+  }, function(t, db) {
     var tx1 = db.transaction('store', 'readwrite');
-    var tx2 = db.transaction('store', 'readwrite');
     obs.observe(db, tx1, {operationTypes: ['put']});
-    tx2.objectStore('store').put(1, 1);
-    tx1.oncomplete = t.step_func(function() {
-      countCallbacks(callback_count, 0);
-    });
-    tx2.oncomplete = t.step_func(function() {
-      countCallbacks(callback_count, 1);
-      t.done();
-    });
     tx1.onerror = t.unreached_func('transaction should not fail');
+    var tx2 = db.transaction('store', 'readwrite');
+    tx2.objectStore('store').put(1, 1);
     tx2.onerror = t.unreached_func('transaction should not fail');
   });
 }, 'Registering observe call with empty transaction');
 
 async_test(function(t) {
-  var dbname = location.pathname + ' - ' + 'observer in version change';
-  var openRequest = indexedDB.open(dbname);
-  var callback_count = 0;
-  var obs;
-  openRequest.onupgradeneeded = t.step_func(function() {
-      openRequest.result.createObjectStore('store');
-      obs = new IDBObserver(t.step_func(function(changes) { callback_count++; }));
-  });
-  openRequest.onsuccess = t.step_func(function() {
-    var db = openRequest.result;
-    var tx1 = db.transaction('store', 'readwrite');
-    var tx2 = db.transaction('store', 'readwrite');
-    tx1.objectStore('store').get(1);
-    tx2.objectStore('store').put(1, 1);
-    obs.observe(db, tx1, { operationTypes: ['put'] });
-    tx1.oncomplete = t.step_func(function() {
-      countCallbacks(callback_count, 0);
-    });
-    tx2.oncomplete = t.step_func(function() {
-      countCallbacks(callback_count, 1);
-      t.done();
-    });
-    tx1.onerror = t.unreached_func('transaction should not fail');
-    tx2.onerror = t.unreached_func('transaction should not fail');
-   });
-  }, 'Create IDBObserver during version change');
+  var dbname = location.pathname + ' - ' + 'observe in version change';
+  var obs = new IDBObserver(t.step_func(function(changes) { }));
 
-async_test(function(t) {
-  var dbname = location.pathname + ' - ' + 'ignore observe call';
-  var openRequest = indexedDB.open(dbname);
-  var callback_count = 0;
-  var obs = new IDBObserver(t.step_func(function() { callback_count++; }));
-  openRequest.onupgradeneeded = t.step_func(function() {
-      var db = openRequest.result;
-      db.createObjectStore('store');
-      obs.observe(db, openRequest.transaction, { operationTypes: ['put'] });
-  });
-  openRequest.onsuccess = t.step_func(function() {
-    var db = openRequest.result;
-    var tx = db.transaction('store', 'readwrite');
-    tx.objectStore('store').put(1, 1);
-    tx.oncomplete = t.step_func(function() {
-      countCallbacks(callback_count, 0);
-      t.done();
+  delete_then_open(t, dbname, function(t, db, request) {
+    request.result.createObjectStore('store');
+    assert_throws(null, function() {
+      obs.observe(db, request.transaction, { operationTypes: ['put'] });
     });
-    tx.onerror = t.unreached_func('transaction should not fail');
-  });
-}, 'Observe call during version change ignored');
+    t.done();
+  }, function() {});
+}, 'Cannot observe during version change');
 
 async_test(function(t) {
   var dbname = location.pathname + ' - ' + 'abort associated transaction';
-  var openRequest = indexedDB.open(dbname);
-  var callback_count = 0;
-  var obs = new IDBObserver(t.step_func(function() { callback_count++; }));
-  openRequest.onupgradeneeded = t.step_func(function() {
-    openRequest.result.createObjectStore('store');
-  });
-  openRequest.onsuccess = t.step_func(function() {
-    var db = openRequest.result;
+  var obs = new IDBObserver(t.unreached_func('Observe in aborted transaction should be ignored'));
+  delete_then_open(t, dbname, function(t, db, request) {
+    request.result.createObjectStore('store');
+  }, function(t, db) {
     var tx1 = db.transaction('store', 'readwrite');
-    var tx2 = db.transaction('store', 'readwrite');
     tx1.objectStore('store').get(1);
-    tx2.objectStore('store').put(1, 1);
     obs.observe(db, tx1, { operationTypes: ['put'] });
+    tx1.oncomplete = t.unreached_func('transaction should not complete');
     tx1.abort();
 
-    tx1.onabort = t.step_func(function(){
-      countCallbacks(callback_count, 0);
-    });
-    tx1.oncomplete = t.unreached_func('transaction should not complete');
+    var tx2 = db.transaction('store', 'readwrite');
+    tx2.objectStore('store').put(1, 1);
+    tx2.onerror = t.unreached_func('transaction error should not fail');
     tx2.oncomplete = t.step_func(function() {
-      countCallbacks(callback_count, 0);
       t.done();
     });
-    tx2.onerror = t.unreached_func('transaction error should not fail');
   });
 }, 'Abort transaction associated with observer');
 
 async_test(function(t) {
-  var dbname = location.pathname + ' - ' + 'abort transaction';
-  var openRequest = indexedDB.open(dbname);
+  var dbname = location.pathname + ' - ' + 'abort transaction not recorded';
   var callback_count = 0;
-  var obs = new IDBObserver(t.step_func(function() { callback_count++; }));
-  openRequest.onupgradeneeded = t.step_func(function() {
-    openRequest.result.createObjectStore('store');
-  });
-  openRequest.onsuccess = t.step_func(function() {
-    var db = openRequest.result;
-    var tx1 = db.transaction('store', 'readwrite');
-    var tx2 = db.transaction('store', 'readwrite');
-    var tx3 = db.transaction('store', 'readwrite');
-    tx1.objectStore('store').get(1);
-    tx2.objectStore('store').put(1, 1);
-    tx3.objectStore('store').put(1, 1);
-    obs.observe(db, tx1, { operationTypes: ['put'] });
-    tx2.abort();
-    tx1.oncomplete = t.step_func(function() {
-      countCallbacks(callback_count, 0);
-    });
-    tx2.oncomplete = t.unreached_func('transaction should not complete');
-    tx2.onabort = t.step_func(function() {
-      countCallbacks(callback_count, 0);
-    });
-    tx3.oncomplete = t.step_func(function() {
-      countCallbacks(callback_count, 1);
+  var obs = new IDBObserver(t.step_func(function(changes) {
+      assert_equals(changes.records.get('store')[0].key.lower, 1);
       t.done();
-    });
+    }));
+
+  delete_then_open(t, dbname, function(t, db, request) {
+    request.result.createObjectStore('store');
+  }, function(t, db) {
+    var tx1 = db.transaction('store', 'readwrite');
+    obs.observe(db, tx1, { operationTypes: ['put'] });
     tx1.onerror = t.unreached_func('transaction should not fail');
+
+    var tx2 = db.transaction('store', 'readwrite');
+    tx2.objectStore('store').put(2, 2);
+    tx2.oncomplete = t.unreached_func('transaction should not complete');
+    tx2.abort();
+
+    var tx3 = db.transaction('store', 'readwrite');
+    tx3.objectStore('store').put(1, 1);
     tx3.onerror = t.unreached_func('transaction should not fail');
   });
-}, 'Abort transaction recorded by observer');
+}, 'Aborted transaction not recorded by observer');
 
 done();
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 9c93825..9c59386 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -217,6 +217,11 @@
     method toString
     method transformPoint
     method translate
+interface DOMStringList
+    getter length
+    method constructor
+    method contains
+    method item
 interface DataView
     getter buffer
     getter byteLength
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 179caa5..9071a419 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -94,6 +94,11 @@
     getter name
     method constructor
     method toString
+interface DOMStringList
+    getter length
+    method constructor
+    method contains
+    method item
 interface DataView
     getter buffer
     getter byteLength
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
index d859f5d..c2625299 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -98,6 +98,13 @@
 [Worker]     getter name
 [Worker]     method constructor
 [Worker]     method toString
+[Worker] interface DOMStringList
+[Worker]     attribute @@toStringTag
+[Worker]     getter length
+[Worker]     method @@iterator
+[Worker]     method constructor
+[Worker]     method contains
+[Worker]     method item
 [Worker] interface DataView
 [Worker]     attribute @@toStringTag
 [Worker]     getter buffer
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
index c644e8f..4f6d367 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -98,6 +98,13 @@
 [Worker]     getter name
 [Worker]     method constructor
 [Worker]     method toString
+[Worker] interface DOMStringList
+[Worker]     attribute @@toStringTag
+[Worker]     getter length
+[Worker]     method @@iterator
+[Worker]     method constructor
+[Worker]     method contains
+[Worker]     method item
 [Worker] interface DataView
 [Worker]     attribute @@toStringTag
 [Worker]     getter buffer
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 0e953d1..bf1e2d4 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -228,6 +228,13 @@
 [Worker]     method toString
 [Worker]     method transformPoint
 [Worker]     method translate
+[Worker] interface DOMStringList
+[Worker]     attribute @@toStringTag
+[Worker]     getter length
+[Worker]     method @@iterator
+[Worker]     method constructor
+[Worker]     method contains
+[Worker]     method item
 [Worker] interface DataView
 [Worker]     attribute @@toStringTag
 [Worker]     getter buffer
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index 087a14e..2be997b 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -228,6 +228,13 @@
 [Worker]     method toString
 [Worker]     method transformPoint
 [Worker]     method translate
+[Worker] interface DOMStringList
+[Worker]     attribute @@toStringTag
+[Worker]     getter length
+[Worker]     method @@iterator
+[Worker]     method constructor
+[Worker]     method contains
+[Worker]     method item
 [Worker] interface DataView
 [Worker]     attribute @@toStringTag
 [Worker]     getter buffer
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index 231a6b0c..278364c 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -377,6 +377,8 @@
     "properties/CSSPropertyAPIWillChange.cpp",
     "properties/CSSPropertyAPIZIndex.cpp",
     "properties/CSSPropertyAPIZoom.cpp",
+    "properties/CSSPropertyAlignmentUtils.cpp",
+    "properties/CSSPropertyAlignmentUtils.h",
     "properties/CSSPropertyDescriptor.h",
     "resolver/AnimatedStyleBuilder.cpp",
     "resolver/AnimatedStyleBuilder.h",
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index b47f79a..b8d9ac3 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -41,6 +41,7 @@
 #include "core/css/parser/CSSParserIdioms.h"
 #include "core/css/parser/CSSPropertyParserHelpers.h"
 #include "core/css/parser/CSSVariableParser.h"
+#include "core/css/properties/CSSPropertyAlignmentUtils.h"
 #include "core/css/properties/CSSPropertyDescriptor.h"
 #include "core/frame/UseCounter.h"
 #include "core/layout/LayoutTheme.h"
@@ -2436,41 +2437,11 @@
   return result;
 }
 
-static CSSIdentifierValue* consumeSelfPositionKeyword(
-    CSSParserTokenRange& range) {
-  CSSValueID id = range.peek().id();
-  if (id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter ||
-      id == CSSValueSelfStart || id == CSSValueSelfEnd ||
-      id == CSSValueFlexStart || id == CSSValueFlexEnd || id == CSSValueLeft ||
-      id == CSSValueRight)
-    return consumeIdent(range);
-  return nullptr;
-}
-
-static CSSValue* consumeSelfPositionOverflowPosition(
-    CSSParserTokenRange& range) {
-  if (identMatches<CSSValueAuto, CSSValueNormal, CSSValueStretch,
-                   CSSValueBaseline, CSSValueLastBaseline>(range.peek().id()))
-    return consumeIdent(range);
-
-  CSSIdentifierValue* overflowPosition =
-      consumeIdent<CSSValueUnsafe, CSSValueSafe>(range);
-  CSSIdentifierValue* selfPosition = consumeSelfPositionKeyword(range);
-  if (!selfPosition)
-    return nullptr;
-  if (!overflowPosition)
-    overflowPosition = consumeIdent<CSSValueUnsafe, CSSValueSafe>(range);
-  if (overflowPosition)
-    return CSSValuePair::create(selfPosition, overflowPosition,
-                                CSSValuePair::DropIdenticalValues);
-  return selfPosition;
-}
-
 static CSSValue* consumeAlignItems(CSSParserTokenRange& range) {
   // align-items property does not allow the 'auto' value.
   if (identMatches<CSSValueAuto>(range.peek().id()))
     return nullptr;
-  return consumeSelfPositionOverflowPosition(range);
+  return CSSPropertyAlignmentUtils::consumeSelfPositionOverflowPosition(range);
 }
 
 static CSSValue* consumeJustifyItems(CSSParserTokenRange& range) {
@@ -2485,7 +2456,7 @@
     return CSSValuePair::create(legacy, positionKeyword,
                                 CSSValuePair::DropIdenticalValues);
   }
-  return consumeSelfPositionOverflowPosition(range);
+  return CSSPropertyAlignmentUtils::consumeSelfPositionOverflowPosition(range);
 }
 
 static CSSValue* consumeFitContent(CSSParserTokenRange& range,
@@ -3290,7 +3261,8 @@
     case CSSPropertyJustifySelf:
     case CSSPropertyAlignSelf:
       ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-      return consumeSelfPositionOverflowPosition(m_range);
+      return CSSPropertyAlignmentUtils::consumeSelfPositionOverflowPosition(
+          m_range);
     case CSSPropertyJustifyItems:
       ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
       return consumeJustifyItems(m_range);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAlignmentUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAlignmentUtils.cpp
new file mode 100644
index 0000000..d88b18eb
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAlignmentUtils.cpp
@@ -0,0 +1,53 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSPropertyAlignmentUtils.h"
+
+#include "core/css/CSSValuePair.h"
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+
+namespace blink {
+
+namespace {
+
+CSSIdentifierValue* consumeSelfPositionKeyword(
+    CSSParserTokenRange& range) {
+  CSSValueID id = range.peek().id();
+  if (id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter ||
+      id == CSSValueSelfStart || id == CSSValueSelfEnd ||
+      id == CSSValueFlexStart || id == CSSValueFlexEnd || id == CSSValueLeft ||
+      id == CSSValueRight)
+    return CSSPropertyParserHelpers::consumeIdent(range);
+  return nullptr;
+}
+
+} // namespace
+
+CSSValue* CSSPropertyAlignmentUtils::consumeSelfPositionOverflowPosition(
+    CSSParserTokenRange& range) {
+  if (CSSPropertyParserHelpers::identMatches<CSSValueAuto, CSSValueNormal,
+                                             CSSValueStretch, CSSValueBaseline,
+                                             CSSValueLastBaseline>(
+          range.peek().id()))
+    return CSSPropertyParserHelpers::consumeIdent(range);
+
+  CSSIdentifierValue* overflowPosition =
+      CSSPropertyParserHelpers::consumeIdent<CSSValueUnsafe, CSSValueSafe>(
+          range);
+  CSSIdentifierValue* selfPosition = consumeSelfPositionKeyword(range);
+  if (!selfPosition)
+    return nullptr;
+  if (!overflowPosition) {
+    overflowPosition =
+        CSSPropertyParserHelpers::consumeIdent<CSSValueUnsafe, CSSValueSafe>(
+            range);
+  }
+  if (overflowPosition) {
+    return CSSValuePair::create(selfPosition, overflowPosition,
+                                CSSValuePair::DropIdenticalValues);
+  }
+  return selfPosition;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAlignmentUtils.h b/third_party/WebKit/Source/core/css/properties/CSSPropertyAlignmentUtils.h
new file mode 100644
index 0000000..544b902
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAlignmentUtils.h
@@ -0,0 +1,23 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSSPropertyAlignmentUtils_h
+#define CSSPropertyAlignmentUtils_h
+
+#include "wtf/Allocator.h"
+
+namespace blink {
+
+class CSSParserTokenRange;
+class CSSValue;
+
+class CSSPropertyAlignmentUtils {
+  STATIC_ONLY(CSSPropertyAlignmentUtils);
+
+  static CSSValue* consumeSelfPositionOverflowPosition(CSSParserTokenRange& range);
+};
+
+}  // namespace blink
+
+#endif  // CSSPropertyAlignmentUtils_h
diff --git a/third_party/WebKit/Source/core/dom/DOMStringList.cpp b/third_party/WebKit/Source/core/dom/DOMStringList.cpp
index de258f5..ca7ea60e 100644
--- a/third_party/WebKit/Source/core/dom/DOMStringList.cpp
+++ b/third_party/WebKit/Source/core/dom/DOMStringList.cpp
@@ -25,55 +25,20 @@
 
 #include "core/dom/DOMStringList.h"
 
-#include "bindings/core/v8/ScriptState.h"
-#include "core/frame/UseCounter.h"
 #include <algorithm>
 
 namespace blink {
 
-String DOMStringList::anonymousIndexedGetter(unsigned index) const {
+String DOMStringList::item(unsigned index) const {
   if (index >= m_strings.size())
     return String();
   return m_strings[index];
 }
 
-String DOMStringList::item(ScriptState* scriptState, unsigned index) const {
-  switch (m_source) {
-    case DOMStringList::IndexedDB:
-      UseCounter::count(
-          scriptState->getExecutionContext(),
-          UseCounter::DOMStringList_Item_AttributeGetter_IndexedDB);
-      break;
-    case DOMStringList::Location:
-      UseCounter::count(
-          scriptState->getExecutionContext(),
-          UseCounter::DOMStringList_Item_AttributeGetter_Location);
-      break;
-    default:
-      NOTREACHED();
-  }
-
-  return anonymousIndexedGetter(index);
-}
-
-bool DOMStringList::contains(ScriptState* scriptState,
-                             const String& string) const {
-  switch (m_source) {
-    case DOMStringList::IndexedDB:
-      UseCounter::count(scriptState->getExecutionContext(),
-                        UseCounter::DOMStringList_Contains_Method_IndexedDB);
-      break;
-    case DOMStringList::Location:
-      UseCounter::count(scriptState->getExecutionContext(),
-                        UseCounter::DOMStringList_Contains_Method_Location);
-      break;
-    default:
-      NOTREACHED();
-  }
-
-  // FIXME: Currently, all consumers of DOMStringList store fairly small lists
-  // and thus an O(n) algorithm is OK.  But this may need to be optimized if
-  // larger amounts of data are stored in m_strings.
+bool DOMStringList::contains(const String& string) const {
+  // All producers of DOMStringList have reasonably small lists; an O(n)
+  // algorithm is preferred over maintaining an additional structure just for
+  // lookups.
   for (const auto& item : m_strings) {
     if (item == string)
       return true;
diff --git a/third_party/WebKit/Source/core/dom/DOMStringList.h b/third_party/WebKit/Source/core/dom/DOMStringList.h
index 96da3e9..c04d46f 100644
--- a/third_party/WebKit/Source/core/dom/DOMStringList.h
+++ b/third_party/WebKit/Source/core/dom/DOMStringList.h
@@ -34,8 +34,6 @@
 
 namespace blink {
 
-class ScriptState;
-
 // FIXME: Some consumers of this class may benefit from lazily fetching items
 // rather than creating the list statically as is currently the only option.
 class CORE_EXPORT DOMStringList final
@@ -44,15 +42,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  // We would like to remove DOMStringList from the platform if possible.
-  // Track the source of each instance so we can measure the use of methods
-  // not present on Arrays and determine the feasibility of removal and
-  // what path it should take. http://crbug.com/460726
-  enum Source { IndexedDB, Location };
-
-  static DOMStringList* create(Source source) {
-    return new DOMStringList(source);
-  }
+  static DOMStringList* create() { return new DOMStringList(); }
 
   bool isEmpty() const { return m_strings.isEmpty(); }
   void clear() { m_strings.clear(); }
@@ -61,20 +51,18 @@
 
   // Implements the IDL.
   size_t length() const { return m_strings.size(); }
-  String anonymousIndexedGetter(unsigned index) const;
 
-  String item(ScriptState*, unsigned index) const;
-  bool contains(ScriptState*, const String&) const;
+  String item(unsigned index) const;
+  bool contains(const String&) const;
 
   operator const Vector<String>&() const { return m_strings; }
 
   DEFINE_INLINE_TRACE() {}
 
  private:
-  explicit DOMStringList(Source source) : m_source(source) {}
+  explicit DOMStringList() {}
 
   Vector<String> m_strings;
-  Source m_source;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/DOMStringList.idl b/third_party/WebKit/Source/core/dom/DOMStringList.idl
index 7d110b9..aabd5f5 100644
--- a/third_party/WebKit/Source/core/dom/DOMStringList.idl
+++ b/third_party/WebKit/Source/core/dom/DOMStringList.idl
@@ -23,13 +23,11 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// https://dom.spec.whatwg.org/#domstringlist
+// https://html.spec.whatwg.org/multipage/infrastructure.html#domstringlist
 
-// FIXME: DOMStringList has been removed from the spec. crbug.com/460726
+[Exposed=(Window,Worker)]
 interface DOMStringList {
     readonly attribute unsigned long length;
-    getter DOMString? (unsigned long index);
-
-    [CallWith=ScriptState] DOMString? item(unsigned long index);
-    [CallWith=ScriptState,MeasureAs=DOMStringListContains] boolean contains(DOMString string);
+    getter DOMString? item(unsigned long index);
+    boolean contains(DOMString string);
 };
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 150f6e08..c124c05f 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -5819,6 +5819,14 @@
     checkLoadEventSoon();
 }
 
+void Document::decrementLoadEventDelayCountAndCheckLoadEvent() {
+  DCHECK(m_loadEventDelayCount);
+  --m_loadEventDelayCount;
+
+  if (!m_loadEventDelayCount && frame())
+    frame()->loader().checkCompleted();
+}
+
 void Document::checkLoadEventSoon() {
   if (frame() && !m_loadEventDelayTimer.isActive())
     m_loadEventDelayTimer.startOneShot(0, BLINK_FROM_HERE);
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 9700908d..a2acadd 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1098,6 +1098,8 @@
   void checkLoadEventSoon();
   bool isDelayingLoadEvent();
   void loadPluginsSoon();
+  // This calls checkCompleted() sync and thus can cause JavaScript execution.
+  void decrementLoadEventDelayCountAndCheckLoadEvent();
 
   Touch* createTouch(DOMWindow*,
                      EventTarget*,
diff --git a/third_party/WebKit/Source/core/dom/ElementIntersectionObserverData.cpp b/third_party/WebKit/Source/core/dom/ElementIntersectionObserverData.cpp
index ff76561d..d7b5590 100644
--- a/third_party/WebKit/Source/core/dom/ElementIntersectionObserverData.cpp
+++ b/third_party/WebKit/Source/core/dom/ElementIntersectionObserverData.cpp
@@ -33,8 +33,9 @@
 
 void ElementIntersectionObserverData::addObservation(
     IntersectionObservation& observation) {
+  DCHECK(observation.observer());
   m_intersectionObservations.add(
-      TraceWrapperMember<IntersectionObserver>(this, &observation.observer()),
+      TraceWrapperMember<IntersectionObserver>(this, observation.observer()),
       &observation);
 }
 
diff --git a/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp b/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp
index 86b68d16..fc85a1c 100644
--- a/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp
+++ b/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp
@@ -21,12 +21,19 @@
 }
 
 IncrementLoadEventDelayCount::~IncrementLoadEventDelayCount() {
-  m_document->decrementLoadEventDelayCount();
+  if (m_document)
+    m_document->decrementLoadEventDelayCount();
+}
+
+void IncrementLoadEventDelayCount::clearAndCheckLoadEvent() {
+  m_document->decrementLoadEventDelayCountAndCheckLoadEvent();
+  m_document = nullptr;
 }
 
 void IncrementLoadEventDelayCount::documentChanged(Document& newDocument) {
   newDocument.incrementLoadEventDelayCount();
-  m_document->decrementLoadEventDelayCount();
+  if (m_document)
+    m_document->decrementLoadEventDelayCount();
   m_document = &newDocument;
 }
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h b/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
index c125614..23f9eb0 100644
--- a/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
+++ b/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
@@ -24,6 +24,13 @@
   static std::unique_ptr<IncrementLoadEventDelayCount> create(Document&);
   ~IncrementLoadEventDelayCount();
 
+  // Decrements the loadEventDelayCount and checks load event synchronously,
+  // and thus can cause synchronous Document load event/JavaScript execution.
+  // Call this only when it is safe, e.g. at the top of an async task.
+  // After calling this, |this| no longer blocks document's load event and
+  // will not decrement loadEventDelayCount at destruction.
+  void clearAndCheckLoadEvent();
+
   // Increments the new document's count and decrements the old count.
   void documentChanged(Document& newDocument);
 
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
index 6effa41..2d55282 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
@@ -20,6 +20,7 @@
 
 void IntersectionObservation::computeIntersectionObservations(
     DOMHighResTimeStamp timestamp) {
+  DCHECK(observer());
   if (!m_target)
     return;
   Vector<Length> rootMargin(4);
@@ -57,7 +58,7 @@
                          geometry.targetRect().size().height().toFloat();
       newVisibleRatio = intersectionArea / targetArea;
     }
-    newThresholdIndex = observer().firstThresholdGreaterThan(newVisibleRatio);
+    newThresholdIndex = observer()->firstThresholdGreaterThan(newVisibleRatio);
   } else {
     newVisibleRatio = 0;
     newThresholdIndex = 0;
@@ -69,20 +70,15 @@
     IntersectionObserverEntry* newEntry = new IntersectionObserverEntry(
         timestamp, newVisibleRatio, geometry.targetIntRect(), rootBoundsPointer,
         geometry.intersectionIntRect(), target());
-    observer().enqueueIntersectionObserverEntry(*newEntry);
+    observer()->enqueueIntersectionObserverEntry(*newEntry);
     setLastThresholdIndex(newThresholdIndex);
   }
 }
 
 void IntersectionObservation::disconnect() {
-  IntersectionObserver* observer = m_observer;
-  clearRootAndRemoveFromTarget();
-  observer->removeObservation(*this);
-}
-
-void IntersectionObservation::clearRootAndRemoveFromTarget() {
+  DCHECK(observer());
   if (m_target)
-    target()->ensureIntersectionObserverData().removeObservation(observer());
+    target()->ensureIntersectionObserverData().removeObservation(*observer());
   m_observer.clear();
 }
 
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObservation.h b/third_party/WebKit/Source/core/dom/IntersectionObservation.h
index 68fe7337..dcb9323 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObservation.h
+++ b/third_party/WebKit/Source/core/dom/IntersectionObservation.h
@@ -20,13 +20,12 @@
                           Element&,
                           bool shouldReportRootBounds);
 
-  IntersectionObserver& observer() const { return *m_observer; }
+  IntersectionObserver* observer() const { return m_observer.get(); }
   Element* target() const { return m_target; }
   unsigned lastThresholdIndex() const { return m_lastThresholdIndex; }
   void setLastThresholdIndex(unsigned index) { m_lastThresholdIndex = index; }
   void computeIntersectionObservations(DOMHighResTimeStamp);
   void disconnect();
-  void clearRootAndRemoveFromTarget();
 
   DECLARE_TRACE();
 
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
index 9cf2e7d..408fc2c 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
@@ -230,12 +230,8 @@
 
 void IntersectionObserver::observe(Element* target,
                                    ExceptionState& exceptionState) {
-  if (!rootIsValid()) {
-    exceptionState.throwDOMException(
-        InvalidStateError,
-        "observe() called on an IntersectionObserver with an invalid root.");
+  if (!rootIsValid())
     return;
-  }
 
   if (!target || root() == target)
     return;
@@ -287,19 +283,14 @@
 
 void IntersectionObserver::unobserve(Element* target,
                                      ExceptionState& exceptionState) {
-  if (!rootIsValid()) {
-    exceptionState.throwDOMException(
-        InvalidStateError,
-        "unobserve() called on an IntersectionObserver with an invalid root.");
-    return;
-  }
-
   if (!target || !target->intersectionObserverData())
     return;
 
   if (IntersectionObservation* observation =
-          target->intersectionObserverData()->getObservationFor(*this))
+          target->intersectionObserverData()->getObservationFor(*this)) {
     observation->disconnect();
+    m_observations.remove(observation);
+  }
 }
 
 void IntersectionObserver::computeIntersectionObservations() {
@@ -318,23 +309,11 @@
 }
 
 void IntersectionObserver::disconnect(ExceptionState& exceptionState) {
-  if (!rootIsValid()) {
-    exceptionState.throwDOMException(
-        InvalidStateError,
-        "disconnect() called on an IntersectionObserver with an invalid root.");
-    return;
-  }
-
   for (auto& observation : m_observations)
-    observation->clearRootAndRemoveFromTarget();
+    observation->disconnect();
   m_observations.clear();
 }
 
-void IntersectionObserver::removeObservation(
-    IntersectionObservation& observation) {
-  m_observations.remove(&observation);
-}
-
 void IntersectionObserver::setInitialState(InitialState initialState) {
   DCHECK(m_observations.isEmpty());
   m_initialState = initialState;
@@ -343,16 +322,7 @@
 HeapVector<Member<IntersectionObserverEntry>> IntersectionObserver::takeRecords(
     ExceptionState& exceptionState) {
   HeapVector<Member<IntersectionObserverEntry>> entries;
-
-  if (!rootIsValid()) {
-    exceptionState.throwDOMException(InvalidStateError,
-                                     "takeRecords() called on an "
-                                     "IntersectionObserver with an invalid "
-                                     "root.");
-  } else {
-    entries.swap(m_entries);
-  }
-
+  entries.swap(m_entries);
   return entries;
 }
 
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.h b/third_party/WebKit/Source/core/dom/IntersectionObserver.h
index b040129..894652eacf2 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserver.h
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.h
@@ -87,7 +87,6 @@
   void enqueueIntersectionObserverEntry(IntersectionObserverEntry&);
   unsigned firstThresholdGreaterThan(float ratio) const;
   void deliver();
-  void removeObservation(IntersectionObservation&);
   bool hasEntries() const { return m_entries.size(); }
   const HeapLinkedHashSet<WeakMember<IntersectionObservation>>& observations()
       const {
diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp
index 8d15d2d..f1fb70a1 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.cpp
+++ b/third_party/WebKit/Source/core/fetch/Resource.cpp
@@ -933,8 +933,8 @@
   m_resourceRequest.setCachePolicy(WebCachePolicy::BypassingCache);
 }
 
-void Resource::setLoFiStateOff() {
-  m_resourceRequest.setPreviewsState(WebURLRequest::PreviewsOff);
+void Resource::setPreviewsStateNoTransform() {
+  m_resourceRequest.setPreviewsState(WebURLRequest::PreviewsNoTransform);
 }
 
 void Resource::clearRangeRequestHeader() {
diff --git a/third_party/WebKit/Source/core/fetch/Resource.h b/third_party/WebKit/Source/core/fetch/Resource.h
index b5fdd2fe..f78725a 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.h
+++ b/third_party/WebKit/Source/core/fetch/Resource.h
@@ -400,7 +400,7 @@
   }
 
   void setCachePolicyBypassingCache();
-  void setLoFiStateOff();
+  void setPreviewsStateNoTransform();
   void clearRangeRequestHeader();
 
   SharedBuffer* data() const { return m_data.get(); }
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.cpp b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
index 2e3704b..3e47239 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
@@ -81,8 +81,11 @@
   return frame() ? frame()->tree().scopedChildCount() : 0;
 }
 
-v8::Local<v8::Object> DOMWindow::self(ScriptState* scriptState) const {
-  return scriptState->context()->Global();
+DOMWindow* DOMWindow::self() const {
+  if (!frame())
+    return nullptr;
+
+  return frame()->domWindow();
 }
 
 DOMWindow* DOMWindow::opener() const {
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.h b/third_party/WebKit/Source/core/frame/DOMWindow.h
index 44f155c..448360a 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.h
@@ -118,13 +118,9 @@
   virtual void setDefaultStatus(const String&) = 0;
 
   // Self-referential attributes
-  v8::Local<v8::Object> self(ScriptState*) const;
-  v8::Local<v8::Object> window(ScriptState* scriptState) const {
-    return self(scriptState);
-  }
-  v8::Local<v8::Object> frames(ScriptState* scriptState) const {
-    return self(scriptState);
-  }
+  DOMWindow* self() const;
+  DOMWindow* window() const { return self(); }
+  DOMWindow* frames() const { return self(); }
 
   DOMWindow* opener() const;
   DOMWindow* parent() const;
diff --git a/third_party/WebKit/Source/core/frame/Location.cpp b/third_party/WebKit/Source/core/frame/Location.cpp
index 59396a9..46f2c1c 100644
--- a/third_party/WebKit/Source/core/frame/Location.cpp
+++ b/third_party/WebKit/Source/core/frame/Location.cpp
@@ -109,7 +109,7 @@
 }
 
 DOMStringList* Location::ancestorOrigins() const {
-  DOMStringList* origins = DOMStringList::create(DOMStringList::Location);
+  DOMStringList* origins = DOMStringList::create();
   if (!m_frame)
     return origins;
   for (Frame* frame = m_frame->tree().parent(); frame;
diff --git a/third_party/WebKit/Source/core/frame/Location.idl b/third_party/WebKit/Source/core/frame/Location.idl
index 06f56ab..24b40ea 100644
--- a/third_party/WebKit/Source/core/frame/Location.idl
+++ b/third_party/WebKit/Source/core/frame/Location.idl
@@ -52,9 +52,8 @@
     [CallWith=(CurrentWindow,EnteredWindow), CrossOrigin, RaisesException] void replace(DOMString url);
     [CallWith=CurrentWindow] void reload();
 
-    // TODO(foolip): |ancestorOrigins| should have [Unforgeable, SameObject] and
-    // be of type FrozenArray<USVString>.
-    [Measure] readonly attribute DOMStringList ancestorOrigins;
+    // TODO(foolip): |ancestorOrigins| should have [Unforgeable, SameObject].
+    readonly attribute DOMStringList ancestorOrigins;
 
     // TODO(foolip): Per spec, Location implements URLUtils. The below is
     // mostly like the URLUtils interface, but with some members missing and
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 66c1d0b4..d0a928d 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -240,7 +240,6 @@
     HTMLMediaElementPauseAtFragmentEnd = 282,
     PrefixedWindowURL = 283,
     WindowOrientation = 285,
-    DOMStringListContains = 286,
     DocumentCaptureEvents = 287,
     DocumentReleaseEvents = 288,
     WindowCaptureEvents = 289,
@@ -603,10 +602,6 @@
     V8DOMError_Constructor = 816,
     V8DOMError_Name_AttributeGetter = 817,
     V8DOMError_Message_AttributeGetter = 818,
-    V8Location_AncestorOrigins_AttributeGetter = 823,
-    V8IDBDatabase_ObjectStoreNames_AttributeGetter = 824,
-    V8IDBObjectStore_IndexNames_AttributeGetter = 825,
-    V8IDBTransaction_ObjectStoreNames_AttributeGetter = 826,
     TextInputFired = 830,
     V8TextEvent_Data_AttributeGetter = 831,
     V8TextEvent_InitTextEvent_Method = 832,
@@ -616,10 +611,6 @@
     SRIElementIntegrityAttributeButIneligible = 838,
     FormDataAppendNull = 843,
     NonHTMLElementSetAttributeNodeFromHTMLDocumentNameNotLowercase = 845,
-    DOMStringList_Item_AttributeGetter_IndexedDB = 846,
-    DOMStringList_Item_AttributeGetter_Location = 847,
-    DOMStringList_Contains_Method_IndexedDB = 848,
-    DOMStringList_Contains_Method_Location = 849,
     NavigatorVibrate = 850,
     NavigatorVibrateSubFrame = 851,
     V8XPathEvaluator_Constructor = 853,
@@ -1444,6 +1435,12 @@
     CSSSelectorInternalMediaControlsTextTrackListItemInput = 1774,
     CSSSelectorInternalMediaControlsTextTrackListKindCaptions = 1775,
     CSSSelectorInternalMediaControlsTextTrackListKindSubtitles = 1776,
+    ScrollbarUseVerticalScrollbarButton = 1777,
+    ScrollbarUseVerticalScrollbarThumb = 1778,
+    ScrollbarUseVerticalScrollbarTrack = 1779,
+    ScrollbarUseHorizontalScrollbarButton = 1780,
+    ScrollbarUseHorizontalScrollbarThumb = 1781,
+    ScrollbarUseHorizontalScrollbarTrack = 1782,
 
     // Add new features immediately above this line. Don't change assigned
     // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/frame/Window.idl b/third_party/WebKit/Source/core/frame/Window.idl
index 265cc88..8b45bb3a 100644
--- a/third_party/WebKit/Source/core/frame/Window.idl
+++ b/third_party/WebKit/Source/core/frame/Window.idl
@@ -34,8 +34,8 @@
 ] interface Window : EventTarget {
     // the current browsing context
     // FIXME: The spec uses the WindowProxy type for this and many other attributes.
-    [Unforgeable, CallWith=ScriptState, CrossOrigin] readonly attribute Window window;
-    [Replaceable, CallWith=ScriptState, CrossOrigin] readonly attribute Window self;
+    [Unforgeable, CrossOrigin] readonly attribute Window window;
+    [Replaceable, CrossOrigin] readonly attribute Window self;
     [Unforgeable, CachedAccessor] readonly attribute Document document;
     attribute DOMString name;
     [PutForwards=href, Unforgeable, CrossOrigin=(Getter,Setter)] readonly attribute Location location;
@@ -54,7 +54,7 @@
     [CrossOrigin] void blur();
 
     // other browsing contexts
-    [Replaceable, CallWith=ScriptState, CrossOrigin] readonly attribute Window frames;
+    [Replaceable, CrossOrigin] readonly attribute Window frames;
     [Replaceable, CrossOrigin] readonly attribute unsigned long length;
     [Unforgeable, CrossOrigin] readonly attribute Window? top;
     // FIXME: opener should be of type any.
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
index d564e57..0895da43 100644
--- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -289,7 +289,9 @@
 }
 
 void HTMLLinkElement::scheduleEvent() {
-  TaskRunnerHelper::get(TaskType::DOMManipulation, &document())
+  // TODO(hiroshige): Use DOMManipulation task runner. Unthrottled
+  // is temporarily used for fixing https://crbug.com/649942 only on M-56.
+  TaskRunnerHelper::get(TaskType::Unthrottled, &document())
       ->postTask(
           BLINK_FROM_HERE,
           WTF::bind(
diff --git a/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp b/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
index 8b7d3d5..2dfd1d4 100644
--- a/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
@@ -117,7 +117,9 @@
   if (m_firedLoad && isLoadEvent)
     return;
   m_loadedSheet = isLoadEvent;
-  TaskRunnerHelper::get(TaskType::DOMManipulation, &document())
+  // TODO(hiroshige): Use DOMManipulation task runner. Unthrottled
+  // is temporarily used for fixing https://crbug.com/649942 only on M-56.
+  TaskRunnerHelper::get(TaskType::Unthrottled, &document())
       ->postTask(
           BLINK_FROM_HERE,
           WTF::bind(
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index e848908..c8847b8e 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -235,7 +235,6 @@
   updateTransform(layoutObject()->styleRef());
   updateFilters(layoutObject()->styleRef());
   updateBackdropFilters(layoutObject()->styleRef());
-  updateStickyConstraints(layoutObject()->styleRef());
   updateLayerBlendMode(layoutObject()->styleRef());
   updateIsRootForIsolatedGroup();
 }
@@ -315,7 +314,9 @@
                                enclosingLayerOffset);
     FloatPoint stickyBoxOffset =
         constraints.scrollContainerRelativeStickyBoxRect().location();
-    stickyBoxOffset.moveBy(FloatPoint(-enclosingLayerOffset));
+    DCHECK(!m_contentOffsetInCompositingLayerDirty);
+    stickyBoxOffset.moveBy(FloatPoint(-enclosingLayerOffset) -
+                           FloatSize(contentOffsetInCompositingLayer()));
 
     webConstraint.isSticky = true;
     webConstraint.isAnchoredLeft =
@@ -943,8 +944,6 @@
   if (!layoutObject()->style()->isRunningBackdropFilterAnimationOnCompositor())
     updateBackdropFilters(layoutObject()->styleRef());
 
-  updateStickyConstraints(layoutObject()->styleRef());
-
   // We compute everything relative to the enclosing compositing layer.
   IntRect ancestorCompositingBounds;
   if (compositingContainer) {
@@ -981,6 +980,7 @@
                                           graphicsLayerParentLocation);
   updateContentsOffsetInCompositingLayer(snappedOffsetFromCompositedAncestor,
                                          graphicsLayerParentLocation);
+  updateStickyConstraints(layoutObject()->styleRef());
   updateSquashingLayerGeometry(
       graphicsLayerParentLocation, compositingContainer, m_squashedLayers,
       m_squashingLayer.get(), &m_squashingLayerOffsetFromTransformedAncestor,
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
index c063e364..c01a0df3 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
@@ -11,6 +11,7 @@
 #include "core/page/scrolling/TopDocumentRootScrollerController.h"
 #include "core/paint/PaintLayer.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
+#include "public/platform/WebContentLayer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
@@ -1246,4 +1247,56 @@
   EXPECT_FALSE(childMapping->ancestorClippingMaskLayer());
 }
 
+TEST_P(CompositedLayerMappingTest, StickyPositionContentOffset) {
+  setBodyInnerHTML(
+      "<div style='width: 400px; height: 400px; overflow: auto; "
+      "will-change: transform;' >"
+      "    <div id='sticky1' style='position: sticky; top: 0px; width: 100px; "
+      "height: 100px; box-shadow: -5px -5px 5px 0 black; "
+      "will-change: transform;'></div>"
+      "    <div style='height: 2000px;'></div>"
+      "</div>"
+
+      "<div style='width: 400px; height: 400px; overflow: auto; "
+      "will-change: transform;' >"
+      "    <div id='sticky2' style='position: sticky; top: 0px; width: 100px; "
+      "height: 100px; will-change: transform;'>"
+      "        <div style='position: absolute; top: -50px; left: -50px; "
+      "width: 5px; height: 5px; background: red;'></div></div>"
+      "    <div style='height: 2000px;'></div>"
+      "</div>");
+  document().view()->updateLifecycleToCompositingCleanPlusScrolling();
+
+  CompositedLayerMapping* sticky1 =
+      toLayoutBlock(getLayoutObjectByElementId("sticky1"))
+          ->layer()
+          ->compositedLayerMapping();
+  CompositedLayerMapping* sticky2 =
+      toLayoutBlock(getLayoutObjectByElementId("sticky2"))
+          ->layer()
+          ->compositedLayerMapping();
+
+  // Box offsets the content by the combination of the shadow offset and blur
+  // radius plus an additional pixel of anti-aliasing.
+  ASSERT_TRUE(sticky1);
+  WebLayerStickyPositionConstraint constraint1 =
+      sticky1->mainGraphicsLayer()
+          ->contentLayer()
+          ->layer()
+          ->stickyPositionConstraint();
+  EXPECT_EQ(IntPoint(-11, -11),
+            IntPoint(constraint1.parentRelativeStickyBoxOffset));
+
+  // Since the nested div will be squashed into the same composited layer the
+  // sticky element is offset by the nested element's offset.
+  ASSERT_TRUE(sticky2);
+  WebLayerStickyPositionConstraint constraint2 =
+      sticky2->mainGraphicsLayer()
+          ->contentLayer()
+          ->layer()
+          ->stickyPositionConstraint();
+  EXPECT_EQ(IntPoint(-50, -50),
+            IntPoint(constraint2.parentRelativeStickyBoxOffset));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
index 9dbafbc..0938032 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -1128,15 +1128,21 @@
     m_overflowControlsHostLayer = GraphicsLayer::create(this);
     m_containerLayer = GraphicsLayer::create(this);
 
+    // TODO(skobes): When root layer scrolling is enabled, we should not even
+    // create m_scrollLayer or most of the layers in PLC.
     m_scrollLayer = GraphicsLayer::create(this);
     if (ScrollingCoordinator* scrollingCoordinator =
             this->scrollingCoordinator())
       scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(
           m_scrollLayer.get(), true);
 
-    m_scrollLayer->setElementId(createCompositorElementId(
-        DOMNodeIds::idForNode(&m_layoutView.document()),
-        CompositorSubElementId::Scroll));
+    // In RLS mode, LayoutView scrolling contents layer gets this element ID (in
+    // CompositedLayerMapping::updateElementIdAndCompositorMutableProperties).
+    if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
+      m_scrollLayer->setElementId(createCompositorElementId(
+          DOMNodeIds::idForNode(&m_layoutView.document()),
+          CompositorSubElementId::Scroll));
+    }
 
     // Hook them up
     m_overflowControlsHostLayer->addChild(m_containerLayer.get());
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_break_token.h b/third_party/WebKit/Source/core/layout/ng/ng_block_break_token.h
new file mode 100644
index 0000000..14e50e4
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_break_token.h
@@ -0,0 +1,43 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NGBlockBreakToken_h
+#define NGBlockBreakToken_h
+
+#include "core/layout/ng/ng_break_token.h"
+#include "platform/LayoutUnit.h"
+
+namespace blink {
+
+class NGBlockNode;
+
+class NGBlockBreakToken : public NGBreakToken {
+ public:
+  NGBlockBreakToken(NGBlockNode* node, LayoutUnit break_offset)
+      : NGBreakToken(kBlockBreakToken),
+        node_(node),
+        break_offset_(break_offset) {}
+
+  NGBlockNode& InputNode() const { return *node_.get(); }
+  LayoutUnit BreakOffset() const { return break_offset_; }
+
+  DEFINE_INLINE_VIRTUAL_TRACE() {
+    NGBreakToken::trace(visitor);
+    visitor->trace(node_);
+  }
+
+ private:
+  Member<NGBlockNode> node_;
+  LayoutUnit break_offset_;
+};
+
+DEFINE_TYPE_CASTS(NGBlockBreakToken,
+                  NGBreakToken,
+                  token,
+                  token->Type() == NGBreakToken::kBlockBreakToken,
+                  token.Type() == NGBreakToken::kBlockBreakToken);
+
+}  // namespace blink
+
+#endif  // NGBlockBreakToken_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index ef259608..b2852ff 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -4,8 +4,9 @@
 
 #include "core/layout/ng/ng_block_layout_algorithm.h"
 
+#include "core/layout/ng/ng_block_break_token.h"
 #include "core/layout/ng/ng_box_fragment.h"
-#include "core/layout/ng/ng_break_token.h"
+#include "core/layout/ng/ng_column_mapper.h"
 #include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_constraint_space_builder.h"
 #include "core/layout/ng/ng_fragment.h"
@@ -274,20 +275,30 @@
         space_builder_->SetFragmentationType(kFragmentColumn);
         adjusted_inline_size =
             ResolveUsedColumnInlineSize(adjusted_inline_size, Style());
+        LayoutUnit inline_progression =
+            adjusted_inline_size + ResolveUsedColumnGap(Style());
+        fragmentainer_mapper_ =
+            new NGColumnMapper(inline_progression, adjusted_block_size);
       }
       space_builder_->SetAvailableSize(
           NGLogicalSize(adjusted_inline_size, adjusted_block_size));
       space_builder_->SetPercentageResolutionSize(
           NGLogicalSize(adjusted_inline_size, adjusted_block_size));
 
-      content_size_ = border_and_padding_.block_start;
-
       builder_ = new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox);
       builder_->SetDirection(constraint_space_->Direction());
       builder_->SetWritingMode(constraint_space_->WritingMode());
       builder_->SetInlineSize(inline_size).SetBlockSize(block_size);
 
-      current_child_ = first_child_;
+      if (NGBlockBreakToken* token = CurrentBlockBreakToken()) {
+        // Resume after a previous break.
+        content_size_ = token->BreakOffset();
+        current_child_ = token->InputNode();
+      } else {
+        content_size_ = border_and_padding_.block_start;
+        current_child_ = first_child_;
+      }
+
       layout_state_ = kStatePrepareForChildLayout;
       return kNotFinished;
     }
@@ -300,6 +311,8 @@
           current_child_ = current_child_->NextSibling();
           return kNotFinished;
         }
+        DCHECK(!ConstraintSpace().HasBlockFragmentation() ||
+               SpaceAvailableForCurrentChild() > LayoutUnit());
         space_for_current_child_ = CreateConstraintSpaceForCurrentChild();
         *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode(
             current_child_, space_for_current_child_);
@@ -336,8 +349,11 @@
       FinishCurrentChildLayout(new NGBoxFragment(
           ConstraintSpace().WritingMode(), ConstraintSpace().Direction(),
           toNGPhysicalBoxFragment(child_fragment)));
-      current_child_ = current_child_->NextSibling();
-      layout_state_ = kStatePrepareForChildLayout;
+
+      if (ProceedToNextUnfinishedSibling(child_fragment))
+        layout_state_ = kStatePrepareForChildLayout;
+      else
+        layout_state_ = kStateFinalize;
       return kNotFinished;
     }
     case kStateOutOfFlowLayout:
@@ -347,6 +363,10 @@
     case kStateFinalize: {
       builder_->SetInlineOverflow(max_inline_size_)
           .SetBlockOverflow(content_size_);
+
+      if (ConstraintSpace().HasBlockFragmentation())
+        FinalizeForFragmentation();
+
       *fragment_out = builder_->ToBoxFragment();
       layout_state_ = kStateInit;
       return kNewFragment;
@@ -370,6 +390,10 @@
                      &child_margins);
     fragment_offset = PositionFragment(*fragment, child_margins);
   }
+  if (fragmentainer_mapper_)
+    fragmentainer_mapper_->ToVisualOffset(fragment_offset);
+  else
+    fragment_offset.block_offset -= PreviousBreakOffset();
   builder_->AddChild(fragment, fragment_offset);
 }
 
@@ -401,6 +425,146 @@
   return false;
 }
 
+bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling(
+    NGPhysicalFragment* child_fragment) {
+  DCHECK(current_child_);
+  NGBlockNode* finished_child = current_child_;
+  current_child_ = current_child_->NextSibling();
+  if (!ConstraintSpace().HasBlockFragmentation() && !fragmentainer_mapper_)
+    return true;
+  // If we're resuming layout after a fragmentainer break, we need to skip
+  // siblings that we're done with. We may have been able to fully lay out some
+  // node(s) preceding a node that we had to break inside (and therefore were
+  // not able to fully lay out). This happens when we have parallel flows [1],
+  // which are caused by floats, overflow, etc.
+  //
+  // [1] https://drafts.csswg.org/css-break/#parallel-flows
+  if (CurrentBlockBreakToken()) {
+    // TODO(layout-ng): Figure out if we need a better way to determine if the
+    // node is finished. Maybe something to encode in a break token?
+    while (current_child_ && current_child_->IsLayoutFinished())
+      current_child_ = current_child_->NextSibling();
+  }
+  LayoutUnit break_offset = NextBreakOffset();
+  bool is_out_of_space = content_size_ - PreviousBreakOffset() >= break_offset;
+  if (!HasPendingBreakToken()) {
+    bool child_broke = child_fragment->BreakToken();
+    // This block needs to break if the child broke, or if we're out of space
+    // and there's more content waiting to be laid out. Otherwise, just bail
+    // now.
+    if (!child_broke && (!is_out_of_space || !current_child_))
+      return true;
+    // Prepare a break token for this block, so that we know where to resume
+    // when the time comes for that. We may not be able to abort layout of this
+    // block right away, due to the posibility of parallel flows. We can only
+    // abort when we're out of space, or when there are no siblings left to
+    // process.
+    NGBlockBreakToken* token;
+    if (child_broke) {
+      // The child we just laid out was the first one to break. So that is
+      // where we need to resume.
+      token = new NGBlockBreakToken(finished_child, break_offset);
+    } else {
+      // Resume layout at the next sibling that needs layout.
+      DCHECK(current_child_);
+      token = new NGBlockBreakToken(current_child_, break_offset);
+    }
+    SetPendingBreakToken(token);
+  }
+
+  if (!fragmentainer_mapper_) {
+    if (!is_out_of_space)
+      return true;
+    // We have run out of space in this flow, so there's no work left to do for
+    // this block in this fragmentainer. We should finalize the fragment and get
+    // back to the remaining content when laying out the next fragmentainer(s).
+    return false;
+  }
+
+  if (is_out_of_space || !current_child_) {
+    NGBlockBreakToken* token = fragmentainer_mapper_->Advance();
+    DCHECK(token || !is_out_of_space);
+    if (token) {
+      break_token_ = token;
+      content_size_ = token->BreakOffset();
+      current_child_ = token->InputNode();
+    }
+  }
+  return true;
+}
+
+void NGBlockLayoutAlgorithm::SetPendingBreakToken(NGBlockBreakToken* token) {
+  if (fragmentainer_mapper_)
+    fragmentainer_mapper_->SetBreakToken(token);
+  else
+    builder_->SetBreakToken(token);
+}
+
+bool NGBlockLayoutAlgorithm::HasPendingBreakToken() const {
+  if (fragmentainer_mapper_)
+    return fragmentainer_mapper_->HasBreakToken();
+  return builder_->HasBreakToken();
+}
+
+void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
+  LayoutUnit block_size =
+      ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_);
+  LayoutUnit previous_break_offset = PreviousBreakOffset();
+  block_size -= previous_break_offset;
+  block_size = std::max(LayoutUnit(), block_size);
+  LayoutUnit space_left = ConstraintSpace().FragmentainerSpaceAvailable();
+  DCHECK_GE(space_left, LayoutUnit());
+  if (builder_->HasBreakToken()) {
+    // A break token is ready, which means that we're going to break
+    // before or inside a block-level child.
+    builder_->SetBlockSize(std::min(space_left, block_size));
+    builder_->SetBlockOverflow(space_left);
+    return;
+  }
+  if (block_size > space_left) {
+    // Need a break inside this block.
+    builder_->SetBreakToken(new NGBlockBreakToken(nullptr, NextBreakOffset()));
+    builder_->SetBlockSize(space_left);
+    builder_->SetBlockOverflow(space_left);
+    return;
+  }
+  // The end of the block fits in the current fragmentainer.
+  builder_->SetBlockSize(block_size);
+  builder_->SetBlockOverflow(content_size_ - previous_break_offset);
+}
+
+NGBlockBreakToken* NGBlockLayoutAlgorithm::CurrentBlockBreakToken() const {
+  NGBreakToken* token = break_token_;
+  if (!token || token->Type() != NGBreakToken::kBlockBreakToken)
+    return nullptr;
+  return toNGBlockBreakToken(token);
+}
+
+LayoutUnit NGBlockLayoutAlgorithm::PreviousBreakOffset() const {
+  const NGBlockBreakToken* token = CurrentBlockBreakToken();
+  return token ? token->BreakOffset() : LayoutUnit();
+}
+
+LayoutUnit NGBlockLayoutAlgorithm::NextBreakOffset() const {
+  if (fragmentainer_mapper_)
+    return fragmentainer_mapper_->NextBreakOffset();
+  DCHECK(ConstraintSpace().HasBlockFragmentation());
+  return PreviousBreakOffset() +
+         ConstraintSpace().FragmentainerSpaceAvailable();
+}
+
+LayoutUnit NGBlockLayoutAlgorithm::SpaceAvailableForCurrentChild() const {
+  LayoutUnit space_left;
+  if (fragmentainer_mapper_)
+    space_left = fragmentainer_mapper_->BlockSize();
+  else if (ConstraintSpace().HasBlockFragmentation())
+    space_left = ConstraintSpace().FragmentainerSpaceAvailable();
+  else
+    return NGSizeIndefinite;
+  space_left -= BorderEdgeForCurrentChild() - PreviousBreakOffset();
+  return space_left;
+}
+
 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
     const NGBoxStrut& margins,
     const NGBoxFragment& fragment) {
@@ -544,6 +708,8 @@
       .SetWritingMode(
           FromPlatformWritingMode(CurrentChildStyle().getWritingMode()))
       .SetTextDirection(CurrentChildStyle().direction());
+  LayoutUnit space_available = SpaceAvailableForCurrentChild();
+  space_builder_->SetFragmentainerSpaceAvailable(space_available);
   NGConstraintSpace* child_space = space_builder_->ToConstraintSpace();
 
   // TODO(layout-ng): Set offset through the space builder.
@@ -563,6 +729,7 @@
   visitor->trace(current_minmax_child_);
   visitor->trace(out_of_flow_layout_);
   visitor->trace(out_of_flow_candidates_);
+  visitor->trace(fragmentainer_mapper_);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
index 13f67cc..7750f7f 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -14,7 +14,9 @@
 namespace blink {
 
 class ComputedStyle;
+class NGBlockBreakToken;
 class NGBreakToken;
+class NGColumnMapper;
 class NGConstraintSpace;
 class NGConstraintSpaceBuilder;
 class NGBoxFragment;
@@ -50,6 +52,49 @@
   void FinishCurrentChildLayout(NGFragment* fragment);
   bool LayoutOutOfFlowChild();
 
+  // Proceed to the next sibling that still needs layout.
+  //
+  // @param child_fragment The newly created fragment for the current child.
+  // @return true if we can continue to lay out, or false if we need to abort
+  // due to a fragmentainer break.
+  bool ProceedToNextUnfinishedSibling(NGPhysicalFragment* child_fragment);
+
+  // Set a break token which contains enough information to be able to resume
+  // layout in the next fragmentainer.
+  void SetPendingBreakToken(NGBlockBreakToken*);
+
+  // Check if we have a pending break token set. Once we have set a pending
+  // break token, we cannot set another one. First we need to abort layout in
+  // the current fragmentainer and resume in the next one.
+  bool HasPendingBreakToken() const;
+
+  // Final adjusstments before fragment creation. We need to prevent the
+  // fragment from crossing fragmentainer boundaries, and rather create a break
+  // token if we're out of space.
+  void FinalizeForFragmentation();
+
+  // Return the break token, if any, at which we resumed layout after a
+  // previous break.
+  NGBlockBreakToken* CurrentBlockBreakToken() const;
+
+  // Return the block offset of the previous break, in the fragmented flow
+  // coordinate space, relatively to the start edge of this block.
+  LayoutUnit PreviousBreakOffset() const;
+
+  // Return the offset of the potential next break, in the fragmented flow
+  // coordinate space, relatively to the start edge of this block.
+  LayoutUnit NextBreakOffset() const;
+
+  // Get the amount of block space left in the current fragmentainer for the
+  // child that is about to be laid out.
+  LayoutUnit SpaceAvailableForCurrentChild() const;
+
+  LayoutUnit BorderEdgeForCurrentChild() const {
+    // TODO(mstensho): Need to take care of margin collapsing somehow. We
+    // should at least attempt to estimate what the top margin is going to be.
+    return content_size_;
+  }
+
   // Computes collapsed margins for 2 adjoining blocks and updates the resultant
   // fragment's MarginStrut if needed.
   // See https://www.w3.org/TR/CSS2/box.html#collapsing-margins
@@ -115,7 +160,10 @@
 
   Member<NGBlockNode> first_child_;
   Member<NGConstraintSpace> constraint_space_;
+
+  // The break token from which we are currently resuming layout.
   Member<NGBreakToken> break_token_;
+
   Member<NGFragmentBuilder> builder_;
   Member<NGConstraintSpaceBuilder> space_builder_;
   Member<NGConstraintSpace> space_for_current_child_;
@@ -128,6 +176,11 @@
   Vector<NGStaticPosition> out_of_flow_candidate_positions_;
   size_t out_of_flow_candidate_positions_index_;
 
+  // Mapper from the fragmented flow coordinate space coordinates to visual
+  // coordinates. Only set on fragmentation context roots, such as multicol
+  // containers. Keeps track of the current fragmentainer.
+  Member<NGColumnMapper> fragmentainer_mapper_;
+
   NGBoxStrut border_and_padding_;
   LayoutUnit content_size_;
   LayoutUnit max_inline_size_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
index ab9624f2..32a615d3 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -847,5 +847,723 @@
   EXPECT_EQ(LayoutUnit(30), frag->Width());
 }
 
+class FragmentChildIterator
+    : public GarbageCollectedFinalized<FragmentChildIterator> {
+ public:
+  FragmentChildIterator() {}
+  FragmentChildIterator(const NGPhysicalBoxFragment* parent) {
+    SetParent(parent);
+  }
+  void SetParent(const NGPhysicalBoxFragment* parent) {
+    parent_ = parent;
+    index_ = 0;
+  }
+
+  const NGPhysicalBoxFragment* NextChild() {
+    if (!parent_)
+      return nullptr;
+    if (index_ >= parent_->Children().size())
+      return nullptr;
+    while (parent_->Children()[index_]->Type() !=
+           NGPhysicalFragment::kFragmentBox) {
+      ++index_;
+      if (index_ >= parent_->Children().size())
+        return nullptr;
+    }
+    return toNGPhysicalBoxFragment(parent_->Children()[index_++]);
+  }
+
+  DEFINE_INLINE_TRACE() { visitor->trace(parent_); }
+
+ private:
+  Member<const NGPhysicalBoxFragment> parent_;
+  unsigned index_;
+};
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:2; column-fill:auto; column-gap:10px;
+//                          width:210px; height:100px;">
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, EmptyMulticol) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(2);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(210, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(210), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  // There should be nothing inside the multicol container.
+  EXPECT_FALSE(FragmentChildIterator(fragment).NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:2; column-fill:auto; column-gap:10px;
+//                          width:210px; height:100px;">
+//    <div id="child"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, EmptyBlock) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(2);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(210, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child
+  RefPtr<ComputedStyle> child_style = ComputedStyle::create();
+  NGBlockNode* child = new NGBlockNode(child_style.get());
+
+  parent->SetFirstChild(child);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  EXPECT_EQ(LayoutUnit(210), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  ASSERT_TRUE(fragment);
+  EXPECT_FALSE(iterator.NextChild());
+  iterator.SetParent(fragment);
+
+  // #child fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(100), fragment->Width());
+  EXPECT_EQ(LayoutUnit(), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:2; column-fill:auto; column-gap:10px;
+//                          width:310px; height:100px;">
+//    <div id="child" style="width:60%; height:100px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, BlockInOneColumn) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(2);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(310, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child
+  RefPtr<ComputedStyle> child_style = ComputedStyle::create();
+  child_style->setWidth(Length(60, Percent));
+  child_style->setHeight(Length(100, Fixed));
+  NGBlockNode* child = new NGBlockNode(child_style.get());
+
+  parent->SetFirstChild(child);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(310), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+  iterator.SetParent(fragment);
+
+  // #child fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(90), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:2; column-fill:auto; column-gap:10px;
+//                          width:210px; height:100px;">
+//    <div id="child" style="width:75%; height:150px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, BlockInTwoColumns) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(2);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(210, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child
+  RefPtr<ComputedStyle> child_style = ComputedStyle::create();
+  child_style->setWidth(Length(75, Percent));
+  child_style->setHeight(Length(150, Fixed));
+  NGBlockNode* child = new NGBlockNode(child_style.get());
+
+  parent->SetFirstChild(child);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(210), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  iterator.SetParent(fragment);
+  // #child fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+
+  // #child fragment in second column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(50), fragment->Height());
+  EXPECT_EQ(0U, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:3; column-fill:auto; column-gap:10px;
+//                          width:320px; height:100px;">
+//    <div id="child" style="width:75%; height:250px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, BlockInThreeColumns) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(3);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(320, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child
+  RefPtr<ComputedStyle> child_style = ComputedStyle::create();
+  child_style->setWidth(Length(75, Percent));
+  child_style->setHeight(Length(250, Fixed));
+  NGBlockNode* child = new NGBlockNode(child_style.get());
+
+  parent->SetFirstChild(child);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(320), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  iterator.SetParent(fragment);
+  // #child fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+
+  // #child fragment in second column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0U, fragment->Children().size());
+
+  // #child fragment in third column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(220), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(50), fragment->Height());
+  EXPECT_EQ(0U, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:2; column-fill:auto; column-gap:10px;
+//                          width:210px; height:100px;">
+//    <div id="child" style="width:1px; height:250px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, ActualColumnCountGreaterThanSpecified) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(2);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(210, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child
+  RefPtr<ComputedStyle> child_style = ComputedStyle::create();
+  child_style->setWidth(Length(1, Fixed));
+  child_style->setHeight(Length(250, Fixed));
+  NGBlockNode* child = new NGBlockNode(child_style.get());
+
+  parent->SetFirstChild(child);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(210), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  iterator.SetParent(fragment);
+  // #child fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(1), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+
+  // #child fragment in second column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(1), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0U, fragment->Children().size());
+
+  // #child fragment in third column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(220), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(1), fragment->Width());
+  EXPECT_EQ(LayoutUnit(50), fragment->Height());
+  EXPECT_EQ(0U, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:3; column-fill:auto; column-gap:10px;
+//                          width:320px; height:100px;">
+//    <div id="child1" style="width:75%; height:60px;"></div>
+//    <div id="child2" style="width:85%; height:60px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, TwoBlocksInTwoColumns) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(3);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(320, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child1
+  RefPtr<ComputedStyle> child1_style = ComputedStyle::create();
+  child1_style->setWidth(Length(75, Percent));
+  child1_style->setHeight(Length(60, Fixed));
+  NGBlockNode* child1 = new NGBlockNode(child1_style.get());
+
+  // child2
+  RefPtr<ComputedStyle> child2_style = ComputedStyle::create();
+  child2_style->setWidth(Length(85, Percent));
+  child2_style->setHeight(Length(60, Fixed));
+  NGBlockNode* child2 = new NGBlockNode(child2_style.get());
+
+  parent->SetFirstChild(child1);
+  child1->SetNextSibling(child2);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(320), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  iterator.SetParent(fragment);
+  // #child1 fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(60), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  // #child2 fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(60), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(85), fragment->Width());
+  EXPECT_EQ(LayoutUnit(40), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+
+  // #child2 fragment in second column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(85), fragment->Width());
+  EXPECT_EQ(LayoutUnit(20), fragment->Height());
+  EXPECT_EQ(0U, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:3; column-fill:auto; column-gap:10px;
+//                          width:320px; height:100px;">
+//    <div id="child1" style="width:75%; height:60px;">
+//      <div id="grandchild1" style="width:50px; height:120px;"></div>
+//      <div id="grandchild2" style="width:40px; height:20px;"></div>
+//    </div>
+//    <div id="child2" style="width:85%; height:10px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, OverflowedBlock) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(3);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(320, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child1
+  RefPtr<ComputedStyle> child1_style = ComputedStyle::create();
+  child1_style->setWidth(Length(75, Percent));
+  child1_style->setHeight(Length(60, Fixed));
+  NGBlockNode* child1 = new NGBlockNode(child1_style.get());
+
+  // grandchild1
+  RefPtr<ComputedStyle> grandchild1_style = ComputedStyle::create();
+  grandchild1_style->setWidth(Length(50, Fixed));
+  grandchild1_style->setHeight(Length(120, Fixed));
+  NGBlockNode* grandchild1 = new NGBlockNode(grandchild1_style.get());
+
+  // grandchild2
+  RefPtr<ComputedStyle> grandchild2_style = ComputedStyle::create();
+  grandchild2_style->setWidth(Length(40, Fixed));
+  grandchild2_style->setHeight(Length(20, Fixed));
+  NGBlockNode* grandchild2 = new NGBlockNode(grandchild2_style.get());
+
+  // child2
+  RefPtr<ComputedStyle> child2_style = ComputedStyle::create();
+  child2_style->setWidth(Length(85, Percent));
+  child2_style->setHeight(Length(10, Fixed));
+  NGBlockNode* child2 = new NGBlockNode(child2_style.get());
+
+  parent->SetFirstChild(child1);
+  child1->SetNextSibling(child2);
+  child1->SetFirstChild(grandchild1);
+  grandchild1->SetNextSibling(grandchild2);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(320), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  iterator.SetParent(fragment);
+  // #child1 fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(60), fragment->Height());
+  FragmentChildIterator grandchild_iterator(fragment);
+  // #grandchild1 fragment in first column
+  fragment = grandchild_iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(50), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(grandchild_iterator.NextChild());
+  // #child2 fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(60), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(85), fragment->Width());
+  EXPECT_EQ(LayoutUnit(10), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+
+  // #child1 fragment in second column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(), fragment->Height());
+  grandchild_iterator.SetParent(fragment);
+  // #grandchild1 fragment in second column
+  fragment = grandchild_iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(50), fragment->Width());
+  EXPECT_EQ(LayoutUnit(20), fragment->Height());
+  // #grandchild2 fragment in second column
+  fragment = grandchild_iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(20), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(40), fragment->Width());
+  EXPECT_EQ(LayoutUnit(20), fragment->Height());
+  EXPECT_FALSE(grandchild_iterator.NextChild());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:3; column-fill:auto; column-gap:10px;
+//                          width:320px; height:100px;">
+//    <div id="child" style="float:left; width:75%; height:100px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, FloatInOneColumn) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(3);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(320, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child
+  RefPtr<ComputedStyle> child_style = ComputedStyle::create();
+  child_style->setFloating(EFloat::kLeft);
+  child_style->setWidth(Length(75, Percent));
+  child_style->setHeight(Length(100, Fixed));
+  NGBlockNode* child = new NGBlockNode(child_style.get());
+
+  parent->SetFirstChild(child);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(320), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  iterator.SetParent(fragment);
+  // #child fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(75), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:3; column-fill:auto; column-gap:10px;
+//                          width:320px; height:100px;">
+//    <div id="child1" style="float:left; width:15%; height:100px;"></div>
+//    <div id="child2" style="float:right; width:16%; height:100px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, TwoFloatsInOneColumn) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(3);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(320, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child1
+  RefPtr<ComputedStyle> child1_style = ComputedStyle::create();
+  child1_style->setFloating(EFloat::kLeft);
+  child1_style->setWidth(Length(15, Percent));
+  child1_style->setHeight(Length(100, Fixed));
+  NGBlockNode* child1 = new NGBlockNode(child1_style.get());
+
+  // child2
+  RefPtr<ComputedStyle> child2_style = ComputedStyle::create();
+  child2_style->setFloating(EFloat::kRight);
+  child2_style->setWidth(Length(16, Percent));
+  child2_style->setHeight(Length(100, Fixed));
+  NGBlockNode* child2 = new NGBlockNode(child2_style.get());
+
+  parent->SetFirstChild(child1);
+  child1->SetNextSibling(child2);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(320), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  iterator.SetParent(fragment);
+  // #child1 fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(15), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  // #child2 fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(84), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(16), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
+// Test case's HTML representation:
+//  <div id="parent" style="columns:3; column-fill:auto; column-gap:10px;
+//                          width:320px; height:100px;">
+//    <div id="child1" style="float:left; width:15%; height:150px;"></div>
+//    <div id="child2" style="float:right; width:16%; height:150px;"></div>
+//  </div>
+TEST_F(NGBlockLayoutAlgorithmTest, TwoFloatsInTwoColumns) {
+  // parent
+  RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
+  parent_style->setColumnCount(3);
+  parent_style->setColumnFill(ColumnFillAuto);
+  parent_style->setColumnGap(10);
+  parent_style->setHeight(Length(100, Fixed));
+  parent_style->setWidth(Length(320, Fixed));
+  NGBlockNode* parent = new NGBlockNode(parent_style.get());
+
+  // child1
+  RefPtr<ComputedStyle> child1_style = ComputedStyle::create();
+  child1_style->setFloating(EFloat::kLeft);
+  child1_style->setWidth(Length(15, Percent));
+  child1_style->setHeight(Length(150, Fixed));
+  NGBlockNode* child1 = new NGBlockNode(child1_style.get());
+
+  // child2
+  RefPtr<ComputedStyle> child2_style = ComputedStyle::create();
+  child2_style->setFloating(EFloat::kRight);
+  child2_style->setWidth(Length(16, Percent));
+  child2_style->setHeight(Length(150, Fixed));
+  NGBlockNode* child2 = new NGBlockNode(child2_style.get());
+
+  parent->SetFirstChild(child1);
+  child1->SetNextSibling(child2);
+
+  auto* space = ConstructConstraintSpace(
+      kHorizontalTopBottom, TextDirection::kLtr,
+      NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
+  const auto* fragment = RunBlockLayoutAlgorithm(space, parent);
+
+  FragmentChildIterator iterator(fragment);
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(320), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_FALSE(iterator.NextChild());
+
+  iterator.SetParent(fragment);
+  // #child1 fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(15), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  // #child2 fragment in first column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(84), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(16), fragment->Width());
+  EXPECT_EQ(LayoutUnit(100), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+
+  // #child1 fragment in second column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(15), fragment->Width());
+  EXPECT_EQ(LayoutUnit(50), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  // #child2 fragment in second column
+  fragment = iterator.NextChild();
+  ASSERT_TRUE(fragment);
+  EXPECT_EQ(LayoutUnit(194), fragment->LeftOffset());
+  EXPECT_EQ(LayoutUnit(), fragment->TopOffset());
+  EXPECT_EQ(LayoutUnit(16), fragment->Width());
+  EXPECT_EQ(LayoutUnit(50), fragment->Height());
+  EXPECT_EQ(0UL, fragment->Children().size());
+  EXPECT_FALSE(iterator.NextChild());
+}
+
 }  // namespace
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
index d900723c5..da60564 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -203,6 +203,10 @@
   first_child_ = child;
 }
 
+NGBreakToken* NGBlockNode::CurrentBreakToken() const {
+  return fragment_ ? fragment_->BreakToken() : nullptr;
+}
+
 DEFINE_TRACE(NGBlockNode) {
   visitor->trace(layout_coordinator_);
   visitor->trace(minmax_algorithm_);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
index d2b9a38..29ac63e3 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -7,6 +7,7 @@
 
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_layout_input_node.h"
+#include "core/layout/ng/ng_physical_box_fragment.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -14,11 +15,11 @@
 class ComputedStyle;
 class LayoutBox;
 class LayoutObject;
+class NGBreakToken;
 class NGConstraintSpace;
 class NGFragment;
 class NGLayoutAlgorithm;
 class NGLayoutCoordinator;
-class NGPhysicalBoxFragment;
 struct MinAndMaxContentSizes;
 
 // Represents a node to be laid out.
@@ -55,6 +56,12 @@
   void SetNextSibling(NGBlockNode*);
   void SetFirstChild(NGLayoutInputNode*);
 
+  void SetFragment(NGPhysicalBoxFragment* fragment) { fragment_ = fragment; }
+  NGBreakToken* CurrentBreakToken() const;
+  bool IsLayoutFinished() const {
+    return fragment_ && !fragment_->BreakToken();
+  }
+
   DECLARE_VIRTUAL_TRACE();
 
   // Runs layout on layout_box_ and creates a fragment for the resulting
@@ -89,6 +96,9 @@
   Member<NGLayoutInputNode> first_child_;
   Member<NGLayoutCoordinator> layout_coordinator_;
   Member<NGLayoutAlgorithm> minmax_algorithm_;
+  // TODO(mstensho): An input node may produce multiple fragments, so this
+  // should probably be renamed to last_fragment_ or something like that, since
+  // the last fragment is all we care about when resuming layout.
   Member<NGPhysicalBoxFragment> fragment_;
 };
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_break_token.h b/third_party/WebKit/Source/core/layout/ng/ng_break_token.h
index 2ddb1112..7a1778f 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_break_token.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_break_token.h
@@ -13,10 +13,20 @@
 class CORE_EXPORT NGBreakToken
     : public GarbageCollectedFinalized<NGBreakToken> {
  public:
-  NGBreakToken() {}
+  virtual ~NGBreakToken() {}
 
-  DEFINE_INLINE_TRACE() {}
+  enum NGBreakTokenType { kBlockBreakToken, kTextBreakToken };
+  NGBreakTokenType Type() const { return static_cast<NGBreakTokenType>(type_); }
+
+  DEFINE_INLINE_VIRTUAL_TRACE() {}
+
+ protected:
+  NGBreakToken(NGBreakTokenType type) : type_(type) {}
+
+ private:
+  unsigned type_ : 1;
 };
-}
 
-#endif
+}  // namespace blink
+
+#endif  // NGBreakToken_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_column_mapper.h b/third_party/WebKit/Source/core/layout/ng/ng_column_mapper.h
new file mode 100644
index 0000000..b4ab09f9
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_column_mapper.h
@@ -0,0 +1,82 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NGColumnMapper_h
+#define NGColumnMapper_h
+
+#include "core/CoreExport.h"
+#include "core/layout/ng/ng_block_break_token.h"
+#include "platform/heap/Handle.h"
+
+namespace blink {
+
+// Keeps track of the current column, and is used to map offsets from the
+// coordinate established by the fragmented flow [1] to visual coordinates.
+//
+// [1] https://drafts.csswg.org/css-break/#fragmented-flow
+//
+// TODO(mstensho): Add a NGFragmentainerMapper super class. There are other
+// fragmentation types than multicol (regions, pagination for printing).
+class CORE_EXPORT NGColumnMapper
+    : public GarbageCollectedFinalized<NGColumnMapper> {
+ public:
+  NGColumnMapper(LayoutUnit inline_progression, LayoutUnit block_size)
+      : inline_progression_(inline_progression), block_size_(block_size) {}
+
+  // Column block length.
+  LayoutUnit BlockSize() const { return block_size_; }
+
+  // Offset for next break, in the fragmented flow coordinate space.
+  LayoutUnit NextBreakOffset() const {
+    return last_break_block_offset_ + block_size_;
+  }
+
+  // Convert an offset in the fragmented flow coordinate space to the visual
+  // coordinate space.
+  void ToVisualOffset(NGLogicalOffset& offset) {
+    offset.inline_offset += inline_offset_;
+    offset.block_offset -= last_break_block_offset_;
+  }
+
+  // Specify where in the content to start layout of the next column.
+  void SetBreakToken(NGBlockBreakToken* token) {
+    DCHECK(!break_token_);
+    break_token_ = token;
+  }
+  bool HasBreakToken() const { return break_token_; }
+
+  // Advance to the next column. Returns the break token to resume at. If
+  // nullptr is returned, there's no more content to process.
+  NGBlockBreakToken* Advance() {
+    NGBlockBreakToken* token = break_token_;
+    break_token_ = nullptr;
+    if (token) {
+      inline_offset_ += inline_progression_;
+      last_break_block_offset_ += block_size_;
+    }
+    return token;
+  }
+
+  DEFINE_INLINE_TRACE() { visitor->trace(break_token_); }
+
+ private:
+  // Where to resume in the next column.
+  Member<NGBlockBreakToken> break_token_;
+
+  // The sum of used column-width and column_gap.
+  LayoutUnit inline_progression_;
+
+  // Inline offset to the current column.
+  LayoutUnit inline_offset_;
+
+  // Block size of a column.
+  LayoutUnit block_size_;
+
+  // Amount of content held by previous columns.
+  LayoutUnit last_break_block_offset_;
+};
+
+}  // namespace blink
+
+#endif  // NGColumnMapper_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
index 366a40c..f392161 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
@@ -16,6 +16,7 @@
     TextDirection direction,
     NGLogicalSize available_size,
     NGLogicalSize percentage_resolution_size,
+    LayoutUnit fragmentainer_space_available,
     bool is_fixed_size_inline,
     bool is_fixed_size_block,
     bool is_shrink_to_fit,
@@ -26,6 +27,7 @@
     const std::shared_ptr<NGExclusions>& exclusions_)
     : available_size_(available_size),
       percentage_resolution_size_(percentage_resolution_size),
+      fragmentainer_space_available_(fragmentainer_space_available),
       is_fixed_size_inline_(is_fixed_size_inline),
       is_fixed_size_block_(is_fixed_size_block),
       is_shrink_to_fit_(is_shrink_to_fit),
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
index ccbe235e..b04888f 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
@@ -70,6 +70,12 @@
   // TODO(layout-ng): Set offset via NGConstraintSpacebuilder.
   void SetOffset(const NGLogicalOffset& offset) { offset_ = offset; }
 
+  // Return the block-direction space available in the current fragmentainer.
+  LayoutUnit FragmentainerSpaceAvailable() const {
+    DCHECK(HasBlockFragmentation());
+    return fragmentainer_space_available_;
+  }
+
   // Whether the current constraint space is for the newly established
   // Formatting Context.
   bool IsNewFormattingContext() const { return is_new_fc_; }
@@ -104,6 +110,12 @@
   // blockSize if possible.
   NGFragmentationType BlockFragmentationType() const;
 
+  // Return true if this contraint space participates in a fragmentation
+  // context.
+  bool HasBlockFragmentation() const {
+    return BlockFragmentationType() != kFragmentNone;
+  }
+
   // Modifies constraint space to account for a placed fragment. Depending on
   // the shape of the fragment this will either modify the inline or block
   // size, or add an exclusion.
@@ -124,6 +136,7 @@
                     TextDirection,
                     NGLogicalSize available_size,
                     NGLogicalSize percentage_resolution_size,
+                    LayoutUnit fragmentainer_space_available,
                     bool is_fixed_size_inline,
                     bool is_fixed_size_block,
                     bool is_shrink_to_fit,
@@ -136,6 +149,8 @@
   NGLogicalSize available_size_;
   NGLogicalSize percentage_resolution_size_;
 
+  LayoutUnit fragmentainer_space_available_;
+
   unsigned is_fixed_size_inline_ : 1;
   unsigned is_fixed_size_block_ : 1;
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
index 9d72ce9..ac99cdd 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
@@ -4,12 +4,15 @@
 
 #include "core/layout/ng/ng_constraint_space_builder.h"
 
+#include "core/layout/ng/ng_length_utils.h"
+
 namespace blink {
 
 NGConstraintSpaceBuilder::NGConstraintSpaceBuilder(
     const NGConstraintSpace* parent_space)
     : available_size_(parent_space->AvailableSize()),
       percentage_resolution_size_(parent_space->PercentageResolutionSize()),
+      fragmentainer_space_available_(NGSizeIndefinite),
       writing_mode_(parent_space->WritingMode()),
       parent_writing_mode_(writing_mode_),
       is_fixed_size_inline_(false),
@@ -17,13 +20,14 @@
       is_shrink_to_fit_(false),
       is_inline_direction_triggers_scrollbar_(false),
       is_block_direction_triggers_scrollbar_(false),
-      fragmentation_type_(kFragmentNone),
+      fragmentation_type_(parent_space->BlockFragmentationType()),
       is_new_fc_(parent_space->IsNewFormattingContext()),
       text_direction_(static_cast<unsigned>(parent_space->Direction())),
       exclusions_(parent_space->Exclusions()) {}
 
 NGConstraintSpaceBuilder::NGConstraintSpaceBuilder(NGWritingMode writing_mode)
-    : writing_mode_(writing_mode),
+    : fragmentainer_space_available_(NGSizeIndefinite),
+      writing_mode_(writing_mode),
       parent_writing_mode_(writing_mode_),
       is_fixed_size_inline_(false),
       is_fixed_size_block_(false),
@@ -122,7 +126,8 @@
         {available_size_.inline_size, available_size_.block_size},
         {percentage_resolution_size_.inline_size,
          percentage_resolution_size_.block_size},
-        is_fixed_size_inline_, is_fixed_size_block_, is_shrink_to_fit_,
+        fragmentainer_space_available_, is_fixed_size_inline_,
+        is_fixed_size_block_, is_shrink_to_fit_,
         is_inline_direction_triggers_scrollbar_,
         is_block_direction_triggers_scrollbar_,
         static_cast<NGFragmentationType>(fragmentation_type_), is_new_fc_,
@@ -135,7 +140,8 @@
       {available_size_.block_size, available_size_.inline_size},
       {percentage_resolution_size_.block_size,
        percentage_resolution_size_.inline_size},
-      is_fixed_size_block_, is_fixed_size_inline_, is_shrink_to_fit_,
+      fragmentainer_space_available_, is_fixed_size_block_,
+      is_fixed_size_inline_, is_shrink_to_fit_,
       is_block_direction_triggers_scrollbar_,
       is_inline_direction_triggers_scrollbar_,
       static_cast<NGFragmentationType>(fragmentation_type_), is_new_fc_,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
index 4ba9e69..5bbcbf7 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
@@ -22,6 +22,11 @@
   NGConstraintSpaceBuilder& SetPercentageResolutionSize(
       NGLogicalSize percentage_resolution_size);
 
+  NGConstraintSpaceBuilder& SetFragmentainerSpaceAvailable(LayoutUnit space) {
+    fragmentainer_space_available_ = space;
+    return *this;
+  }
+
   NGConstraintSpaceBuilder& SetTextDirection(TextDirection);
 
   NGConstraintSpaceBuilder& SetIsFixedSizeInline(bool is_fixed_size_inline);
@@ -52,6 +57,7 @@
  private:
   NGLogicalSize available_size_;
   NGLogicalSize percentage_resolution_size_;
+  LayoutUnit fragmentainer_space_available_;
 
   unsigned writing_mode_ : 2;
   unsigned parent_writing_mode_ : 2;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
index 5ca6488..78f30d7d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -5,6 +5,7 @@
 #include "core/layout/ng/ng_fragment_builder.h"
 
 #include "core/layout/ng/ng_block_node.h"
+#include "core/layout/ng/ng_break_token.h"
 #include "core/layout/ng/ng_fragment.h"
 #include "core/layout/ng/ng_physical_box_fragment.h"
 #include "core/layout/ng/ng_physical_text_fragment.h"
@@ -136,6 +137,9 @@
   DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox);
   DCHECK_EQ(offsets_.size(), children_.size());
 
+  auto* break_token = break_token_.get();
+  break_token_ = nullptr;
+
   NGPhysicalSize physical_size = size_.ConvertToPhysical(writing_mode_);
   HeapVector<Member<const NGPhysicalFragment>> children;
   children.reserveCapacity(children_.size());
@@ -148,7 +152,8 @@
   }
   return new NGPhysicalBoxFragment(
       physical_size, overflow_.ConvertToPhysical(writing_mode_), children,
-      out_of_flow_descendants_, out_of_flow_positions_, margin_strut_);
+      out_of_flow_descendants_, out_of_flow_positions_, margin_strut_,
+      break_token);
 }
 
 NGPhysicalTextFragment* NGFragmentBuilder::ToTextFragment(NGInlineNode* node,
@@ -167,6 +172,7 @@
   visitor->trace(children_);
   visitor->trace(out_of_flow_descendant_candidates_);
   visitor->trace(out_of_flow_descendants_);
+  visitor->trace(break_token_);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
index c96ad00..72ca485 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -81,6 +81,12 @@
   NGFragmentBuilder& AddOutOfFlowDescendant(NGBlockNode*,
                                             const NGStaticPosition&);
 
+  void SetBreakToken(NGBreakToken* token) {
+    DCHECK(!break_token_);
+    break_token_ = token;
+  }
+  bool HasBreakToken() const { return break_token_; }
+
   // Sets MarginStrut for the resultant fragment.
   NGFragmentBuilder& SetMarginStrutBlockStart(const NGMarginStrut& from);
   NGFragmentBuilder& SetMarginStrutBlockEnd(const NGMarginStrut& from);
@@ -132,6 +138,8 @@
 
   WeakBoxList out_of_flow_descendants_;
   Vector<NGStaticPosition> out_of_flow_positions_;
+
+  Member<NGBreakToken> break_token_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc
index 2f2e074..1050b23c 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc
@@ -31,6 +31,9 @@
     return new NGInlineLayoutAlgorithm(style, child, constraint_space);
   }
   NGBlockNode* child = toNGBlockNode(block->FirstChild());
-  return new NGBlockLayoutAlgorithm(style, child, constraint_space);
+  // TODO(layout-ng): The break token should be passed as an argument to this
+  // method instead of getting it from the NGBlockNode
+  NGBreakToken* token = block->CurrentBreakToken();
+  return new NGBlockLayoutAlgorithm(style, child, constraint_space, token);
 }
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc
index f5e2c41..5fd19a9 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc
@@ -12,12 +12,14 @@
     HeapVector<Member<const NGPhysicalFragment>>& children,
     HeapLinkedHashSet<WeakMember<NGBlockNode>>& out_of_flow_descendants,
     Vector<NGStaticPosition>& out_of_flow_positions,
-    NGMarginStrut margin_strut)
+    NGMarginStrut margin_strut,
+    NGBreakToken* break_token)
     : NGPhysicalFragment(size,
                          overflow,
                          kFragmentBox,
                          out_of_flow_descendants,
-                         out_of_flow_positions),
+                         out_of_flow_positions,
+                         break_token),
       margin_strut_(margin_strut) {
   children_.swap(children);
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
index c49793d..68013588 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
@@ -23,7 +23,8 @@
       HeapVector<Member<const NGPhysicalFragment>>& children,
       HeapLinkedHashSet<WeakMember<NGBlockNode>>& out_of_flow_descendants,
       Vector<NGStaticPosition>& out_of_flow_positions,
-      NGMarginStrut margin_strut);
+      NGMarginStrut margin_strut,
+      NGBreakToken* break_token = nullptr);
 
   const HeapVector<Member<const NGPhysicalFragment>>& Children() const {
     return children_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
index 4a4c533..b9ddfdfd 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
@@ -61,6 +61,8 @@
     has_been_placed_ = true;
   }
 
+  NGBreakToken* BreakToken() const { return break_token_; }
+
   const HeapLinkedHashSet<WeakMember<NGBlockNode>>& OutOfFlowDescendants()
       const {
     return out_of_flow_descendants_;
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 77a7519..9cfa91a 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -185,8 +185,6 @@
       networkStateNotifier().connectionType() == WebConnectionTypeCellular2G;
   WebEffectiveConnectionType effectiveConnection =
       document.frame()->client()->getEffectiveConnectionType();
-  const bool is2GOrLike2G =
-      is2G || isConnectionEffectively2G(effectiveConnection);
 
   return document.settings()
              ->getDisallowFetchForDocWrittenScriptsInMainFrame() ||
@@ -195,7 +193,7 @@
           is2G) ||
          (document.settings()
               ->getDisallowFetchForDocWrittenScriptsInMainFrameIfEffectively2G() &&
-          is2GOrLike2G);
+          isConnectionEffectively2G(effectiveConnection));
 }
 
 }  // namespace
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
index 4ce4081..3dd9552 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -298,7 +298,7 @@
     ResourceRequest resourceRequest(url);
     if (updateBehavior == UpdateForcedReload) {
       resourceRequest.setCachePolicy(WebCachePolicy::BypassingCache);
-      resourceRequest.setPreviewsState(WebURLRequest::PreviewsOff);
+      resourceRequest.setPreviewsState(WebURLRequest::PreviewsNoTransform);
     }
 
     if (referrerPolicy != ReferrerPolicyDefault) {
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
index b319b9a3..dd1d1395b 100644
--- a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
@@ -426,7 +426,8 @@
 
   if (policy != kReloadAlwaysWithExistingCachePolicy)
     setCachePolicyBypassingCache();
-  setLoFiStateOff();
+
+  setPreviewsStateNoTransform();
 
   if (m_isPlaceholder) {
     m_isPlaceholder = false;
diff --git a/third_party/WebKit/Source/core/paint/BoxClipper.cpp b/third_party/WebKit/Source/core/paint/BoxClipper.cpp
index a56f689..87d5224 100644
--- a/third_party/WebKit/Source/core/paint/BoxClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxClipper.cpp
@@ -24,13 +24,12 @@
 // An exception is control clip, which is currently never applied by
 // PaintLayerClipper.
 static bool boxNeedsClip(const LayoutBox& box) {
-  if (box.hasControlClip())
-    return true;
   if (box.hasLayer() && box.layer()->isSelfPaintingLayer())
     return false;
   if (box.isSVGRoot() && toLayoutSVGRoot(box).shouldApplyViewportClip())
     return true;
-  return box.hasOverflowClip() || box.styleRef().containsPaint();
+  return box.hasOverflowClip() || box.styleRef().containsPaint() ||
+         box.hasControlClip();
 }
 
 DISABLE_CFI_PERF
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.cpp b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
index fd646a7..e27b590 100644
--- a/third_party/WebKit/Source/core/paint/BoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
@@ -37,9 +37,7 @@
 
 namespace blink {
 
-namespace {
-
-bool isPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+bool BoxPainter::isPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
     const LayoutBoxModelObject* obj,
     const PaintInfo& paintInfo) {
   return paintInfo.paintFlags() & PaintLayerPaintingOverflowContents &&
@@ -48,8 +46,6 @@
          obj == paintInfo.paintContainer();
 }
 
-}  // namespace
-
 void BoxPainter::paint(const PaintInfo& paintInfo,
                        const LayoutPoint& paintOffset) {
   ObjectPainter(m_layoutBox).checkPaintOffset(paintInfo, paintOffset);
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.h b/third_party/WebKit/Source/core/paint/BoxPainter.h
index 3b72868..c322af00 100644
--- a/third_party/WebKit/Source/core/paint/BoxPainter.h
+++ b/third_party/WebKit/Source/core/paint/BoxPainter.h
@@ -118,6 +118,10 @@
   LayoutRect boundsForDrawingRecorder(const PaintInfo&,
                                       const LayoutPoint& adjustedPaintOffset);
 
+  static bool isPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+      const LayoutBoxModelObject*,
+      const PaintInfo&);
+
  private:
   void paintBackground(const PaintInfo&,
                        const LayoutRect&,
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp
index 36899a9..0fdbed2 100644
--- a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp
@@ -5,6 +5,7 @@
 #include "core/paint/PaintInvalidationCapableScrollableArea.h"
 
 #include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/layout/LayoutBox.h"
 #include "core/layout/LayoutScrollbar.h"
@@ -204,4 +205,38 @@
   layoutBox()->setMayNeedPaintInvalidation();
 }
 
+void PaintInvalidationCapableScrollableArea::didScrollWithScrollbar(
+    ScrollbarPart part,
+    ScrollbarOrientation orientation) {
+  UseCounter::Feature scrollbarUseUMA;
+  switch (part) {
+    case BackButtonStartPart:
+    case ForwardButtonStartPart:
+    case BackButtonEndPart:
+    case ForwardButtonEndPart:
+      scrollbarUseUMA =
+          (orientation == VerticalScrollbar
+               ? UseCounter::ScrollbarUseVerticalScrollbarButton
+               : UseCounter::ScrollbarUseHorizontalScrollbarButton);
+      break;
+    case ThumbPart:
+      scrollbarUseUMA =
+          (orientation == VerticalScrollbar
+               ? UseCounter::ScrollbarUseVerticalScrollbarThumb
+               : UseCounter::ScrollbarUseHorizontalScrollbarThumb);
+      break;
+    case BackTrackPart:
+    case ForwardTrackPart:
+      scrollbarUseUMA =
+          (orientation == VerticalScrollbar
+               ? UseCounter::ScrollbarUseVerticalScrollbarTrack
+               : UseCounter::ScrollbarUseHorizontalScrollbarTrack);
+      break;
+    default:
+      return;
+  }
+
+  UseCounter::count(layoutBox()->document(), scrollbarUseUMA);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.h b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.h
index 8633f59a..77ce4c6 100644
--- a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.h
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.h
@@ -40,6 +40,8 @@
 
   LayoutRect visualRectForScrollbarParts() const override;
 
+  void didScrollWithScrollbar(ScrollbarPart, ScrollbarOrientation) override;
+
  private:
   virtual LayoutScrollbarPart* scrollCorner() const = 0;
   virtual LayoutScrollbarPart* resizer() const = 0;
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index 77b9cdd..bdba2ba 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -2513,8 +2513,9 @@
       !hasVisibleDescendant())
     return LayoutRect();
 
-  // Without composited scrolling, the root layer is the size of the document.
-  if (isRootLayer() && !needsCompositedScrolling()) {
+  // The root layer is the size of the document, plus any additional area due
+  // to layout viewport being different than initial containing block.
+  if (isRootLayer()) {
     IntRect documentRect = layoutObject()->view()->documentRect();
 
     if (FrameView* frameView = layoutObject()->document().view()) {
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
index 7f5ee06..72d1876 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -74,39 +74,39 @@
                            const LayoutBoxModelObject& layoutObject,
                            LayoutPoint offset,
                            ClipRects& clipRects) {
-  DCHECK(layoutObject.hasClipRelatedProperty() ||
-         (layoutObject.isSVGRoot() &&
-          toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()));
-  LayoutView* view = layoutObject.view();
+  DCHECK(layoutObject.isBox());
+  const LayoutBox& box = *toLayoutBox(&layoutObject);
+
+  DCHECK(box.hasClipRelatedProperty() || box.hasControlClip() ||
+         (box.isSVGRoot() && toLayoutSVGRoot(&box)->shouldApplyViewportClip()));
+  LayoutView* view = box.view();
   DCHECK(view);
   if (clipRects.fixed() && context.rootLayer->layoutObject() == view)
     offset -= LayoutSize(view->frameView()->getScrollOffset());
-  if (layoutObject.hasOverflowClip() ||
-      (layoutObject.isSVGRoot() &&
-       toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) ||
-      (layoutObject.styleRef().containsPaint() && layoutObject.isBox())) {
+
+  if (box.hasOverflowClip() ||
+      (box.isSVGRoot() && toLayoutSVGRoot(&box)->shouldApplyViewportClip()) ||
+      box.styleRef().containsPaint() || box.hasControlClip()) {
     ClipRect newOverflowClip =
-        toLayoutBox(layoutObject)
-            .overflowClipRect(offset, context.overlayScrollbarClipBehavior);
-    newOverflowClip.setHasRadius(layoutObject.styleRef().hasBorderRadius());
+        box.overflowClipRect(offset, context.overlayScrollbarClipBehavior);
+    newOverflowClip.setHasRadius(box.styleRef().hasBorderRadius());
     clipRects.setOverflowClipRect(
         intersection(newOverflowClip, clipRects.overflowClipRect()));
-    if (layoutObject.isPositioned())
+    if (box.isPositioned())
       clipRects.setPosClipRect(
           intersection(newOverflowClip, clipRects.posClipRect()));
-    if (layoutObject.isLayoutView() ||
-        layoutObject.hasTransformRelatedProperty())
+    if (box.isLayoutView() || box.hasTransformRelatedProperty())
       clipRects.setFixedClipRect(
           intersection(newOverflowClip, clipRects.fixedClipRect()));
-    if (layoutObject.styleRef().containsPaint()) {
+    if (box.styleRef().containsPaint()) {
       clipRects.setPosClipRect(
           intersection(newOverflowClip, clipRects.posClipRect()));
       clipRects.setFixedClipRect(
           intersection(newOverflowClip, clipRects.fixedClipRect()));
     }
   }
-  if (layoutObject.hasClip()) {
-    LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset);
+  if (box.hasClip()) {
+    LayoutRect newClip = box.clipRect(offset);
     clipRects.setPosClipRect(
         intersection(newClip, clipRects.posClipRect()).setIsClippedByClipCss());
     clipRects.setOverflowClipRect(
@@ -544,12 +544,16 @@
 
 bool PaintLayerClipper::shouldClipOverflow(
     const ClipRectsContext& context) const {
-  LayoutObject* layoutObject = m_layer.layoutObject();
-  return (layoutObject->hasOverflowClip() ||
-          layoutObject->styleRef().containsPaint() ||
-          (layoutObject->isSVGRoot() &&
-           toLayoutSVGRoot(layoutObject)->shouldApplyViewportClip())) &&
-         shouldRespectOverflowClip(context);
+  if (!m_layer.layoutObject()->isBox())
+    return false;
+  const LayoutBox& box = *toLayoutBox(m_layer.layoutObject());
+
+  if (!shouldRespectOverflowClip(context))
+    return false;
+
+  return box.hasOverflowClip() || box.styleRef().containsPaint() ||
+         box.hasControlClip() ||
+         (box.isSVGRoot() && toLayoutSVGRoot(&box)->shouldApplyViewportClip());
 }
 
 bool PaintLayerClipper::shouldRespectOverflowClip(
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp
index 43dfa47..4731fcc 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp
@@ -8,6 +8,7 @@
 #include "core/layout/LayoutTestHelper.h"
 #include "core/layout/LayoutView.h"
 #include "core/paint/PaintLayer.h"
+#include "platform/LayoutTestSupport.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
 
@@ -21,6 +22,16 @@
       : ScopedSlimmingPaintV2ForTest(GetParam()),
         RenderingTest(EmptyFrameLoaderClient::create()) {}
 
+  void SetUp() override {
+    LayoutTestSupport::setMockThemeEnabledForTest(true);
+    RenderingTest::SetUp();
+  }
+
+  void TearDown() override {
+    LayoutTestSupport::setMockThemeEnabledForTest(false);
+    RenderingTest::TearDown();
+  }
+
   bool geometryMapperCacheEmpty(const PaintLayerClipper& clipper) {
     return clipper.m_geometryMapper->m_data.isEmpty();
   }
@@ -55,6 +66,41 @@
   EXPECT_EQ(LayoutRect(8, 8, 200, 300), layerBounds);
 }
 
+TEST_P(PaintLayerClipperTest, ControlClip) {
+  setBodyInnerHTML(
+      "<!DOCTYPE html>"
+      "<input id=target style='position:absolute; width: 200px; height: 300px'"
+      "    type=button>");
+  Element* target = document().getElementById("target");
+  PaintLayer* targetPaintLayer =
+      toLayoutBoxModelObject(target->layoutObject())->layer();
+  ClipRectsContext context(document().layoutView()->layer(), UncachedClipRects);
+  // When RLS is enabled, the LayoutView will have a composited scrolling layer,
+  // so don't apply an overflow clip.
+  if (RuntimeEnabledFeatures::rootLayerScrollingEnabled())
+    context.setIgnoreOverflowClip();
+  LayoutRect layerBounds;
+  ClipRect backgroundRect, foregroundRect;
+  targetPaintLayer->clipper().calculateRects(
+      context, LayoutRect(LayoutRect::infiniteIntRect()), layerBounds,
+      backgroundRect, foregroundRect);
+#if OS(MACOSX)
+  // If the PaintLayer clips overflow, the background rect is intersected with
+  // the PaintLayer bounds...
+  EXPECT_EQ(LayoutRect(3, 4, 210, 28), backgroundRect.rect());
+  // and the foreground rect is intersected with the control clip in this case.
+  EXPECT_EQ(LayoutRect(8, 8, 200, 18), foregroundRect.rect());
+  EXPECT_EQ(LayoutRect(8, 8, 200, 18), layerBounds);
+#else
+  // If the PaintLayer clips overflow, the background rect is intersected with
+  // the PaintLayer bounds...
+  EXPECT_EQ(LayoutRect(8, 8, 200, 300), backgroundRect.rect());
+  // and the foreground rect is intersected with the control clip in this case.
+  EXPECT_EQ(LayoutRect(10, 10, 196, 296), foregroundRect.rect());
+  EXPECT_EQ(LayoutRect(8, 8, 200, 300), layerBounds);
+#endif
+}
+
 TEST_P(PaintLayerClipperTest, LayoutSVGRootChild) {
   setBodyInnerHTML(
       "<svg width=200 height=300 style='position: relative'>"
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index c19c18e4..f7aeadb 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -1820,7 +1820,7 @@
   if (!frameView)
     return;
 
-  // Decrese the number of layers that have any main thread
+  // Decrease the number of layers that have any main thread
   // scrolling reasons stored in FrameView
   for (uint32_t i = 0;
        i < MainThreadScrollingReason::kMainThreadScrollingReasonCount; ++i) {
diff --git a/third_party/WebKit/Source/core/paint/ViewPainter.cpp b/third_party/WebKit/Source/core/paint/ViewPainter.cpp
index 2d3ac26..6920030 100644
--- a/third_party/WebKit/Source/core/paint/ViewPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ViewPainter.cpp
@@ -58,10 +58,17 @@
           context, m_layoutView, DisplayItem::kDocumentBackground))
     return;
 
-  // The background fill rect is the size of the LayoutView's main
-  // GraphicsLayer.
-  IntRect backgroundRect =
-      pixelSnappedIntRect(m_layoutView.layer()->boundingBoxForCompositing());
+  // The background rect always includes at least the visible content size.
+  IntRect backgroundRect(IntRect(m_layoutView.viewRect()));
+
+  if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() ||
+      BoxPainter::
+          isPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+              &m_layoutView, paintInfo)) {
+    // Layout overflow, combined with the visible content size.
+    backgroundRect.unite(m_layoutView.documentRect());
+  }
+
   const Document& document = m_layoutView.document();
   const FrameView& frameView = *m_layoutView.frameView();
   bool isMainFrame = document.isInMainFrame();
diff --git a/third_party/WebKit/Source/core/style/StyleMultiColData.h b/third_party/WebKit/Source/core/style/StyleMultiColData.h
index 0b4108e..90c2133 100644
--- a/third_party/WebKit/Source/core/style/StyleMultiColData.h
+++ b/third_party/WebKit/Source/core/style/StyleMultiColData.h
@@ -25,6 +25,7 @@
 #ifndef StyleMultiColData_h
 #define StyleMultiColData_h
 
+#include "core/CoreExport.h"
 #include "core/style/BorderValue.h"
 #include "core/style/ComputedStyleConstants.h"
 #include "wtf/PassRefPtr.h"
@@ -34,7 +35,7 @@
 
 // CSS3 Multi Column Layout
 
-class StyleMultiColData : public RefCounted<StyleMultiColData> {
+class CORE_EXPORT StyleMultiColData : public RefCounted<StyleMultiColData> {
  public:
   static PassRefPtr<StyleMultiColData> create() {
     return adoptRef(new StyleMultiColData);
diff --git a/third_party/WebKit/Source/core/workers/SharedWorker.h b/third_party/WebKit/Source/core/workers/SharedWorker.h
index bc43f0b1..e89e43c 100644
--- a/third_party/WebKit/Source/core/workers/SharedWorker.h
+++ b/third_party/WebKit/Source/core/workers/SharedWorker.h
@@ -61,6 +61,7 @@
   const AtomicString& interfaceName() const override;
 
   void setIsBeingConnected(bool b) { m_isBeingConnected = b; }
+  bool isBeingConnected() { return m_isBeingConnected; }
 
   bool hasPendingActivity() const final;
 
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index 6737b2e0..3c0cd9c 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -554,6 +554,7 @@
   "front_end/timeline/MemoryCountersGraph.js",
   "front_end/timeline/module.json",
   "front_end/timeline/TimelineController.js",
+  "front_end/timeline/TimelineDetailsView.js",
   "front_end/timeline/TimelineEventOverview.js",
   "front_end/timeline/TimelineFlameChart.js",
   "front_end/timeline/timelineFlamechartPopover.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
index ea846dc..152a9c3b 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -5,7 +5,7 @@
     "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
     "smallIcons.svg": "e42007c7e8da94ecab276fd254f0623e",
     "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
-    "toolbarButtonGlyphs.svg": "a2f97ba793fb31f61930f934c0837e34",
+    "toolbarButtonGlyphs.svg": "ae43d11a5ce96de41357cca39f90e37c",
     "breakpoint.svg": "69cd92d807259c022791112809b97799",
     "search.svg": "fc990dd3836aec510d7ca1f36c2a3142"
 }
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
index ea846dc..152a9c3b 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -5,7 +5,7 @@
     "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
     "smallIcons.svg": "e42007c7e8da94ecab276fd254f0623e",
     "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
-    "toolbarButtonGlyphs.svg": "a2f97ba793fb31f61930f934c0837e34",
+    "toolbarButtonGlyphs.svg": "ae43d11a5ce96de41357cca39f90e37c",
     "breakpoint.svg": "69cd92d807259c022791112809b97799",
     "search.svg": "fc990dd3836aec510d7ca1f36c2a3142"
 }
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
index ff8ce6de..37ac2fa 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
@@ -1147,12 +1147,18 @@
      inkscape:connector-curvature="0"
      d="m 288,72 h 24 v 24 h -24 z"
      id="path3763" /><g
-     id="g3844"
-     transform="matrix(-1,0,0,-1,607.00004,168)"><path
-       sodipodi:nodetypes="ssccccccccsssssss"
-       inkscape:connector-curvature="0"
-       id="path3654"
-       d="m 304.5,76 c -0.73331,0 -1.5,0.7 -1.5,1.5 l 0,1.5 1.5,0 0,-1 7,0 0.0781,12 -7.07819,0 1.3e-4,-1 -1.5,0 0,1.5 c 0,0.8 0.76669,1.5 1.5,1.5 l 7,0 c 0.7333,0 1.5,-0.7 1.5,-1.5 l 0,-13 c 0,-0.8 -0.61045,-1.5 -1.34375,-1.5 z" /><path
-       id="path3765"
-       d="m 304.58443,84.588 c 0.0247,-0.192 0.0432,-0.384 0.0432,-0.588 0,-0.204 -0.0185,-0.396 -0.0432,-0.588 l 1.30152,-0.99 c 0.1172,-0.09 0.14804,-0.252 0.074,-0.384 l -1.23366,-2.076 c -0.0741,-0.132 -0.24056,-0.18 -0.37627,-0.132 l -1.53591,0.6 c -0.32075,-0.24 -0.66617,-0.438 -1.04244,-0.588 l -0.2344,-1.59 C 301.51877,78.108 301.38923,78 301.23502,78 h -2.46732 c -0.15421,0 -0.28374,0.108 -0.30225,0.252 l -0.23439,1.59 c -0.37627,0.15 -0.7217,0.354 -1.04245,0.588 l -1.5359,-0.6 c -0.14187,-0.054 -0.30225,0 -0.37627,0.132 l -1.23366,2.076 c -0.0802,0.132 -0.0432,0.294 0.074,0.384 l 1.30151,0.99 c -0.0247,0.192 -0.0432,0.39 -0.0432,0.588 0,0.198 0.0185,0.396 0.0432,0.588 l -1.30151,0.99 c -0.11719,0.09 -0.14803,0.252 -0.074,0.384 l 1.23366,2.076 c 0.0741,0.132 0.24057,0.18 0.37627,0.132 l 1.5359,-0.6 c 0.32075,0.24 0.66618,0.438 1.04245,0.588 l 0.23439,1.59 c 0.0185,0.144 0.14804,0.252 0.30225,0.252 h 2.46732 c 0.15421,0 0.28375,-0.108 0.30225,-0.252 l 0.2344,-1.59 c 0.37627,-0.15 0.72169,-0.354 1.04244,-0.588 l 1.53591,0.6 c 0.14188,0.054 0.30225,0 0.37627,-0.132 l 1.23366,-2.076 c 0.0741,-0.132 0.0432,-0.294 -0.074,-0.384 l -1.30152,-0.99 z m -4.58305,1.512 c -1.19048,0 -2.15891,-0.942 -2.15891,-2.1 0,-1.158 0.96843,-2.1 2.15891,-2.1 1.19048,0 2.15891,0.942 2.15891,2.1 0,1.158 -0.96843,2.1 -2.15891,2.1 z"
-       inkscape:connector-curvature="0" /></g></svg>
\ No newline at end of file
+     style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:1"
+     id="Page-1-6"
+     transform="translate(296,76)"><g
+       id="gear2"><g
+         id="Group-3-Copy-2"><rect
+           style="fill:#212121;fill-opacity:0"
+           id="Rectangle-2-Copy"
+           x="0"
+           y="0"
+           width="16"
+           height="16" /><path
+           style="fill:#000000"
+           inkscape:connector-curvature="0"
+           d="M 6,3.4160437 6,1 l 4,0 0,2.4160437 c 0.345025,0.1507477 0.669748,0.3393074 0.968932,0.5604413 l 2.093246,-1.2085358 2,3.4641016 -2.093129,1.2084688 C 12.989499,7.6241929 13,7.8108702 13,8 13,8.1891298 12.9895,8.3758071 12.96905,8.5594805 l 2.093129,1.2084687 -2,3.4641018 -2.093246,-1.208536 C 10.669748,12.244649 10.345025,12.433209 10,12.583956 L 10,15 6,15 6,12.583956 C 5.6549754,12.433209 5.3302519,12.244649 5.0310676,12.023515 L 2.9378222,13.232051 0.93782217,9.7679492 3.0309514,8.5594805 C 3.0105009,8.3758071 3,8.1891298 3,8 3,7.8108702 3.0105009,7.6241929 3.0309514,7.4405196 L 0.93782217,6.2320508 2.9378222,2.7679492 5.0310676,3.976485 C 5.3302519,3.7553511 5.6549754,3.5667914 6,3.4160437 Z M 8,10.5 C 9.3807119,10.5 10.5,9.3807119 10.5,8 10.5,6.6192881 9.3807119,5.5 8,5.5 6.6192881,5.5 5.5,6.6192881 5.5,8 c 0,1.3807119 1.1192881,2.5 2.5,2.5 z"
+           id="Combined-Shape" /></g></g></g></svg>
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png
index 6e16294..c9c5971 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png
+++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png
index 4f809ef..736ef9c 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png
+++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
index 8fa80f7c..fb351a7 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
@@ -63,7 +63,7 @@
   /**
    * @param {!SDK.ExecutionContext} executionContext
    * @param {string} text
-   * @param {boolean=} useCommandLineAPI
+   * @param {boolean} useCommandLineAPI
    */
   static evaluateCommandInConsole(executionContext, text, useCommandLineAPI) {
     var target = executionContext.target();
@@ -116,7 +116,7 @@
     if (looksLikeAnObjectLiteral(text))
       text = '(' + text + ')';
 
-    executionContext.evaluate(text, 'console', !!useCommandLineAPI, false, false, true, true, printResult);
+    executionContext.evaluate(text, 'console', useCommandLineAPI, false, false, true, true, printResult);
     Host.userMetrics.actionTaken(Host.UserMetrics.Action.ConsoleEvaluated);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
index ba2ade0..eb32043 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -957,7 +957,8 @@
         failedToSave(result);
       } else {
         SDK.ConsoleModel.evaluateCommandInConsole(
-            /** @type {!SDK.ExecutionContext} */ (currentExecutionContext), result.value);
+            /** @type {!SDK.ExecutionContext} */ (currentExecutionContext), result.value,
+            /* useCommandLineAPI */ false);
       }
     }
 
@@ -1267,7 +1268,7 @@
           var text = frame.textEditor.text(frame.textEditor.selection());
           var executionContext = UI.context.flavor(SDK.ExecutionContext);
           if (executionContext)
-            SDK.ConsoleModel.evaluateCommandInConsole(executionContext, text);
+            SDK.ConsoleModel.evaluateCommandInConsole(executionContext, text, /* useCommandLineAPI */ true);
         }
         return true;
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineDetailsView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineDetailsView.js
new file mode 100644
index 0000000..2020ca6ee
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineDetailsView.js
@@ -0,0 +1,99 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @unrestricted
+ */
+Timeline.TimelineDetailsView = class extends UI.TabbedPane {
+  /**
+   * @param {!TimelineModel.TimelineModel} timelineModel
+   * @param {!Array<!TimelineModel.TimelineModel.Filter>} filters
+   * @param {!Timeline.TimelineModeViewDelegate} delegate
+   */
+  constructor(timelineModel, filters, delegate) {
+    super();
+    this.element.classList.add('timeline-details');
+
+    var tabIds = Timeline.TimelinePanel.DetailsTab;
+    this._defaultDetailsWidget = new UI.VBox();
+    this._defaultDetailsWidget.element.classList.add('timeline-details-view');
+    this._defaultDetailsContentElement =
+        this._defaultDetailsWidget.element.createChild('div', 'timeline-details-view-body vbox');
+    this._defaultDetailsContentElement.tabIndex = 0;
+    this.appendTab(tabIds.Details, Common.UIString('Summary'), this._defaultDetailsWidget);
+    this.setPreferredTab(tabIds.Details);
+
+    /** @type Map<string, Timeline.TimelineTreeView> */
+    this._rangeDetailViews = new Map();
+
+    var bottomUpView = new Timeline.BottomUpTimelineTreeView(timelineModel, filters);
+    this.appendTab(tabIds.BottomUp, Common.UIString('Bottom-Up'), bottomUpView);
+    this._rangeDetailViews.set(tabIds.BottomUp, bottomUpView);
+
+    var callTreeView = new Timeline.CallTreeTimelineTreeView(timelineModel, filters);
+    this.appendTab(tabIds.CallTree, Common.UIString('Call Tree'), callTreeView);
+    this._rangeDetailViews.set(tabIds.CallTree, callTreeView);
+
+    var eventsView = new Timeline.EventsTimelineTreeView(timelineModel, filters, delegate);
+    this.appendTab(tabIds.Events, Common.UIString('Event Log'), eventsView);
+    this._rangeDetailViews.set(tabIds.Events, eventsView);
+
+    this.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
+  }
+
+  /**
+   * @param {!Node} node
+   */
+  setContent(node) {
+    var allTabs = this.otherTabs(Timeline.TimelinePanel.DetailsTab.Details);
+    for (var i = 0; i < allTabs.length; ++i) {
+      if (!this._rangeDetailViews.has(allTabs[i]))
+        this.closeTab(allTabs[i]);
+    }
+    this._defaultDetailsContentElement.removeChildren();
+    this._defaultDetailsContentElement.appendChild(node);
+  }
+
+  /**
+   * @param {!Timeline.TimelineSelection} selection
+   */
+  updateContents(selection) {
+    this._selection = selection;
+    var view = this.selectedTabId ? this._rangeDetailViews.get(this.selectedTabId) : null;
+    if (view)
+      view.updateContents(selection);
+  }
+
+  /**
+   * @override
+   * @param {string} id
+   * @param {string} tabTitle
+   * @param {!UI.Widget} view
+   * @param {string=} tabTooltip
+   * @param {boolean=} userGesture
+   * @param {boolean=} isCloseable
+   */
+  appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable) {
+    super.appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable);
+    if (this._preferredTabId !== this.selectedTabId)
+      this.selectTab(id);
+  }
+
+  /**
+   * @param {string} tabId
+   */
+  setPreferredTab(tabId) {
+    this._preferredTabId = tabId;
+  }
+
+  /**
+   * @param {!Common.Event} event
+   */
+  _tabSelected(event) {
+    if (!event.data.isUserGesture)
+      return;
+    this.setPreferredTab(event.data.tabId);
+    this.updateContents(this._selection);
+  }
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
index 768b004..c68dcca 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -1322,105 +1322,6 @@
   sessionGeneration() {}
 };
 
-/**
- * @unrestricted
- */
-Timeline.TimelineDetailsView = class extends UI.TabbedPane {
-  /**
-   * @param {!TimelineModel.TimelineModel} timelineModel
-   * @param {!Array<!TimelineModel.TimelineModel.Filter>} filters
-   * @param {!Timeline.TimelineModeViewDelegate} delegate
-   */
-  constructor(timelineModel, filters, delegate) {
-    super();
-    this.element.classList.add('timeline-details');
-
-    var tabIds = Timeline.TimelinePanel.DetailsTab;
-    this._defaultDetailsWidget = new UI.VBox();
-    this._defaultDetailsWidget.element.classList.add('timeline-details-view');
-    this._defaultDetailsContentElement =
-        this._defaultDetailsWidget.element.createChild('div', 'timeline-details-view-body vbox');
-    this._defaultDetailsContentElement.tabIndex = 0;
-    this.appendTab(tabIds.Details, Common.UIString('Summary'), this._defaultDetailsWidget);
-    this.setPreferredTab(tabIds.Details);
-
-    /** @type Map<string, Timeline.TimelineTreeView> */
-    this._rangeDetailViews = new Map();
-
-    var bottomUpView = new Timeline.BottomUpTimelineTreeView(timelineModel, filters);
-    this.appendTab(tabIds.BottomUp, Common.UIString('Bottom-Up'), bottomUpView);
-    this._rangeDetailViews.set(tabIds.BottomUp, bottomUpView);
-
-    var callTreeView = new Timeline.CallTreeTimelineTreeView(timelineModel, filters);
-    this.appendTab(tabIds.CallTree, Common.UIString('Call Tree'), callTreeView);
-    this._rangeDetailViews.set(tabIds.CallTree, callTreeView);
-
-    var eventsView = new Timeline.EventsTimelineTreeView(timelineModel, filters, delegate);
-    this.appendTab(tabIds.Events, Common.UIString('Event Log'), eventsView);
-    this._rangeDetailViews.set(tabIds.Events, eventsView);
-
-    this.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
-  }
-
-  /**
-   * @param {!Node} node
-   */
-  setContent(node) {
-    var allTabs = this.otherTabs(Timeline.TimelinePanel.DetailsTab.Details);
-    for (var i = 0; i < allTabs.length; ++i) {
-      if (!this._rangeDetailViews.has(allTabs[i]))
-        this.closeTab(allTabs[i]);
-    }
-    this._defaultDetailsContentElement.removeChildren();
-    this._defaultDetailsContentElement.appendChild(node);
-  }
-
-  /**
-   * @param {!Timeline.TimelineSelection} selection
-   */
-  updateContents(selection) {
-    this._selection = selection;
-    var view = this.selectedTabId ? this._rangeDetailViews.get(this.selectedTabId) : null;
-    if (view)
-      view.updateContents(selection);
-  }
-
-  /**
-   * @override
-   * @param {string} id
-   * @param {string} tabTitle
-   * @param {!UI.Widget} view
-   * @param {string=} tabTooltip
-   * @param {boolean=} userGesture
-   * @param {boolean=} isCloseable
-   */
-  appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable) {
-    super.appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable);
-    if (this._preferredTabId !== this.selectedTabId)
-      this.selectTab(id);
-  }
-
-  /**
-   * @param {string} tabId
-   */
-  setPreferredTab(tabId) {
-    this._preferredTabId = tabId;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _tabSelected(event) {
-    if (!event.data.isUserGesture)
-      return;
-    this.setPreferredTab(event.data.tabId);
-    this.updateContents(this._selection);
-  }
-};
-
-/**
- * @unrestricted
- */
 Timeline.TimelineSelection = class {
   /**
    * @param {!Timeline.TimelineSelection.Type} type
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/module.json b/third_party/WebKit/Source/devtools/front_end/timeline/module.json
index 725bf60..39ef5fd 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/module.json
@@ -143,6 +143,7 @@
         "ExtensionTracingSession.js",
         "MemoryCountersGraph.js",
         "TimelineController.js",
+        "TimelineDetailsView.js",
         "TimelineLoader.js",
         "TimelineEventOverview.js",
         "TimelineFlameChartView.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ShortcutsScreen.js b/third_party/WebKit/Source/devtools/front_end/ui/ShortcutsScreen.js
index 83a9b8f..ead1725e 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/ShortcutsScreen.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/ShortcutsScreen.js
@@ -140,8 +140,8 @@
         UI.shortcutRegistry.shortcutDescriptorsForAction('sources.switch-file'),
         Common.UIString('Switch between files with the same name and different extensions.'));
 
-    // Timeline panel
-    section = UI.shortcutsScreen.section(Common.UIString('Timeline Panel'));
+    // Performance panel
+    section = UI.shortcutsScreen.section(Common.UIString('Performance Panel'));
     section.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.toggle-recording'),
         Common.UIString('Start/stop recording'));
@@ -156,8 +156,8 @@
             .concat(UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.jump-to-next-frame')),
         Common.UIString('Jump to previous/next frame'));
 
-    // Profiles panel
-    section = UI.shortcutsScreen.section(Common.UIString('Profiles Panel'));
+    // Memory panel
+    section = UI.shortcutsScreen.section(Common.UIString('Memory Panel'));
     section.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('profiler.heap-toggle-recording'),
         Common.UIString('Start/stop recording'));
diff --git a/third_party/WebKit/Source/devtools/package.json b/third_party/WebKit/Source/devtools/package.json
index aba895be..1ca4a06 100644
--- a/third_party/WebKit/Source/devtools/package.json
+++ b/third_party/WebKit/Source/devtools/package.json
@@ -9,7 +9,8 @@
     "debug-test": "node scripts/npm_test.js --debug-devtools",
     "lint": "eslint front_end",
     "format": "node scripts/format.js",
-    "closure": "python scripts/compile_frontend.py"
+    "closure": "python scripts/compile_frontend.py",
+    "setup-dtrun": "cd scripts/devtools_run && npm link"
   },
   "repository": {
     "type": "git",
diff --git a/third_party/WebKit/Source/devtools/readme.md b/third_party/WebKit/Source/devtools/readme.md
index 3ea053d..fdbc2d49 100644
--- a/third_party/WebKit/Source/devtools/readme.md
+++ b/third_party/WebKit/Source/devtools/readme.md
@@ -48,19 +48,54 @@
 
 ### Useful Commands
 
-Basic:
-* `npm run format` - formats your code using clang-format
-* `npm test` - builds devtools and runs all inspector layout tests
+#### Simpler npm commands w/ `dtrun`
+If you want to run these npm commands anywhere in the chromium repo (e.g. in chromium/src), you'll want to setup our `dtrun` CLI helper.
+
+One-time setup:
+```
+npm run setup-dtrun
+```
+
+Now, you can use any of the following commands by simply doing: `dtrun test`. 
+
+In addition, you no longer need to pass double dashes (e.g. `--`) before you pass in the flags. So you can do: `dtrun test -d inspector/test.html`.
+
+#### `npm run format` 
+Formats your code using clang-format
+
+#### `npm test`
+Builds devtools and runs all inspector/devtools layout tests.
 
 > Note: If you're using a full chromium checkout and compiled content shell in out/Release, then `npm test` uses that. Otherwise, with only a front-end checkout (i.e. cloning from GitHub), then `npm test` will fetch a previously compiled content shell from the cloud (and cache it for future test runs).
 
-Advanced testing:
-* `npm test -- --fetch-content-shell` - even if you're using a full chromium checkout and have a compiled content shell, this will fetch a pre-compiled content shell. This is useful if you haven't compiled your content shell recently.
-* `npm test -- -f --child-processes=16` - pass in additional flags to the test harness
-* `npm test -- inspector/sources inspector/console` - run specific tests
-* `npm test -- inspector/cookie-resource-match.html --debug-devtools` OR `npm run debug-test inspector/cookie-resource-match.html` - debug a specific test (non-bundled & minified). You can use "-d" as a shorthand for "--debug-devtools".
+#### `npm test` basics
+```
+# run specific tests
+npm test -- inspector/sources inspector/console
 
-#### Development
+# debug a specific test. Any one of:
+npm run debug-test inspector/cookie-resource-match.html
+npm test -- --debug-devtools inspector/cookie-resource-match.html 
+npm test -- -d inspector/cookie-resource-match.html 
+
+# pass in additional flags to the test harness
+npm test -- -f --child-processes=16
+
+# ...for example, use a higher test timeout
+npm test -- --time-out-ms=6000000 <test_path>
+```
+
+> **Tip**: [Learn about the test harness flags](https://chromium.googlesource.com/chromium/src/+/master/docs/testing/layout_tests.md#Test-Harness-Options)
+
+#### `--fetch-content-shell`
+```
+# If you're using a full chromium checkout and have a compiled content shell, 
+# this will fetch a pre-compiled content shell. This is useful if you 
+# haven't compiled your content shell recently
+npm test -- --fetch-content-shell
+```
+
+### Development
 * All devtools commits: [View the log], [RSS feed] or [@DevToolsCommits] on Twitter
 * [All open DevTools tickets] on crbug.com
 * File a new DevTools ticket: [new.crbug.com](https://bugs.chromium.org/p/chromium/issues/entry?labels=OS-All,Type-Bug,Pri-2&components=Platform%3EDevTools)
diff --git a/third_party/WebKit/Source/devtools/scripts/devtools_run/devtools_run_cli b/third_party/WebKit/Source/devtools/scripts/devtools_run/devtools_run_cli
new file mode 100755
index 0000000..4b50ead
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/scripts/devtools_run/devtools_run_cli
@@ -0,0 +1,49 @@
+#!/usr/bin/env node
+
+// 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.
+
+var childProcess = require('child_process');
+var fs = require('fs');
+var path = require('path');
+var shell = require('child_process').execSync;
+
+var repoRootPath;
+try {
+  repoRootPath = shellOutput('git rev-parse --show-toplevel');
+} catch (error) {
+  console.log('ERROR: cannot use dtrun outside of chromium repo');
+  process.exit(1);
+}
+
+var devtoolsPath = path.join(repoRootPath, 'third_party', 'WebKit', 'Source', 'devtools');
+
+if (!isDir(devtoolsPath)) {
+  console.log('ERROR: cannot use dtrun outside of chromium repo');
+  process.exit(1);
+}
+
+var npmPath = shellOutput('which npm');
+var args = ['run'];
+if (process.argv.length > 2) {
+  args.push(process.argv[2]);
+  args.push('--');
+  args = args.concat(process.argv.slice(3));
+}
+var child = childProcess.spawn(npmPath, args, {
+  cwd: devtoolsPath,
+  stdio: 'inherit',
+});
+
+function shellOutput(command) {
+  return shell(command).toString().trim();
+}
+
+function isDir(path) {
+  try {
+    return fs.statSync(path).isDirectory();
+  } catch (error) {
+    return false;
+  }
+}
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/scripts/devtools_run/package.json b/third_party/WebKit/Source/devtools/scripts/devtools_run/package.json
new file mode 100644
index 0000000..a1e4563
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/scripts/devtools_run/package.json
@@ -0,0 +1,13 @@
+{
+  "name": "devtools-run",
+  "description": "cli helper for using devtools npm commands anywhere in a chromium repo",
+  "version": "0.1.0",
+  "author": "The Chromium Authors",
+  "license": "SEE LICENSE IN https://chromium.googlesource.com/chromium/src/+/master/LICENSE",
+  "bugs": {
+    "url": "https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component:Platform%3EDevTools%20&sort=-opened&colspec=ID%20Stars%20Owner%20Summary%20Modified%20Opened"
+  },
+  "bin": {
+    "dtrun": "./devtools_run_cli"
+  }
+}
diff --git a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
index 08e9cd9..81b5cef 100644
--- a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
@@ -25,13 +25,14 @@
 namespace blink {
 
 namespace {
-// A device name can never be longer than 29 bytes. A adv packet is at most
-// 31 bytes long. The length and identifier of the length field take 2 bytes.
-// That least 29 bytes for the name.
-const size_t kMaxFilterNameLength = 29;
+// A name coming from an adv packet is max 29 bytes (adv packet max size
+// 31 bytes - 2 byte length field), but the name can also be acquired via
+// gap.device_name, so it is limited to the max EIR packet size of 240 bytes.
+// See Core Spec 5.0, vol 3, C, 8.1.2.
+const size_t kMaxFilterNameLength = 240;
 const char kFilterNameTooLong[] =
-    "A 'name' or 'namePrefix' longer than 29 bytes results in no devices being "
-    "found, because a device can't advertise a name longer than 29 bytes.";
+    "A 'name' or 'namePrefix' longer than 240 bytes results in no devices "
+    "being found, because a device can't acquire a name longer than 240 bytes.";
 // Per the Bluetooth Spec: The name is a user-friendly name associated with the
 // device and consists of a maximum of 248 bytes coded according to the UTF-8
 // standard.
diff --git a/third_party/WebKit/Source/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py b/third_party/WebKit/Source/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py
index ec87810..530c2d4 100644
--- a/third_party/WebKit/Source/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py
+++ b/third_party/WebKit/Source/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py
@@ -34,6 +34,7 @@
     'heart_rate',
     'human_interface_device',
     'device_information',
+    'a_device_name_that_is_longer_than_29_bytes_but_shorter_than_240_bytes',
     BLOCKLISTED_UUID,
     CONNECTION_ERROR_UUIDS[0],
     DISCONNECTION_UUID,
@@ -48,6 +49,7 @@
     'generic_access',
     'heart_rate',
     'human_interface_device',
+    'a_device_name_that_is_longer_than_29_bytes_but_shorter_than_240_bytes',
     BLOCKLISTED_UUID,
     DISCONNECTION_UUID,
     GATT_ERROR_UUID,
@@ -90,6 +92,7 @@
     'FailingConnectionsAdapter',
     'FailingGATTOperationsAdapter',
     'DelayedServicesDiscoveryAdapter',
+    'DeviceNameLongerThan29BytesAdapter',
 ]
 
 # List of fake adapters that include devices.
@@ -135,6 +138,10 @@
         'DelayedServicesDiscoveryAdapter',
         ['generic_access', 'heart_rate'],
     ),
+    (
+        'DeviceNameLongerThan29BytesAdapter',
+        ['a_device_name_that_is_longer_than_29_bytes_but_shorter_than_240_bytes'],
+    ),
 ]
 
 # List of fake adapters with services.
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.cpp
index 2322a09..cd44122 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.cpp
@@ -46,6 +46,7 @@
 #include "public/platform/modules/indexeddb/WebIDBKeyPath.h"
 #include "public/platform/modules/indexeddb/WebIDBTypes.h"
 #include "wtf/Atomics.h"
+
 #include <limits>
 #include <memory>
 
@@ -53,6 +54,8 @@
 
 namespace blink {
 
+const char IDBDatabase::cannotObserveVersionChangeTransaction[] =
+    "An observer cannot target a version change transaction.";
 const char IDBDatabase::indexDeletedErrorMessage[] =
     "The index or its object store has been deleted.";
 const char IDBDatabase::indexNameTakenErrorMessage[] =
@@ -177,21 +180,37 @@
 void IDBDatabase::onChanges(
     const std::unordered_map<int32_t, std::vector<int32_t>>&
         observation_index_map,
-    const WebVector<WebIDBObservation>& observations) {
+    const WebVector<WebIDBObservation>& observations,
+    const IDBDatabaseCallbacks::TransactionMap& transactions) {
   for (const auto& map_entry : observation_index_map) {
     auto it = m_observers.find(map_entry.first);
     if (it != m_observers.end()) {
       IDBObserver* observer = it->value;
+
+      IDBTransaction* transaction = nullptr;
+      auto it = transactions.find(map_entry.first);
+      if (it != transactions.end()) {
+        const std::pair<int64_t, std::vector<int64_t>>& obs_txn = it->second;
+        HashSet<String> stores;
+        for (int64_t store_id : obs_txn.second) {
+          stores.add(m_metadata.objectStores.get(store_id)->name);
+        }
+
+        transaction = IDBTransaction::createObserver(
+            getExecutionContext(), obs_txn.first, stores, this);
+      }
+
       observer->callback()->call(
-          observer,
-          IDBObserverChanges::create(this, observations, map_entry.second));
+          observer, IDBObserverChanges::create(this, transaction, observations,
+                                               map_entry.second));
+      if (transaction)
+        transaction->setActive(false);
     }
   }
 }
 
 DOMStringList* IDBDatabase::objectStoreNames() const {
-  DOMStringList* objectStoreNames =
-      DOMStringList::create(DOMStringList::IndexedDB);
+  DOMStringList* objectStoreNames = DOMStringList::create();
   for (const auto& it : m_metadata.objectStores)
     objectStoreNames->append(it.value->name);
   objectStoreNames->sort();
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.h b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.h
index 390096f..94c0e50e 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.h
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.h
@@ -45,6 +45,7 @@
 #include "public/platform/modules/indexeddb/WebIDBDatabase.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
+
 #include <memory>
 
 namespace blink {
@@ -118,7 +119,8 @@
   void onComplete(int64_t);
   void onChanges(const std::unordered_map<int32_t, std::vector<int32_t>>&
                      observation_index_map,
-                 const WebVector<WebIDBObservation>& observations);
+                 const WebVector<WebIDBObservation>& observations,
+                 const IDBDatabaseCallbacks::TransactionMap& transactions);
 
   // ScriptWrappable
   bool hasPendingActivity() const final;
@@ -149,6 +151,7 @@
   static int64_t nextTransactionId();
   static int32_t nextObserverId();
 
+  static const char cannotObserveVersionChangeTransaction[];
   static const char indexDeletedErrorMessage[];
   static const char indexNameTakenErrorMessage[];
   static const char isKeyCursorErrorMessage[];
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.idl b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.idl
index 2697f257..12f3aea 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.idl
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.idl
@@ -33,7 +33,7 @@
 ] interface IDBDatabase : EventTarget {
     readonly attribute DOMString name;
     readonly attribute unsigned long long version;
-    [Measure] readonly attribute DOMStringList objectStoreNames;
+    readonly attribute DOMStringList objectStoreNames;
 
     [RaisesException] IDBObjectStore createObjectStore(DOMString name, optional IDBObjectStoreParameters options);
     [RaisesException] void deleteObjectStore(DOMString name);
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.cpp
index 885bbbbf..53a3384 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.cpp
@@ -66,9 +66,12 @@
 void IDBDatabaseCallbacks::onChanges(
     const std::unordered_map<int32_t, std::vector<int32_t>>&
         observation_index_map,
-    const WebVector<WebIDBObservation>& observations) {
-  if (m_database)
-    m_database->onChanges(observation_index_map, observations);
+    const WebVector<WebIDBObservation>& observations,
+    const TransactionMap& transactions) {
+  if (!m_database)
+    return;
+
+  m_database->onChanges(observation_index_map, observations, transactions);
 }
 
 void IDBDatabaseCallbacks::connect(IDBDatabase* database) {
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.h b/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.h
index b120c14..b5a7ce3 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.h
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.h
@@ -43,6 +43,10 @@
 class MODULES_EXPORT IDBDatabaseCallbacks
     : public GarbageCollectedFinalized<IDBDatabaseCallbacks> {
  public:
+  // Maps observer to transaction, which needs an id and a scope.
+  using TransactionMap =
+      std::unordered_map<int32_t, std::pair<int64_t, std::vector<int64_t>>>;
+
   static IDBDatabaseCallbacks* create();
   virtual ~IDBDatabaseCallbacks();
   DECLARE_TRACE();
@@ -56,7 +60,8 @@
   virtual void onChanges(
       const std::unordered_map<int32_t, std::vector<int32_t>>&
           observation_index_map,
-      const WebVector<WebIDBObservation>& observations);
+      const WebVector<WebIDBObservation>& observations,
+      const TransactionMap& transactions);
 
   void connect(IDBDatabase*);
 
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
index 96b0214..34ff64c 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
@@ -122,7 +122,7 @@
 
 DOMStringList* IDBObjectStore::indexNames() const {
   IDB_TRACE("IDBObjectStore::indexNames");
-  DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB);
+  DOMStringList* indexNames = DOMStringList::create();
   for (const auto& it : metadata().indexes)
     indexNames->append(it.value->name);
   indexNames->sort();
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.idl b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.idl
index abafe06..e198156 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.idl
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.idl
@@ -30,7 +30,7 @@
 ] interface IDBObjectStore {
     [RaisesException=Setter] attribute DOMString name;
     [CallWith=ScriptState] readonly attribute any keyPath;
-    [Measure] readonly attribute DOMStringList indexNames;
+    readonly attribute DOMStringList indexNames;
     readonly attribute IDBTransaction transaction;
     readonly attribute boolean autoIncrement;
 
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObserver.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObserver.cpp
index 0d026f1..13bd2e2 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObserver.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObserver.cpp
@@ -40,6 +40,12 @@
         TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage);
     return;
   }
+  if (transaction->isVersionChange()) {
+    exceptionState.throwDOMException(
+        TransactionInactiveError,
+        IDBDatabase::cannotObserveVersionChangeTransaction);
+    return;
+  }
   if (!database->backend()) {
     exceptionState.throwDOMException(InvalidStateError,
                                      IDBDatabase::databaseClosedErrorMessage);
@@ -74,7 +80,7 @@
 
   int32_t observerId =
       database->addObserver(this, transaction->id(), options.transaction(),
-                            options.values(), options.noRecords(), types);
+                            options.noRecords(), options.values(), types);
   m_observerIds.add(observerId, database);
 }
 
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObserverChanges.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObserverChanges.cpp
index 5e80fe6..f0a8ba9 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObserverChanges.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObserverChanges.cpp
@@ -31,28 +31,40 @@
 IDBObserverChanges* IDBObserverChanges::create(
     IDBDatabase* database,
     const WebVector<WebIDBObservation>& observations,
-    const WebVector<int32_t>& observationIndex) {
-  return new IDBObserverChanges(database, observations, observationIndex);
+    const WebVector<int32_t>& observationIndices) {
+  return new IDBObserverChanges(database, nullptr, observations,
+                                observationIndices);
+}
+
+IDBObserverChanges* IDBObserverChanges::create(
+    IDBDatabase* database,
+    IDBTransaction* transaction,
+    const WebVector<WebIDBObservation>& observations,
+    const WebVector<int32_t>& observationIndices) {
+  return new IDBObserverChanges(database, transaction, observations,
+                                observationIndices);
 }
 
 IDBObserverChanges::IDBObserverChanges(
     IDBDatabase* database,
+    IDBTransaction* transaction,
     const WebVector<WebIDBObservation>& observations,
-    const WebVector<int32_t>& observationIndex)
-    : m_database(database) {
-  extractChanges(observations, observationIndex);
+    const WebVector<int32_t>& observationIndices)
+    : m_database(database), m_transaction(transaction) {
+  extractChanges(observations, observationIndices);
 }
 
 void IDBObserverChanges::extractChanges(
     const WebVector<WebIDBObservation>& observations,
-    const WebVector<int32_t>& observationIndex) {
+    const WebVector<int32_t>& observationIndices) {
   // TODO(dmurph): Avoid getting and setting repeated times.
-  for (const auto& idx : observationIndex)
+  for (const auto& idx : observationIndices) {
     m_records
         .add(observations[idx].objectStoreId,
              HeapVector<Member<IDBObservation>>())
         .storedValue->value.push_back(
             IDBObservation::create(observations[idx]));
+  }
 }
 
 DEFINE_TRACE(IDBObserverChanges) {
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObserverChanges.h b/third_party/WebKit/Source/modules/indexeddb/IDBObserverChanges.h
index 30e612e..456cb9e 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObserverChanges.h
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObserverChanges.h
@@ -22,9 +22,15 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static IDBObserverChanges* create(IDBDatabase*,
-                                    const WebVector<WebIDBObservation>&,
-                                    const WebVector<int32_t>& observationIndex);
+  static IDBObserverChanges* create(
+      IDBDatabase*,
+      const WebVector<WebIDBObservation>&,
+      const WebVector<int32_t>& observationIndices);
+  static IDBObserverChanges* create(
+      IDBDatabase*,
+      IDBTransaction*,
+      const WebVector<WebIDBObservation>&,
+      const WebVector<int32_t>& observationIndices);
 
   DECLARE_TRACE();
 
@@ -35,11 +41,12 @@
 
  private:
   IDBObserverChanges(IDBDatabase*,
+                     IDBTransaction*,
                      const WebVector<WebIDBObservation>&,
-                     const WebVector<int32_t>& observationIndex);
+                     const WebVector<int32_t>& observationIndices);
 
   void extractChanges(const WebVector<WebIDBObservation>&,
-                      const WebVector<int32_t>& observationIndex);
+                      const WebVector<int32_t>& observationIndices);
 
   Member<IDBDatabase> m_database;
   Member<IDBTransaction> m_transaction;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp
index 0766234..75b08ef 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp
@@ -253,8 +253,7 @@
   if (!shouldEnqueueEvent())
     return;
 
-  DOMStringList* domStringList =
-      DOMStringList::create(DOMStringList::IndexedDB);
+  DOMStringList* domStringList = DOMStringList::create();
   for (size_t i = 0; i < stringList.size(); ++i)
     domStringList->append(stringList[i]);
   onSuccessInternal(IDBAny::create(domStringList));
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
index 42669ba..bbb1889 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
@@ -40,12 +40,25 @@
 #include "modules/indexeddb/IDBOpenDBRequest.h"
 #include "modules/indexeddb/IDBTracing.h"
 #include "wtf/PtrUtil.h"
+
 #include <memory>
 
 using blink::WebIDBDatabase;
 
 namespace blink {
 
+IDBTransaction* IDBTransaction::createObserver(
+    ExecutionContext* executionContext,
+    int64_t id,
+    const HashSet<String>& scope,
+    IDBDatabase* db) {
+  DCHECK(!scope.isEmpty()) << "Observer transactions must operate on a "
+                              "well-defined set of stores";
+  IDBTransaction* transaction =
+      new IDBTransaction(executionContext, id, scope, db);
+  return transaction;
+}
+
 IDBTransaction* IDBTransaction::createNonVersionChange(
     ScriptState* scriptState,
     int64_t id,
@@ -91,6 +104,22 @@
 
 }  // namespace
 
+IDBTransaction::IDBTransaction(ExecutionContext* executionContext,
+                               int64_t id,
+                               const HashSet<String>& scope,
+                               IDBDatabase* db)
+    : ContextLifecycleObserver(executionContext),
+      m_id(id),
+      m_database(db),
+      m_mode(WebIDBTransactionModeReadOnly),
+      m_scope(scope),
+      m_state(Active) {
+  DCHECK(m_database);
+  DCHECK(!m_scope.isEmpty()) << "Observer transactions must operate "
+                                "on a well-defined set of stores";
+  m_database->transactionCreated(this);
+}
+
 IDBTransaction::IDBTransaction(ScriptState* scriptState,
                                int64_t id,
                                const HashSet<String>& scope,
@@ -438,8 +467,7 @@
   if (isVersionChange())
     return m_database->objectStoreNames();
 
-  DOMStringList* objectStoreNames =
-      DOMStringList::create(DOMStringList::IndexedDB);
+  DOMStringList* objectStoreNames = DOMStringList::create();
   for (const String& objectStoreName : m_scope)
     objectStoreNames->append(objectStoreName);
   objectStoreNames->sort();
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.h b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.h
index 1c3a124..148d947 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.h
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.h
@@ -61,6 +61,11 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  static IDBTransaction* createObserver(ExecutionContext*,
+                                        int64_t,
+                                        const HashSet<String>& scope,
+                                        IDBDatabase*);
+
   static IDBTransaction* createNonVersionChange(ScriptState*,
                                                 int64_t,
                                                 const HashSet<String>& scope,
@@ -142,6 +147,12 @@
  private:
   using IDBObjectStoreMap = HeapHashMap<String, Member<IDBObjectStore>>;
 
+  // For observer transactions.
+  IDBTransaction(ExecutionContext*,
+                 int64_t,
+                 const HashSet<String>& scope,
+                 IDBDatabase*);
+
   // For non-upgrade transactions.
   IDBTransaction(ScriptState*,
                  int64_t,
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.idl b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.idl
index 59d2ea6..d35641a 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.idl
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.idl
@@ -41,7 +41,7 @@
 ] interface IDBTransaction : EventTarget {
 
     // Properties
-    [Measure] readonly attribute DOMStringList objectStoreNames;
+    readonly attribute DOMStringList objectStoreNames;
     readonly attribute IDBTransactionMode mode;
     readonly attribute IDBDatabase db;
     readonly attribute DOMException error;
diff --git a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
index a0d610b..decb032 100644
--- a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
@@ -124,7 +124,7 @@
     std::unique_ptr<protocol::Array<String>> databaseNames =
         protocol::Array<String>::create();
     for (size_t i = 0; i < databaseNamesList->length(); ++i)
-      databaseNames->addItem(databaseNamesList->anonymousIndexedGetter(i));
+      databaseNames->addItem(databaseNamesList->item(i));
     m_requestCallback->sendSuccess(std::move(databaseNames));
   }
 
diff --git a/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp b/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp
index e26ae2e..2d72c40 100644
--- a/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp
@@ -27,6 +27,7 @@
 
 #include "core/dom/DOMException.h"
 #include "wtf/PtrUtil.h"
+
 #include <memory>
 
 namespace blink {
@@ -73,9 +74,10 @@
 void WebIDBDatabaseCallbacksImpl::onChanges(
     const std::unordered_map<int32_t, std::vector<int32_t>>&
         observation_index_map,
-    const WebVector<WebIDBObservation>& observations) {
+    const WebVector<WebIDBObservation>& observations,
+    const IDBDatabaseCallbacks::TransactionMap& transactions) {
   if (m_callbacks)
-    m_callbacks->onChanges(observation_index_map, observations);
+    m_callbacks->onChanges(observation_index_map, observations, transactions);
 }
 
 void WebIDBDatabaseCallbacksImpl::detach() {
diff --git a/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.h b/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.h
index d1f764d..defb9101 100644
--- a/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.h
+++ b/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.h
@@ -32,6 +32,7 @@
 #include "public/platform/modules/indexeddb/WebIDBDatabaseError.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
+
 #include <memory>
 
 namespace blink {
@@ -49,9 +50,11 @@
   void onVersionChange(long long oldVersion, long long newVersion) override;
   void onAbort(long long transactionId, const WebIDBDatabaseError&) override;
   void onComplete(long long transactionId) override;
-  void onChanges(const std::unordered_map<int32_t, std::vector<int32_t>>&
-                     observation_index_map,
-                 const WebVector<WebIDBObservation>& observations) override;
+  void onChanges(
+      const std::unordered_map<int32_t, std::vector<int32_t>>&
+          observation_index_map,
+      const WebVector<WebIDBObservation>& observations,
+      const IDBDatabaseCallbacks::TransactionMap& transactions) override;
   void detach() override;
 
  private:
diff --git a/third_party/WebKit/Source/platform/LifecycleNotifier.h b/third_party/WebKit/Source/platform/LifecycleNotifier.h
index 4589d8d..f6b7412 100644
--- a/third_party/WebKit/Source/platform/LifecycleNotifier.h
+++ b/third_party/WebKit/Source/platform/LifecycleNotifier.h
@@ -112,8 +112,8 @@
 template <typename Observer,
           typename T,
           bool = HasContextDestroyed<Observer, T>::value>
-class NotifyContextDestroyed {
-  STATIC_ONLY(NotifyContextDestroyed);
+class ContextDestroyedNotifier {
+  STATIC_ONLY(ContextDestroyedNotifier);
 
  public:
   static void call(Observer* observer, T* context) {
@@ -122,8 +122,8 @@
 };
 
 template <typename Observer, typename T>
-class NotifyContextDestroyed<Observer, T, false> {
-  STATIC_ONLY(NotifyContextDestroyed);
+class ContextDestroyedNotifier<Observer, T, false> {
+  STATIC_ONLY(ContextDestroyedNotifier);
 
  public:
   static void call(Observer*, T*) {}
@@ -137,7 +137,7 @@
   m_observers.swap(observers);
   for (Observer* observer : observers) {
     DCHECK(observer->lifecycleContext() == context());
-    NotifyContextDestroyed<Observer, T>::call(observer, context());
+    ContextDestroyedNotifier<Observer, T>::call(observer, context());
     observer->clearContext();
   }
 }
diff --git a/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp b/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp
index 5b66c0b..b189b62 100644
--- a/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp
+++ b/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp
@@ -200,9 +200,12 @@
 void PartitionAllocMemoryDumpProvider::insert(void* address,
                                               size_t size,
                                               const char* typeName) {
-  base::trace_event::AllocationContext context =
-      base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()
-          ->GetContextSnapshot();
+  base::trace_event::AllocationContext context;
+  if (!base::trace_event::AllocationContextTracker::
+           GetInstanceForCurrentThread()
+               ->GetContextSnapshot(&context))
+    return;
+
   context.type_name = typeName;
   MutexLocker locker(m_allocationRegisterMutex);
   if (m_allocationRegister)
diff --git a/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.cpp b/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.cpp
index b4f686df..65ef5de 100644
--- a/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.cpp
+++ b/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.cpp
@@ -127,9 +127,11 @@
 void BlinkGCMemoryDumpProvider::insert(Address address,
                                        size_t size,
                                        const char* typeName) {
-  base::trace_event::AllocationContext context =
-      base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()
-          ->GetContextSnapshot();
+  base::trace_event::AllocationContext context;
+  if (!base::trace_event::AllocationContextTracker::
+           GetInstanceForCurrentThread()
+               ->GetContextSnapshot(&context))
+    return;
   context.type_name = typeName;
   MutexLocker locker(m_allocationRegisterMutex);
   if (m_allocationRegister)
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index a73aa82..8c433da 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -364,6 +364,8 @@
 
   virtual ScrollAnchor* scrollAnchor() { return nullptr; }
 
+  virtual void didScrollWithScrollbar(ScrollbarPart, ScrollbarOrientation) {}
+
  protected:
   ScrollableArea();
 
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
index ed1ffd69..d724c21 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
@@ -317,6 +317,10 @@
       || m_hoveredPart != NoPart)
     setNeedsPaintInvalidation(
         static_cast<ScrollbarPart>(m_pressedPart | m_hoveredPart | part));
+
+  if (getScrollableArea())
+    getScrollableArea()->didScrollWithScrollbar(part, orientation());
+
   m_pressedPart = part;
 }
 
diff --git a/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp b/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
index 1dbbfdf..dd43f21 100644
--- a/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
+++ b/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
@@ -44,6 +44,7 @@
 #include "public/web/WebFrameClient.h"
 #include "public/web/WebKit.h"
 #include "public/web/WebSharedWorker.h"
+#include "public/web/WebSharedWorkerConnectListener.h"
 #include "public/web/WebSharedWorkerCreationErrors.h"
 #include "public/web/WebSharedWorkerRepositoryClient.h"
 #include "web/WebLocalFrameImpl.h"
@@ -53,54 +54,51 @@
 
 namespace blink {
 
-// Callback class that keeps the SharedWorker and WebSharedWorker objects alive
-// while connecting.
-class SharedWorkerConnector
-    : private WebSharedWorkerConnector::ConnectListener {
+// Implementation of the callback interface passed to the embedder. This will be
+// destructed when a connection to a shared worker is established.
+class SharedWorkerConnectListener final
+    : public WebSharedWorkerConnectListener {
  public:
-  SharedWorkerConnector(
-      SharedWorker* worker,
-      WebMessagePortChannelUniquePtr channel,
-      std::unique_ptr<WebSharedWorkerConnector> webWorkerConnector)
-      : m_worker(worker),
-        m_webWorkerConnector(std::move(webWorkerConnector)),
-        m_channel(std::move(channel)) {}
+  explicit SharedWorkerConnectListener(SharedWorker* worker)
+      : m_worker(worker) {}
 
-  virtual ~SharedWorkerConnector();
-  void connect();
+  ~SharedWorkerConnectListener() override {
+    DCHECK(!m_worker->isBeingConnected());
+  }
 
- private:
-  // WebSharedWorkerConnector::ConnectListener overrides.
-  void connected() override;
-  void scriptLoadFailed() override;
+  // WebSharedWorkerConnectListener overrides.
+
+  void workerCreated(WebWorkerCreationError creationError) override {
+    m_worker->setIsBeingConnected(true);
+
+    // No nested workers (for now) - connect() should only be called from
+    // document context.
+    DCHECK(m_worker->getExecutionContext()->isDocument());
+    Document* document = toDocument(m_worker->getExecutionContext());
+    bool isSecureContext = m_worker->getExecutionContext()->isSecureContext();
+    switch (creationError) {
+      case WebWorkerCreationErrorNone:
+        return;
+      case WebWorkerCreationErrorSecureContextMismatch:
+        UseCounter::Feature feature =
+            isSecureContext
+                ? UseCounter::NonSecureSharedWorkerAccessedFromSecureContext
+                : UseCounter::SecureSharedWorkerAccessedFromNonSecureContext;
+        UseCounter::count(document, feature);
+        return;
+    }
+  }
+
+  void scriptLoadFailed() override {
+    m_worker->dispatchEvent(Event::createCancelable(EventTypeNames::error));
+    m_worker->setIsBeingConnected(false);
+  }
+
+  void connected() override { m_worker->setIsBeingConnected(false); }
 
   Persistent<SharedWorker> m_worker;
-  std::unique_ptr<WebSharedWorkerConnector> m_webWorkerConnector;
-  WebMessagePortChannelUniquePtr m_channel;
 };
 
-SharedWorkerConnector::~SharedWorkerConnector() {
-  m_worker->setIsBeingConnected(false);
-}
-
-void SharedWorkerConnector::connect() {
-  m_worker->setIsBeingConnected(true);
-  m_webWorkerConnector->connect(m_channel.release(), this);
-}
-
-void SharedWorkerConnector::connected() {
-  // Free ourselves (this releases the SharedWorker so it can be freed as well
-  // if unreferenced).
-  delete this;
-}
-
-void SharedWorkerConnector::scriptLoadFailed() {
-  m_worker->dispatchEvent(Event::createCancelable(EventTypeNames::error));
-  // Free ourselves (this releases the SharedWorker so it can be freed as well
-  // if unreferenced).
-  delete this;
-}
-
 static WebSharedWorkerRepositoryClient::DocumentID getId(void* document) {
   DCHECK(document);
   return reinterpret_cast<WebSharedWorkerRepositoryClient::DocumentID>(
@@ -121,7 +119,7 @@
 
   // TODO(estark): this is broken, as it only uses the first header
   // when multiple might have been sent. Fix by making the
-  // SharedWorkerConnector interface take a map that can contain
+  // SharedWorkerConnectListener interface take a map that can contain
   // multiple headers.
   std::unique_ptr<Vector<CSPHeaderAndType>> headers =
       worker->getExecutionContext()->contentSecurityPolicy()->headers();
@@ -134,33 +132,15 @@
         static_cast<WebContentSecurityPolicyType>((*headers)[0].second);
   }
 
-  WebWorkerCreationError creationError;
   bool isSecureContext = worker->getExecutionContext()->isSecureContext();
-  std::unique_ptr<WebSharedWorkerConnector> webWorkerConnector =
-      m_client->createSharedWorkerConnector(
-          url, name, getId(document), header, headerType,
-          worker->getExecutionContext()->securityContext().addressSpace(),
-          isSecureContext ? WebSharedWorkerCreationContextTypeSecure
-                          : WebSharedWorkerCreationContextTypeNonsecure,
-          &creationError);
-
-  switch (creationError) {
-    case WebWorkerCreationErrorNone:
-      break;
-    case WebWorkerCreationErrorSecureContextMismatch:
-      UseCounter::Feature feature =
-          isSecureContext
-              ? UseCounter::NonSecureSharedWorkerAccessedFromSecureContext
-              : UseCounter::SecureSharedWorkerAccessedFromNonSecureContext;
-      UseCounter::count(document, feature);
-      break;
-  }
-
-  // The connector object manages its own lifecycle (and the lifecycles of the
-  // two worker objects).  It will free itself once connecting is completed.
-  SharedWorkerConnector* connector = new SharedWorkerConnector(
-      worker, std::move(port), std::move(webWorkerConnector));
-  connector->connect();
+  std::unique_ptr<WebSharedWorkerConnectListener> listener =
+      WTF::makeUnique<SharedWorkerConnectListener>(worker);
+  m_client->connect(
+      url, name, getId(document), header, headerType,
+      worker->getExecutionContext()->securityContext().addressSpace(),
+      isSecureContext ? WebSharedWorkerCreationContextTypeSecure
+                      : WebSharedWorkerCreationContextTypeNonsecure,
+      port.release(), std::move(listener));
 }
 
 void SharedWorkerRepositoryClientImpl::documentDetached(Document* document) {
diff --git a/third_party/WebKit/Tools/Scripts/import-w3c-tests b/third_party/WebKit/Tools/Scripts/import-w3c-tests
deleted file mode 100755
index bb72096..0000000
--- a/third_party/WebKit/Tools/Scripts/import-w3c-tests
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above
-#    copyright notice, this list of conditions and the following
-#    disclaimer.
-# 2. Redistributions in binary form must reproduce the above
-#    copyright notice, this list of conditions and the following
-#    disclaimer in the documentation and/or other materials
-#    provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-
-import sys
-
-from webkitpy.w3c import test_importer
-
-
-sys.exit(test_importer.main(sys.argv[1:], sys.stdout, sys.stderr))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/detection.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/detection.py
deleted file mode 100644
index aa3570c..0000000
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/detection.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (c) 2009, 2010, 2011 Google Inc. All rights reserved.
-# Copyright (c) 2009 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import logging
-
-from webkitpy.common.system.filesystem import FileSystem
-from webkitpy.common.system.executive import Executive
-
-from .git import Git
-
-_log = logging.getLogger(__name__)
-
-
-class SCMDetector(object):
-
-    def __init__(self, filesystem, executive):
-        self._filesystem = filesystem
-        self._executive = executive
-
-    def default_scm(self, patch_directories=None):
-        """Return the default SCM object as determined by the CWD and running code.
-
-        Returns the default SCM object for the current working directory; if the
-        CWD is not in a checkout, then we attempt to figure out if the SCM module
-        itself is part of a checkout, and return that one. If neither is part of
-        a checkout, None is returned.
-        """
-        cwd = self._filesystem.getcwd()
-        scm_system = self.detect_scm_system(cwd, patch_directories)
-        if not scm_system:
-            script_directory = self._filesystem.dirname(self._filesystem.path_to_module(self.__module__))
-            scm_system = self.detect_scm_system(script_directory, patch_directories)
-            if scm_system:
-                _log.info("The current directory (%s) is not a WebKit checkout, using %s", cwd, scm_system.checkout_root)
-            else:
-                raise Exception("FATAL: Failed to determine the SCM system for either %s or %s" % (cwd, script_directory))
-        return scm_system
-
-    def detect_scm_system(self, path, patch_directories=None):
-        absolute_path = self._filesystem.abspath(path)
-
-        if patch_directories == []:
-            patch_directories = None
-
-        if Git.in_working_directory(absolute_path, executive=self._executive):
-            return Git(cwd=absolute_path, filesystem=self._filesystem, executive=self._executive)
-
-        return None
-
-
-# FIXME: These free functions are all deprecated:
-
-def detect_scm_system(path, patch_directories=None):
-    return SCMDetector(FileSystem(), Executive()).detect_scm_system(path, patch_directories)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/detection_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/detection_unittest.py
deleted file mode 100644
index bab79ed..0000000
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/detection_unittest.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2009 Google Inc. All rights reserved.
-# Copyright (C) 2009 Apple Inc. All rights reserved.
-# Copyright (C) 2011 Daniel Bates (dbates@intudata.com). All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#    * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#    * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import unittest
-
-from .detection import SCMDetector
-from webkitpy.common.system.filesystem_mock import MockFileSystem
-from webkitpy.common.system.executive_mock import MockExecutive
-from webkitpy.common.system.output_capture import OutputCapture
-
-
-class SCMDetectorTest(unittest.TestCase):
-
-    def test_detect_scm_system(self):
-        filesystem = MockFileSystem()
-        executive = MockExecutive(should_log=True)
-        detector = SCMDetector(filesystem, executive)
-
-        expected_logs = """\
-MOCK run_command: ['git', 'rev-parse', '--is-inside-work-tree'], cwd=/
-"""
-        scm = OutputCapture().assert_outputs(self, detector.detect_scm_system, ["/"], expected_logs=expected_logs)
-        self.assertIsNone(scm)
-        # FIXME: This should make a synthetic tree and test Git detection in that tree.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_unittest.py
index 7305f7c..fe9180e 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_unittest.py
@@ -8,7 +8,6 @@
 from webkitpy.common.system.executive_mock import MockExecutive
 from webkitpy.common.system.filesystem import FileSystem
 from webkitpy.common.system.filesystem_mock import MockFileSystem
-from webkitpy.common.checkout.scm.detection import detect_scm_system
 from webkitpy.common.checkout.scm.git import Git
 
 
@@ -26,13 +25,14 @@
         self._write_text_file('foo_file', 'foo')
         self._run(['git', 'add', 'foo_file'])
         self._run(['git', 'commit', '-am', 'dummy commit'])
-        self.untracking_scm = detect_scm_system(self.untracking_checkout_path)
+        self.untracking_scm = Git(cwd=self.untracking_checkout_path, filesystem=self.filesystem, executive=self.executive)
 
         # Then set up a second git repo that tracks the first one.
         self.tracking_git_checkout_path = self._mkdtemp(suffix='-git_unittest_tracking')
         self._run(['git', 'clone', '--quiet', self.untracking_checkout_path, self.tracking_git_checkout_path])
         self._chdir(self.tracking_git_checkout_path)
-        self.tracking_scm = detect_scm_system(self.tracking_git_checkout_path)
+        self.tracking_scm = Git(cwd=self.tracking_git_checkout_path, filesystem=self.filesystem, executive=self.executive)
+
 
     def tearDown(self):
         self._chdir(self.original_cwd)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/host.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/host.py
index ca6ca95..9f31e25 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/host.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/host.py
@@ -30,7 +30,7 @@
 import logging
 import sys
 
-from webkitpy.common.checkout.scm.detection import SCMDetector
+from webkitpy.common.checkout.scm.git import Git
 from webkitpy.common.config.builders import BUILDERS
 from webkitpy.common.net.buildbot import BuildBot
 from webkitpy.common.net import web
@@ -98,18 +98,32 @@
                 # don't provide use shell=True. Rather than use shell=True on Windows,
                 # We hack the git.bat name into the SVN class.
                 _log.debug('Engaging git.bat Windows hack.')
-                from webkitpy.common.checkout.scm.git import Git
                 Git.executable_name = 'git.bat'
             except OSError:
                 _log.debug('Failed to engage git.bat Windows hack.')
 
-    def initialize_scm(self, patch_directories=None):
-        if sys.platform == "win32":
+    def initialize_scm(self):
+        # TODO(qyearsley): Refactor this so that scm is initialized
+        # when self.scm() is called the first time; put any initialization
+        # code in the git module.
+        if sys.platform == 'win32':
             self._engage_awesome_windows_hacks()
-        detector = SCMDetector(self.filesystem, self.executive)
-        self._scm = detector.default_scm(patch_directories)
 
-    def scm(self):
+        cwd = self.filesystem.abspath(self.filesystem.getcwd())
+        if Git.in_working_directory(cwd, executive=self.executive):
+            self._scm = Git(cwd=cwd, filesystem=self.filesystem, executive=self.executive)
+            return
+
+        script_directory = self.filesystem.abspath(
+            self.filesystem.dirname(self.filesystem.path_to_module(self.__module__)))
+        _log.info('The current directory (%s) is not in a git repo, trying script directory %s.', cwd, script_directory)
+        if Git.in_working_directory(script_directory, executive=self.executive):
+            self._scm = Git(cwd=script_directory, filesystem=self.filesystem, executive=self.executive)
+            return
+
+        raise Exception('FATAL: Failed to find Git repo for %s or %s' % (cwd, script_directory))
+
+    def scm(self,):
         return self._scm
 
     def scm_for_path(self, path):
@@ -117,4 +131,4 @@
         # callers call initialize_scm() (to remove patch_directories) and scm().
         if sys.platform == "win32":
             self._engage_awesome_windows_hacks()
-        return SCMDetector(self.filesystem, self.executive).detect_scm_system(path)
+        return Git(cwd=path, executive=self.executive, filesystem=self.filesystem)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py b/third_party/WebKit/Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py
index 0db4fd9..4d2ae5b 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py
@@ -36,7 +36,6 @@
 import datetime
 
 from webkitpy.common import find_files
-from webkitpy.common.checkout.scm.detection import SCMDetector
 from webkitpy.common.host import Host
 from webkitpy.common.net.file_uploader import FileUploader
 from webkitpy.performance_tests.perftest import PerfTestFactory
@@ -263,9 +262,9 @@
     def _generate_results_dict(self, timestamp, description, platform, builder_name, build_number):
         revisions = {}
         path = self._port.repository_path()
-        scm = SCMDetector(self._host.filesystem, self._host.executive).detect_scm_system(path) or self._host.scm()
-        revision = str(scm.commit_position(path))
-        revisions['chromium'] = {'revision': revision, 'timestamp': scm.timestamp_of_revision(path, revision)}
+        git = self._host.scm_for_path(path)
+        revision = str(git.commit_position(path))
+        revisions['chromium'] = {'revision': revision, 'timestamp': git.timestamp_of_revision(path, revision)}
 
         meta_info = {
             'description': description,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/patchreader.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/patchreader.py
index 493b13c..54b13a6 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/style/patchreader.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/patchreader.py
@@ -32,9 +32,7 @@
 import re
 
 from webkitpy.common.checkout.diff_parser import DiffParser
-from webkitpy.common.system.executive import Executive
 from webkitpy.common.system.filesystem import FileSystem
-from webkitpy.common.checkout.scm.detection import SCMDetector
 
 
 _log = logging.getLogger(__name__)
@@ -57,6 +55,7 @@
         patch_files = DiffParser(patch_string.splitlines()).files
 
         # If the user uses git, checking subversion config file only once is enough.
+        # TODO(qyearsley): Simplify this since git is now the only supported SCM system.
         call_only_once = True
 
         for path, diff_file in patch_files.iteritems():
@@ -68,10 +67,7 @@
                 if match and fs.exists(path):
                     if call_only_once:
                         self._text_file_reader.process_file(file_path=path, line_numbers=None)
-                        cwd = FileSystem().getcwd()
-                        detection = SCMDetector(fs, Executive()).detect_scm_system(cwd)
-                        if detection.display_name() == "git":
-                            call_only_once = False
+                        call_only_once = False
                     continue
                 # Don't check files which contain only deleted lines
                 # as they can never add style errors. However, mark them as
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/webkit_patch.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/webkit_patch.py
index 78663c1e..b300451 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/webkit_patch.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/webkit_patch.py
@@ -70,7 +70,7 @@
             "-v", "--verbose", action="store_true", dest="verbose", default=False,
             help="enable all logging"),
         optparse.make_option(
-            "-d", "--directory", action="append", dest="patch_directories", default=[],
+            "-d", "--directory", action="append", default=[],
             help="Directory to look at for changed files"),
     ]
 
@@ -112,7 +112,7 @@
 
         command.set_option_parser(option_parser)
         (options, args) = command.parse_args(args)
-        self._handle_global_options(options)
+        self.initialize_scm()
 
         (should_execute, failure_reason) = self._should_execute_command(command)
         if not should_execute:
@@ -149,10 +149,6 @@
         for option in global_options:
             option_parser.add_option(option)
 
-    # FIXME: This may be unnecessary since we pass global options to all commands during execute() as well.
-    def _handle_global_options(self, options):
-        self.initialize_scm(options.patch_directories)
-
     def _should_execute_command(self, command):
         if command.requires_local_commits and not self.scm().supports_local_commits():
             failure_reason = "%s requires local commits using %s in %s." % (
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
index 0c4ec00..aa6824c 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
@@ -4,9 +4,11 @@
 
 """Fetches a copy of the latest state of a W3C test repository and commits.
 
-If this script is given the argument --auto-update, it will also attempt to
-upload a CL, triggery try jobs, and make any changes that are required for
-new failing tests before committing.
+If this script is given the argument --auto-update, it will also:
+ 1. Upload a CL.
+ 2. Trigger try jobs and wait for them to complete.
+ 3. Make any changes that are required for new failing tests.
+ 4. Commit the CL.
 """
 
 import logging
@@ -16,6 +18,7 @@
 from webkitpy.common.net.git_cl import GitCL
 from webkitpy.common.webkit_finder import WebKitFinder
 from webkitpy.layout_tests.models.test_expectations import TestExpectations, TestExpectationParser
+from webkitpy.w3c.test_importer import TestImporter
 
 # Import destination directories (under LayoutTests/external/).
 WPT_DEST_NAME = 'wpt'
@@ -148,11 +151,10 @@
             self.copyfile(source, destination)
             self.run(['git', 'add', destination])
 
-    def _generate_manifest(self, original_repo_path, dest_path):
+    def _generate_manifest(self, dest_path):
         """Generates MANIFEST.json for imported tests.
 
         Args:
-            original_repo_path: Path to the temporary source WPT repo directory.
             dest_path: Path to the destination WPT directory.
 
         Runs the (newly-updated) manifest command if it's found, and then
@@ -198,9 +200,8 @@
             self.remove('LayoutTests', 'external', subpath)
 
         _log.info('Importing the tests.')
-        src_repo = self.path_from_webkit_base(dest_dir_name)
-        import_path = self.path_from_webkit_base('Tools', 'Scripts', 'import-w3c-tests')
-        self.run([self.host.executable, import_path, '-d', 'external', src_repo])
+        test_importer = TestImporter(self.host, temp_repo_path)
+        test_importer.do_import()
 
         self.run(['git', 'add', '--all', 'LayoutTests/external/%s' % dest_dir_name])
 
@@ -214,7 +215,7 @@
             if self.fs.glob(full_path.replace('-expected.txt', '*')) == [full_path]:
                 self.fs.remove(full_path)
 
-        self._generate_manifest(temp_repo_path, dest_path)
+        self._generate_manifest(dest_path)
 
         if not keep_w3c_repos_around:
             _log.info('Deleting temp repo directory %s.', temp_repo_path)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py
index d2d98bce..8b0c9ea7 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py
@@ -96,7 +96,6 @@
         host.filesystem.files = {}
         updater = DepsUpdater(host)
         updater._generate_manifest(
-            '/mock-checkout/third_party/WebKit/css',
             '/mock-checkout/third_party/WebKit/LayoutTests/external/csswg-test')
         self.assertEqual(host.executive.calls, [])
 
@@ -106,7 +105,6 @@
         host = MockHost()
         updater = DepsUpdater(host)
         updater._generate_manifest(
-            '/mock-checkout/third_party/WebKit/wpt',
             '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt')
         self.assertEqual(
             host.executive.calls,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
index ef0501d..2c43c08 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
@@ -10,7 +10,7 @@
 from webkitpy.w3c.chromium_commit import ChromiumCommit
 
 WPT_REPO_URL = 'https://chromium.googlesource.com/external/w3c/web-platform-tests.git'
-WPT_TMP_DIR = '/tmp/wpt'
+WPT_TEMP_DIR = '/tmp/wpt'
 WPT_SSH_URL = 'git@github.com:w3c/web-platform-tests.git'
 REMOTE_NAME = 'github'
 CHROMIUM_WPT_DIR = 'third_party/WebKit/LayoutTests/external/wpt/'
@@ -20,22 +20,19 @@
 
 class LocalWPT(object):
 
-    def __init__(self, host, path=WPT_TMP_DIR, no_fetch=False):
+    def __init__(self, host, path=WPT_TEMP_DIR):
         """
         Args:
             host: A Host object.
-            path: Optional, the directory where LocalWPT will check out web-platform-tests.
-            no_fetch: Optional, passing true will skip updating the local WPT.
-                Intended for use only in development after fetching once.
+            path: Optional, the path to the web-platform-tests repo.
+                If this directory already exists, it is assumed that the
+                web-platform-tests repo is already checked out at this path.
         """
         self.host = host
         self.path = path
         self.branch_name = 'chromium-export-try'
 
-        if no_fetch:
-            _log.info('Skipping remote WPT fetch')
-            return
-
+    def fetch(self):
         if self.host.filesystem.exists(self.path):
             _log.info('WPT checkout exists at %s, fetching latest', self.path)
             self.run(['git', 'fetch', '--all'])
@@ -122,7 +119,7 @@
             self.run(['git', 'apply', '-'], input=patch)
             self.run(['git', 'add', '.'])
             output = self.run(['git', 'diff', 'origin/master'])
-        except ScriptError as error:
+        except ScriptError:
             _log.warning('Patch did not apply cleanly, skipping...')
             output = ''
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
index 0f4b380a..f90c772 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
@@ -12,48 +12,44 @@
 
 class LocalWPTTest(unittest.TestCase):
 
-    def test_constructor_fetches_if_wpt_dir_exists(self):
+    def test_fetch_when_wpt_dir_exists(self):
         host = MockHost()
         host.filesystem = MockFileSystem(files={
             '/tmp/wpt': ''
         })
 
-        LocalWPT(host)
+        local_wpt = LocalWPT(host)
+        local_wpt.fetch()
 
         self.assertEqual(host.executive.calls, [
             ['git', 'fetch', '--all'],
             ['git', 'checkout', 'origin/master'],
             ['git', 'remote'],
-            ['git', 'remote', 'add', 'github', 'git@github.com:w3c/web-platform-tests.git']])
+            ['git', 'remote', 'add', 'github', 'git@github.com:w3c/web-platform-tests.git']
+        ])
 
-    def test_constructor_clones_if_wpt_dir_does_not_exist(self):
+    def test_fetch_when_wpt_dir_does_not_exist(self):
         host = MockHost()
         host.filesystem = MockFileSystem()
 
-        LocalWPT(host)
+        local_wpt = LocalWPT(host)
+        local_wpt.fetch()
 
         self.assertEqual(len(host.executive.calls), 3)
         self.assertEqual(host.executive.calls[0][1], 'clone')
 
-    def test_constructor_no_fetch_flag(self):
+    def test_constructor(self):
+        #
         host = MockHost()
-        host.filesystem = MockFileSystem(files={
-            '/tmp/wpt': ''
-        })
-
-        LocalWPT(host, no_fetch=True)
-
+        LocalWPT(host)
         self.assertEqual(len(host.executive.calls), 0)
 
     def test_run(self):
         host = MockHost()
         host.filesystem = MockFileSystem()
-
         local_wpt = LocalWPT(host)
-
         local_wpt.run(['echo', 'rutabaga'])
-        self.assertEqual(len(host.executive.calls), 4)
-        self.assertEqual(host.executive.calls[3], ['echo', 'rutabaga'])
+        self.assertEqual(host.executive.calls, [['echo', 'rutabaga']])
 
     def test_last_wpt_exported_commit(self):
         host = MockHost()
@@ -64,7 +60,7 @@
         ]
         host.executive = MockExecutive(run_command_fn=lambda _: return_vals.pop())
         host.filesystem = MockFileSystem()
-        local_wpt = LocalWPT(host, no_fetch=True)
+        local_wpt = LocalWPT(host)
 
         wpt_sha, chromium_commit = local_wpt.most_recent_chromium_commit()
         self.assertEqual(wpt_sha, '9ea4fc353a4b1c11c6e524270b11baa4d1ddfde8')
@@ -85,6 +81,7 @@
         host.filesystem = MockFileSystem()
 
         local_wpt = LocalWPT(host)
+        local_wpt.fetch()
 
         local_branch_name = local_wpt.create_branch_with_patch('message', 'patch', 'author')
         self.assertEqual(local_branch_name, 'chromium-export-try')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_exporter.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_exporter.py
index 758fbd8..1eae98a 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_exporter.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_exporter.py
@@ -19,6 +19,7 @@
         self.wpt_github = wpt_github
         self.dry_run = dry_run
         self.local_wpt = LocalWPT(self.host)
+        self.local_wpt.fetch()
 
     def run(self):
         """Query in-flight pull requests, then merge PR or create one.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
index d2a67bc7..d7e0e43d 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -25,125 +25,43 @@
 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 
-"""This script imports a directory of W3C tests into Blink.
+"""Logic for converting and copying files from a W3C repo.
 
-This script takes a source repository directory, which it searches for files,
-then converts and copies files over to a destination directory.
-
-Rules for importing:
-
- * By default, only reference tests and JS tests are imported, (because pixel
-   tests take longer to run). This can be overridden with the --all flag.
-
- * By default, if test files by the same name already exist in the destination
-   directory, they are overwritten. This is because this script is used to
-   refresh files periodically. This can be overridden with the --no-overwrite flag.
-
- * All files are converted to work in Blink:
-     1. All CSS properties requiring the -webkit- vendor prefix are prefixed
-        (the list of what needs prefixes is read from Source/core/css/CSSProperties.in).
-     2. Each reftest has its own copy of its reference file following
-        the naming conventions new-run-webkit-tests expects.
-     3. If a reference files lives outside the directory of the test that
-        uses it, it is checked for paths to support files as it will be
-        imported into a different relative position to the test file
-        (in the same directory).
-     4. Any tags with the class "instructions" have style="display:none" added
-        to them. Some w3c tests contain instructions to manual testers which we
-        want to strip out (the test result parser only recognizes pure testharness.js
-        output and not those instructions).
-
- * Upon completion, script outputs the total number tests imported,
-   broken down by test type.
-
- * Also upon completion, if we are not importing the files in place, each
-   directory where files are imported will have a w3c-import.log file written with
-   a timestamp, the list of CSS properties used that require prefixes, the list
-   of imported files, and guidance for future test modification and maintenance.
-   On subsequent imports, this file is read to determine if files have been
-   removed in the newer changesets. The script removes these files accordingly.
+This module is responsible for modifying and copying a subset of the tests from
+a local W3C repository source directory into a destination directory.
 """
 
 import logging
 import mimetypes
-import re
-import optparse
 import os
-import sys
+import re
 
-from webkitpy.common.host import Host
 from webkitpy.common.webkit_finder import WebKitFinder
 from webkitpy.layout_tests.models.test_expectations import TestExpectationParser
 from webkitpy.w3c.test_parser import TestParser
 from webkitpy.w3c.test_converter import convert_for_webkit
 
-
 # Maximum length of import path starting from top of source repository.
 # This limit is here because the Windows builders cannot create paths that are
 # longer than the Windows max path length (260). See http://crbug.com/609871.
 MAX_PATH_LENGTH = 125
 
-
 _log = logging.getLogger(__name__)
 
 
-def main(_argv, _stdout, _stderr):
-    options, args = parse_args()
-    host = Host()
-    source_repo_path = host.filesystem.normpath(os.path.abspath(args[0]))
-
-    if not host.filesystem.exists(source_repo_path):
-        sys.exit('Repository directory %s not found!' % source_repo_path)
-
-    configure_logging()
-    test_importer = TestImporter(host, source_repo_path, options)
-    test_importer.do_import()
-
-
-def configure_logging():
-    class LogHandler(logging.StreamHandler):
-
-        def format(self, record):
-            if record.levelno > logging.INFO:
-                return "%s: %s" % (record.levelname, record.getMessage())
-            return record.getMessage()
-
-    logger = logging.getLogger()
-    logger.setLevel(logging.INFO)
-    handler = LogHandler()
-    handler.setLevel(logging.INFO)
-    logger.addHandler(handler)
-    return handler
-
-
-def parse_args():
-    parser = optparse.OptionParser(usage='usage: %prog [options] source_repo_path')
-    parser.add_option('-n', '--no-overwrite', dest='overwrite', action='store_false', default=True,
-                      help=('Flag to prevent duplicate test files from overwriting existing tests. '
-                            'By default, they will be overwritten.'))
-    parser.add_option('-a', '--all', action='store_true', default=False,
-                      help=('Import all tests including reftests, JS tests, and manual/pixel tests. '
-                            'By default, only reftests and JS tests are imported.'))
-    parser.add_option('-d', '--dest-dir', dest='destination', default='w3c',
-                      help=('Import into a specified directory relative to the LayoutTests root. '
-                            'By default, files are imported under LayoutTests/w3c.'))
-    parser.add_option('--ignore-expectations', action='store_true', default=False,
-                      help='Ignore the W3CImportExpectations file and import everything.')
-    parser.add_option('--dry-run', action='store_true', default=False,
-                      help='Dry run only (don\'t actually write any results).')
-
-    options, args = parser.parse_args()
-    if len(args) != 1:
-        parser.error('Incorrect number of arguments; source repo path is required.')
-    return options, args
-
-
 class TestImporter(object):
 
-    def __init__(self, host, source_repo_path, options):
+    def __init__(self, host, source_repo_path, dest_dir_name='external'):
+        """Initializes variables to prepare for copying and converting files.
+
+        Args:
+            source_repo_path: Path to the local checkout of a WPT
+        """
         self.host = host
+
+        assert self.host.filesystem.exists(source_repo_path)
         self.source_repo_path = source_repo_path
-        self.options = options
+        self.dest_dir_name = dest_dir_name
 
         self.filesystem = self.host.filesystem
         self.webkit_finder = WebKitFinder(self.filesystem)
@@ -152,7 +70,7 @@
         self.destination_directory = self.filesystem.normpath(
             self.filesystem.join(
                 self.layout_tests_dir,
-                options.destination,
+                dest_dir_name,
                 self.filesystem.basename(self.source_repo_path)))
         self.import_in_place = (self.source_repo_path == self.destination_directory)
         self.dir_above_repo = self.filesystem.dirname(self.source_repo_path)
@@ -197,12 +115,12 @@
                         dirs.remove(name)
 
                 for path in paths_to_skip:
-                    path_base = path.replace(self.options.destination + '/', '')
+                    path_base = path.replace(self.dest_dir_name + '/', '')
                     path_base = path_base.replace(cur_dir, '')
                     path_full = self.filesystem.join(root, path_base)
                     if path_base in dirs:
                         dirs.remove(path_base)
-                        if not self.options.dry_run and self.import_in_place:
+                        if self.import_in_place:
                             _log.info("  pruning %s", path_base)
                             self.filesystem.rmtree(path_full)
                         else:
@@ -215,7 +133,7 @@
                 path_base = path_full.replace(self.source_repo_path + '/', '')
                 path_base = self.destination_directory.replace(self.layout_tests_dir + '/', '') + '/' + path_base
                 if path_base in paths_to_skip:
-                    if not self.options.dry_run and self.import_in_place:
+                    if self.import_in_place:
                         _log.info("  pruning %s", path_base)
                         self.filesystem.remove(path_full)
                         continue
@@ -291,19 +209,12 @@
                     total_tests += 1
                     copy_list.append({'src': fullpath, 'dest': filename, 'is_jstest': True})
 
-                elif self.options.all:
-                    total_tests += 1
-                    copy_list.append({'src': fullpath, 'dest': filename})
-
             if copy_list:
                 # Only add this directory to the list if there's something to import
                 self.import_list.append({'dirname': root, 'copy_list': copy_list,
                                          'reftests': reftests, 'jstests': jstests, 'total_tests': total_tests})
 
     def find_paths_to_skip(self):
-        if self.options.ignore_expectations:
-            return set()
-
         paths_to_skip = set()
         port = self.host.port_factory.get()
         w3c_import_expectations_path = self.webkit_finder.path_from_webkit_base('LayoutTests', 'W3CImportExpectations')
@@ -387,23 +298,17 @@
             _log.error('%s not found. Possible error in the test.', source_path)
             return None
 
-        if file_to_copy.get('reference_support_info'):
-            reference_support_info = file_to_copy['reference_support_info']
-        else:
-            reference_support_info = None
+        reference_support_info = file_to_copy.get('reference_support_info') or None
 
         if not self.filesystem.exists(self.filesystem.dirname(dest_path)):
-            if not self.import_in_place and not self.options.dry_run:
+            if not self.import_in_place:
                 self.filesystem.maybe_make_directory(self.filesystem.dirname(dest_path))
 
         relpath = self.filesystem.relpath(dest_path, self.layout_tests_dir)
-        if not self.options.overwrite and self.filesystem.exists(dest_path):
-            _log.info('  skipping %s', relpath)
-        else:
-            # FIXME: Maybe doing a file diff is in order here for existing files?
-            # In other words, there's no sense in overwriting identical files, but
-            # there's no harm in copying the identical thing.
-            _log.info('  %s', relpath)
+        # FIXME: Maybe doing a file diff is in order here for existing files?
+        # In other words, there's no sense in overwriting identical files, but
+        # there's no harm in copying the identical thing.
+        _log.info('  %s', relpath)
 
         if self.should_try_to_convert(file_to_copy, source_path, dest_dir):
             converted_file = convert_for_webkit(
@@ -414,10 +319,9 @@
                 self._prefixed_properties.setdefault(prefixed_property, 0)
                 self._prefixed_properties[prefixed_property] += 1
 
-            if not self.options.dry_run:
-                self.filesystem.write_text_file(dest_path, converted_file[1])
+            self.filesystem.write_text_file(dest_path, converted_file[1])
         else:
-            if not self.import_in_place and not self.options.dry_run:
+            if not self.import_in_place:
                 self.filesystem.copyfile(source_path, dest_path)
                 if self.filesystem.read_binary_file(source_path)[:2] == '#!':
                     self.filesystem.make_executable(dest_path)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
index 2984d842..ba022f7 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
@@ -25,7 +25,6 @@
 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 
-import optparse
 import unittest
 
 from webkitpy.common.host_mock import MockHost
@@ -37,52 +36,43 @@
 FAKE_SOURCE_REPO_DIR = '/blink'
 
 FAKE_FILES = {
-    '/mock-checkout/third_party/Webkit/LayoutTests/w3c/OWNERS': '',
+    '/mock-checkout/third_party/Webkit/LayoutTests/external/OWNERS': '',
     '/blink/w3c/dir/has_shebang.txt': '#!',
     '/blink/w3c/dir/README.txt': '',
     '/blink/w3c/dir/OWNERS': '',
     '/blink/w3c/dir/reftest.list': '',
     '/blink/w3c/dir1/OWNERS': '',
     '/blink/w3c/dir1/reftest.list': '',
-    '/mock-checkout/third_party/WebKit/LayoutTests/w3c/README.txt': '',
+    '/mock-checkout/third_party/WebKit/LayoutTests/external/README.txt': '',
     '/mock-checkout/third_party/WebKit/LayoutTests/W3CImportExpectations': '',
 }
 
 
 class TestImporterTest(unittest.TestCase):
 
-    @staticmethod
-    def options(**kwargs):
-        """Returns a set of option values for TestImporter."""
-        options = {
-            "overwrite": False,
-            "destination": "w3c",
-            "ignore_expectations": False,
-            "dry_run": False,
-        }
-        options.update(kwargs)
-        return optparse.Values(options)
-
     def test_import_dir_with_no_tests(self):
         host = MockHost()
-        host.executive = MockExecutive(exception=ScriptError(
-            "abort: no repository found in '/Volumes/Source/src/wk/Tools/Scripts/webkitpy/w3c'"))
+        host.executive = MockExecutive(exception=ScriptError('error'))
         host.filesystem = MockFileSystem(files=FAKE_FILES)
-        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR, self.options())
+        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR, 'destination')
         importer.do_import()  # No exception raised.
 
     def test_path_too_long_true(self):
-        importer = TestImporter(MockHost(), FAKE_SOURCE_REPO_DIR, self.options())
+        host = MockHost()
+        host.filesystem = MockFileSystem(files=FAKE_FILES)
+        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR)
         self.assertTrue(importer.path_too_long(FAKE_SOURCE_REPO_DIR + '/' + ('x' * 150) + '.html'))
 
     def test_path_too_long_false(self):
-        importer = TestImporter(MockHost(), FAKE_SOURCE_REPO_DIR, self.options())
+        host = MockHost()
+        host.filesystem = MockFileSystem(files=FAKE_FILES)
+        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR)
         self.assertFalse(importer.path_too_long(FAKE_SOURCE_REPO_DIR + '/x.html'))
 
     def test_does_not_import_owner_files(self):
         host = MockHost()
         host.filesystem = MockFileSystem(files=FAKE_FILES)
-        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR, self.options())
+        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR)
         importer.find_importable_tests()
         self.assertEqual(
             importer.import_list,
@@ -102,7 +92,7 @@
     def test_does_not_import_reftestlist_file(self):
         host = MockHost()
         host.filesystem = MockFileSystem(files=FAKE_FILES)
-        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR, self.options())
+        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR)
         importer.find_importable_tests()
         self.assertEqual(
             importer.import_list,
@@ -122,11 +112,11 @@
     def test_files_with_shebang_are_made_executable(self):
         host = MockHost()
         host.filesystem = MockFileSystem(files=FAKE_FILES)
-        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR, self.options())
+        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR)
         importer.do_import()
         self.assertEqual(
             host.filesystem.executable_files,
-            set(['/mock-checkout/third_party/WebKit/LayoutTests/w3c/blink/w3c/dir/has_shebang.txt']))
+            set(['/mock-checkout/third_party/WebKit/LayoutTests/external/blink/w3c/dir/has_shebang.txt']))
 
     def test_ref_test_with_ref_is_copied(self):
         host = MockHost()
@@ -136,7 +126,7 @@
             '/mock-checkout/third_party/WebKit/LayoutTests/W3CImportExpectations': '',
             '/mock-checkout/third_party/WebKit/Source/core/css/CSSProperties.in': '',
         })
-        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR, self.options())
+        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR)
         importer.find_importable_tests()
         self.assertEqual(
             importer.import_list,
@@ -161,7 +151,7 @@
             '/mock-checkout/third_party/WebKit/LayoutTests/W3CImportExpectations': '',
             '/mock-checkout/third_party/WebKit/Source/core/css/CSSProperties.in': '',
         })
-        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR, self.options())
+        importer = TestImporter(host, FAKE_SOURCE_REPO_DIR)
         importer.find_importable_tests()
         self.assertEqual(importer.import_list, [])
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests.py
index 5a30225..4982736 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests.py
@@ -26,16 +26,14 @@
 import optparse
 import os
 import re
-import sys
-
-from webkitpy.common.checkout.scm.detection import SCMDetector
-from webkitpy.common.system.executive import Executive
-from webkitpy.common.system.filesystem import FileSystem
 
 
 _log = logging.getLogger(__name__)
 
 
+# TODO(qyearsley): Remove this module if update-webgl-conformance-tests is now unused.
+
+
 def remove_first_line_comment(text):
     return re.compile(r'^<!--.*?-->\s*', re.DOTALL).sub('', text)
 
@@ -91,16 +89,6 @@
 
 
 def default_out_dir():
-    detector = SCMDetector(FileSystem(), Executive())
-    current_scm = detector.detect_scm_system(os.path.dirname(sys.argv[0]))
-    if not current_scm:
-        return os.getcwd()
-    root_dir = current_scm.checkout_root
-    if not root_dir:
-        return os.getcwd()
-    out_dir = os.path.join(root_dir, "LayoutTests/fast/canvas/webgl")
-    if os.path.isdir(out_dir):
-        return out_dir
     return os.getcwd()
 
 
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index 45fe5330..2c288bab 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -545,7 +545,7 @@
     "web/WebSettings.h",
     "web/WebSharedWorker.h",
     "web/WebSharedWorkerClient.h",
-    "web/WebSharedWorkerConnector.h",
+    "web/WebSharedWorkerConnectListener.h",
     "web/WebSharedWorkerCreationErrors.h",
     "web/WebSharedWorkerRepositoryClient.h",
     "web/WebSpeechGrammar.h",
diff --git a/third_party/WebKit/public/platform/WebURLRequest.h b/third_party/WebKit/public/platform/WebURLRequest.h
index b8a3ea4b..57c31b6 100644
--- a/third_party/WebKit/public/platform/WebURLRequest.h
+++ b/third_party/WebKit/public/platform/WebURLRequest.h
@@ -139,14 +139,17 @@
   // The Previews state which determines whether to request a Preview version of
   // the resource.
   enum PreviewsState {
-    PreviewsUnspecified = 0,  // Let the browser process decide whether or
-                              // not to request Preview types.
-    ServerLoFiOn = 1 << 0,    // Request a Lo-Fi version of the resource
-                              // from the server.
-    ClientLoFiOn = 1 << 1,    // Request a Lo-Fi version of the resource
-                              // from the client.
-    PreviewsOff = 1 << 2,     // Request a normal (non-Preview) version of
-                              // the resource.
+    PreviewsUnspecified = 0,       // Let the browser process decide whether or
+                                   // not to request Preview types.
+    ServerLoFiOn = 1 << 0,         // Request a Lo-Fi version of the resource
+                                   // from the server.
+    ClientLoFiOn = 1 << 1,         // Request a Lo-Fi version of the resource
+                                   // from the client.
+    PreviewsNoTransform = 1 << 2,  // Explicitly forbid Previews
+                                   // transformations.
+    PreviewsOff = 1 << 3,          // Request a normal (non-Preview) version of
+                                   // the resource. Server transformations may
+                                   // still happen if the page is heavy.
     PreviewsStateLast = PreviewsOff
   };
 
diff --git a/third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h b/third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h
index 26a12748..8d245b88 100644
--- a/third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h
+++ b/third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h
@@ -31,6 +31,8 @@
 #include "public/platform/modules/indexeddb/WebIDBDatabaseError.h"
 
 #include <unordered_map>
+#include <utility>
+#include <vector>
 
 namespace blink {
 
@@ -48,7 +50,10 @@
   virtual void onChanges(
       const std::unordered_map<int32_t, std::vector<int32_t>>&
           observation_index_map,
-      const WebVector<WebIDBObservation>& observations) = 0;
+      const WebVector<WebIDBObservation>& observations,
+      const std::unordered_map<int32_t,
+                               std::pair<int64_t, std::vector<int64_t>>>&
+          transactions) = 0;
   virtual void detach() = 0;
 };
 
diff --git a/third_party/WebKit/public/web/WebSharedWorkerConnector.h b/third_party/WebKit/public/web/WebSharedWorkerConnectListener.h
similarity index 66%
rename from third_party/WebKit/public/web/WebSharedWorkerConnector.h
rename to third_party/WebKit/public/web/WebSharedWorkerConnectListener.h
index c922c7b..078eb028 100644
--- a/third_party/WebKit/public/web/WebSharedWorkerConnector.h
+++ b/third_party/WebKit/public/web/WebSharedWorkerConnectListener.h
@@ -28,33 +28,26 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef WebSharedWorkerConnector_h
-#define WebSharedWorkerConnector_h
+#ifndef WebSharedWorkerConnectListener_h
+#define WebSharedWorkerConnectListener_h
 
-#include "WebContentSecurityPolicy.h"
+#include "WebSharedWorkerCreationErrors.h"
 
 namespace blink {
 
-class WebMessagePortChannel;
-
-// This is the interface to conncect to SharedWorker.
-// Since SharedWorkers communicate entirely through MessagePorts this interface
-// only contains APIs for starting up a SharedWorker.
-class WebSharedWorkerConnector {
+// This is the callback interface passed from blink to the embedder.
+class WebSharedWorkerConnectListener {
  public:
-  virtual ~WebSharedWorkerConnector() {}
+  virtual ~WebSharedWorkerConnectListener() = default;
 
-  class ConnectListener {
-   public:
-    // Invoked once the connect event has been sent so the caller can free this
-    // object.
-    virtual void connected() = 0;
-    virtual void scriptLoadFailed() = 0;
-  };
+  // Called when a worker is created.
+  virtual void workerCreated(WebWorkerCreationError) = 0;
 
-  // Sends a connect event to the SharedWorker context. The listener is invoked
-  // when this async operation completes.
-  virtual void connect(WebMessagePortChannel*, ConnectListener*) = 0;
+  // Called when worker script load fails.
+  virtual void scriptLoadFailed() = 0;
+
+  // Called when a connection is established.
+  virtual void connected() = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/public/web/WebSharedWorkerRepositoryClient.h b/third_party/WebKit/public/web/WebSharedWorkerRepositoryClient.h
index b139ce6..db36308 100644
--- a/third_party/WebKit/public/web/WebSharedWorkerRepositoryClient.h
+++ b/third_party/WebKit/public/web/WebSharedWorkerRepositoryClient.h
@@ -31,7 +31,6 @@
 #ifndef WebSharedWorkerRepositoryClient_h
 #define WebSharedWorkerRepositoryClient_h
 
-#include "WebSharedWorkerConnector.h"
 #include "WebSharedWorkerCreationContextType.h"
 #include "WebSharedWorkerCreationErrors.h"
 #include "public/platform/WebAddressSpace.h"
@@ -40,6 +39,8 @@
 namespace blink {
 
 enum WebContentSecurityPolicyType;
+class WebMessagePortChannel;
+class WebSharedWorkerConnectListener;
 class WebString;
 class WebURL;
 
@@ -49,17 +50,16 @@
   // given process).
   using DocumentID = unsigned long long;
 
-  // Creates a new shared worker connector.
-  virtual std::unique_ptr<WebSharedWorkerConnector> createSharedWorkerConnector(
-      const WebURL& url,
-      const WebString& name,
-      DocumentID id,
-      const WebString& contentSecurityPolicy,
-      WebContentSecurityPolicyType,
-      WebAddressSpace,
-      WebSharedWorkerCreationContextType,
-      WebWorkerCreationError* error) {
-    return nullptr;
+  // Connects to a shared worker.
+  virtual void connect(const WebURL& url,
+                       const WebString& name,
+                       DocumentID id,
+                       const WebString& contentSecurityPolicy,
+                       WebContentSecurityPolicyType,
+                       WebAddressSpace,
+                       WebSharedWorkerCreationContextType,
+                       WebMessagePortChannel*,
+                       std::unique_ptr<blink::WebSharedWorkerConnectListener>) {
   }
 
   // Invoked when a document has been detached. DocumentID can be re-used after
diff --git a/third_party/boringssl/BUILD.generated.gni b/third_party/boringssl/BUILD.generated.gni
index 61618d8f..79d3e94f 100644
--- a/third_party/boringssl/BUILD.generated.gni
+++ b/third_party/boringssl/BUILD.generated.gni
@@ -193,6 +193,7 @@
   "src/crypto/pool/internal.h",
   "src/crypto/pool/pool.c",
   "src/crypto/rand/deterministic.c",
+  "src/crypto/rand/fuchsia.c",
   "src/crypto/rand/internal.h",
   "src/crypto/rand/rand.c",
   "src/crypto/rand/urandom.c",
@@ -403,6 +404,7 @@
   "src/ssl/ssl_file.c",
   "src/ssl/ssl_lib.c",
   "src/ssl/ssl_rsa.c",
+  "src/ssl/ssl_rsa_cc.cc",
   "src/ssl/ssl_session.c",
   "src/ssl/ssl_stat.c",
   "src/ssl/t1_enc.c",
diff --git a/third_party/boringssl/linux-x86/crypto/modes/ghash-x86.S b/third_party/boringssl/linux-x86/crypto/modes/ghash-x86.S
index 2872088..84ff2f4 100644
--- a/third_party/boringssl/linux-x86/crypto/modes/ghash-x86.S
+++ b/third_party/boringssl/linux-x86/crypto/modes/ghash-x86.S
@@ -1,211 +1,6 @@
 #if defined(__i386__)
 .file	"ghash-x86.S"
 .text
-.globl	gcm_gmult_4bit_x86
-.hidden	gcm_gmult_4bit_x86
-.type	gcm_gmult_4bit_x86,@function
-.align	16
-gcm_gmult_4bit_x86:
-.L_gcm_gmult_4bit_x86_begin:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	subl	$84,%esp
-	movl	104(%esp),%edi
-	movl	108(%esp),%esi
-	movl	(%edi),%ebp
-	movl	4(%edi),%edx
-	movl	8(%edi),%ecx
-	movl	12(%edi),%ebx
-	movl	$0,16(%esp)
-	movl	$471859200,20(%esp)
-	movl	$943718400,24(%esp)
-	movl	$610271232,28(%esp)
-	movl	$1887436800,32(%esp)
-	movl	$1822425088,36(%esp)
-	movl	$1220542464,40(%esp)
-	movl	$1423966208,44(%esp)
-	movl	$3774873600,48(%esp)
-	movl	$4246732800,52(%esp)
-	movl	$3644850176,56(%esp)
-	movl	$3311403008,60(%esp)
-	movl	$2441084928,64(%esp)
-	movl	$2376073216,68(%esp)
-	movl	$2847932416,72(%esp)
-	movl	$3051356160,76(%esp)
-	movl	%ebp,(%esp)
-	movl	%edx,4(%esp)
-	movl	%ecx,8(%esp)
-	movl	%ebx,12(%esp)
-	shrl	$20,%ebx
-	andl	$240,%ebx
-	movl	4(%esi,%ebx,1),%ebp
-	movl	(%esi,%ebx,1),%edx
-	movl	12(%esi,%ebx,1),%ecx
-	movl	8(%esi,%ebx,1),%ebx
-	xorl	%eax,%eax
-	movl	$15,%edi
-	jmp	.L000x86_loop
-.align	16
-.L000x86_loop:
-	movb	%bl,%al
-	shrdl	$4,%ecx,%ebx
-	andb	$15,%al
-	shrdl	$4,%edx,%ecx
-	shrdl	$4,%ebp,%edx
-	shrl	$4,%ebp
-	xorl	16(%esp,%eax,4),%ebp
-	movb	(%esp,%edi,1),%al
-	andb	$240,%al
-	xorl	8(%esi,%eax,1),%ebx
-	xorl	12(%esi,%eax,1),%ecx
-	xorl	(%esi,%eax,1),%edx
-	xorl	4(%esi,%eax,1),%ebp
-	decl	%edi
-	js	.L001x86_break
-	movb	%bl,%al
-	shrdl	$4,%ecx,%ebx
-	andb	$15,%al
-	shrdl	$4,%edx,%ecx
-	shrdl	$4,%ebp,%edx
-	shrl	$4,%ebp
-	xorl	16(%esp,%eax,4),%ebp
-	movb	(%esp,%edi,1),%al
-	shlb	$4,%al
-	xorl	8(%esi,%eax,1),%ebx
-	xorl	12(%esi,%eax,1),%ecx
-	xorl	(%esi,%eax,1),%edx
-	xorl	4(%esi,%eax,1),%ebp
-	jmp	.L000x86_loop
-.align	16
-.L001x86_break:
-	bswap	%ebx
-	bswap	%ecx
-	bswap	%edx
-	bswap	%ebp
-	movl	104(%esp),%edi
-	movl	%ebx,12(%edi)
-	movl	%ecx,8(%edi)
-	movl	%edx,4(%edi)
-	movl	%ebp,(%edi)
-	addl	$84,%esp
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.size	gcm_gmult_4bit_x86,.-.L_gcm_gmult_4bit_x86_begin
-.globl	gcm_ghash_4bit_x86
-.hidden	gcm_ghash_4bit_x86
-.type	gcm_ghash_4bit_x86,@function
-.align	16
-gcm_ghash_4bit_x86:
-.L_gcm_ghash_4bit_x86_begin:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	subl	$84,%esp
-	movl	104(%esp),%ebx
-	movl	108(%esp),%esi
-	movl	112(%esp),%edi
-	movl	116(%esp),%ecx
-	addl	%edi,%ecx
-	movl	%ecx,116(%esp)
-	movl	(%ebx),%ebp
-	movl	4(%ebx),%edx
-	movl	8(%ebx),%ecx
-	movl	12(%ebx),%ebx
-	movl	$0,16(%esp)
-	movl	$471859200,20(%esp)
-	movl	$943718400,24(%esp)
-	movl	$610271232,28(%esp)
-	movl	$1887436800,32(%esp)
-	movl	$1822425088,36(%esp)
-	movl	$1220542464,40(%esp)
-	movl	$1423966208,44(%esp)
-	movl	$3774873600,48(%esp)
-	movl	$4246732800,52(%esp)
-	movl	$3644850176,56(%esp)
-	movl	$3311403008,60(%esp)
-	movl	$2441084928,64(%esp)
-	movl	$2376073216,68(%esp)
-	movl	$2847932416,72(%esp)
-	movl	$3051356160,76(%esp)
-.align	16
-.L002x86_outer_loop:
-	xorl	12(%edi),%ebx
-	xorl	8(%edi),%ecx
-	xorl	4(%edi),%edx
-	xorl	(%edi),%ebp
-	movl	%ebx,12(%esp)
-	movl	%ecx,8(%esp)
-	movl	%edx,4(%esp)
-	movl	%ebp,(%esp)
-	shrl	$20,%ebx
-	andl	$240,%ebx
-	movl	4(%esi,%ebx,1),%ebp
-	movl	(%esi,%ebx,1),%edx
-	movl	12(%esi,%ebx,1),%ecx
-	movl	8(%esi,%ebx,1),%ebx
-	xorl	%eax,%eax
-	movl	$15,%edi
-	jmp	.L003x86_loop
-.align	16
-.L003x86_loop:
-	movb	%bl,%al
-	shrdl	$4,%ecx,%ebx
-	andb	$15,%al
-	shrdl	$4,%edx,%ecx
-	shrdl	$4,%ebp,%edx
-	shrl	$4,%ebp
-	xorl	16(%esp,%eax,4),%ebp
-	movb	(%esp,%edi,1),%al
-	andb	$240,%al
-	xorl	8(%esi,%eax,1),%ebx
-	xorl	12(%esi,%eax,1),%ecx
-	xorl	(%esi,%eax,1),%edx
-	xorl	4(%esi,%eax,1),%ebp
-	decl	%edi
-	js	.L004x86_break
-	movb	%bl,%al
-	shrdl	$4,%ecx,%ebx
-	andb	$15,%al
-	shrdl	$4,%edx,%ecx
-	shrdl	$4,%ebp,%edx
-	shrl	$4,%ebp
-	xorl	16(%esp,%eax,4),%ebp
-	movb	(%esp,%edi,1),%al
-	shlb	$4,%al
-	xorl	8(%esi,%eax,1),%ebx
-	xorl	12(%esi,%eax,1),%ecx
-	xorl	(%esi,%eax,1),%edx
-	xorl	4(%esi,%eax,1),%ebp
-	jmp	.L003x86_loop
-.align	16
-.L004x86_break:
-	bswap	%ebx
-	bswap	%ecx
-	bswap	%edx
-	bswap	%ebp
-	movl	112(%esp),%edi
-	leal	16(%edi),%edi
-	cmpl	116(%esp),%edi
-	movl	%edi,112(%esp)
-	jb	.L002x86_outer_loop
-	movl	104(%esp),%edi
-	movl	%ebx,12(%edi)
-	movl	%ecx,8(%edi)
-	movl	%edx,4(%edi)
-	movl	%ebp,(%edi)
-	addl	$84,%esp
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.size	gcm_ghash_4bit_x86,.-.L_gcm_ghash_4bit_x86_begin
 .globl	gcm_gmult_4bit_mmx
 .hidden	gcm_gmult_4bit_mmx
 .type	gcm_gmult_4bit_mmx,@function
@@ -218,10 +13,10 @@
 	pushl	%edi
 	movl	20(%esp),%edi
 	movl	24(%esp),%esi
-	call	.L005pic_point
-.L005pic_point:
+	call	.L000pic_point
+.L000pic_point:
 	popl	%eax
-	leal	.Lrem_4bit-.L005pic_point(%eax),%eax
+	leal	.Lrem_4bit-.L000pic_point(%eax),%eax
 	movzbl	15(%edi),%ebx
 	xorl	%ecx,%ecx
 	movl	%ebx,%edx
@@ -232,9 +27,9 @@
 	movq	8(%esi,%ecx,1),%mm0
 	movq	(%esi,%ecx,1),%mm1
 	movd	%mm0,%ebx
-	jmp	.L006mmx_loop
+	jmp	.L001mmx_loop
 .align	16
-.L006mmx_loop:
+.L001mmx_loop:
 	psrlq	$4,%mm0
 	andl	$15,%ebx
 	movq	%mm1,%mm2
@@ -248,7 +43,7 @@
 	pxor	(%esi,%edx,1),%mm1
 	movl	%ecx,%edx
 	pxor	%mm2,%mm0
-	js	.L007mmx_break
+	js	.L002mmx_break
 	shlb	$4,%cl
 	andl	$15,%ebx
 	psrlq	$4,%mm0
@@ -261,9 +56,9 @@
 	movd	%mm0,%ebx
 	pxor	(%esi,%ecx,1),%mm1
 	pxor	%mm2,%mm0
-	jmp	.L006mmx_loop
+	jmp	.L001mmx_loop
 .align	16
-.L007mmx_break:
+.L002mmx_break:
 	shlb	$4,%cl
 	andl	$15,%ebx
 	psrlq	$4,%mm0
@@ -321,10 +116,10 @@
 	movl	28(%esp),%ecx
 	movl	32(%esp),%edx
 	movl	%esp,%ebp
-	call	.L008pic_point
-.L008pic_point:
+	call	.L003pic_point
+.L003pic_point:
 	popl	%esi
-	leal	.Lrem_8bit-.L008pic_point(%esi),%esi
+	leal	.Lrem_8bit-.L003pic_point(%esi),%esi
 	subl	$544,%esp
 	andl	$-64,%esp
 	subl	$16,%esp
@@ -563,7 +358,7 @@
 	movl	8(%eax),%ebx
 	movl	12(%eax),%edx
 .align	16
-.L009outer:
+.L004outer:
 	xorl	12(%ecx),%edx
 	xorl	8(%ecx),%ebx
 	pxor	(%ecx),%mm6
@@ -898,7 +693,7 @@
 	pshufw	$27,%mm6,%mm6
 	bswap	%ebx
 	cmpl	552(%esp),%ecx
-	jne	.L009outer
+	jne	.L004outer
 	movl	544(%esp),%eax
 	movl	%edx,12(%eax)
 	movl	%ebx,8(%eax)
@@ -919,10 +714,10 @@
 .L_gcm_init_clmul_begin:
 	movl	4(%esp),%edx
 	movl	8(%esp),%eax
-	call	.L010pic
-.L010pic:
+	call	.L005pic
+.L005pic:
 	popl	%ecx
-	leal	.Lbswap-.L010pic(%ecx),%ecx
+	leal	.Lbswap-.L005pic(%ecx),%ecx
 	movdqu	(%eax),%xmm2
 	pshufd	$78,%xmm2,%xmm2
 	pshufd	$255,%xmm2,%xmm4
@@ -989,10 +784,10 @@
 .L_gcm_gmult_clmul_begin:
 	movl	4(%esp),%eax
 	movl	8(%esp),%edx
-	call	.L011pic
-.L011pic:
+	call	.L006pic
+.L006pic:
 	popl	%ecx
-	leal	.Lbswap-.L011pic(%ecx),%ecx
+	leal	.Lbswap-.L006pic(%ecx),%ecx
 	movdqu	(%eax),%xmm0
 	movdqa	(%ecx),%xmm5
 	movups	(%edx),%xmm2
@@ -1049,16 +844,16 @@
 	movl	24(%esp),%edx
 	movl	28(%esp),%esi
 	movl	32(%esp),%ebx
-	call	.L012pic
-.L012pic:
+	call	.L007pic
+.L007pic:
 	popl	%ecx
-	leal	.Lbswap-.L012pic(%ecx),%ecx
+	leal	.Lbswap-.L007pic(%ecx),%ecx
 	movdqu	(%eax),%xmm0
 	movdqa	(%ecx),%xmm5
 	movdqu	(%edx),%xmm2
 .byte	102,15,56,0,197
 	subl	$16,%ebx
-	jz	.L013odd_tail
+	jz	.L008odd_tail
 	movdqu	(%esi),%xmm3
 	movdqu	16(%esi),%xmm6
 .byte	102,15,56,0,221
@@ -1075,10 +870,10 @@
 	movups	16(%edx),%xmm2
 	nop
 	subl	$32,%ebx
-	jbe	.L014even_tail
-	jmp	.L015mod_loop
+	jbe	.L009even_tail
+	jmp	.L010mod_loop
 .align	32
-.L015mod_loop:
+.L010mod_loop:
 	pshufd	$78,%xmm0,%xmm4
 	movdqa	%xmm0,%xmm1
 	pxor	%xmm0,%xmm4
@@ -1133,8 +928,8 @@
 .byte	102,15,58,68,221,0
 	leal	32(%esi),%esi
 	subl	$32,%ebx
-	ja	.L015mod_loop
-.L014even_tail:
+	ja	.L010mod_loop
+.L009even_tail:
 	pshufd	$78,%xmm0,%xmm4
 	movdqa	%xmm0,%xmm1
 	pxor	%xmm0,%xmm4
@@ -1173,9 +968,9 @@
 	psrlq	$1,%xmm0
 	pxor	%xmm1,%xmm0
 	testl	%ebx,%ebx
-	jnz	.L016done
+	jnz	.L011done
 	movups	(%edx),%xmm2
-.L013odd_tail:
+.L008odd_tail:
 	movdqu	(%esi),%xmm3
 .byte	102,15,56,0,221
 	pxor	%xmm3,%xmm0
@@ -1214,7 +1009,7 @@
 	pxor	%xmm4,%xmm0
 	psrlq	$1,%xmm0
 	pxor	%xmm1,%xmm0
-.L016done:
+.L011done:
 .byte	102,15,56,0,197
 	movdqu	%xmm0,(%eax)
 	popl	%edi
diff --git a/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S b/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S
index e059dd6..785f269 100644
--- a/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S
+++ b/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -17,48 +17,6 @@
 .LONE_mont:
 .quad	0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
 
-.type	ecp_nistz256_mul_by_2,@function
-.align	64
-ecp_nistz256_mul_by_2:
-	pushq	%r12
-	pushq	%r13
-
-	movq	0(%rsi),%r8
-	xorq	%r13,%r13
-	movq	8(%rsi),%r9
-	addq	%r8,%r8
-	movq	16(%rsi),%r10
-	adcq	%r9,%r9
-	movq	24(%rsi),%r11
-	leaq	.Lpoly(%rip),%rsi
-	movq	%r8,%rax
-	adcq	%r10,%r10
-	adcq	%r11,%r11
-	movq	%r9,%rdx
-	adcq	$0,%r13
-
-	subq	0(%rsi),%r8
-	movq	%r10,%rcx
-	sbbq	8(%rsi),%r9
-	sbbq	16(%rsi),%r10
-	movq	%r11,%r12
-	sbbq	24(%rsi),%r11
-	sbbq	$0,%r13
-
-	cmovcq	%rax,%r8
-	cmovcq	%rdx,%r9
-	movq	%r8,0(%rdi)
-	cmovcq	%rcx,%r10
-	movq	%r9,8(%rdi)
-	cmovcq	%r12,%r11
-	movq	%r10,16(%rdi)
-	movq	%r11,24(%rdi)
-
-	popq	%r13
-	popq	%r12
-	.byte	0xf3,0xc3
-.size	ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
-
 
 
 .globl	ecp_nistz256_neg
@@ -554,103 +512,6 @@
 .size	__ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq
 
 
-
-
-
-
-.globl	ecp_nistz256_from_mont
-.hidden ecp_nistz256_from_mont
-.type	ecp_nistz256_from_mont,@function
-.align	32
-ecp_nistz256_from_mont:
-	pushq	%r12
-	pushq	%r13
-
-	movq	0(%rsi),%rax
-	movq	.Lpoly+24(%rip),%r13
-	movq	8(%rsi),%r9
-	movq	16(%rsi),%r10
-	movq	24(%rsi),%r11
-	movq	%rax,%r8
-	movq	.Lpoly+8(%rip),%r12
-
-
-
-	movq	%rax,%rcx
-	shlq	$32,%r8
-	mulq	%r13
-	shrq	$32,%rcx
-	addq	%r8,%r9
-	adcq	%rcx,%r10
-	adcq	%rax,%r11
-	movq	%r9,%rax
-	adcq	$0,%rdx
-
-
-
-	movq	%r9,%rcx
-	shlq	$32,%r9
-	movq	%rdx,%r8
-	mulq	%r13
-	shrq	$32,%rcx
-	addq	%r9,%r10
-	adcq	%rcx,%r11
-	adcq	%rax,%r8
-	movq	%r10,%rax
-	adcq	$0,%rdx
-
-
-
-	movq	%r10,%rcx
-	shlq	$32,%r10
-	movq	%rdx,%r9
-	mulq	%r13
-	shrq	$32,%rcx
-	addq	%r10,%r11
-	adcq	%rcx,%r8
-	adcq	%rax,%r9
-	movq	%r11,%rax
-	adcq	$0,%rdx
-
-
-
-	movq	%r11,%rcx
-	shlq	$32,%r11
-	movq	%rdx,%r10
-	mulq	%r13
-	shrq	$32,%rcx
-	addq	%r11,%r8
-	adcq	%rcx,%r9
-	movq	%r8,%rcx
-	adcq	%rax,%r10
-	movq	%r9,%rsi
-	adcq	$0,%rdx
-
-
-
-	subq	$-1,%r8
-	movq	%r10,%rax
-	sbbq	%r12,%r9
-	sbbq	$0,%r10
-	movq	%rdx,%r11
-	sbbq	%r13,%rdx
-	sbbq	%r13,%r13
-
-	cmovnzq	%rcx,%r8
-	cmovnzq	%rsi,%r9
-	movq	%r8,0(%rdi)
-	cmovnzq	%rax,%r10
-	movq	%r9,8(%rdi)
-	cmovzq	%rdx,%r11
-	movq	%r10,16(%rdi)
-	movq	%r11,24(%rdi)
-
-	popq	%r13
-	popq	%r12
-	.byte	0xf3,0xc3
-.size	ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
-
-
 .globl	ecp_nistz256_select_w5
 .hidden ecp_nistz256_select_w5
 .type	ecp_nistz256_select_w5,@function
diff --git a/third_party/boringssl/linux-x86_64/crypto/modes/aesni-gcm-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/modes/aesni-gcm-x86_64.S
index f01692e..9953e4c 100644
--- a/third_party/boringssl/linux-x86_64/crypto/modes/aesni-gcm-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/modes/aesni-gcm-x86_64.S
@@ -1,19 +1,798 @@
 #if defined(__x86_64__)
 .text	
 
-.globl	aesni_gcm_encrypt
-.hidden aesni_gcm_encrypt
-.type	aesni_gcm_encrypt,@function
-aesni_gcm_encrypt:
-	xorl	%eax,%eax
-	.byte	0xf3,0xc3
-.size	aesni_gcm_encrypt,.-aesni_gcm_encrypt
+.type	_aesni_ctr32_ghash_6x,@function
+.align	32
+_aesni_ctr32_ghash_6x:
+	vmovdqu	32(%r11),%xmm2
+	subq	$6,%rdx
+	vpxor	%xmm4,%xmm4,%xmm4
+	vmovdqu	0-128(%rcx),%xmm15
+	vpaddb	%xmm2,%xmm1,%xmm10
+	vpaddb	%xmm2,%xmm10,%xmm11
+	vpaddb	%xmm2,%xmm11,%xmm12
+	vpaddb	%xmm2,%xmm12,%xmm13
+	vpaddb	%xmm2,%xmm13,%xmm14
+	vpxor	%xmm15,%xmm1,%xmm9
+	vmovdqu	%xmm4,16+8(%rsp)
+	jmp	.Loop6x
 
+.align	32
+.Loop6x:
+	addl	$100663296,%ebx
+	jc	.Lhandle_ctr32
+	vmovdqu	0-32(%r9),%xmm3
+	vpaddb	%xmm2,%xmm14,%xmm1
+	vpxor	%xmm15,%xmm10,%xmm10
+	vpxor	%xmm15,%xmm11,%xmm11
+
+.Lresume_ctr32:
+	vmovdqu	%xmm1,(%r8)
+	vpclmulqdq	$0x10,%xmm3,%xmm7,%xmm5
+	vpxor	%xmm15,%xmm12,%xmm12
+	vmovups	16-128(%rcx),%xmm2
+	vpclmulqdq	$0x01,%xmm3,%xmm7,%xmm6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	xorq	%r12,%r12
+	cmpq	%r14,%r15
+
+	vaesenc	%xmm2,%xmm9,%xmm9
+	vmovdqu	48+8(%rsp),%xmm0
+	vpxor	%xmm15,%xmm13,%xmm13
+	vpclmulqdq	$0x00,%xmm3,%xmm7,%xmm1
+	vaesenc	%xmm2,%xmm10,%xmm10
+	vpxor	%xmm15,%xmm14,%xmm14
+	setnc	%r12b
+	vpclmulqdq	$0x11,%xmm3,%xmm7,%xmm7
+	vaesenc	%xmm2,%xmm11,%xmm11
+	vmovdqu	16-32(%r9),%xmm3
+	negq	%r12
+	vaesenc	%xmm2,%xmm12,%xmm12
+	vpxor	%xmm5,%xmm6,%xmm6
+	vpclmulqdq	$0x00,%xmm3,%xmm0,%xmm5
+	vpxor	%xmm4,%xmm8,%xmm8
+	vaesenc	%xmm2,%xmm13,%xmm13
+	vpxor	%xmm5,%xmm1,%xmm4
+	andq	$0x60,%r12
+	vmovups	32-128(%rcx),%xmm15
+	vpclmulqdq	$0x10,%xmm3,%xmm0,%xmm1
+	vaesenc	%xmm2,%xmm14,%xmm14
+
+	vpclmulqdq	$0x01,%xmm3,%xmm0,%xmm2
+	leaq	(%r14,%r12,1),%r14
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	16+8(%rsp),%xmm8,%xmm8
+	vpclmulqdq	$0x11,%xmm3,%xmm0,%xmm3
+	vmovdqu	64+8(%rsp),%xmm0
+	vaesenc	%xmm15,%xmm10,%xmm10
+	movbeq	88(%r14),%r13
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	80(%r14),%r12
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r13,32+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	movq	%r12,40+8(%rsp)
+	vmovdqu	48-32(%r9),%xmm5
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vmovups	48-128(%rcx),%xmm15
+	vpxor	%xmm1,%xmm6,%xmm6
+	vpclmulqdq	$0x00,%xmm5,%xmm0,%xmm1
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm5,%xmm0,%xmm2
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vpxor	%xmm3,%xmm7,%xmm7
+	vpclmulqdq	$0x01,%xmm5,%xmm0,%xmm3
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vpclmulqdq	$0x11,%xmm5,%xmm0,%xmm5
+	vmovdqu	80+8(%rsp),%xmm0
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vpxor	%xmm1,%xmm4,%xmm4
+	vmovdqu	64-32(%r9),%xmm1
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vmovups	64-128(%rcx),%xmm15
+	vpxor	%xmm2,%xmm6,%xmm6
+	vpclmulqdq	$0x00,%xmm1,%xmm0,%xmm2
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm3,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm1,%xmm0,%xmm3
+	vaesenc	%xmm15,%xmm10,%xmm10
+	movbeq	72(%r14),%r13
+	vpxor	%xmm5,%xmm7,%xmm7
+	vpclmulqdq	$0x01,%xmm1,%xmm0,%xmm5
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	64(%r14),%r12
+	vpclmulqdq	$0x11,%xmm1,%xmm0,%xmm1
+	vmovdqu	96+8(%rsp),%xmm0
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r13,48+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	movq	%r12,56+8(%rsp)
+	vpxor	%xmm2,%xmm4,%xmm4
+	vmovdqu	96-32(%r9),%xmm2
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vmovups	80-128(%rcx),%xmm15
+	vpxor	%xmm3,%xmm6,%xmm6
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm3
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm5,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm2,%xmm0,%xmm5
+	vaesenc	%xmm15,%xmm10,%xmm10
+	movbeq	56(%r14),%r13
+	vpxor	%xmm1,%xmm7,%xmm7
+	vpclmulqdq	$0x01,%xmm2,%xmm0,%xmm1
+	vpxor	112+8(%rsp),%xmm8,%xmm8
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	48(%r14),%r12
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm2
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r13,64+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	movq	%r12,72+8(%rsp)
+	vpxor	%xmm3,%xmm4,%xmm4
+	vmovdqu	112-32(%r9),%xmm3
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vmovups	96-128(%rcx),%xmm15
+	vpxor	%xmm5,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm3,%xmm8,%xmm5
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm1,%xmm6,%xmm6
+	vpclmulqdq	$0x01,%xmm3,%xmm8,%xmm1
+	vaesenc	%xmm15,%xmm10,%xmm10
+	movbeq	40(%r14),%r13
+	vpxor	%xmm2,%xmm7,%xmm7
+	vpclmulqdq	$0x00,%xmm3,%xmm8,%xmm2
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	32(%r14),%r12
+	vpclmulqdq	$0x11,%xmm3,%xmm8,%xmm8
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r13,80+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	movq	%r12,88+8(%rsp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	vaesenc	%xmm15,%xmm14,%xmm14
+	vpxor	%xmm1,%xmm6,%xmm6
+
+	vmovups	112-128(%rcx),%xmm15
+	vpslldq	$8,%xmm6,%xmm5
+	vpxor	%xmm2,%xmm4,%xmm4
+	vmovdqu	16(%r11),%xmm3
+
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm8,%xmm7,%xmm7
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vpxor	%xmm5,%xmm4,%xmm4
+	movbeq	24(%r14),%r13
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	16(%r14),%r12
+	vpalignr	$8,%xmm4,%xmm4,%xmm0
+	vpclmulqdq	$0x10,%xmm3,%xmm4,%xmm4
+	movq	%r13,96+8(%rsp)
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r12,104+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vmovups	128-128(%rcx),%xmm1
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vaesenc	%xmm1,%xmm9,%xmm9
+	vmovups	144-128(%rcx),%xmm15
+	vaesenc	%xmm1,%xmm10,%xmm10
+	vpsrldq	$8,%xmm6,%xmm6
+	vaesenc	%xmm1,%xmm11,%xmm11
+	vpxor	%xmm6,%xmm7,%xmm7
+	vaesenc	%xmm1,%xmm12,%xmm12
+	vpxor	%xmm0,%xmm4,%xmm4
+	movbeq	8(%r14),%r13
+	vaesenc	%xmm1,%xmm13,%xmm13
+	movbeq	0(%r14),%r12
+	vaesenc	%xmm1,%xmm14,%xmm14
+	vmovups	160-128(%rcx),%xmm1
+	cmpl	$11,%ebp
+	jb	.Lenc_tail
+
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vaesenc	%xmm1,%xmm9,%xmm9
+	vaesenc	%xmm1,%xmm10,%xmm10
+	vaesenc	%xmm1,%xmm11,%xmm11
+	vaesenc	%xmm1,%xmm12,%xmm12
+	vaesenc	%xmm1,%xmm13,%xmm13
+	vmovups	176-128(%rcx),%xmm15
+	vaesenc	%xmm1,%xmm14,%xmm14
+	vmovups	192-128(%rcx),%xmm1
+	je	.Lenc_tail
+
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vaesenc	%xmm1,%xmm9,%xmm9
+	vaesenc	%xmm1,%xmm10,%xmm10
+	vaesenc	%xmm1,%xmm11,%xmm11
+	vaesenc	%xmm1,%xmm12,%xmm12
+	vaesenc	%xmm1,%xmm13,%xmm13
+	vmovups	208-128(%rcx),%xmm15
+	vaesenc	%xmm1,%xmm14,%xmm14
+	vmovups	224-128(%rcx),%xmm1
+	jmp	.Lenc_tail
+
+.align	32
+.Lhandle_ctr32:
+	vmovdqu	(%r11),%xmm0
+	vpshufb	%xmm0,%xmm1,%xmm6
+	vmovdqu	48(%r11),%xmm5
+	vpaddd	64(%r11),%xmm6,%xmm10
+	vpaddd	%xmm5,%xmm6,%xmm11
+	vmovdqu	0-32(%r9),%xmm3
+	vpaddd	%xmm5,%xmm10,%xmm12
+	vpshufb	%xmm0,%xmm10,%xmm10
+	vpaddd	%xmm5,%xmm11,%xmm13
+	vpshufb	%xmm0,%xmm11,%xmm11
+	vpxor	%xmm15,%xmm10,%xmm10
+	vpaddd	%xmm5,%xmm12,%xmm14
+	vpshufb	%xmm0,%xmm12,%xmm12
+	vpxor	%xmm15,%xmm11,%xmm11
+	vpaddd	%xmm5,%xmm13,%xmm1
+	vpshufb	%xmm0,%xmm13,%xmm13
+	vpshufb	%xmm0,%xmm14,%xmm14
+	vpshufb	%xmm0,%xmm1,%xmm1
+	jmp	.Lresume_ctr32
+
+.align	32
+.Lenc_tail:
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vmovdqu	%xmm7,16+8(%rsp)
+	vpalignr	$8,%xmm4,%xmm4,%xmm8
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vpclmulqdq	$0x10,%xmm3,%xmm4,%xmm4
+	vpxor	0(%rdi),%xmm1,%xmm2
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vpxor	16(%rdi),%xmm1,%xmm0
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vpxor	32(%rdi),%xmm1,%xmm5
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vpxor	48(%rdi),%xmm1,%xmm6
+	vaesenc	%xmm15,%xmm14,%xmm14
+	vpxor	64(%rdi),%xmm1,%xmm7
+	vpxor	80(%rdi),%xmm1,%xmm3
+	vmovdqu	(%r8),%xmm1
+
+	vaesenclast	%xmm2,%xmm9,%xmm9
+	vmovdqu	32(%r11),%xmm2
+	vaesenclast	%xmm0,%xmm10,%xmm10
+	vpaddb	%xmm2,%xmm1,%xmm0
+	movq	%r13,112+8(%rsp)
+	leaq	96(%rdi),%rdi
+	vaesenclast	%xmm5,%xmm11,%xmm11
+	vpaddb	%xmm2,%xmm0,%xmm5
+	movq	%r12,120+8(%rsp)
+	leaq	96(%rsi),%rsi
+	vmovdqu	0-128(%rcx),%xmm15
+	vaesenclast	%xmm6,%xmm12,%xmm12
+	vpaddb	%xmm2,%xmm5,%xmm6
+	vaesenclast	%xmm7,%xmm13,%xmm13
+	vpaddb	%xmm2,%xmm6,%xmm7
+	vaesenclast	%xmm3,%xmm14,%xmm14
+	vpaddb	%xmm2,%xmm7,%xmm3
+
+	addq	$0x60,%r10
+	subq	$0x6,%rdx
+	jc	.L6x_done
+
+	vmovups	%xmm9,-96(%rsi)
+	vpxor	%xmm15,%xmm1,%xmm9
+	vmovups	%xmm10,-80(%rsi)
+	vmovdqa	%xmm0,%xmm10
+	vmovups	%xmm11,-64(%rsi)
+	vmovdqa	%xmm5,%xmm11
+	vmovups	%xmm12,-48(%rsi)
+	vmovdqa	%xmm6,%xmm12
+	vmovups	%xmm13,-32(%rsi)
+	vmovdqa	%xmm7,%xmm13
+	vmovups	%xmm14,-16(%rsi)
+	vmovdqa	%xmm3,%xmm14
+	vmovdqu	32+8(%rsp),%xmm7
+	jmp	.Loop6x
+
+.L6x_done:
+	vpxor	16+8(%rsp),%xmm8,%xmm8
+	vpxor	%xmm4,%xmm8,%xmm8
+
+	.byte	0xf3,0xc3
+.size	_aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x
 .globl	aesni_gcm_decrypt
 .hidden aesni_gcm_decrypt
 .type	aesni_gcm_decrypt,@function
+.align	32
 aesni_gcm_decrypt:
-	xorl	%eax,%eax
+	xorq	%r10,%r10
+
+
+
+	cmpq	$0x60,%rdx
+	jb	.Lgcm_dec_abort
+
+	leaq	(%rsp),%rax
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	vzeroupper
+
+	vmovdqu	(%r8),%xmm1
+	addq	$-128,%rsp
+	movl	12(%r8),%ebx
+	leaq	.Lbswap_mask(%rip),%r11
+	leaq	-128(%rcx),%r14
+	movq	$0xf80,%r15
+	vmovdqu	(%r9),%xmm8
+	andq	$-128,%rsp
+	vmovdqu	(%r11),%xmm0
+	leaq	128(%rcx),%rcx
+	leaq	32+32(%r9),%r9
+	movl	240-128(%rcx),%ebp
+	vpshufb	%xmm0,%xmm8,%xmm8
+
+	andq	%r15,%r14
+	andq	%rsp,%r15
+	subq	%r14,%r15
+	jc	.Ldec_no_key_aliasing
+	cmpq	$768,%r15
+	jnc	.Ldec_no_key_aliasing
+	subq	%r15,%rsp
+.Ldec_no_key_aliasing:
+
+	vmovdqu	80(%rdi),%xmm7
+	leaq	(%rdi),%r14
+	vmovdqu	64(%rdi),%xmm4
+
+
+
+
+
+
+
+	leaq	-192(%rdi,%rdx,1),%r15
+
+	vmovdqu	48(%rdi),%xmm5
+	shrq	$4,%rdx
+	xorq	%r10,%r10
+	vmovdqu	32(%rdi),%xmm6
+	vpshufb	%xmm0,%xmm7,%xmm7
+	vmovdqu	16(%rdi),%xmm2
+	vpshufb	%xmm0,%xmm4,%xmm4
+	vmovdqu	(%rdi),%xmm3
+	vpshufb	%xmm0,%xmm5,%xmm5
+	vmovdqu	%xmm4,48(%rsp)
+	vpshufb	%xmm0,%xmm6,%xmm6
+	vmovdqu	%xmm5,64(%rsp)
+	vpshufb	%xmm0,%xmm2,%xmm2
+	vmovdqu	%xmm6,80(%rsp)
+	vpshufb	%xmm0,%xmm3,%xmm3
+	vmovdqu	%xmm2,96(%rsp)
+	vmovdqu	%xmm3,112(%rsp)
+
+	call	_aesni_ctr32_ghash_6x
+
+	vmovups	%xmm9,-96(%rsi)
+	vmovups	%xmm10,-80(%rsi)
+	vmovups	%xmm11,-64(%rsi)
+	vmovups	%xmm12,-48(%rsi)
+	vmovups	%xmm13,-32(%rsi)
+	vmovups	%xmm14,-16(%rsi)
+
+	vpshufb	(%r11),%xmm8,%xmm8
+	vmovdqu	%xmm8,-64(%r9)
+
+	vzeroupper
+	movq	-48(%rax),%r15
+	movq	-40(%rax),%r14
+	movq	-32(%rax),%r13
+	movq	-24(%rax),%r12
+	movq	-16(%rax),%rbp
+	movq	-8(%rax),%rbx
+	leaq	(%rax),%rsp
+.Lgcm_dec_abort:
+	movq	%r10,%rax
 	.byte	0xf3,0xc3
 .size	aesni_gcm_decrypt,.-aesni_gcm_decrypt
+.type	_aesni_ctr32_6x,@function
+.align	32
+_aesni_ctr32_6x:
+	vmovdqu	0-128(%rcx),%xmm4
+	vmovdqu	32(%r11),%xmm2
+	leaq	-1(%rbp),%r13
+	vmovups	16-128(%rcx),%xmm15
+	leaq	32-128(%rcx),%r12
+	vpxor	%xmm4,%xmm1,%xmm9
+	addl	$100663296,%ebx
+	jc	.Lhandle_ctr32_2
+	vpaddb	%xmm2,%xmm1,%xmm10
+	vpaddb	%xmm2,%xmm10,%xmm11
+	vpxor	%xmm4,%xmm10,%xmm10
+	vpaddb	%xmm2,%xmm11,%xmm12
+	vpxor	%xmm4,%xmm11,%xmm11
+	vpaddb	%xmm2,%xmm12,%xmm13
+	vpxor	%xmm4,%xmm12,%xmm12
+	vpaddb	%xmm2,%xmm13,%xmm14
+	vpxor	%xmm4,%xmm13,%xmm13
+	vpaddb	%xmm2,%xmm14,%xmm1
+	vpxor	%xmm4,%xmm14,%xmm14
+	jmp	.Loop_ctr32
+
+.align	16
+.Loop_ctr32:
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vaesenc	%xmm15,%xmm14,%xmm14
+	vmovups	(%r12),%xmm15
+	leaq	16(%r12),%r12
+	decl	%r13d
+	jnz	.Loop_ctr32
+
+	vmovdqu	(%r12),%xmm3
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	0(%rdi),%xmm3,%xmm4
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vpxor	16(%rdi),%xmm3,%xmm5
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vpxor	32(%rdi),%xmm3,%xmm6
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vpxor	48(%rdi),%xmm3,%xmm8
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vpxor	64(%rdi),%xmm3,%xmm2
+	vaesenc	%xmm15,%xmm14,%xmm14
+	vpxor	80(%rdi),%xmm3,%xmm3
+	leaq	96(%rdi),%rdi
+
+	vaesenclast	%xmm4,%xmm9,%xmm9
+	vaesenclast	%xmm5,%xmm10,%xmm10
+	vaesenclast	%xmm6,%xmm11,%xmm11
+	vaesenclast	%xmm8,%xmm12,%xmm12
+	vaesenclast	%xmm2,%xmm13,%xmm13
+	vaesenclast	%xmm3,%xmm14,%xmm14
+	vmovups	%xmm9,0(%rsi)
+	vmovups	%xmm10,16(%rsi)
+	vmovups	%xmm11,32(%rsi)
+	vmovups	%xmm12,48(%rsi)
+	vmovups	%xmm13,64(%rsi)
+	vmovups	%xmm14,80(%rsi)
+	leaq	96(%rsi),%rsi
+
+	.byte	0xf3,0xc3
+.align	32
+.Lhandle_ctr32_2:
+	vpshufb	%xmm0,%xmm1,%xmm6
+	vmovdqu	48(%r11),%xmm5
+	vpaddd	64(%r11),%xmm6,%xmm10
+	vpaddd	%xmm5,%xmm6,%xmm11
+	vpaddd	%xmm5,%xmm10,%xmm12
+	vpshufb	%xmm0,%xmm10,%xmm10
+	vpaddd	%xmm5,%xmm11,%xmm13
+	vpshufb	%xmm0,%xmm11,%xmm11
+	vpxor	%xmm4,%xmm10,%xmm10
+	vpaddd	%xmm5,%xmm12,%xmm14
+	vpshufb	%xmm0,%xmm12,%xmm12
+	vpxor	%xmm4,%xmm11,%xmm11
+	vpaddd	%xmm5,%xmm13,%xmm1
+	vpshufb	%xmm0,%xmm13,%xmm13
+	vpxor	%xmm4,%xmm12,%xmm12
+	vpshufb	%xmm0,%xmm14,%xmm14
+	vpxor	%xmm4,%xmm13,%xmm13
+	vpshufb	%xmm0,%xmm1,%xmm1
+	vpxor	%xmm4,%xmm14,%xmm14
+	jmp	.Loop_ctr32
+.size	_aesni_ctr32_6x,.-_aesni_ctr32_6x
+
+.globl	aesni_gcm_encrypt
+.hidden aesni_gcm_encrypt
+.type	aesni_gcm_encrypt,@function
+.align	32
+aesni_gcm_encrypt:
+	xorq	%r10,%r10
+
+
+
+
+	cmpq	$288,%rdx
+	jb	.Lgcm_enc_abort
+
+	leaq	(%rsp),%rax
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	vzeroupper
+
+	vmovdqu	(%r8),%xmm1
+	addq	$-128,%rsp
+	movl	12(%r8),%ebx
+	leaq	.Lbswap_mask(%rip),%r11
+	leaq	-128(%rcx),%r14
+	movq	$0xf80,%r15
+	leaq	128(%rcx),%rcx
+	vmovdqu	(%r11),%xmm0
+	andq	$-128,%rsp
+	movl	240-128(%rcx),%ebp
+
+	andq	%r15,%r14
+	andq	%rsp,%r15
+	subq	%r14,%r15
+	jc	.Lenc_no_key_aliasing
+	cmpq	$768,%r15
+	jnc	.Lenc_no_key_aliasing
+	subq	%r15,%rsp
+.Lenc_no_key_aliasing:
+
+	leaq	(%rsi),%r14
+
+
+
+
+
+
+
+
+	leaq	-192(%rsi,%rdx,1),%r15
+
+	shrq	$4,%rdx
+
+	call	_aesni_ctr32_6x
+	vpshufb	%xmm0,%xmm9,%xmm8
+	vpshufb	%xmm0,%xmm10,%xmm2
+	vmovdqu	%xmm8,112(%rsp)
+	vpshufb	%xmm0,%xmm11,%xmm4
+	vmovdqu	%xmm2,96(%rsp)
+	vpshufb	%xmm0,%xmm12,%xmm5
+	vmovdqu	%xmm4,80(%rsp)
+	vpshufb	%xmm0,%xmm13,%xmm6
+	vmovdqu	%xmm5,64(%rsp)
+	vpshufb	%xmm0,%xmm14,%xmm7
+	vmovdqu	%xmm6,48(%rsp)
+
+	call	_aesni_ctr32_6x
+
+	vmovdqu	(%r9),%xmm8
+	leaq	32+32(%r9),%r9
+	subq	$12,%rdx
+	movq	$192,%r10
+	vpshufb	%xmm0,%xmm8,%xmm8
+
+	call	_aesni_ctr32_ghash_6x
+	vmovdqu	32(%rsp),%xmm7
+	vmovdqu	(%r11),%xmm0
+	vmovdqu	0-32(%r9),%xmm3
+	vpunpckhqdq	%xmm7,%xmm7,%xmm1
+	vmovdqu	32-32(%r9),%xmm15
+	vmovups	%xmm9,-96(%rsi)
+	vpshufb	%xmm0,%xmm9,%xmm9
+	vpxor	%xmm7,%xmm1,%xmm1
+	vmovups	%xmm10,-80(%rsi)
+	vpshufb	%xmm0,%xmm10,%xmm10
+	vmovups	%xmm11,-64(%rsi)
+	vpshufb	%xmm0,%xmm11,%xmm11
+	vmovups	%xmm12,-48(%rsi)
+	vpshufb	%xmm0,%xmm12,%xmm12
+	vmovups	%xmm13,-32(%rsi)
+	vpshufb	%xmm0,%xmm13,%xmm13
+	vmovups	%xmm14,-16(%rsi)
+	vpshufb	%xmm0,%xmm14,%xmm14
+	vmovdqu	%xmm9,16(%rsp)
+	vmovdqu	48(%rsp),%xmm6
+	vmovdqu	16-32(%r9),%xmm0
+	vpunpckhqdq	%xmm6,%xmm6,%xmm2
+	vpclmulqdq	$0x00,%xmm3,%xmm7,%xmm5
+	vpxor	%xmm6,%xmm2,%xmm2
+	vpclmulqdq	$0x11,%xmm3,%xmm7,%xmm7
+	vpclmulqdq	$0x00,%xmm15,%xmm1,%xmm1
+
+	vmovdqu	64(%rsp),%xmm9
+	vpclmulqdq	$0x00,%xmm0,%xmm6,%xmm4
+	vmovdqu	48-32(%r9),%xmm3
+	vpxor	%xmm5,%xmm4,%xmm4
+	vpunpckhqdq	%xmm9,%xmm9,%xmm5
+	vpclmulqdq	$0x11,%xmm0,%xmm6,%xmm6
+	vpxor	%xmm9,%xmm5,%xmm5
+	vpxor	%xmm7,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm15,%xmm2,%xmm2
+	vmovdqu	80-32(%r9),%xmm15
+	vpxor	%xmm1,%xmm2,%xmm2
+
+	vmovdqu	80(%rsp),%xmm1
+	vpclmulqdq	$0x00,%xmm3,%xmm9,%xmm7
+	vmovdqu	64-32(%r9),%xmm0
+	vpxor	%xmm4,%xmm7,%xmm7
+	vpunpckhqdq	%xmm1,%xmm1,%xmm4
+	vpclmulqdq	$0x11,%xmm3,%xmm9,%xmm9
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpxor	%xmm6,%xmm9,%xmm9
+	vpclmulqdq	$0x00,%xmm15,%xmm5,%xmm5
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vmovdqu	96(%rsp),%xmm2
+	vpclmulqdq	$0x00,%xmm0,%xmm1,%xmm6
+	vmovdqu	96-32(%r9),%xmm3
+	vpxor	%xmm7,%xmm6,%xmm6
+	vpunpckhqdq	%xmm2,%xmm2,%xmm7
+	vpclmulqdq	$0x11,%xmm0,%xmm1,%xmm1
+	vpxor	%xmm2,%xmm7,%xmm7
+	vpxor	%xmm9,%xmm1,%xmm1
+	vpclmulqdq	$0x10,%xmm15,%xmm4,%xmm4
+	vmovdqu	128-32(%r9),%xmm15
+	vpxor	%xmm5,%xmm4,%xmm4
+
+	vpxor	112(%rsp),%xmm8,%xmm8
+	vpclmulqdq	$0x00,%xmm3,%xmm2,%xmm5
+	vmovdqu	112-32(%r9),%xmm0
+	vpunpckhqdq	%xmm8,%xmm8,%xmm9
+	vpxor	%xmm6,%xmm5,%xmm5
+	vpclmulqdq	$0x11,%xmm3,%xmm2,%xmm2
+	vpxor	%xmm8,%xmm9,%xmm9
+	vpxor	%xmm1,%xmm2,%xmm2
+	vpclmulqdq	$0x00,%xmm15,%xmm7,%xmm7
+	vpxor	%xmm4,%xmm7,%xmm4
+
+	vpclmulqdq	$0x00,%xmm0,%xmm8,%xmm6
+	vmovdqu	0-32(%r9),%xmm3
+	vpunpckhqdq	%xmm14,%xmm14,%xmm1
+	vpclmulqdq	$0x11,%xmm0,%xmm8,%xmm8
+	vpxor	%xmm14,%xmm1,%xmm1
+	vpxor	%xmm5,%xmm6,%xmm5
+	vpclmulqdq	$0x10,%xmm15,%xmm9,%xmm9
+	vmovdqu	32-32(%r9),%xmm15
+	vpxor	%xmm2,%xmm8,%xmm7
+	vpxor	%xmm4,%xmm9,%xmm6
+
+	vmovdqu	16-32(%r9),%xmm0
+	vpxor	%xmm5,%xmm7,%xmm9
+	vpclmulqdq	$0x00,%xmm3,%xmm14,%xmm4
+	vpxor	%xmm9,%xmm6,%xmm6
+	vpunpckhqdq	%xmm13,%xmm13,%xmm2
+	vpclmulqdq	$0x11,%xmm3,%xmm14,%xmm14
+	vpxor	%xmm13,%xmm2,%xmm2
+	vpslldq	$8,%xmm6,%xmm9
+	vpclmulqdq	$0x00,%xmm15,%xmm1,%xmm1
+	vpxor	%xmm9,%xmm5,%xmm8
+	vpsrldq	$8,%xmm6,%xmm6
+	vpxor	%xmm6,%xmm7,%xmm7
+
+	vpclmulqdq	$0x00,%xmm0,%xmm13,%xmm5
+	vmovdqu	48-32(%r9),%xmm3
+	vpxor	%xmm4,%xmm5,%xmm5
+	vpunpckhqdq	%xmm12,%xmm12,%xmm9
+	vpclmulqdq	$0x11,%xmm0,%xmm13,%xmm13
+	vpxor	%xmm12,%xmm9,%xmm9
+	vpxor	%xmm14,%xmm13,%xmm13
+	vpalignr	$8,%xmm8,%xmm8,%xmm14
+	vpclmulqdq	$0x10,%xmm15,%xmm2,%xmm2
+	vmovdqu	80-32(%r9),%xmm15
+	vpxor	%xmm1,%xmm2,%xmm2
+
+	vpclmulqdq	$0x00,%xmm3,%xmm12,%xmm4
+	vmovdqu	64-32(%r9),%xmm0
+	vpxor	%xmm5,%xmm4,%xmm4
+	vpunpckhqdq	%xmm11,%xmm11,%xmm1
+	vpclmulqdq	$0x11,%xmm3,%xmm12,%xmm12
+	vpxor	%xmm11,%xmm1,%xmm1
+	vpxor	%xmm13,%xmm12,%xmm12
+	vxorps	16(%rsp),%xmm7,%xmm7
+	vpclmulqdq	$0x00,%xmm15,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm9,%xmm9
+
+	vpclmulqdq	$0x10,16(%r11),%xmm8,%xmm8
+	vxorps	%xmm14,%xmm8,%xmm8
+
+	vpclmulqdq	$0x00,%xmm0,%xmm11,%xmm5
+	vmovdqu	96-32(%r9),%xmm3
+	vpxor	%xmm4,%xmm5,%xmm5
+	vpunpckhqdq	%xmm10,%xmm10,%xmm2
+	vpclmulqdq	$0x11,%xmm0,%xmm11,%xmm11
+	vpxor	%xmm10,%xmm2,%xmm2
+	vpalignr	$8,%xmm8,%xmm8,%xmm14
+	vpxor	%xmm12,%xmm11,%xmm11
+	vpclmulqdq	$0x10,%xmm15,%xmm1,%xmm1
+	vmovdqu	128-32(%r9),%xmm15
+	vpxor	%xmm9,%xmm1,%xmm1
+
+	vxorps	%xmm7,%xmm14,%xmm14
+	vpclmulqdq	$0x10,16(%r11),%xmm8,%xmm8
+	vxorps	%xmm14,%xmm8,%xmm8
+
+	vpclmulqdq	$0x00,%xmm3,%xmm10,%xmm4
+	vmovdqu	112-32(%r9),%xmm0
+	vpxor	%xmm5,%xmm4,%xmm4
+	vpunpckhqdq	%xmm8,%xmm8,%xmm9
+	vpclmulqdq	$0x11,%xmm3,%xmm10,%xmm10
+	vpxor	%xmm8,%xmm9,%xmm9
+	vpxor	%xmm11,%xmm10,%xmm10
+	vpclmulqdq	$0x00,%xmm15,%xmm2,%xmm2
+	vpxor	%xmm1,%xmm2,%xmm2
+
+	vpclmulqdq	$0x00,%xmm0,%xmm8,%xmm5
+	vpclmulqdq	$0x11,%xmm0,%xmm8,%xmm7
+	vpxor	%xmm4,%xmm5,%xmm5
+	vpclmulqdq	$0x10,%xmm15,%xmm9,%xmm6
+	vpxor	%xmm10,%xmm7,%xmm7
+	vpxor	%xmm2,%xmm6,%xmm6
+
+	vpxor	%xmm5,%xmm7,%xmm4
+	vpxor	%xmm4,%xmm6,%xmm6
+	vpslldq	$8,%xmm6,%xmm1
+	vmovdqu	16(%r11),%xmm3
+	vpsrldq	$8,%xmm6,%xmm6
+	vpxor	%xmm1,%xmm5,%xmm8
+	vpxor	%xmm6,%xmm7,%xmm7
+
+	vpalignr	$8,%xmm8,%xmm8,%xmm2
+	vpclmulqdq	$0x10,%xmm3,%xmm8,%xmm8
+	vpxor	%xmm2,%xmm8,%xmm8
+
+	vpalignr	$8,%xmm8,%xmm8,%xmm2
+	vpclmulqdq	$0x10,%xmm3,%xmm8,%xmm8
+	vpxor	%xmm7,%xmm2,%xmm2
+	vpxor	%xmm2,%xmm8,%xmm8
+	vpshufb	(%r11),%xmm8,%xmm8
+	vmovdqu	%xmm8,-64(%r9)
+
+	vzeroupper
+	movq	-48(%rax),%r15
+	movq	-40(%rax),%r14
+	movq	-32(%rax),%r13
+	movq	-24(%rax),%r12
+	movq	-16(%rax),%rbp
+	movq	-8(%rax),%rbx
+	leaq	(%rax),%rsp
+.Lgcm_enc_abort:
+	movq	%r10,%rax
+	.byte	0xf3,0xc3
+.size	aesni_gcm_encrypt,.-aesni_gcm_encrypt
+.align	64
+.Lbswap_mask:
+.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+.Lpoly:
+.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
+.Lone_msb:
+.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
+.Ltwo_lsb:
+.byte	2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.Lone_lsb:
+.byte	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.byte	65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	64
 #endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S
index b47bdc9..b6ca45ff 100644
--- a/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S
@@ -1257,7 +1257,108 @@
 .type	gcm_init_avx,@function
 .align	32
 gcm_init_avx:
-	jmp	.L_init_clmul
+	vzeroupper
+
+	vmovdqu	(%rsi),%xmm2
+	vpshufd	$78,%xmm2,%xmm2
+
+
+	vpshufd	$255,%xmm2,%xmm4
+	vpsrlq	$63,%xmm2,%xmm3
+	vpsllq	$1,%xmm2,%xmm2
+	vpxor	%xmm5,%xmm5,%xmm5
+	vpcmpgtd	%xmm4,%xmm5,%xmm5
+	vpslldq	$8,%xmm3,%xmm3
+	vpor	%xmm3,%xmm2,%xmm2
+
+
+	vpand	.L0x1c2_polynomial(%rip),%xmm5,%xmm5
+	vpxor	%xmm5,%xmm2,%xmm2
+
+	vpunpckhqdq	%xmm2,%xmm2,%xmm6
+	vmovdqa	%xmm2,%xmm0
+	vpxor	%xmm2,%xmm6,%xmm6
+	movq	$4,%r10
+	jmp	.Linit_start_avx
+.align	32
+.Linit_loop_avx:
+	vpalignr	$8,%xmm3,%xmm4,%xmm5
+	vmovdqu	%xmm5,-16(%rdi)
+	vpunpckhqdq	%xmm0,%xmm0,%xmm3
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3
+	vpxor	%xmm0,%xmm1,%xmm4
+	vpxor	%xmm4,%xmm3,%xmm3
+
+	vpslldq	$8,%xmm3,%xmm4
+	vpsrldq	$8,%xmm3,%xmm3
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpxor	%xmm3,%xmm1,%xmm1
+	vpsllq	$57,%xmm0,%xmm3
+	vpsllq	$62,%xmm0,%xmm4
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpsllq	$63,%xmm0,%xmm3
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpslldq	$8,%xmm4,%xmm3
+	vpsrldq	$8,%xmm4,%xmm4
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpxor	%xmm4,%xmm1,%xmm1
+
+	vpsrlq	$1,%xmm0,%xmm4
+	vpxor	%xmm0,%xmm1,%xmm1
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$5,%xmm4,%xmm4
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$1,%xmm0,%xmm0
+	vpxor	%xmm1,%xmm0,%xmm0
+.Linit_start_avx:
+	vmovdqa	%xmm0,%xmm5
+	vpunpckhqdq	%xmm0,%xmm0,%xmm3
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3
+	vpxor	%xmm0,%xmm1,%xmm4
+	vpxor	%xmm4,%xmm3,%xmm3
+
+	vpslldq	$8,%xmm3,%xmm4
+	vpsrldq	$8,%xmm3,%xmm3
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpxor	%xmm3,%xmm1,%xmm1
+	vpsllq	$57,%xmm0,%xmm3
+	vpsllq	$62,%xmm0,%xmm4
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpsllq	$63,%xmm0,%xmm3
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpslldq	$8,%xmm4,%xmm3
+	vpsrldq	$8,%xmm4,%xmm4
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpxor	%xmm4,%xmm1,%xmm1
+
+	vpsrlq	$1,%xmm0,%xmm4
+	vpxor	%xmm0,%xmm1,%xmm1
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$5,%xmm4,%xmm4
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$1,%xmm0,%xmm0
+	vpxor	%xmm1,%xmm0,%xmm0
+	vpshufd	$78,%xmm5,%xmm3
+	vpshufd	$78,%xmm0,%xmm4
+	vpxor	%xmm5,%xmm3,%xmm3
+	vmovdqu	%xmm5,0(%rdi)
+	vpxor	%xmm0,%xmm4,%xmm4
+	vmovdqu	%xmm0,16(%rdi)
+	leaq	48(%rdi),%rdi
+	subq	$1,%r10
+	jnz	.Linit_loop_avx
+
+	vpalignr	$8,%xmm4,%xmm3,%xmm5
+	vmovdqu	%xmm5,-16(%rdi)
+
+	vzeroupper
+	.byte	0xf3,0xc3
 .size	gcm_init_avx,.-gcm_init_avx
 .globl	gcm_gmult_avx
 .hidden gcm_gmult_avx
@@ -1271,7 +1372,377 @@
 .type	gcm_ghash_avx,@function
 .align	32
 gcm_ghash_avx:
-	jmp	.L_ghash_clmul
+	vzeroupper
+
+	vmovdqu	(%rdi),%xmm10
+	leaq	.L0x1c2_polynomial(%rip),%r10
+	leaq	64(%rsi),%rsi
+	vmovdqu	.Lbswap_mask(%rip),%xmm13
+	vpshufb	%xmm13,%xmm10,%xmm10
+	cmpq	$0x80,%rcx
+	jb	.Lshort_avx
+	subq	$0x80,%rcx
+
+	vmovdqu	112(%rdx),%xmm14
+	vmovdqu	0-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vmovdqu	32-64(%rsi),%xmm7
+
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vmovdqu	96(%rdx),%xmm15
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm14,%xmm9,%xmm9
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	16-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vmovdqu	80(%rdx),%xmm14
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm15,%xmm8,%xmm8
+
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	48-64(%rsi),%xmm6
+	vpxor	%xmm14,%xmm9,%xmm9
+	vmovdqu	64(%rdx),%xmm15
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	80-64(%rsi),%xmm7
+
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	64-64(%rsi),%xmm6
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm15,%xmm8,%xmm8
+
+	vmovdqu	48(%rdx),%xmm14
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpxor	%xmm4,%xmm1,%xmm1
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	96-64(%rsi),%xmm6
+	vpxor	%xmm5,%xmm2,%xmm2
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	128-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+
+	vmovdqu	32(%rdx),%xmm15
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	112-64(%rsi),%xmm6
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm15,%xmm8,%xmm8
+
+	vmovdqu	16(%rdx),%xmm14
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpxor	%xmm4,%xmm1,%xmm1
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	144-64(%rsi),%xmm6
+	vpxor	%xmm5,%xmm2,%xmm2
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	176-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+
+	vmovdqu	(%rdx),%xmm15
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	160-64(%rsi),%xmm6
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x10,%xmm7,%xmm9,%xmm2
+
+	leaq	128(%rdx),%rdx
+	cmpq	$0x80,%rcx
+	jb	.Ltail_avx
+
+	vpxor	%xmm10,%xmm15,%xmm15
+	subq	$0x80,%rcx
+	jmp	.Loop8x_avx
+
+.align	32
+.Loop8x_avx:
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vmovdqu	112(%rdx),%xmm14
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpxor	%xmm15,%xmm8,%xmm8
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm10
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm11
+	vmovdqu	0-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm12
+	vmovdqu	32-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+
+	vmovdqu	96(%rdx),%xmm15
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm3,%xmm10,%xmm10
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vxorps	%xmm4,%xmm11,%xmm11
+	vmovdqu	16-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm5,%xmm12,%xmm12
+	vxorps	%xmm15,%xmm8,%xmm8
+
+	vmovdqu	80(%rdx),%xmm14
+	vpxor	%xmm10,%xmm12,%xmm12
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpxor	%xmm11,%xmm12,%xmm12
+	vpslldq	$8,%xmm12,%xmm9
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vpsrldq	$8,%xmm12,%xmm12
+	vpxor	%xmm9,%xmm10,%xmm10
+	vmovdqu	48-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vxorps	%xmm12,%xmm11,%xmm11
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	80-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vmovdqu	64(%rdx),%xmm15
+	vpalignr	$8,%xmm10,%xmm10,%xmm12
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	64-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm4,%xmm1,%xmm1
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vxorps	%xmm15,%xmm8,%xmm8
+	vpxor	%xmm5,%xmm2,%xmm2
+
+	vmovdqu	48(%rdx),%xmm14
+	vpclmulqdq	$0x10,(%r10),%xmm10,%xmm10
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	96-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	128-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vmovdqu	32(%rdx),%xmm15
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	112-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm4,%xmm1,%xmm1
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm15,%xmm8,%xmm8
+	vpxor	%xmm5,%xmm2,%xmm2
+	vxorps	%xmm12,%xmm10,%xmm10
+
+	vmovdqu	16(%rdx),%xmm14
+	vpalignr	$8,%xmm10,%xmm10,%xmm12
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	144-64(%rsi),%xmm6
+	vpclmulqdq	$0x10,(%r10),%xmm10,%xmm10
+	vxorps	%xmm11,%xmm12,%xmm12
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	176-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vmovdqu	(%rdx),%xmm15
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	160-64(%rsi),%xmm6
+	vpxor	%xmm12,%xmm15,%xmm15
+	vpclmulqdq	$0x10,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm10,%xmm15,%xmm15
+
+	leaq	128(%rdx),%rdx
+	subq	$0x80,%rcx
+	jnc	.Loop8x_avx
+
+	addq	$0x80,%rcx
+	jmp	.Ltail_no_xor_avx
+
+.align	32
+.Lshort_avx:
+	vmovdqu	-16(%rdx,%rcx,1),%xmm14
+	leaq	(%rdx,%rcx,1),%rdx
+	vmovdqu	0-64(%rsi),%xmm6
+	vmovdqu	32-64(%rsi),%xmm7
+	vpshufb	%xmm13,%xmm14,%xmm15
+
+	vmovdqa	%xmm0,%xmm3
+	vmovdqa	%xmm1,%xmm4
+	vmovdqa	%xmm2,%xmm5
+	subq	$0x10,%rcx
+	jz	.Ltail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-32(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	16-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vpsrldq	$8,%xmm7,%xmm7
+	subq	$0x10,%rcx
+	jz	.Ltail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-48(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	48-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vmovdqu	80-64(%rsi),%xmm7
+	subq	$0x10,%rcx
+	jz	.Ltail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-64(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	64-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vpsrldq	$8,%xmm7,%xmm7
+	subq	$0x10,%rcx
+	jz	.Ltail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-80(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	96-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vmovdqu	128-64(%rsi),%xmm7
+	subq	$0x10,%rcx
+	jz	.Ltail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-96(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	112-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vpsrldq	$8,%xmm7,%xmm7
+	subq	$0x10,%rcx
+	jz	.Ltail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-112(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	144-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vmovq	184-64(%rsi),%xmm7
+	subq	$0x10,%rcx
+	jmp	.Ltail_avx
+
+.align	32
+.Ltail_avx:
+	vpxor	%xmm10,%xmm15,%xmm15
+.Ltail_no_xor_avx:
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+
+	vmovdqu	(%r10),%xmm12
+
+	vpxor	%xmm0,%xmm3,%xmm10
+	vpxor	%xmm1,%xmm4,%xmm11
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vpxor	%xmm10,%xmm5,%xmm5
+	vpxor	%xmm11,%xmm5,%xmm5
+	vpslldq	$8,%xmm5,%xmm9
+	vpsrldq	$8,%xmm5,%xmm5
+	vpxor	%xmm9,%xmm10,%xmm10
+	vpxor	%xmm5,%xmm11,%xmm11
+
+	vpclmulqdq	$0x10,%xmm12,%xmm10,%xmm9
+	vpalignr	$8,%xmm10,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm10,%xmm10
+
+	vpclmulqdq	$0x10,%xmm12,%xmm10,%xmm9
+	vpalignr	$8,%xmm10,%xmm10,%xmm10
+	vpxor	%xmm11,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm10,%xmm10
+
+	cmpq	$0,%rcx
+	jne	.Lshort_avx
+
+	vpshufb	%xmm13,%xmm10,%xmm10
+	vmovdqu	%xmm10,(%rdi)
+	vzeroupper
+	.byte	0xf3,0xc3
 .size	gcm_ghash_avx,.-gcm_ghash_avx
 .align	64
 .Lbswap_mask:
diff --git a/third_party/boringssl/mac-x86/crypto/modes/ghash-x86.S b/third_party/boringssl/mac-x86/crypto/modes/ghash-x86.S
index 8693b82a1..8ae2183 100644
--- a/third_party/boringssl/mac-x86/crypto/modes/ghash-x86.S
+++ b/third_party/boringssl/mac-x86/crypto/modes/ghash-x86.S
@@ -1,207 +1,6 @@
 #if defined(__i386__)
 .file	"ghash-x86.S"
 .text
-.globl	_gcm_gmult_4bit_x86
-.private_extern	_gcm_gmult_4bit_x86
-.align	4
-_gcm_gmult_4bit_x86:
-L_gcm_gmult_4bit_x86_begin:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	subl	$84,%esp
-	movl	104(%esp),%edi
-	movl	108(%esp),%esi
-	movl	(%edi),%ebp
-	movl	4(%edi),%edx
-	movl	8(%edi),%ecx
-	movl	12(%edi),%ebx
-	movl	$0,16(%esp)
-	movl	$471859200,20(%esp)
-	movl	$943718400,24(%esp)
-	movl	$610271232,28(%esp)
-	movl	$1887436800,32(%esp)
-	movl	$1822425088,36(%esp)
-	movl	$1220542464,40(%esp)
-	movl	$1423966208,44(%esp)
-	movl	$3774873600,48(%esp)
-	movl	$4246732800,52(%esp)
-	movl	$3644850176,56(%esp)
-	movl	$3311403008,60(%esp)
-	movl	$2441084928,64(%esp)
-	movl	$2376073216,68(%esp)
-	movl	$2847932416,72(%esp)
-	movl	$3051356160,76(%esp)
-	movl	%ebp,(%esp)
-	movl	%edx,4(%esp)
-	movl	%ecx,8(%esp)
-	movl	%ebx,12(%esp)
-	shrl	$20,%ebx
-	andl	$240,%ebx
-	movl	4(%esi,%ebx,1),%ebp
-	movl	(%esi,%ebx,1),%edx
-	movl	12(%esi,%ebx,1),%ecx
-	movl	8(%esi,%ebx,1),%ebx
-	xorl	%eax,%eax
-	movl	$15,%edi
-	jmp	L000x86_loop
-.align	4,0x90
-L000x86_loop:
-	movb	%bl,%al
-	shrdl	$4,%ecx,%ebx
-	andb	$15,%al
-	shrdl	$4,%edx,%ecx
-	shrdl	$4,%ebp,%edx
-	shrl	$4,%ebp
-	xorl	16(%esp,%eax,4),%ebp
-	movb	(%esp,%edi,1),%al
-	andb	$240,%al
-	xorl	8(%esi,%eax,1),%ebx
-	xorl	12(%esi,%eax,1),%ecx
-	xorl	(%esi,%eax,1),%edx
-	xorl	4(%esi,%eax,1),%ebp
-	decl	%edi
-	js	L001x86_break
-	movb	%bl,%al
-	shrdl	$4,%ecx,%ebx
-	andb	$15,%al
-	shrdl	$4,%edx,%ecx
-	shrdl	$4,%ebp,%edx
-	shrl	$4,%ebp
-	xorl	16(%esp,%eax,4),%ebp
-	movb	(%esp,%edi,1),%al
-	shlb	$4,%al
-	xorl	8(%esi,%eax,1),%ebx
-	xorl	12(%esi,%eax,1),%ecx
-	xorl	(%esi,%eax,1),%edx
-	xorl	4(%esi,%eax,1),%ebp
-	jmp	L000x86_loop
-.align	4,0x90
-L001x86_break:
-	bswap	%ebx
-	bswap	%ecx
-	bswap	%edx
-	bswap	%ebp
-	movl	104(%esp),%edi
-	movl	%ebx,12(%edi)
-	movl	%ecx,8(%edi)
-	movl	%edx,4(%edi)
-	movl	%ebp,(%edi)
-	addl	$84,%esp
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.globl	_gcm_ghash_4bit_x86
-.private_extern	_gcm_ghash_4bit_x86
-.align	4
-_gcm_ghash_4bit_x86:
-L_gcm_ghash_4bit_x86_begin:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	subl	$84,%esp
-	movl	104(%esp),%ebx
-	movl	108(%esp),%esi
-	movl	112(%esp),%edi
-	movl	116(%esp),%ecx
-	addl	%edi,%ecx
-	movl	%ecx,116(%esp)
-	movl	(%ebx),%ebp
-	movl	4(%ebx),%edx
-	movl	8(%ebx),%ecx
-	movl	12(%ebx),%ebx
-	movl	$0,16(%esp)
-	movl	$471859200,20(%esp)
-	movl	$943718400,24(%esp)
-	movl	$610271232,28(%esp)
-	movl	$1887436800,32(%esp)
-	movl	$1822425088,36(%esp)
-	movl	$1220542464,40(%esp)
-	movl	$1423966208,44(%esp)
-	movl	$3774873600,48(%esp)
-	movl	$4246732800,52(%esp)
-	movl	$3644850176,56(%esp)
-	movl	$3311403008,60(%esp)
-	movl	$2441084928,64(%esp)
-	movl	$2376073216,68(%esp)
-	movl	$2847932416,72(%esp)
-	movl	$3051356160,76(%esp)
-.align	4,0x90
-L002x86_outer_loop:
-	xorl	12(%edi),%ebx
-	xorl	8(%edi),%ecx
-	xorl	4(%edi),%edx
-	xorl	(%edi),%ebp
-	movl	%ebx,12(%esp)
-	movl	%ecx,8(%esp)
-	movl	%edx,4(%esp)
-	movl	%ebp,(%esp)
-	shrl	$20,%ebx
-	andl	$240,%ebx
-	movl	4(%esi,%ebx,1),%ebp
-	movl	(%esi,%ebx,1),%edx
-	movl	12(%esi,%ebx,1),%ecx
-	movl	8(%esi,%ebx,1),%ebx
-	xorl	%eax,%eax
-	movl	$15,%edi
-	jmp	L003x86_loop
-.align	4,0x90
-L003x86_loop:
-	movb	%bl,%al
-	shrdl	$4,%ecx,%ebx
-	andb	$15,%al
-	shrdl	$4,%edx,%ecx
-	shrdl	$4,%ebp,%edx
-	shrl	$4,%ebp
-	xorl	16(%esp,%eax,4),%ebp
-	movb	(%esp,%edi,1),%al
-	andb	$240,%al
-	xorl	8(%esi,%eax,1),%ebx
-	xorl	12(%esi,%eax,1),%ecx
-	xorl	(%esi,%eax,1),%edx
-	xorl	4(%esi,%eax,1),%ebp
-	decl	%edi
-	js	L004x86_break
-	movb	%bl,%al
-	shrdl	$4,%ecx,%ebx
-	andb	$15,%al
-	shrdl	$4,%edx,%ecx
-	shrdl	$4,%ebp,%edx
-	shrl	$4,%ebp
-	xorl	16(%esp,%eax,4),%ebp
-	movb	(%esp,%edi,1),%al
-	shlb	$4,%al
-	xorl	8(%esi,%eax,1),%ebx
-	xorl	12(%esi,%eax,1),%ecx
-	xorl	(%esi,%eax,1),%edx
-	xorl	4(%esi,%eax,1),%ebp
-	jmp	L003x86_loop
-.align	4,0x90
-L004x86_break:
-	bswap	%ebx
-	bswap	%ecx
-	bswap	%edx
-	bswap	%ebp
-	movl	112(%esp),%edi
-	leal	16(%edi),%edi
-	cmpl	116(%esp),%edi
-	movl	%edi,112(%esp)
-	jb	L002x86_outer_loop
-	movl	104(%esp),%edi
-	movl	%ebx,12(%edi)
-	movl	%ecx,8(%edi)
-	movl	%edx,4(%edi)
-	movl	%ebp,(%edi)
-	addl	$84,%esp
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
 .globl	_gcm_gmult_4bit_mmx
 .private_extern	_gcm_gmult_4bit_mmx
 .align	4
@@ -213,10 +12,10 @@
 	pushl	%edi
 	movl	20(%esp),%edi
 	movl	24(%esp),%esi
-	call	L005pic_point
-L005pic_point:
+	call	L000pic_point
+L000pic_point:
 	popl	%eax
-	leal	Lrem_4bit-L005pic_point(%eax),%eax
+	leal	Lrem_4bit-L000pic_point(%eax),%eax
 	movzbl	15(%edi),%ebx
 	xorl	%ecx,%ecx
 	movl	%ebx,%edx
@@ -227,9 +26,9 @@
 	movq	8(%esi,%ecx,1),%mm0
 	movq	(%esi,%ecx,1),%mm1
 	movd	%mm0,%ebx
-	jmp	L006mmx_loop
+	jmp	L001mmx_loop
 .align	4,0x90
-L006mmx_loop:
+L001mmx_loop:
 	psrlq	$4,%mm0
 	andl	$15,%ebx
 	movq	%mm1,%mm2
@@ -243,7 +42,7 @@
 	pxor	(%esi,%edx,1),%mm1
 	movl	%ecx,%edx
 	pxor	%mm2,%mm0
-	js	L007mmx_break
+	js	L002mmx_break
 	shlb	$4,%cl
 	andl	$15,%ebx
 	psrlq	$4,%mm0
@@ -256,9 +55,9 @@
 	movd	%mm0,%ebx
 	pxor	(%esi,%ecx,1),%mm1
 	pxor	%mm2,%mm0
-	jmp	L006mmx_loop
+	jmp	L001mmx_loop
 .align	4,0x90
-L007mmx_break:
+L002mmx_break:
 	shlb	$4,%cl
 	andl	$15,%ebx
 	psrlq	$4,%mm0
@@ -314,10 +113,10 @@
 	movl	28(%esp),%ecx
 	movl	32(%esp),%edx
 	movl	%esp,%ebp
-	call	L008pic_point
-L008pic_point:
+	call	L003pic_point
+L003pic_point:
 	popl	%esi
-	leal	Lrem_8bit-L008pic_point(%esi),%esi
+	leal	Lrem_8bit-L003pic_point(%esi),%esi
 	subl	$544,%esp
 	andl	$-64,%esp
 	subl	$16,%esp
@@ -556,7 +355,7 @@
 	movl	8(%eax),%ebx
 	movl	12(%eax),%edx
 .align	4,0x90
-L009outer:
+L004outer:
 	xorl	12(%ecx),%edx
 	xorl	8(%ecx),%ebx
 	pxor	(%ecx),%mm6
@@ -891,7 +690,7 @@
 	pshufw	$27,%mm6,%mm6
 	bswap	%ebx
 	cmpl	552(%esp),%ecx
-	jne	L009outer
+	jne	L004outer
 	movl	544(%esp),%eax
 	movl	%edx,12(%eax)
 	movl	%ebx,8(%eax)
@@ -910,10 +709,10 @@
 L_gcm_init_clmul_begin:
 	movl	4(%esp),%edx
 	movl	8(%esp),%eax
-	call	L010pic
-L010pic:
+	call	L005pic
+L005pic:
 	popl	%ecx
-	leal	Lbswap-L010pic(%ecx),%ecx
+	leal	Lbswap-L005pic(%ecx),%ecx
 	movdqu	(%eax),%xmm2
 	pshufd	$78,%xmm2,%xmm2
 	pshufd	$255,%xmm2,%xmm4
@@ -978,10 +777,10 @@
 L_gcm_gmult_clmul_begin:
 	movl	4(%esp),%eax
 	movl	8(%esp),%edx
-	call	L011pic
-L011pic:
+	call	L006pic
+L006pic:
 	popl	%ecx
-	leal	Lbswap-L011pic(%ecx),%ecx
+	leal	Lbswap-L006pic(%ecx),%ecx
 	movdqu	(%eax),%xmm0
 	movdqa	(%ecx),%xmm5
 	movups	(%edx),%xmm2
@@ -1036,16 +835,16 @@
 	movl	24(%esp),%edx
 	movl	28(%esp),%esi
 	movl	32(%esp),%ebx
-	call	L012pic
-L012pic:
+	call	L007pic
+L007pic:
 	popl	%ecx
-	leal	Lbswap-L012pic(%ecx),%ecx
+	leal	Lbswap-L007pic(%ecx),%ecx
 	movdqu	(%eax),%xmm0
 	movdqa	(%ecx),%xmm5
 	movdqu	(%edx),%xmm2
 .byte	102,15,56,0,197
 	subl	$16,%ebx
-	jz	L013odd_tail
+	jz	L008odd_tail
 	movdqu	(%esi),%xmm3
 	movdqu	16(%esi),%xmm6
 .byte	102,15,56,0,221
@@ -1062,10 +861,10 @@
 	movups	16(%edx),%xmm2
 	nop
 	subl	$32,%ebx
-	jbe	L014even_tail
-	jmp	L015mod_loop
+	jbe	L009even_tail
+	jmp	L010mod_loop
 .align	5,0x90
-L015mod_loop:
+L010mod_loop:
 	pshufd	$78,%xmm0,%xmm4
 	movdqa	%xmm0,%xmm1
 	pxor	%xmm0,%xmm4
@@ -1120,8 +919,8 @@
 .byte	102,15,58,68,221,0
 	leal	32(%esi),%esi
 	subl	$32,%ebx
-	ja	L015mod_loop
-L014even_tail:
+	ja	L010mod_loop
+L009even_tail:
 	pshufd	$78,%xmm0,%xmm4
 	movdqa	%xmm0,%xmm1
 	pxor	%xmm0,%xmm4
@@ -1160,9 +959,9 @@
 	psrlq	$1,%xmm0
 	pxor	%xmm1,%xmm0
 	testl	%ebx,%ebx
-	jnz	L016done
+	jnz	L011done
 	movups	(%edx),%xmm2
-L013odd_tail:
+L008odd_tail:
 	movdqu	(%esi),%xmm3
 .byte	102,15,56,0,221
 	pxor	%xmm3,%xmm0
@@ -1201,7 +1000,7 @@
 	pxor	%xmm4,%xmm0
 	psrlq	$1,%xmm0
 	pxor	%xmm1,%xmm0
-L016done:
+L011done:
 .byte	102,15,56,0,197
 	movdqu	%xmm0,(%eax)
 	popl	%edi
diff --git a/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S b/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S
index 97fb75a..aa434bf 100644
--- a/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S
+++ b/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -17,48 +17,6 @@
 .quad	0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
 
 
-.p2align	6
-ecp_nistz256_mul_by_2:
-	pushq	%r12
-	pushq	%r13
-
-	movq	0(%rsi),%r8
-	xorq	%r13,%r13
-	movq	8(%rsi),%r9
-	addq	%r8,%r8
-	movq	16(%rsi),%r10
-	adcq	%r9,%r9
-	movq	24(%rsi),%r11
-	leaq	L$poly(%rip),%rsi
-	movq	%r8,%rax
-	adcq	%r10,%r10
-	adcq	%r11,%r11
-	movq	%r9,%rdx
-	adcq	$0,%r13
-
-	subq	0(%rsi),%r8
-	movq	%r10,%rcx
-	sbbq	8(%rsi),%r9
-	sbbq	16(%rsi),%r10
-	movq	%r11,%r12
-	sbbq	24(%rsi),%r11
-	sbbq	$0,%r13
-
-	cmovcq	%rax,%r8
-	cmovcq	%rdx,%r9
-	movq	%r8,0(%rdi)
-	cmovcq	%rcx,%r10
-	movq	%r9,8(%rdi)
-	cmovcq	%r12,%r11
-	movq	%r10,16(%rdi)
-	movq	%r11,24(%rdi)
-
-	popq	%r13
-	popq	%r12
-	.byte	0xf3,0xc3
-
-
-
 
 .globl	_ecp_nistz256_neg
 .private_extern _ecp_nistz256_neg
@@ -553,103 +511,6 @@
 
 
 
-
-
-
-
-.globl	_ecp_nistz256_from_mont
-.private_extern _ecp_nistz256_from_mont
-
-.p2align	5
-_ecp_nistz256_from_mont:
-	pushq	%r12
-	pushq	%r13
-
-	movq	0(%rsi),%rax
-	movq	L$poly+24(%rip),%r13
-	movq	8(%rsi),%r9
-	movq	16(%rsi),%r10
-	movq	24(%rsi),%r11
-	movq	%rax,%r8
-	movq	L$poly+8(%rip),%r12
-
-
-
-	movq	%rax,%rcx
-	shlq	$32,%r8
-	mulq	%r13
-	shrq	$32,%rcx
-	addq	%r8,%r9
-	adcq	%rcx,%r10
-	adcq	%rax,%r11
-	movq	%r9,%rax
-	adcq	$0,%rdx
-
-
-
-	movq	%r9,%rcx
-	shlq	$32,%r9
-	movq	%rdx,%r8
-	mulq	%r13
-	shrq	$32,%rcx
-	addq	%r9,%r10
-	adcq	%rcx,%r11
-	adcq	%rax,%r8
-	movq	%r10,%rax
-	adcq	$0,%rdx
-
-
-
-	movq	%r10,%rcx
-	shlq	$32,%r10
-	movq	%rdx,%r9
-	mulq	%r13
-	shrq	$32,%rcx
-	addq	%r10,%r11
-	adcq	%rcx,%r8
-	adcq	%rax,%r9
-	movq	%r11,%rax
-	adcq	$0,%rdx
-
-
-
-	movq	%r11,%rcx
-	shlq	$32,%r11
-	movq	%rdx,%r10
-	mulq	%r13
-	shrq	$32,%rcx
-	addq	%r11,%r8
-	adcq	%rcx,%r9
-	movq	%r8,%rcx
-	adcq	%rax,%r10
-	movq	%r9,%rsi
-	adcq	$0,%rdx
-
-
-
-	subq	$-1,%r8
-	movq	%r10,%rax
-	sbbq	%r12,%r9
-	sbbq	$0,%r10
-	movq	%rdx,%r11
-	sbbq	%r13,%rdx
-	sbbq	%r13,%r13
-
-	cmovnzq	%rcx,%r8
-	cmovnzq	%rsi,%r9
-	movq	%r8,0(%rdi)
-	cmovnzq	%rax,%r10
-	movq	%r9,8(%rdi)
-	cmovzq	%rdx,%r11
-	movq	%r10,16(%rdi)
-	movq	%r11,24(%rdi)
-
-	popq	%r13
-	popq	%r12
-	.byte	0xf3,0xc3
-
-
-
 .globl	_ecp_nistz256_select_w5
 .private_extern _ecp_nistz256_select_w5
 
diff --git a/third_party/boringssl/mac-x86_64/crypto/modes/aesni-gcm-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/modes/aesni-gcm-x86_64.S
index 21d5ad6..901bb962 100644
--- a/third_party/boringssl/mac-x86_64/crypto/modes/aesni-gcm-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/modes/aesni-gcm-x86_64.S
@@ -1,19 +1,798 @@
 #if defined(__x86_64__)
 .text	
 
-.globl	_aesni_gcm_encrypt
-.private_extern _aesni_gcm_encrypt
 
-_aesni_gcm_encrypt:
-	xorl	%eax,%eax
+.p2align	5
+_aesni_ctr32_ghash_6x:
+	vmovdqu	32(%r11),%xmm2
+	subq	$6,%rdx
+	vpxor	%xmm4,%xmm4,%xmm4
+	vmovdqu	0-128(%rcx),%xmm15
+	vpaddb	%xmm2,%xmm1,%xmm10
+	vpaddb	%xmm2,%xmm10,%xmm11
+	vpaddb	%xmm2,%xmm11,%xmm12
+	vpaddb	%xmm2,%xmm12,%xmm13
+	vpaddb	%xmm2,%xmm13,%xmm14
+	vpxor	%xmm15,%xmm1,%xmm9
+	vmovdqu	%xmm4,16+8(%rsp)
+	jmp	L$oop6x
+
+.p2align	5
+L$oop6x:
+	addl	$100663296,%ebx
+	jc	L$handle_ctr32
+	vmovdqu	0-32(%r9),%xmm3
+	vpaddb	%xmm2,%xmm14,%xmm1
+	vpxor	%xmm15,%xmm10,%xmm10
+	vpxor	%xmm15,%xmm11,%xmm11
+
+L$resume_ctr32:
+	vmovdqu	%xmm1,(%r8)
+	vpclmulqdq	$0x10,%xmm3,%xmm7,%xmm5
+	vpxor	%xmm15,%xmm12,%xmm12
+	vmovups	16-128(%rcx),%xmm2
+	vpclmulqdq	$0x01,%xmm3,%xmm7,%xmm6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	xorq	%r12,%r12
+	cmpq	%r14,%r15
+
+	vaesenc	%xmm2,%xmm9,%xmm9
+	vmovdqu	48+8(%rsp),%xmm0
+	vpxor	%xmm15,%xmm13,%xmm13
+	vpclmulqdq	$0x00,%xmm3,%xmm7,%xmm1
+	vaesenc	%xmm2,%xmm10,%xmm10
+	vpxor	%xmm15,%xmm14,%xmm14
+	setnc	%r12b
+	vpclmulqdq	$0x11,%xmm3,%xmm7,%xmm7
+	vaesenc	%xmm2,%xmm11,%xmm11
+	vmovdqu	16-32(%r9),%xmm3
+	negq	%r12
+	vaesenc	%xmm2,%xmm12,%xmm12
+	vpxor	%xmm5,%xmm6,%xmm6
+	vpclmulqdq	$0x00,%xmm3,%xmm0,%xmm5
+	vpxor	%xmm4,%xmm8,%xmm8
+	vaesenc	%xmm2,%xmm13,%xmm13
+	vpxor	%xmm5,%xmm1,%xmm4
+	andq	$0x60,%r12
+	vmovups	32-128(%rcx),%xmm15
+	vpclmulqdq	$0x10,%xmm3,%xmm0,%xmm1
+	vaesenc	%xmm2,%xmm14,%xmm14
+
+	vpclmulqdq	$0x01,%xmm3,%xmm0,%xmm2
+	leaq	(%r14,%r12,1),%r14
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	16+8(%rsp),%xmm8,%xmm8
+	vpclmulqdq	$0x11,%xmm3,%xmm0,%xmm3
+	vmovdqu	64+8(%rsp),%xmm0
+	vaesenc	%xmm15,%xmm10,%xmm10
+	movbeq	88(%r14),%r13
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	80(%r14),%r12
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r13,32+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	movq	%r12,40+8(%rsp)
+	vmovdqu	48-32(%r9),%xmm5
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vmovups	48-128(%rcx),%xmm15
+	vpxor	%xmm1,%xmm6,%xmm6
+	vpclmulqdq	$0x00,%xmm5,%xmm0,%xmm1
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm5,%xmm0,%xmm2
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vpxor	%xmm3,%xmm7,%xmm7
+	vpclmulqdq	$0x01,%xmm5,%xmm0,%xmm3
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vpclmulqdq	$0x11,%xmm5,%xmm0,%xmm5
+	vmovdqu	80+8(%rsp),%xmm0
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vpxor	%xmm1,%xmm4,%xmm4
+	vmovdqu	64-32(%r9),%xmm1
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vmovups	64-128(%rcx),%xmm15
+	vpxor	%xmm2,%xmm6,%xmm6
+	vpclmulqdq	$0x00,%xmm1,%xmm0,%xmm2
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm3,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm1,%xmm0,%xmm3
+	vaesenc	%xmm15,%xmm10,%xmm10
+	movbeq	72(%r14),%r13
+	vpxor	%xmm5,%xmm7,%xmm7
+	vpclmulqdq	$0x01,%xmm1,%xmm0,%xmm5
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	64(%r14),%r12
+	vpclmulqdq	$0x11,%xmm1,%xmm0,%xmm1
+	vmovdqu	96+8(%rsp),%xmm0
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r13,48+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	movq	%r12,56+8(%rsp)
+	vpxor	%xmm2,%xmm4,%xmm4
+	vmovdqu	96-32(%r9),%xmm2
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vmovups	80-128(%rcx),%xmm15
+	vpxor	%xmm3,%xmm6,%xmm6
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm3
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm5,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm2,%xmm0,%xmm5
+	vaesenc	%xmm15,%xmm10,%xmm10
+	movbeq	56(%r14),%r13
+	vpxor	%xmm1,%xmm7,%xmm7
+	vpclmulqdq	$0x01,%xmm2,%xmm0,%xmm1
+	vpxor	112+8(%rsp),%xmm8,%xmm8
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	48(%r14),%r12
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm2
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r13,64+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	movq	%r12,72+8(%rsp)
+	vpxor	%xmm3,%xmm4,%xmm4
+	vmovdqu	112-32(%r9),%xmm3
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vmovups	96-128(%rcx),%xmm15
+	vpxor	%xmm5,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm3,%xmm8,%xmm5
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm1,%xmm6,%xmm6
+	vpclmulqdq	$0x01,%xmm3,%xmm8,%xmm1
+	vaesenc	%xmm15,%xmm10,%xmm10
+	movbeq	40(%r14),%r13
+	vpxor	%xmm2,%xmm7,%xmm7
+	vpclmulqdq	$0x00,%xmm3,%xmm8,%xmm2
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	32(%r14),%r12
+	vpclmulqdq	$0x11,%xmm3,%xmm8,%xmm8
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r13,80+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	movq	%r12,88+8(%rsp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	vaesenc	%xmm15,%xmm14,%xmm14
+	vpxor	%xmm1,%xmm6,%xmm6
+
+	vmovups	112-128(%rcx),%xmm15
+	vpslldq	$8,%xmm6,%xmm5
+	vpxor	%xmm2,%xmm4,%xmm4
+	vmovdqu	16(%r11),%xmm3
+
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	%xmm8,%xmm7,%xmm7
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vpxor	%xmm5,%xmm4,%xmm4
+	movbeq	24(%r14),%r13
+	vaesenc	%xmm15,%xmm11,%xmm11
+	movbeq	16(%r14),%r12
+	vpalignr	$8,%xmm4,%xmm4,%xmm0
+	vpclmulqdq	$0x10,%xmm3,%xmm4,%xmm4
+	movq	%r13,96+8(%rsp)
+	vaesenc	%xmm15,%xmm12,%xmm12
+	movq	%r12,104+8(%rsp)
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vmovups	128-128(%rcx),%xmm1
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vaesenc	%xmm1,%xmm9,%xmm9
+	vmovups	144-128(%rcx),%xmm15
+	vaesenc	%xmm1,%xmm10,%xmm10
+	vpsrldq	$8,%xmm6,%xmm6
+	vaesenc	%xmm1,%xmm11,%xmm11
+	vpxor	%xmm6,%xmm7,%xmm7
+	vaesenc	%xmm1,%xmm12,%xmm12
+	vpxor	%xmm0,%xmm4,%xmm4
+	movbeq	8(%r14),%r13
+	vaesenc	%xmm1,%xmm13,%xmm13
+	movbeq	0(%r14),%r12
+	vaesenc	%xmm1,%xmm14,%xmm14
+	vmovups	160-128(%rcx),%xmm1
+	cmpl	$11,%ebp
+	jb	L$enc_tail
+
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vaesenc	%xmm1,%xmm9,%xmm9
+	vaesenc	%xmm1,%xmm10,%xmm10
+	vaesenc	%xmm1,%xmm11,%xmm11
+	vaesenc	%xmm1,%xmm12,%xmm12
+	vaesenc	%xmm1,%xmm13,%xmm13
+	vmovups	176-128(%rcx),%xmm15
+	vaesenc	%xmm1,%xmm14,%xmm14
+	vmovups	192-128(%rcx),%xmm1
+	je	L$enc_tail
+
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vaesenc	%xmm15,%xmm14,%xmm14
+
+	vaesenc	%xmm1,%xmm9,%xmm9
+	vaesenc	%xmm1,%xmm10,%xmm10
+	vaesenc	%xmm1,%xmm11,%xmm11
+	vaesenc	%xmm1,%xmm12,%xmm12
+	vaesenc	%xmm1,%xmm13,%xmm13
+	vmovups	208-128(%rcx),%xmm15
+	vaesenc	%xmm1,%xmm14,%xmm14
+	vmovups	224-128(%rcx),%xmm1
+	jmp	L$enc_tail
+
+.p2align	5
+L$handle_ctr32:
+	vmovdqu	(%r11),%xmm0
+	vpshufb	%xmm0,%xmm1,%xmm6
+	vmovdqu	48(%r11),%xmm5
+	vpaddd	64(%r11),%xmm6,%xmm10
+	vpaddd	%xmm5,%xmm6,%xmm11
+	vmovdqu	0-32(%r9),%xmm3
+	vpaddd	%xmm5,%xmm10,%xmm12
+	vpshufb	%xmm0,%xmm10,%xmm10
+	vpaddd	%xmm5,%xmm11,%xmm13
+	vpshufb	%xmm0,%xmm11,%xmm11
+	vpxor	%xmm15,%xmm10,%xmm10
+	vpaddd	%xmm5,%xmm12,%xmm14
+	vpshufb	%xmm0,%xmm12,%xmm12
+	vpxor	%xmm15,%xmm11,%xmm11
+	vpaddd	%xmm5,%xmm13,%xmm1
+	vpshufb	%xmm0,%xmm13,%xmm13
+	vpshufb	%xmm0,%xmm14,%xmm14
+	vpshufb	%xmm0,%xmm1,%xmm1
+	jmp	L$resume_ctr32
+
+.p2align	5
+L$enc_tail:
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vmovdqu	%xmm7,16+8(%rsp)
+	vpalignr	$8,%xmm4,%xmm4,%xmm8
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vpclmulqdq	$0x10,%xmm3,%xmm4,%xmm4
+	vpxor	0(%rdi),%xmm1,%xmm2
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vpxor	16(%rdi),%xmm1,%xmm0
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vpxor	32(%rdi),%xmm1,%xmm5
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vpxor	48(%rdi),%xmm1,%xmm6
+	vaesenc	%xmm15,%xmm14,%xmm14
+	vpxor	64(%rdi),%xmm1,%xmm7
+	vpxor	80(%rdi),%xmm1,%xmm3
+	vmovdqu	(%r8),%xmm1
+
+	vaesenclast	%xmm2,%xmm9,%xmm9
+	vmovdqu	32(%r11),%xmm2
+	vaesenclast	%xmm0,%xmm10,%xmm10
+	vpaddb	%xmm2,%xmm1,%xmm0
+	movq	%r13,112+8(%rsp)
+	leaq	96(%rdi),%rdi
+	vaesenclast	%xmm5,%xmm11,%xmm11
+	vpaddb	%xmm2,%xmm0,%xmm5
+	movq	%r12,120+8(%rsp)
+	leaq	96(%rsi),%rsi
+	vmovdqu	0-128(%rcx),%xmm15
+	vaesenclast	%xmm6,%xmm12,%xmm12
+	vpaddb	%xmm2,%xmm5,%xmm6
+	vaesenclast	%xmm7,%xmm13,%xmm13
+	vpaddb	%xmm2,%xmm6,%xmm7
+	vaesenclast	%xmm3,%xmm14,%xmm14
+	vpaddb	%xmm2,%xmm7,%xmm3
+
+	addq	$0x60,%r10
+	subq	$0x6,%rdx
+	jc	L$6x_done
+
+	vmovups	%xmm9,-96(%rsi)
+	vpxor	%xmm15,%xmm1,%xmm9
+	vmovups	%xmm10,-80(%rsi)
+	vmovdqa	%xmm0,%xmm10
+	vmovups	%xmm11,-64(%rsi)
+	vmovdqa	%xmm5,%xmm11
+	vmovups	%xmm12,-48(%rsi)
+	vmovdqa	%xmm6,%xmm12
+	vmovups	%xmm13,-32(%rsi)
+	vmovdqa	%xmm7,%xmm13
+	vmovups	%xmm14,-16(%rsi)
+	vmovdqa	%xmm3,%xmm14
+	vmovdqu	32+8(%rsp),%xmm7
+	jmp	L$oop6x
+
+L$6x_done:
+	vpxor	16+8(%rsp),%xmm8,%xmm8
+	vpxor	%xmm4,%xmm8,%xmm8
+
 	.byte	0xf3,0xc3
 
-
 .globl	_aesni_gcm_decrypt
 .private_extern _aesni_gcm_decrypt
 
+.p2align	5
 _aesni_gcm_decrypt:
-	xorl	%eax,%eax
+	xorq	%r10,%r10
+
+
+
+	cmpq	$0x60,%rdx
+	jb	L$gcm_dec_abort
+
+	leaq	(%rsp),%rax
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	vzeroupper
+
+	vmovdqu	(%r8),%xmm1
+	addq	$-128,%rsp
+	movl	12(%r8),%ebx
+	leaq	L$bswap_mask(%rip),%r11
+	leaq	-128(%rcx),%r14
+	movq	$0xf80,%r15
+	vmovdqu	(%r9),%xmm8
+	andq	$-128,%rsp
+	vmovdqu	(%r11),%xmm0
+	leaq	128(%rcx),%rcx
+	leaq	32+32(%r9),%r9
+	movl	240-128(%rcx),%ebp
+	vpshufb	%xmm0,%xmm8,%xmm8
+
+	andq	%r15,%r14
+	andq	%rsp,%r15
+	subq	%r14,%r15
+	jc	L$dec_no_key_aliasing
+	cmpq	$768,%r15
+	jnc	L$dec_no_key_aliasing
+	subq	%r15,%rsp
+L$dec_no_key_aliasing:
+
+	vmovdqu	80(%rdi),%xmm7
+	leaq	(%rdi),%r14
+	vmovdqu	64(%rdi),%xmm4
+
+
+
+
+
+
+
+	leaq	-192(%rdi,%rdx,1),%r15
+
+	vmovdqu	48(%rdi),%xmm5
+	shrq	$4,%rdx
+	xorq	%r10,%r10
+	vmovdqu	32(%rdi),%xmm6
+	vpshufb	%xmm0,%xmm7,%xmm7
+	vmovdqu	16(%rdi),%xmm2
+	vpshufb	%xmm0,%xmm4,%xmm4
+	vmovdqu	(%rdi),%xmm3
+	vpshufb	%xmm0,%xmm5,%xmm5
+	vmovdqu	%xmm4,48(%rsp)
+	vpshufb	%xmm0,%xmm6,%xmm6
+	vmovdqu	%xmm5,64(%rsp)
+	vpshufb	%xmm0,%xmm2,%xmm2
+	vmovdqu	%xmm6,80(%rsp)
+	vpshufb	%xmm0,%xmm3,%xmm3
+	vmovdqu	%xmm2,96(%rsp)
+	vmovdqu	%xmm3,112(%rsp)
+
+	call	_aesni_ctr32_ghash_6x
+
+	vmovups	%xmm9,-96(%rsi)
+	vmovups	%xmm10,-80(%rsi)
+	vmovups	%xmm11,-64(%rsi)
+	vmovups	%xmm12,-48(%rsi)
+	vmovups	%xmm13,-32(%rsi)
+	vmovups	%xmm14,-16(%rsi)
+
+	vpshufb	(%r11),%xmm8,%xmm8
+	vmovdqu	%xmm8,-64(%r9)
+
+	vzeroupper
+	movq	-48(%rax),%r15
+	movq	-40(%rax),%r14
+	movq	-32(%rax),%r13
+	movq	-24(%rax),%r12
+	movq	-16(%rax),%rbp
+	movq	-8(%rax),%rbx
+	leaq	(%rax),%rsp
+L$gcm_dec_abort:
+	movq	%r10,%rax
 	.byte	0xf3,0xc3
 
+
+.p2align	5
+_aesni_ctr32_6x:
+	vmovdqu	0-128(%rcx),%xmm4
+	vmovdqu	32(%r11),%xmm2
+	leaq	-1(%rbp),%r13
+	vmovups	16-128(%rcx),%xmm15
+	leaq	32-128(%rcx),%r12
+	vpxor	%xmm4,%xmm1,%xmm9
+	addl	$100663296,%ebx
+	jc	L$handle_ctr32_2
+	vpaddb	%xmm2,%xmm1,%xmm10
+	vpaddb	%xmm2,%xmm10,%xmm11
+	vpxor	%xmm4,%xmm10,%xmm10
+	vpaddb	%xmm2,%xmm11,%xmm12
+	vpxor	%xmm4,%xmm11,%xmm11
+	vpaddb	%xmm2,%xmm12,%xmm13
+	vpxor	%xmm4,%xmm12,%xmm12
+	vpaddb	%xmm2,%xmm13,%xmm14
+	vpxor	%xmm4,%xmm13,%xmm13
+	vpaddb	%xmm2,%xmm14,%xmm1
+	vpxor	%xmm4,%xmm14,%xmm14
+	jmp	L$oop_ctr32
+
+.p2align	4
+L$oop_ctr32:
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vaesenc	%xmm15,%xmm14,%xmm14
+	vmovups	(%r12),%xmm15
+	leaq	16(%r12),%r12
+	decl	%r13d
+	jnz	L$oop_ctr32
+
+	vmovdqu	(%r12),%xmm3
+	vaesenc	%xmm15,%xmm9,%xmm9
+	vpxor	0(%rdi),%xmm3,%xmm4
+	vaesenc	%xmm15,%xmm10,%xmm10
+	vpxor	16(%rdi),%xmm3,%xmm5
+	vaesenc	%xmm15,%xmm11,%xmm11
+	vpxor	32(%rdi),%xmm3,%xmm6
+	vaesenc	%xmm15,%xmm12,%xmm12
+	vpxor	48(%rdi),%xmm3,%xmm8
+	vaesenc	%xmm15,%xmm13,%xmm13
+	vpxor	64(%rdi),%xmm3,%xmm2
+	vaesenc	%xmm15,%xmm14,%xmm14
+	vpxor	80(%rdi),%xmm3,%xmm3
+	leaq	96(%rdi),%rdi
+
+	vaesenclast	%xmm4,%xmm9,%xmm9
+	vaesenclast	%xmm5,%xmm10,%xmm10
+	vaesenclast	%xmm6,%xmm11,%xmm11
+	vaesenclast	%xmm8,%xmm12,%xmm12
+	vaesenclast	%xmm2,%xmm13,%xmm13
+	vaesenclast	%xmm3,%xmm14,%xmm14
+	vmovups	%xmm9,0(%rsi)
+	vmovups	%xmm10,16(%rsi)
+	vmovups	%xmm11,32(%rsi)
+	vmovups	%xmm12,48(%rsi)
+	vmovups	%xmm13,64(%rsi)
+	vmovups	%xmm14,80(%rsi)
+	leaq	96(%rsi),%rsi
+
+	.byte	0xf3,0xc3
+.p2align	5
+L$handle_ctr32_2:
+	vpshufb	%xmm0,%xmm1,%xmm6
+	vmovdqu	48(%r11),%xmm5
+	vpaddd	64(%r11),%xmm6,%xmm10
+	vpaddd	%xmm5,%xmm6,%xmm11
+	vpaddd	%xmm5,%xmm10,%xmm12
+	vpshufb	%xmm0,%xmm10,%xmm10
+	vpaddd	%xmm5,%xmm11,%xmm13
+	vpshufb	%xmm0,%xmm11,%xmm11
+	vpxor	%xmm4,%xmm10,%xmm10
+	vpaddd	%xmm5,%xmm12,%xmm14
+	vpshufb	%xmm0,%xmm12,%xmm12
+	vpxor	%xmm4,%xmm11,%xmm11
+	vpaddd	%xmm5,%xmm13,%xmm1
+	vpshufb	%xmm0,%xmm13,%xmm13
+	vpxor	%xmm4,%xmm12,%xmm12
+	vpshufb	%xmm0,%xmm14,%xmm14
+	vpxor	%xmm4,%xmm13,%xmm13
+	vpshufb	%xmm0,%xmm1,%xmm1
+	vpxor	%xmm4,%xmm14,%xmm14
+	jmp	L$oop_ctr32
+
+
+.globl	_aesni_gcm_encrypt
+.private_extern _aesni_gcm_encrypt
+
+.p2align	5
+_aesni_gcm_encrypt:
+	xorq	%r10,%r10
+
+
+
+
+	cmpq	$288,%rdx
+	jb	L$gcm_enc_abort
+
+	leaq	(%rsp),%rax
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	vzeroupper
+
+	vmovdqu	(%r8),%xmm1
+	addq	$-128,%rsp
+	movl	12(%r8),%ebx
+	leaq	L$bswap_mask(%rip),%r11
+	leaq	-128(%rcx),%r14
+	movq	$0xf80,%r15
+	leaq	128(%rcx),%rcx
+	vmovdqu	(%r11),%xmm0
+	andq	$-128,%rsp
+	movl	240-128(%rcx),%ebp
+
+	andq	%r15,%r14
+	andq	%rsp,%r15
+	subq	%r14,%r15
+	jc	L$enc_no_key_aliasing
+	cmpq	$768,%r15
+	jnc	L$enc_no_key_aliasing
+	subq	%r15,%rsp
+L$enc_no_key_aliasing:
+
+	leaq	(%rsi),%r14
+
+
+
+
+
+
+
+
+	leaq	-192(%rsi,%rdx,1),%r15
+
+	shrq	$4,%rdx
+
+	call	_aesni_ctr32_6x
+	vpshufb	%xmm0,%xmm9,%xmm8
+	vpshufb	%xmm0,%xmm10,%xmm2
+	vmovdqu	%xmm8,112(%rsp)
+	vpshufb	%xmm0,%xmm11,%xmm4
+	vmovdqu	%xmm2,96(%rsp)
+	vpshufb	%xmm0,%xmm12,%xmm5
+	vmovdqu	%xmm4,80(%rsp)
+	vpshufb	%xmm0,%xmm13,%xmm6
+	vmovdqu	%xmm5,64(%rsp)
+	vpshufb	%xmm0,%xmm14,%xmm7
+	vmovdqu	%xmm6,48(%rsp)
+
+	call	_aesni_ctr32_6x
+
+	vmovdqu	(%r9),%xmm8
+	leaq	32+32(%r9),%r9
+	subq	$12,%rdx
+	movq	$192,%r10
+	vpshufb	%xmm0,%xmm8,%xmm8
+
+	call	_aesni_ctr32_ghash_6x
+	vmovdqu	32(%rsp),%xmm7
+	vmovdqu	(%r11),%xmm0
+	vmovdqu	0-32(%r9),%xmm3
+	vpunpckhqdq	%xmm7,%xmm7,%xmm1
+	vmovdqu	32-32(%r9),%xmm15
+	vmovups	%xmm9,-96(%rsi)
+	vpshufb	%xmm0,%xmm9,%xmm9
+	vpxor	%xmm7,%xmm1,%xmm1
+	vmovups	%xmm10,-80(%rsi)
+	vpshufb	%xmm0,%xmm10,%xmm10
+	vmovups	%xmm11,-64(%rsi)
+	vpshufb	%xmm0,%xmm11,%xmm11
+	vmovups	%xmm12,-48(%rsi)
+	vpshufb	%xmm0,%xmm12,%xmm12
+	vmovups	%xmm13,-32(%rsi)
+	vpshufb	%xmm0,%xmm13,%xmm13
+	vmovups	%xmm14,-16(%rsi)
+	vpshufb	%xmm0,%xmm14,%xmm14
+	vmovdqu	%xmm9,16(%rsp)
+	vmovdqu	48(%rsp),%xmm6
+	vmovdqu	16-32(%r9),%xmm0
+	vpunpckhqdq	%xmm6,%xmm6,%xmm2
+	vpclmulqdq	$0x00,%xmm3,%xmm7,%xmm5
+	vpxor	%xmm6,%xmm2,%xmm2
+	vpclmulqdq	$0x11,%xmm3,%xmm7,%xmm7
+	vpclmulqdq	$0x00,%xmm15,%xmm1,%xmm1
+
+	vmovdqu	64(%rsp),%xmm9
+	vpclmulqdq	$0x00,%xmm0,%xmm6,%xmm4
+	vmovdqu	48-32(%r9),%xmm3
+	vpxor	%xmm5,%xmm4,%xmm4
+	vpunpckhqdq	%xmm9,%xmm9,%xmm5
+	vpclmulqdq	$0x11,%xmm0,%xmm6,%xmm6
+	vpxor	%xmm9,%xmm5,%xmm5
+	vpxor	%xmm7,%xmm6,%xmm6
+	vpclmulqdq	$0x10,%xmm15,%xmm2,%xmm2
+	vmovdqu	80-32(%r9),%xmm15
+	vpxor	%xmm1,%xmm2,%xmm2
+
+	vmovdqu	80(%rsp),%xmm1
+	vpclmulqdq	$0x00,%xmm3,%xmm9,%xmm7
+	vmovdqu	64-32(%r9),%xmm0
+	vpxor	%xmm4,%xmm7,%xmm7
+	vpunpckhqdq	%xmm1,%xmm1,%xmm4
+	vpclmulqdq	$0x11,%xmm3,%xmm9,%xmm9
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpxor	%xmm6,%xmm9,%xmm9
+	vpclmulqdq	$0x00,%xmm15,%xmm5,%xmm5
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vmovdqu	96(%rsp),%xmm2
+	vpclmulqdq	$0x00,%xmm0,%xmm1,%xmm6
+	vmovdqu	96-32(%r9),%xmm3
+	vpxor	%xmm7,%xmm6,%xmm6
+	vpunpckhqdq	%xmm2,%xmm2,%xmm7
+	vpclmulqdq	$0x11,%xmm0,%xmm1,%xmm1
+	vpxor	%xmm2,%xmm7,%xmm7
+	vpxor	%xmm9,%xmm1,%xmm1
+	vpclmulqdq	$0x10,%xmm15,%xmm4,%xmm4
+	vmovdqu	128-32(%r9),%xmm15
+	vpxor	%xmm5,%xmm4,%xmm4
+
+	vpxor	112(%rsp),%xmm8,%xmm8
+	vpclmulqdq	$0x00,%xmm3,%xmm2,%xmm5
+	vmovdqu	112-32(%r9),%xmm0
+	vpunpckhqdq	%xmm8,%xmm8,%xmm9
+	vpxor	%xmm6,%xmm5,%xmm5
+	vpclmulqdq	$0x11,%xmm3,%xmm2,%xmm2
+	vpxor	%xmm8,%xmm9,%xmm9
+	vpxor	%xmm1,%xmm2,%xmm2
+	vpclmulqdq	$0x00,%xmm15,%xmm7,%xmm7
+	vpxor	%xmm4,%xmm7,%xmm4
+
+	vpclmulqdq	$0x00,%xmm0,%xmm8,%xmm6
+	vmovdqu	0-32(%r9),%xmm3
+	vpunpckhqdq	%xmm14,%xmm14,%xmm1
+	vpclmulqdq	$0x11,%xmm0,%xmm8,%xmm8
+	vpxor	%xmm14,%xmm1,%xmm1
+	vpxor	%xmm5,%xmm6,%xmm5
+	vpclmulqdq	$0x10,%xmm15,%xmm9,%xmm9
+	vmovdqu	32-32(%r9),%xmm15
+	vpxor	%xmm2,%xmm8,%xmm7
+	vpxor	%xmm4,%xmm9,%xmm6
+
+	vmovdqu	16-32(%r9),%xmm0
+	vpxor	%xmm5,%xmm7,%xmm9
+	vpclmulqdq	$0x00,%xmm3,%xmm14,%xmm4
+	vpxor	%xmm9,%xmm6,%xmm6
+	vpunpckhqdq	%xmm13,%xmm13,%xmm2
+	vpclmulqdq	$0x11,%xmm3,%xmm14,%xmm14
+	vpxor	%xmm13,%xmm2,%xmm2
+	vpslldq	$8,%xmm6,%xmm9
+	vpclmulqdq	$0x00,%xmm15,%xmm1,%xmm1
+	vpxor	%xmm9,%xmm5,%xmm8
+	vpsrldq	$8,%xmm6,%xmm6
+	vpxor	%xmm6,%xmm7,%xmm7
+
+	vpclmulqdq	$0x00,%xmm0,%xmm13,%xmm5
+	vmovdqu	48-32(%r9),%xmm3
+	vpxor	%xmm4,%xmm5,%xmm5
+	vpunpckhqdq	%xmm12,%xmm12,%xmm9
+	vpclmulqdq	$0x11,%xmm0,%xmm13,%xmm13
+	vpxor	%xmm12,%xmm9,%xmm9
+	vpxor	%xmm14,%xmm13,%xmm13
+	vpalignr	$8,%xmm8,%xmm8,%xmm14
+	vpclmulqdq	$0x10,%xmm15,%xmm2,%xmm2
+	vmovdqu	80-32(%r9),%xmm15
+	vpxor	%xmm1,%xmm2,%xmm2
+
+	vpclmulqdq	$0x00,%xmm3,%xmm12,%xmm4
+	vmovdqu	64-32(%r9),%xmm0
+	vpxor	%xmm5,%xmm4,%xmm4
+	vpunpckhqdq	%xmm11,%xmm11,%xmm1
+	vpclmulqdq	$0x11,%xmm3,%xmm12,%xmm12
+	vpxor	%xmm11,%xmm1,%xmm1
+	vpxor	%xmm13,%xmm12,%xmm12
+	vxorps	16(%rsp),%xmm7,%xmm7
+	vpclmulqdq	$0x00,%xmm15,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm9,%xmm9
+
+	vpclmulqdq	$0x10,16(%r11),%xmm8,%xmm8
+	vxorps	%xmm14,%xmm8,%xmm8
+
+	vpclmulqdq	$0x00,%xmm0,%xmm11,%xmm5
+	vmovdqu	96-32(%r9),%xmm3
+	vpxor	%xmm4,%xmm5,%xmm5
+	vpunpckhqdq	%xmm10,%xmm10,%xmm2
+	vpclmulqdq	$0x11,%xmm0,%xmm11,%xmm11
+	vpxor	%xmm10,%xmm2,%xmm2
+	vpalignr	$8,%xmm8,%xmm8,%xmm14
+	vpxor	%xmm12,%xmm11,%xmm11
+	vpclmulqdq	$0x10,%xmm15,%xmm1,%xmm1
+	vmovdqu	128-32(%r9),%xmm15
+	vpxor	%xmm9,%xmm1,%xmm1
+
+	vxorps	%xmm7,%xmm14,%xmm14
+	vpclmulqdq	$0x10,16(%r11),%xmm8,%xmm8
+	vxorps	%xmm14,%xmm8,%xmm8
+
+	vpclmulqdq	$0x00,%xmm3,%xmm10,%xmm4
+	vmovdqu	112-32(%r9),%xmm0
+	vpxor	%xmm5,%xmm4,%xmm4
+	vpunpckhqdq	%xmm8,%xmm8,%xmm9
+	vpclmulqdq	$0x11,%xmm3,%xmm10,%xmm10
+	vpxor	%xmm8,%xmm9,%xmm9
+	vpxor	%xmm11,%xmm10,%xmm10
+	vpclmulqdq	$0x00,%xmm15,%xmm2,%xmm2
+	vpxor	%xmm1,%xmm2,%xmm2
+
+	vpclmulqdq	$0x00,%xmm0,%xmm8,%xmm5
+	vpclmulqdq	$0x11,%xmm0,%xmm8,%xmm7
+	vpxor	%xmm4,%xmm5,%xmm5
+	vpclmulqdq	$0x10,%xmm15,%xmm9,%xmm6
+	vpxor	%xmm10,%xmm7,%xmm7
+	vpxor	%xmm2,%xmm6,%xmm6
+
+	vpxor	%xmm5,%xmm7,%xmm4
+	vpxor	%xmm4,%xmm6,%xmm6
+	vpslldq	$8,%xmm6,%xmm1
+	vmovdqu	16(%r11),%xmm3
+	vpsrldq	$8,%xmm6,%xmm6
+	vpxor	%xmm1,%xmm5,%xmm8
+	vpxor	%xmm6,%xmm7,%xmm7
+
+	vpalignr	$8,%xmm8,%xmm8,%xmm2
+	vpclmulqdq	$0x10,%xmm3,%xmm8,%xmm8
+	vpxor	%xmm2,%xmm8,%xmm8
+
+	vpalignr	$8,%xmm8,%xmm8,%xmm2
+	vpclmulqdq	$0x10,%xmm3,%xmm8,%xmm8
+	vpxor	%xmm7,%xmm2,%xmm2
+	vpxor	%xmm2,%xmm8,%xmm8
+	vpshufb	(%r11),%xmm8,%xmm8
+	vmovdqu	%xmm8,-64(%r9)
+
+	vzeroupper
+	movq	-48(%rax),%r15
+	movq	-40(%rax),%r14
+	movq	-32(%rax),%r13
+	movq	-24(%rax),%r12
+	movq	-16(%rax),%rbp
+	movq	-8(%rax),%rbx
+	leaq	(%rax),%rsp
+L$gcm_enc_abort:
+	movq	%r10,%rax
+	.byte	0xf3,0xc3
+
+.p2align	6
+L$bswap_mask:
+.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+L$poly:
+.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
+L$one_msb:
+.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
+L$two_lsb:
+.byte	2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+L$one_lsb:
+.byte	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.byte	65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	6
 #endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S
index 1072c7f..334f83f 100644
--- a/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S
@@ -1256,7 +1256,108 @@
 
 .p2align	5
 _gcm_init_avx:
-	jmp	L$_init_clmul
+	vzeroupper
+
+	vmovdqu	(%rsi),%xmm2
+	vpshufd	$78,%xmm2,%xmm2
+
+
+	vpshufd	$255,%xmm2,%xmm4
+	vpsrlq	$63,%xmm2,%xmm3
+	vpsllq	$1,%xmm2,%xmm2
+	vpxor	%xmm5,%xmm5,%xmm5
+	vpcmpgtd	%xmm4,%xmm5,%xmm5
+	vpslldq	$8,%xmm3,%xmm3
+	vpor	%xmm3,%xmm2,%xmm2
+
+
+	vpand	L$0x1c2_polynomial(%rip),%xmm5,%xmm5
+	vpxor	%xmm5,%xmm2,%xmm2
+
+	vpunpckhqdq	%xmm2,%xmm2,%xmm6
+	vmovdqa	%xmm2,%xmm0
+	vpxor	%xmm2,%xmm6,%xmm6
+	movq	$4,%r10
+	jmp	L$init_start_avx
+.p2align	5
+L$init_loop_avx:
+	vpalignr	$8,%xmm3,%xmm4,%xmm5
+	vmovdqu	%xmm5,-16(%rdi)
+	vpunpckhqdq	%xmm0,%xmm0,%xmm3
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3
+	vpxor	%xmm0,%xmm1,%xmm4
+	vpxor	%xmm4,%xmm3,%xmm3
+
+	vpslldq	$8,%xmm3,%xmm4
+	vpsrldq	$8,%xmm3,%xmm3
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpxor	%xmm3,%xmm1,%xmm1
+	vpsllq	$57,%xmm0,%xmm3
+	vpsllq	$62,%xmm0,%xmm4
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpsllq	$63,%xmm0,%xmm3
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpslldq	$8,%xmm4,%xmm3
+	vpsrldq	$8,%xmm4,%xmm4
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpxor	%xmm4,%xmm1,%xmm1
+
+	vpsrlq	$1,%xmm0,%xmm4
+	vpxor	%xmm0,%xmm1,%xmm1
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$5,%xmm4,%xmm4
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$1,%xmm0,%xmm0
+	vpxor	%xmm1,%xmm0,%xmm0
+L$init_start_avx:
+	vmovdqa	%xmm0,%xmm5
+	vpunpckhqdq	%xmm0,%xmm0,%xmm3
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3
+	vpxor	%xmm0,%xmm1,%xmm4
+	vpxor	%xmm4,%xmm3,%xmm3
+
+	vpslldq	$8,%xmm3,%xmm4
+	vpsrldq	$8,%xmm3,%xmm3
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpxor	%xmm3,%xmm1,%xmm1
+	vpsllq	$57,%xmm0,%xmm3
+	vpsllq	$62,%xmm0,%xmm4
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpsllq	$63,%xmm0,%xmm3
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpslldq	$8,%xmm4,%xmm3
+	vpsrldq	$8,%xmm4,%xmm4
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpxor	%xmm4,%xmm1,%xmm1
+
+	vpsrlq	$1,%xmm0,%xmm4
+	vpxor	%xmm0,%xmm1,%xmm1
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$5,%xmm4,%xmm4
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$1,%xmm0,%xmm0
+	vpxor	%xmm1,%xmm0,%xmm0
+	vpshufd	$78,%xmm5,%xmm3
+	vpshufd	$78,%xmm0,%xmm4
+	vpxor	%xmm5,%xmm3,%xmm3
+	vmovdqu	%xmm5,0(%rdi)
+	vpxor	%xmm0,%xmm4,%xmm4
+	vmovdqu	%xmm0,16(%rdi)
+	leaq	48(%rdi),%rdi
+	subq	$1,%r10
+	jnz	L$init_loop_avx
+
+	vpalignr	$8,%xmm4,%xmm3,%xmm5
+	vmovdqu	%xmm5,-16(%rdi)
+
+	vzeroupper
+	.byte	0xf3,0xc3
 
 .globl	_gcm_gmult_avx
 .private_extern _gcm_gmult_avx
@@ -1270,7 +1371,377 @@
 
 .p2align	5
 _gcm_ghash_avx:
-	jmp	L$_ghash_clmul
+	vzeroupper
+
+	vmovdqu	(%rdi),%xmm10
+	leaq	L$0x1c2_polynomial(%rip),%r10
+	leaq	64(%rsi),%rsi
+	vmovdqu	L$bswap_mask(%rip),%xmm13
+	vpshufb	%xmm13,%xmm10,%xmm10
+	cmpq	$0x80,%rcx
+	jb	L$short_avx
+	subq	$0x80,%rcx
+
+	vmovdqu	112(%rdx),%xmm14
+	vmovdqu	0-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vmovdqu	32-64(%rsi),%xmm7
+
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vmovdqu	96(%rdx),%xmm15
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm14,%xmm9,%xmm9
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	16-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vmovdqu	80(%rdx),%xmm14
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm15,%xmm8,%xmm8
+
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	48-64(%rsi),%xmm6
+	vpxor	%xmm14,%xmm9,%xmm9
+	vmovdqu	64(%rdx),%xmm15
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	80-64(%rsi),%xmm7
+
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	64-64(%rsi),%xmm6
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm15,%xmm8,%xmm8
+
+	vmovdqu	48(%rdx),%xmm14
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpxor	%xmm4,%xmm1,%xmm1
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	96-64(%rsi),%xmm6
+	vpxor	%xmm5,%xmm2,%xmm2
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	128-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+
+	vmovdqu	32(%rdx),%xmm15
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	112-64(%rsi),%xmm6
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm15,%xmm8,%xmm8
+
+	vmovdqu	16(%rdx),%xmm14
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpxor	%xmm4,%xmm1,%xmm1
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	144-64(%rsi),%xmm6
+	vpxor	%xmm5,%xmm2,%xmm2
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	176-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+
+	vmovdqu	(%rdx),%xmm15
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	160-64(%rsi),%xmm6
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x10,%xmm7,%xmm9,%xmm2
+
+	leaq	128(%rdx),%rdx
+	cmpq	$0x80,%rcx
+	jb	L$tail_avx
+
+	vpxor	%xmm10,%xmm15,%xmm15
+	subq	$0x80,%rcx
+	jmp	L$oop8x_avx
+
+.p2align	5
+L$oop8x_avx:
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vmovdqu	112(%rdx),%xmm14
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpxor	%xmm15,%xmm8,%xmm8
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm10
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm11
+	vmovdqu	0-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm12
+	vmovdqu	32-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+
+	vmovdqu	96(%rdx),%xmm15
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpxor	%xmm3,%xmm10,%xmm10
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vxorps	%xmm4,%xmm11,%xmm11
+	vmovdqu	16-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm5,%xmm12,%xmm12
+	vxorps	%xmm15,%xmm8,%xmm8
+
+	vmovdqu	80(%rdx),%xmm14
+	vpxor	%xmm10,%xmm12,%xmm12
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpxor	%xmm11,%xmm12,%xmm12
+	vpslldq	$8,%xmm12,%xmm9
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vpsrldq	$8,%xmm12,%xmm12
+	vpxor	%xmm9,%xmm10,%xmm10
+	vmovdqu	48-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vxorps	%xmm12,%xmm11,%xmm11
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	80-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vmovdqu	64(%rdx),%xmm15
+	vpalignr	$8,%xmm10,%xmm10,%xmm12
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	64-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm4,%xmm1,%xmm1
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vxorps	%xmm15,%xmm8,%xmm8
+	vpxor	%xmm5,%xmm2,%xmm2
+
+	vmovdqu	48(%rdx),%xmm14
+	vpclmulqdq	$0x10,(%r10),%xmm10,%xmm10
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	96-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	128-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vmovdqu	32(%rdx),%xmm15
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpxor	%xmm3,%xmm0,%xmm0
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	112-64(%rsi),%xmm6
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm4,%xmm1,%xmm1
+	vpclmulqdq	$0x00,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm15,%xmm8,%xmm8
+	vpxor	%xmm5,%xmm2,%xmm2
+	vxorps	%xmm12,%xmm10,%xmm10
+
+	vmovdqu	16(%rdx),%xmm14
+	vpalignr	$8,%xmm10,%xmm10,%xmm12
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm3
+	vpshufb	%xmm13,%xmm14,%xmm14
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm4
+	vmovdqu	144-64(%rsi),%xmm6
+	vpclmulqdq	$0x10,(%r10),%xmm10,%xmm10
+	vxorps	%xmm11,%xmm12,%xmm12
+	vpunpckhqdq	%xmm14,%xmm14,%xmm9
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x10,%xmm7,%xmm8,%xmm5
+	vmovdqu	176-64(%rsi),%xmm7
+	vpxor	%xmm14,%xmm9,%xmm9
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vmovdqu	(%rdx),%xmm15
+	vpclmulqdq	$0x00,%xmm6,%xmm14,%xmm0
+	vpshufb	%xmm13,%xmm15,%xmm15
+	vpclmulqdq	$0x11,%xmm6,%xmm14,%xmm1
+	vmovdqu	160-64(%rsi),%xmm6
+	vpxor	%xmm12,%xmm15,%xmm15
+	vpclmulqdq	$0x10,%xmm7,%xmm9,%xmm2
+	vpxor	%xmm10,%xmm15,%xmm15
+
+	leaq	128(%rdx),%rdx
+	subq	$0x80,%rcx
+	jnc	L$oop8x_avx
+
+	addq	$0x80,%rcx
+	jmp	L$tail_no_xor_avx
+
+.p2align	5
+L$short_avx:
+	vmovdqu	-16(%rdx,%rcx,1),%xmm14
+	leaq	(%rdx,%rcx,1),%rdx
+	vmovdqu	0-64(%rsi),%xmm6
+	vmovdqu	32-64(%rsi),%xmm7
+	vpshufb	%xmm13,%xmm14,%xmm15
+
+	vmovdqa	%xmm0,%xmm3
+	vmovdqa	%xmm1,%xmm4
+	vmovdqa	%xmm2,%xmm5
+	subq	$0x10,%rcx
+	jz	L$tail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-32(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	16-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vpsrldq	$8,%xmm7,%xmm7
+	subq	$0x10,%rcx
+	jz	L$tail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-48(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	48-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vmovdqu	80-64(%rsi),%xmm7
+	subq	$0x10,%rcx
+	jz	L$tail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-64(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	64-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vpsrldq	$8,%xmm7,%xmm7
+	subq	$0x10,%rcx
+	jz	L$tail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-80(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	96-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vmovdqu	128-64(%rsi),%xmm7
+	subq	$0x10,%rcx
+	jz	L$tail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-96(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	112-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vpsrldq	$8,%xmm7,%xmm7
+	subq	$0x10,%rcx
+	jz	L$tail_avx
+
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vmovdqu	-112(%rdx),%xmm14
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vmovdqu	144-64(%rsi),%xmm6
+	vpshufb	%xmm13,%xmm14,%xmm15
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+	vmovq	184-64(%rsi),%xmm7
+	subq	$0x10,%rcx
+	jmp	L$tail_avx
+
+.p2align	5
+L$tail_avx:
+	vpxor	%xmm10,%xmm15,%xmm15
+L$tail_no_xor_avx:
+	vpunpckhqdq	%xmm15,%xmm15,%xmm8
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x00,%xmm6,%xmm15,%xmm0
+	vpxor	%xmm15,%xmm8,%xmm8
+	vpxor	%xmm1,%xmm4,%xmm4
+	vpclmulqdq	$0x11,%xmm6,%xmm15,%xmm1
+	vpxor	%xmm2,%xmm5,%xmm5
+	vpclmulqdq	$0x00,%xmm7,%xmm8,%xmm2
+
+	vmovdqu	(%r10),%xmm12
+
+	vpxor	%xmm0,%xmm3,%xmm10
+	vpxor	%xmm1,%xmm4,%xmm11
+	vpxor	%xmm2,%xmm5,%xmm5
+
+	vpxor	%xmm10,%xmm5,%xmm5
+	vpxor	%xmm11,%xmm5,%xmm5
+	vpslldq	$8,%xmm5,%xmm9
+	vpsrldq	$8,%xmm5,%xmm5
+	vpxor	%xmm9,%xmm10,%xmm10
+	vpxor	%xmm5,%xmm11,%xmm11
+
+	vpclmulqdq	$0x10,%xmm12,%xmm10,%xmm9
+	vpalignr	$8,%xmm10,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm10,%xmm10
+
+	vpclmulqdq	$0x10,%xmm12,%xmm10,%xmm9
+	vpalignr	$8,%xmm10,%xmm10,%xmm10
+	vpxor	%xmm11,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm10,%xmm10
+
+	cmpq	$0,%rcx
+	jne	L$short_avx
+
+	vpshufb	%xmm13,%xmm10,%xmm10
+	vmovdqu	%xmm10,(%rdi)
+	vzeroupper
+	.byte	0xf3,0xc3
 
 .p2align	6
 L$bswap_mask:
diff --git a/third_party/boringssl/win-x86/crypto/modes/ghash-x86.asm b/third_party/boringssl/win-x86/crypto/modes/ghash-x86.asm
index eb493ac..1d350d6a7 100644
--- a/third_party/boringssl/win-x86/crypto/modes/ghash-x86.asm
+++ b/third_party/boringssl/win-x86/crypto/modes/ghash-x86.asm
@@ -14,205 +14,6 @@
 %else
 section	.text	code
 %endif
-global	_gcm_gmult_4bit_x86
-align	16
-_gcm_gmult_4bit_x86:
-L$_gcm_gmult_4bit_x86_begin:
-	push	ebp
-	push	ebx
-	push	esi
-	push	edi
-	sub	esp,84
-	mov	edi,DWORD [104+esp]
-	mov	esi,DWORD [108+esp]
-	mov	ebp,DWORD [edi]
-	mov	edx,DWORD [4+edi]
-	mov	ecx,DWORD [8+edi]
-	mov	ebx,DWORD [12+edi]
-	mov	DWORD [16+esp],0
-	mov	DWORD [20+esp],471859200
-	mov	DWORD [24+esp],943718400
-	mov	DWORD [28+esp],610271232
-	mov	DWORD [32+esp],1887436800
-	mov	DWORD [36+esp],1822425088
-	mov	DWORD [40+esp],1220542464
-	mov	DWORD [44+esp],1423966208
-	mov	DWORD [48+esp],3774873600
-	mov	DWORD [52+esp],4246732800
-	mov	DWORD [56+esp],3644850176
-	mov	DWORD [60+esp],3311403008
-	mov	DWORD [64+esp],2441084928
-	mov	DWORD [68+esp],2376073216
-	mov	DWORD [72+esp],2847932416
-	mov	DWORD [76+esp],3051356160
-	mov	DWORD [esp],ebp
-	mov	DWORD [4+esp],edx
-	mov	DWORD [8+esp],ecx
-	mov	DWORD [12+esp],ebx
-	shr	ebx,20
-	and	ebx,240
-	mov	ebp,DWORD [4+ebx*1+esi]
-	mov	edx,DWORD [ebx*1+esi]
-	mov	ecx,DWORD [12+ebx*1+esi]
-	mov	ebx,DWORD [8+ebx*1+esi]
-	xor	eax,eax
-	mov	edi,15
-	jmp	NEAR L$000x86_loop
-align	16
-L$000x86_loop:
-	mov	al,bl
-	shrd	ebx,ecx,4
-	and	al,15
-	shrd	ecx,edx,4
-	shrd	edx,ebp,4
-	shr	ebp,4
-	xor	ebp,DWORD [16+eax*4+esp]
-	mov	al,BYTE [edi*1+esp]
-	and	al,240
-	xor	ebx,DWORD [8+eax*1+esi]
-	xor	ecx,DWORD [12+eax*1+esi]
-	xor	edx,DWORD [eax*1+esi]
-	xor	ebp,DWORD [4+eax*1+esi]
-	dec	edi
-	js	NEAR L$001x86_break
-	mov	al,bl
-	shrd	ebx,ecx,4
-	and	al,15
-	shrd	ecx,edx,4
-	shrd	edx,ebp,4
-	shr	ebp,4
-	xor	ebp,DWORD [16+eax*4+esp]
-	mov	al,BYTE [edi*1+esp]
-	shl	al,4
-	xor	ebx,DWORD [8+eax*1+esi]
-	xor	ecx,DWORD [12+eax*1+esi]
-	xor	edx,DWORD [eax*1+esi]
-	xor	ebp,DWORD [4+eax*1+esi]
-	jmp	NEAR L$000x86_loop
-align	16
-L$001x86_break:
-	bswap	ebx
-	bswap	ecx
-	bswap	edx
-	bswap	ebp
-	mov	edi,DWORD [104+esp]
-	mov	DWORD [12+edi],ebx
-	mov	DWORD [8+edi],ecx
-	mov	DWORD [4+edi],edx
-	mov	DWORD [edi],ebp
-	add	esp,84
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
-global	_gcm_ghash_4bit_x86
-align	16
-_gcm_ghash_4bit_x86:
-L$_gcm_ghash_4bit_x86_begin:
-	push	ebp
-	push	ebx
-	push	esi
-	push	edi
-	sub	esp,84
-	mov	ebx,DWORD [104+esp]
-	mov	esi,DWORD [108+esp]
-	mov	edi,DWORD [112+esp]
-	mov	ecx,DWORD [116+esp]
-	add	ecx,edi
-	mov	DWORD [116+esp],ecx
-	mov	ebp,DWORD [ebx]
-	mov	edx,DWORD [4+ebx]
-	mov	ecx,DWORD [8+ebx]
-	mov	ebx,DWORD [12+ebx]
-	mov	DWORD [16+esp],0
-	mov	DWORD [20+esp],471859200
-	mov	DWORD [24+esp],943718400
-	mov	DWORD [28+esp],610271232
-	mov	DWORD [32+esp],1887436800
-	mov	DWORD [36+esp],1822425088
-	mov	DWORD [40+esp],1220542464
-	mov	DWORD [44+esp],1423966208
-	mov	DWORD [48+esp],3774873600
-	mov	DWORD [52+esp],4246732800
-	mov	DWORD [56+esp],3644850176
-	mov	DWORD [60+esp],3311403008
-	mov	DWORD [64+esp],2441084928
-	mov	DWORD [68+esp],2376073216
-	mov	DWORD [72+esp],2847932416
-	mov	DWORD [76+esp],3051356160
-align	16
-L$002x86_outer_loop:
-	xor	ebx,DWORD [12+edi]
-	xor	ecx,DWORD [8+edi]
-	xor	edx,DWORD [4+edi]
-	xor	ebp,DWORD [edi]
-	mov	DWORD [12+esp],ebx
-	mov	DWORD [8+esp],ecx
-	mov	DWORD [4+esp],edx
-	mov	DWORD [esp],ebp
-	shr	ebx,20
-	and	ebx,240
-	mov	ebp,DWORD [4+ebx*1+esi]
-	mov	edx,DWORD [ebx*1+esi]
-	mov	ecx,DWORD [12+ebx*1+esi]
-	mov	ebx,DWORD [8+ebx*1+esi]
-	xor	eax,eax
-	mov	edi,15
-	jmp	NEAR L$003x86_loop
-align	16
-L$003x86_loop:
-	mov	al,bl
-	shrd	ebx,ecx,4
-	and	al,15
-	shrd	ecx,edx,4
-	shrd	edx,ebp,4
-	shr	ebp,4
-	xor	ebp,DWORD [16+eax*4+esp]
-	mov	al,BYTE [edi*1+esp]
-	and	al,240
-	xor	ebx,DWORD [8+eax*1+esi]
-	xor	ecx,DWORD [12+eax*1+esi]
-	xor	edx,DWORD [eax*1+esi]
-	xor	ebp,DWORD [4+eax*1+esi]
-	dec	edi
-	js	NEAR L$004x86_break
-	mov	al,bl
-	shrd	ebx,ecx,4
-	and	al,15
-	shrd	ecx,edx,4
-	shrd	edx,ebp,4
-	shr	ebp,4
-	xor	ebp,DWORD [16+eax*4+esp]
-	mov	al,BYTE [edi*1+esp]
-	shl	al,4
-	xor	ebx,DWORD [8+eax*1+esi]
-	xor	ecx,DWORD [12+eax*1+esi]
-	xor	edx,DWORD [eax*1+esi]
-	xor	ebp,DWORD [4+eax*1+esi]
-	jmp	NEAR L$003x86_loop
-align	16
-L$004x86_break:
-	bswap	ebx
-	bswap	ecx
-	bswap	edx
-	bswap	ebp
-	mov	edi,DWORD [112+esp]
-	lea	edi,[16+edi]
-	cmp	edi,DWORD [116+esp]
-	mov	DWORD [112+esp],edi
-	jb	NEAR L$002x86_outer_loop
-	mov	edi,DWORD [104+esp]
-	mov	DWORD [12+edi],ebx
-	mov	DWORD [8+edi],ecx
-	mov	DWORD [4+edi],edx
-	mov	DWORD [edi],ebp
-	add	esp,84
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
 global	_gcm_gmult_4bit_mmx
 align	16
 _gcm_gmult_4bit_mmx:
@@ -223,10 +24,10 @@
 	push	edi
 	mov	edi,DWORD [20+esp]
 	mov	esi,DWORD [24+esp]
-	call	L$005pic_point
-L$005pic_point:
+	call	L$000pic_point
+L$000pic_point:
 	pop	eax
-	lea	eax,[(L$rem_4bit-L$005pic_point)+eax]
+	lea	eax,[(L$rem_4bit-L$000pic_point)+eax]
 	movzx	ebx,BYTE [15+edi]
 	xor	ecx,ecx
 	mov	edx,ebx
@@ -237,9 +38,9 @@
 	movq	mm0,[8+ecx*1+esi]
 	movq	mm1,[ecx*1+esi]
 	movd	ebx,mm0
-	jmp	NEAR L$006mmx_loop
+	jmp	NEAR L$001mmx_loop
 align	16
-L$006mmx_loop:
+L$001mmx_loop:
 	psrlq	mm0,4
 	and	ebx,15
 	movq	mm2,mm1
@@ -253,7 +54,7 @@
 	pxor	mm1,[edx*1+esi]
 	mov	edx,ecx
 	pxor	mm0,mm2
-	js	NEAR L$007mmx_break
+	js	NEAR L$002mmx_break
 	shl	cl,4
 	and	ebx,15
 	psrlq	mm0,4
@@ -266,9 +67,9 @@
 	movd	ebx,mm0
 	pxor	mm1,[ecx*1+esi]
 	pxor	mm0,mm2
-	jmp	NEAR L$006mmx_loop
+	jmp	NEAR L$001mmx_loop
 align	16
-L$007mmx_break:
+L$002mmx_break:
 	shl	cl,4
 	and	ebx,15
 	psrlq	mm0,4
@@ -323,10 +124,10 @@
 	mov	ecx,DWORD [28+esp]
 	mov	edx,DWORD [32+esp]
 	mov	ebp,esp
-	call	L$008pic_point
-L$008pic_point:
+	call	L$003pic_point
+L$003pic_point:
 	pop	esi
-	lea	esi,[(L$rem_8bit-L$008pic_point)+esi]
+	lea	esi,[(L$rem_8bit-L$003pic_point)+esi]
 	sub	esp,544
 	and	esp,-64
 	sub	esp,16
@@ -565,7 +366,7 @@
 	mov	ebx,DWORD [8+eax]
 	mov	edx,DWORD [12+eax]
 align	16
-L$009outer:
+L$004outer:
 	xor	edx,DWORD [12+ecx]
 	xor	ebx,DWORD [8+ecx]
 	pxor	mm6,[ecx]
@@ -900,7 +701,7 @@
 	pshufw	mm6,mm6,27
 	bswap	ebx
 	cmp	ecx,DWORD [552+esp]
-	jne	NEAR L$009outer
+	jne	NEAR L$004outer
 	mov	eax,DWORD [544+esp]
 	mov	DWORD [12+eax],edx
 	mov	DWORD [8+eax],ebx
@@ -918,10 +719,10 @@
 L$_gcm_init_clmul_begin:
 	mov	edx,DWORD [4+esp]
 	mov	eax,DWORD [8+esp]
-	call	L$010pic
-L$010pic:
+	call	L$005pic
+L$005pic:
 	pop	ecx
-	lea	ecx,[(L$bswap-L$010pic)+ecx]
+	lea	ecx,[(L$bswap-L$005pic)+ecx]
 	movdqu	xmm2,[eax]
 	pshufd	xmm2,xmm2,78
 	pshufd	xmm4,xmm2,255
@@ -985,10 +786,10 @@
 L$_gcm_gmult_clmul_begin:
 	mov	eax,DWORD [4+esp]
 	mov	edx,DWORD [8+esp]
-	call	L$011pic
-L$011pic:
+	call	L$006pic
+L$006pic:
 	pop	ecx
-	lea	ecx,[(L$bswap-L$011pic)+ecx]
+	lea	ecx,[(L$bswap-L$006pic)+ecx]
 	movdqu	xmm0,[eax]
 	movdqa	xmm5,[ecx]
 	movups	xmm2,[edx]
@@ -1042,16 +843,16 @@
 	mov	edx,DWORD [24+esp]
 	mov	esi,DWORD [28+esp]
 	mov	ebx,DWORD [32+esp]
-	call	L$012pic
-L$012pic:
+	call	L$007pic
+L$007pic:
 	pop	ecx
-	lea	ecx,[(L$bswap-L$012pic)+ecx]
+	lea	ecx,[(L$bswap-L$007pic)+ecx]
 	movdqu	xmm0,[eax]
 	movdqa	xmm5,[ecx]
 	movdqu	xmm2,[edx]
 db	102,15,56,0,197
 	sub	ebx,16
-	jz	NEAR L$013odd_tail
+	jz	NEAR L$008odd_tail
 	movdqu	xmm3,[esi]
 	movdqu	xmm6,[16+esi]
 db	102,15,56,0,221
@@ -1068,10 +869,10 @@
 	movups	xmm2,[16+edx]
 	nop
 	sub	ebx,32
-	jbe	NEAR L$014even_tail
-	jmp	NEAR L$015mod_loop
+	jbe	NEAR L$009even_tail
+	jmp	NEAR L$010mod_loop
 align	32
-L$015mod_loop:
+L$010mod_loop:
 	pshufd	xmm4,xmm0,78
 	movdqa	xmm1,xmm0
 	pxor	xmm4,xmm0
@@ -1126,8 +927,8 @@
 db	102,15,58,68,221,0
 	lea	esi,[32+esi]
 	sub	ebx,32
-	ja	NEAR L$015mod_loop
-L$014even_tail:
+	ja	NEAR L$010mod_loop
+L$009even_tail:
 	pshufd	xmm4,xmm0,78
 	movdqa	xmm1,xmm0
 	pxor	xmm4,xmm0
@@ -1166,9 +967,9 @@
 	psrlq	xmm0,1
 	pxor	xmm0,xmm1
 	test	ebx,ebx
-	jnz	NEAR L$016done
+	jnz	NEAR L$011done
 	movups	xmm2,[edx]
-L$013odd_tail:
+L$008odd_tail:
 	movdqu	xmm3,[esi]
 db	102,15,56,0,221
 	pxor	xmm0,xmm3
@@ -1207,7 +1008,7 @@
 	pxor	xmm0,xmm4
 	psrlq	xmm0,1
 	pxor	xmm0,xmm1
-L$016done:
+L$011done:
 db	102,15,56,0,197
 	movdqu	[eax],xmm0
 	pop	edi
diff --git a/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm b/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm
index cbcf883..55db00e 100644
--- a/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm
+++ b/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm
@@ -21,58 +21,6 @@
 	DQ	0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe
 
 
-ALIGN	64
-ecp_nistz256_mul_by_2:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_ecp_nistz256_mul_by_2:
-	mov	rdi,rcx
-	mov	rsi,rdx
-
-
-	push	r12
-	push	r13
-
-	mov	r8,QWORD[rsi]
-	xor	r13,r13
-	mov	r9,QWORD[8+rsi]
-	add	r8,r8
-	mov	r10,QWORD[16+rsi]
-	adc	r9,r9
-	mov	r11,QWORD[24+rsi]
-	lea	rsi,[$L$poly]
-	mov	rax,r8
-	adc	r10,r10
-	adc	r11,r11
-	mov	rdx,r9
-	adc	r13,0
-
-	sub	r8,QWORD[rsi]
-	mov	rcx,r10
-	sbb	r9,QWORD[8+rsi]
-	sbb	r10,QWORD[16+rsi]
-	mov	r12,r11
-	sbb	r11,QWORD[24+rsi]
-	sbb	r13,0
-
-	cmovc	r8,rax
-	cmovc	r9,rdx
-	mov	QWORD[rdi],r8
-	cmovc	r10,rcx
-	mov	QWORD[8+rdi],r9
-	cmovc	r11,r12
-	mov	QWORD[16+rdi],r10
-	mov	QWORD[24+rdi],r11
-
-	pop	r13
-	pop	r12
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-$L$SEH_end_ecp_nistz256_mul_by_2:
-
-
 
 global	ecp_nistz256_neg
 
@@ -595,112 +543,6 @@
 
 
 
-
-
-
-
-global	ecp_nistz256_from_mont
-
-ALIGN	32
-ecp_nistz256_from_mont:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_ecp_nistz256_from_mont:
-	mov	rdi,rcx
-	mov	rsi,rdx
-
-
-	push	r12
-	push	r13
-
-	mov	rax,QWORD[rsi]
-	mov	r13,QWORD[(($L$poly+24))]
-	mov	r9,QWORD[8+rsi]
-	mov	r10,QWORD[16+rsi]
-	mov	r11,QWORD[24+rsi]
-	mov	r8,rax
-	mov	r12,QWORD[(($L$poly+8))]
-
-
-
-	mov	rcx,rax
-	shl	r8,32
-	mul	r13
-	shr	rcx,32
-	add	r9,r8
-	adc	r10,rcx
-	adc	r11,rax
-	mov	rax,r9
-	adc	rdx,0
-
-
-
-	mov	rcx,r9
-	shl	r9,32
-	mov	r8,rdx
-	mul	r13
-	shr	rcx,32
-	add	r10,r9
-	adc	r11,rcx
-	adc	r8,rax
-	mov	rax,r10
-	adc	rdx,0
-
-
-
-	mov	rcx,r10
-	shl	r10,32
-	mov	r9,rdx
-	mul	r13
-	shr	rcx,32
-	add	r11,r10
-	adc	r8,rcx
-	adc	r9,rax
-	mov	rax,r11
-	adc	rdx,0
-
-
-
-	mov	rcx,r11
-	shl	r11,32
-	mov	r10,rdx
-	mul	r13
-	shr	rcx,32
-	add	r8,r11
-	adc	r9,rcx
-	mov	rcx,r8
-	adc	r10,rax
-	mov	rsi,r9
-	adc	rdx,0
-
-
-
-	sub	r8,-1
-	mov	rax,r10
-	sbb	r9,r12
-	sbb	r10,0
-	mov	r11,rdx
-	sbb	rdx,r13
-	sbb	r13,r13
-
-	cmovnz	r8,rcx
-	cmovnz	r9,rsi
-	mov	QWORD[rdi],r8
-	cmovnz	r10,rax
-	mov	QWORD[8+rdi],r9
-	cmovz	r11,rdx
-	mov	QWORD[16+rdi],r10
-	mov	QWORD[24+rdi],r11
-
-	pop	r13
-	pop	r12
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-$L$SEH_end_ecp_nistz256_from_mont:
-
-
 global	ecp_nistz256_select_w5
 
 ALIGN	32
diff --git a/third_party/boringssl/win-x86_64/crypto/modes/aesni-gcm-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/modes/aesni-gcm-x86_64.asm
index d7fff6a..741a9e4 100644
--- a/third_party/boringssl/win-x86_64/crypto/modes/aesni-gcm-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/modes/aesni-gcm-x86_64.asm
@@ -5,16 +5,982 @@
 section	.text code align=64
 
 
-global	aesni_gcm_encrypt
 
-aesni_gcm_encrypt:
-	xor	eax,eax
+ALIGN	32
+_aesni_ctr32_ghash_6x:
+	vmovdqu	xmm2,XMMWORD[32+r11]
+	sub	rdx,6
+	vpxor	xmm4,xmm4,xmm4
+	vmovdqu	xmm15,XMMWORD[((0-128))+rcx]
+	vpaddb	xmm10,xmm1,xmm2
+	vpaddb	xmm11,xmm10,xmm2
+	vpaddb	xmm12,xmm11,xmm2
+	vpaddb	xmm13,xmm12,xmm2
+	vpaddb	xmm14,xmm13,xmm2
+	vpxor	xmm9,xmm1,xmm15
+	vmovdqu	XMMWORD[(16+8)+rsp],xmm4
+	jmp	NEAR $L$oop6x
+
+ALIGN	32
+$L$oop6x:
+	add	ebx,100663296
+	jc	NEAR $L$handle_ctr32
+	vmovdqu	xmm3,XMMWORD[((0-32))+r9]
+	vpaddb	xmm1,xmm14,xmm2
+	vpxor	xmm10,xmm10,xmm15
+	vpxor	xmm11,xmm11,xmm15
+
+$L$resume_ctr32:
+	vmovdqu	XMMWORD[r8],xmm1
+	vpclmulqdq	xmm5,xmm7,xmm3,0x10
+	vpxor	xmm12,xmm12,xmm15
+	vmovups	xmm2,XMMWORD[((16-128))+rcx]
+	vpclmulqdq	xmm6,xmm7,xmm3,0x01
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	xor	r12,r12
+	cmp	r15,r14
+
+	vaesenc	xmm9,xmm9,xmm2
+	vmovdqu	xmm0,XMMWORD[((48+8))+rsp]
+	vpxor	xmm13,xmm13,xmm15
+	vpclmulqdq	xmm1,xmm7,xmm3,0x00
+	vaesenc	xmm10,xmm10,xmm2
+	vpxor	xmm14,xmm14,xmm15
+	setnc	r12b
+	vpclmulqdq	xmm7,xmm7,xmm3,0x11
+	vaesenc	xmm11,xmm11,xmm2
+	vmovdqu	xmm3,XMMWORD[((16-32))+r9]
+	neg	r12
+	vaesenc	xmm12,xmm12,xmm2
+	vpxor	xmm6,xmm6,xmm5
+	vpclmulqdq	xmm5,xmm0,xmm3,0x00
+	vpxor	xmm8,xmm8,xmm4
+	vaesenc	xmm13,xmm13,xmm2
+	vpxor	xmm4,xmm1,xmm5
+	and	r12,0x60
+	vmovups	xmm15,XMMWORD[((32-128))+rcx]
+	vpclmulqdq	xmm1,xmm0,xmm3,0x10
+	vaesenc	xmm14,xmm14,xmm2
+
+	vpclmulqdq	xmm2,xmm0,xmm3,0x01
+	lea	r14,[r12*1+r14]
+	vaesenc	xmm9,xmm9,xmm15
+	vpxor	xmm8,xmm8,XMMWORD[((16+8))+rsp]
+	vpclmulqdq	xmm3,xmm0,xmm3,0x11
+	vmovdqu	xmm0,XMMWORD[((64+8))+rsp]
+	vaesenc	xmm10,xmm10,xmm15
+	movbe	r13,QWORD[88+r14]
+	vaesenc	xmm11,xmm11,xmm15
+	movbe	r12,QWORD[80+r14]
+	vaesenc	xmm12,xmm12,xmm15
+	mov	QWORD[((32+8))+rsp],r13
+	vaesenc	xmm13,xmm13,xmm15
+	mov	QWORD[((40+8))+rsp],r12
+	vmovdqu	xmm5,XMMWORD[((48-32))+r9]
+	vaesenc	xmm14,xmm14,xmm15
+
+	vmovups	xmm15,XMMWORD[((48-128))+rcx]
+	vpxor	xmm6,xmm6,xmm1
+	vpclmulqdq	xmm1,xmm0,xmm5,0x00
+	vaesenc	xmm9,xmm9,xmm15
+	vpxor	xmm6,xmm6,xmm2
+	vpclmulqdq	xmm2,xmm0,xmm5,0x10
+	vaesenc	xmm10,xmm10,xmm15
+	vpxor	xmm7,xmm7,xmm3
+	vpclmulqdq	xmm3,xmm0,xmm5,0x01
+	vaesenc	xmm11,xmm11,xmm15
+	vpclmulqdq	xmm5,xmm0,xmm5,0x11
+	vmovdqu	xmm0,XMMWORD[((80+8))+rsp]
+	vaesenc	xmm12,xmm12,xmm15
+	vaesenc	xmm13,xmm13,xmm15
+	vpxor	xmm4,xmm4,xmm1
+	vmovdqu	xmm1,XMMWORD[((64-32))+r9]
+	vaesenc	xmm14,xmm14,xmm15
+
+	vmovups	xmm15,XMMWORD[((64-128))+rcx]
+	vpxor	xmm6,xmm6,xmm2
+	vpclmulqdq	xmm2,xmm0,xmm1,0x00
+	vaesenc	xmm9,xmm9,xmm15
+	vpxor	xmm6,xmm6,xmm3
+	vpclmulqdq	xmm3,xmm0,xmm1,0x10
+	vaesenc	xmm10,xmm10,xmm15
+	movbe	r13,QWORD[72+r14]
+	vpxor	xmm7,xmm7,xmm5
+	vpclmulqdq	xmm5,xmm0,xmm1,0x01
+	vaesenc	xmm11,xmm11,xmm15
+	movbe	r12,QWORD[64+r14]
+	vpclmulqdq	xmm1,xmm0,xmm1,0x11
+	vmovdqu	xmm0,XMMWORD[((96+8))+rsp]
+	vaesenc	xmm12,xmm12,xmm15
+	mov	QWORD[((48+8))+rsp],r13
+	vaesenc	xmm13,xmm13,xmm15
+	mov	QWORD[((56+8))+rsp],r12
+	vpxor	xmm4,xmm4,xmm2
+	vmovdqu	xmm2,XMMWORD[((96-32))+r9]
+	vaesenc	xmm14,xmm14,xmm15
+
+	vmovups	xmm15,XMMWORD[((80-128))+rcx]
+	vpxor	xmm6,xmm6,xmm3
+	vpclmulqdq	xmm3,xmm0,xmm2,0x00
+	vaesenc	xmm9,xmm9,xmm15
+	vpxor	xmm6,xmm6,xmm5
+	vpclmulqdq	xmm5,xmm0,xmm2,0x10
+	vaesenc	xmm10,xmm10,xmm15
+	movbe	r13,QWORD[56+r14]
+	vpxor	xmm7,xmm7,xmm1
+	vpclmulqdq	xmm1,xmm0,xmm2,0x01
+	vpxor	xmm8,xmm8,XMMWORD[((112+8))+rsp]
+	vaesenc	xmm11,xmm11,xmm15
+	movbe	r12,QWORD[48+r14]
+	vpclmulqdq	xmm2,xmm0,xmm2,0x11
+	vaesenc	xmm12,xmm12,xmm15
+	mov	QWORD[((64+8))+rsp],r13
+	vaesenc	xmm13,xmm13,xmm15
+	mov	QWORD[((72+8))+rsp],r12
+	vpxor	xmm4,xmm4,xmm3
+	vmovdqu	xmm3,XMMWORD[((112-32))+r9]
+	vaesenc	xmm14,xmm14,xmm15
+
+	vmovups	xmm15,XMMWORD[((96-128))+rcx]
+	vpxor	xmm6,xmm6,xmm5
+	vpclmulqdq	xmm5,xmm8,xmm3,0x10
+	vaesenc	xmm9,xmm9,xmm15
+	vpxor	xmm6,xmm6,xmm1
+	vpclmulqdq	xmm1,xmm8,xmm3,0x01
+	vaesenc	xmm10,xmm10,xmm15
+	movbe	r13,QWORD[40+r14]
+	vpxor	xmm7,xmm7,xmm2
+	vpclmulqdq	xmm2,xmm8,xmm3,0x00
+	vaesenc	xmm11,xmm11,xmm15
+	movbe	r12,QWORD[32+r14]
+	vpclmulqdq	xmm8,xmm8,xmm3,0x11
+	vaesenc	xmm12,xmm12,xmm15
+	mov	QWORD[((80+8))+rsp],r13
+	vaesenc	xmm13,xmm13,xmm15
+	mov	QWORD[((88+8))+rsp],r12
+	vpxor	xmm6,xmm6,xmm5
+	vaesenc	xmm14,xmm14,xmm15
+	vpxor	xmm6,xmm6,xmm1
+
+	vmovups	xmm15,XMMWORD[((112-128))+rcx]
+	vpslldq	xmm5,xmm6,8
+	vpxor	xmm4,xmm4,xmm2
+	vmovdqu	xmm3,XMMWORD[16+r11]
+
+	vaesenc	xmm9,xmm9,xmm15
+	vpxor	xmm7,xmm7,xmm8
+	vaesenc	xmm10,xmm10,xmm15
+	vpxor	xmm4,xmm4,xmm5
+	movbe	r13,QWORD[24+r14]
+	vaesenc	xmm11,xmm11,xmm15
+	movbe	r12,QWORD[16+r14]
+	vpalignr	xmm0,xmm4,xmm4,8
+	vpclmulqdq	xmm4,xmm4,xmm3,0x10
+	mov	QWORD[((96+8))+rsp],r13
+	vaesenc	xmm12,xmm12,xmm15
+	mov	QWORD[((104+8))+rsp],r12
+	vaesenc	xmm13,xmm13,xmm15
+	vmovups	xmm1,XMMWORD[((128-128))+rcx]
+	vaesenc	xmm14,xmm14,xmm15
+
+	vaesenc	xmm9,xmm9,xmm1
+	vmovups	xmm15,XMMWORD[((144-128))+rcx]
+	vaesenc	xmm10,xmm10,xmm1
+	vpsrldq	xmm6,xmm6,8
+	vaesenc	xmm11,xmm11,xmm1
+	vpxor	xmm7,xmm7,xmm6
+	vaesenc	xmm12,xmm12,xmm1
+	vpxor	xmm4,xmm4,xmm0
+	movbe	r13,QWORD[8+r14]
+	vaesenc	xmm13,xmm13,xmm1
+	movbe	r12,QWORD[r14]
+	vaesenc	xmm14,xmm14,xmm1
+	vmovups	xmm1,XMMWORD[((160-128))+rcx]
+	cmp	ebp,11
+	jb	NEAR $L$enc_tail
+
+	vaesenc	xmm9,xmm9,xmm15
+	vaesenc	xmm10,xmm10,xmm15
+	vaesenc	xmm11,xmm11,xmm15
+	vaesenc	xmm12,xmm12,xmm15
+	vaesenc	xmm13,xmm13,xmm15
+	vaesenc	xmm14,xmm14,xmm15
+
+	vaesenc	xmm9,xmm9,xmm1
+	vaesenc	xmm10,xmm10,xmm1
+	vaesenc	xmm11,xmm11,xmm1
+	vaesenc	xmm12,xmm12,xmm1
+	vaesenc	xmm13,xmm13,xmm1
+	vmovups	xmm15,XMMWORD[((176-128))+rcx]
+	vaesenc	xmm14,xmm14,xmm1
+	vmovups	xmm1,XMMWORD[((192-128))+rcx]
+	je	NEAR $L$enc_tail
+
+	vaesenc	xmm9,xmm9,xmm15
+	vaesenc	xmm10,xmm10,xmm15
+	vaesenc	xmm11,xmm11,xmm15
+	vaesenc	xmm12,xmm12,xmm15
+	vaesenc	xmm13,xmm13,xmm15
+	vaesenc	xmm14,xmm14,xmm15
+
+	vaesenc	xmm9,xmm9,xmm1
+	vaesenc	xmm10,xmm10,xmm1
+	vaesenc	xmm11,xmm11,xmm1
+	vaesenc	xmm12,xmm12,xmm1
+	vaesenc	xmm13,xmm13,xmm1
+	vmovups	xmm15,XMMWORD[((208-128))+rcx]
+	vaesenc	xmm14,xmm14,xmm1
+	vmovups	xmm1,XMMWORD[((224-128))+rcx]
+	jmp	NEAR $L$enc_tail
+
+ALIGN	32
+$L$handle_ctr32:
+	vmovdqu	xmm0,XMMWORD[r11]
+	vpshufb	xmm6,xmm1,xmm0
+	vmovdqu	xmm5,XMMWORD[48+r11]
+	vpaddd	xmm10,xmm6,XMMWORD[64+r11]
+	vpaddd	xmm11,xmm6,xmm5
+	vmovdqu	xmm3,XMMWORD[((0-32))+r9]
+	vpaddd	xmm12,xmm10,xmm5
+	vpshufb	xmm10,xmm10,xmm0
+	vpaddd	xmm13,xmm11,xmm5
+	vpshufb	xmm11,xmm11,xmm0
+	vpxor	xmm10,xmm10,xmm15
+	vpaddd	xmm14,xmm12,xmm5
+	vpshufb	xmm12,xmm12,xmm0
+	vpxor	xmm11,xmm11,xmm15
+	vpaddd	xmm1,xmm13,xmm5
+	vpshufb	xmm13,xmm13,xmm0
+	vpshufb	xmm14,xmm14,xmm0
+	vpshufb	xmm1,xmm1,xmm0
+	jmp	NEAR $L$resume_ctr32
+
+ALIGN	32
+$L$enc_tail:
+	vaesenc	xmm9,xmm9,xmm15
+	vmovdqu	XMMWORD[(16+8)+rsp],xmm7
+	vpalignr	xmm8,xmm4,xmm4,8
+	vaesenc	xmm10,xmm10,xmm15
+	vpclmulqdq	xmm4,xmm4,xmm3,0x10
+	vpxor	xmm2,xmm1,XMMWORD[rdi]
+	vaesenc	xmm11,xmm11,xmm15
+	vpxor	xmm0,xmm1,XMMWORD[16+rdi]
+	vaesenc	xmm12,xmm12,xmm15
+	vpxor	xmm5,xmm1,XMMWORD[32+rdi]
+	vaesenc	xmm13,xmm13,xmm15
+	vpxor	xmm6,xmm1,XMMWORD[48+rdi]
+	vaesenc	xmm14,xmm14,xmm15
+	vpxor	xmm7,xmm1,XMMWORD[64+rdi]
+	vpxor	xmm3,xmm1,XMMWORD[80+rdi]
+	vmovdqu	xmm1,XMMWORD[r8]
+
+	vaesenclast	xmm9,xmm9,xmm2
+	vmovdqu	xmm2,XMMWORD[32+r11]
+	vaesenclast	xmm10,xmm10,xmm0
+	vpaddb	xmm0,xmm1,xmm2
+	mov	QWORD[((112+8))+rsp],r13
+	lea	rdi,[96+rdi]
+	vaesenclast	xmm11,xmm11,xmm5
+	vpaddb	xmm5,xmm0,xmm2
+	mov	QWORD[((120+8))+rsp],r12
+	lea	rsi,[96+rsi]
+	vmovdqu	xmm15,XMMWORD[((0-128))+rcx]
+	vaesenclast	xmm12,xmm12,xmm6
+	vpaddb	xmm6,xmm5,xmm2
+	vaesenclast	xmm13,xmm13,xmm7
+	vpaddb	xmm7,xmm6,xmm2
+	vaesenclast	xmm14,xmm14,xmm3
+	vpaddb	xmm3,xmm7,xmm2
+
+	add	r10,0x60
+	sub	rdx,0x6
+	jc	NEAR $L$6x_done
+
+	vmovups	XMMWORD[(-96)+rsi],xmm9
+	vpxor	xmm9,xmm1,xmm15
+	vmovups	XMMWORD[(-80)+rsi],xmm10
+	vmovdqa	xmm10,xmm0
+	vmovups	XMMWORD[(-64)+rsi],xmm11
+	vmovdqa	xmm11,xmm5
+	vmovups	XMMWORD[(-48)+rsi],xmm12
+	vmovdqa	xmm12,xmm6
+	vmovups	XMMWORD[(-32)+rsi],xmm13
+	vmovdqa	xmm13,xmm7
+	vmovups	XMMWORD[(-16)+rsi],xmm14
+	vmovdqa	xmm14,xmm3
+	vmovdqu	xmm7,XMMWORD[((32+8))+rsp]
+	jmp	NEAR $L$oop6x
+
+$L$6x_done:
+	vpxor	xmm8,xmm8,XMMWORD[((16+8))+rsp]
+	vpxor	xmm8,xmm8,xmm4
+
 	DB	0F3h,0C3h		;repret
 
-
 global	aesni_gcm_decrypt
 
+ALIGN	32
 aesni_gcm_decrypt:
-	xor	eax,eax
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_aesni_gcm_decrypt:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+	mov	r9,QWORD[48+rsp]
+
+
+	xor	r10,r10
+
+
+
+	cmp	rdx,0x60
+	jb	NEAR $L$gcm_dec_abort
+
+	lea	rax,[rsp]
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	lea	rsp,[((-168))+rsp]
+	movaps	XMMWORD[(-216)+rax],xmm6
+	movaps	XMMWORD[(-200)+rax],xmm7
+	movaps	XMMWORD[(-184)+rax],xmm8
+	movaps	XMMWORD[(-168)+rax],xmm9
+	movaps	XMMWORD[(-152)+rax],xmm10
+	movaps	XMMWORD[(-136)+rax],xmm11
+	movaps	XMMWORD[(-120)+rax],xmm12
+	movaps	XMMWORD[(-104)+rax],xmm13
+	movaps	XMMWORD[(-88)+rax],xmm14
+	movaps	XMMWORD[(-72)+rax],xmm15
+$L$gcm_dec_body:
+	vzeroupper
+
+	vmovdqu	xmm1,XMMWORD[r8]
+	add	rsp,-128
+	mov	ebx,DWORD[12+r8]
+	lea	r11,[$L$bswap_mask]
+	lea	r14,[((-128))+rcx]
+	mov	r15,0xf80
+	vmovdqu	xmm8,XMMWORD[r9]
+	and	rsp,-128
+	vmovdqu	xmm0,XMMWORD[r11]
+	lea	rcx,[128+rcx]
+	lea	r9,[((32+32))+r9]
+	mov	ebp,DWORD[((240-128))+rcx]
+	vpshufb	xmm8,xmm8,xmm0
+
+	and	r14,r15
+	and	r15,rsp
+	sub	r15,r14
+	jc	NEAR $L$dec_no_key_aliasing
+	cmp	r15,768
+	jnc	NEAR $L$dec_no_key_aliasing
+	sub	rsp,r15
+$L$dec_no_key_aliasing:
+
+	vmovdqu	xmm7,XMMWORD[80+rdi]
+	lea	r14,[rdi]
+	vmovdqu	xmm4,XMMWORD[64+rdi]
+
+
+
+
+
+
+
+	lea	r15,[((-192))+rdx*1+rdi]
+
+	vmovdqu	xmm5,XMMWORD[48+rdi]
+	shr	rdx,4
+	xor	r10,r10
+	vmovdqu	xmm6,XMMWORD[32+rdi]
+	vpshufb	xmm7,xmm7,xmm0
+	vmovdqu	xmm2,XMMWORD[16+rdi]
+	vpshufb	xmm4,xmm4,xmm0
+	vmovdqu	xmm3,XMMWORD[rdi]
+	vpshufb	xmm5,xmm5,xmm0
+	vmovdqu	XMMWORD[48+rsp],xmm4
+	vpshufb	xmm6,xmm6,xmm0
+	vmovdqu	XMMWORD[64+rsp],xmm5
+	vpshufb	xmm2,xmm2,xmm0
+	vmovdqu	XMMWORD[80+rsp],xmm6
+	vpshufb	xmm3,xmm3,xmm0
+	vmovdqu	XMMWORD[96+rsp],xmm2
+	vmovdqu	XMMWORD[112+rsp],xmm3
+
+	call	_aesni_ctr32_ghash_6x
+
+	vmovups	XMMWORD[(-96)+rsi],xmm9
+	vmovups	XMMWORD[(-80)+rsi],xmm10
+	vmovups	XMMWORD[(-64)+rsi],xmm11
+	vmovups	XMMWORD[(-48)+rsi],xmm12
+	vmovups	XMMWORD[(-32)+rsi],xmm13
+	vmovups	XMMWORD[(-16)+rsi],xmm14
+
+	vpshufb	xmm8,xmm8,XMMWORD[r11]
+	vmovdqu	XMMWORD[(-64)+r9],xmm8
+
+	vzeroupper
+	movaps	xmm6,XMMWORD[((-216))+rax]
+	movaps	xmm7,XMMWORD[((-200))+rax]
+	movaps	xmm8,XMMWORD[((-184))+rax]
+	movaps	xmm9,XMMWORD[((-168))+rax]
+	movaps	xmm10,XMMWORD[((-152))+rax]
+	movaps	xmm11,XMMWORD[((-136))+rax]
+	movaps	xmm12,XMMWORD[((-120))+rax]
+	movaps	xmm13,XMMWORD[((-104))+rax]
+	movaps	xmm14,XMMWORD[((-88))+rax]
+	movaps	xmm15,XMMWORD[((-72))+rax]
+	mov	r15,QWORD[((-48))+rax]
+	mov	r14,QWORD[((-40))+rax]
+	mov	r13,QWORD[((-32))+rax]
+	mov	r12,QWORD[((-24))+rax]
+	mov	rbp,QWORD[((-16))+rax]
+	mov	rbx,QWORD[((-8))+rax]
+	lea	rsp,[rax]
+$L$gcm_dec_abort:
+	mov	rax,r10
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_aesni_gcm_decrypt:
+
+ALIGN	32
+_aesni_ctr32_6x:
+	vmovdqu	xmm4,XMMWORD[((0-128))+rcx]
+	vmovdqu	xmm2,XMMWORD[32+r11]
+	lea	r13,[((-1))+rbp]
+	vmovups	xmm15,XMMWORD[((16-128))+rcx]
+	lea	r12,[((32-128))+rcx]
+	vpxor	xmm9,xmm1,xmm4
+	add	ebx,100663296
+	jc	NEAR $L$handle_ctr32_2
+	vpaddb	xmm10,xmm1,xmm2
+	vpaddb	xmm11,xmm10,xmm2
+	vpxor	xmm10,xmm10,xmm4
+	vpaddb	xmm12,xmm11,xmm2
+	vpxor	xmm11,xmm11,xmm4
+	vpaddb	xmm13,xmm12,xmm2
+	vpxor	xmm12,xmm12,xmm4
+	vpaddb	xmm14,xmm13,xmm2
+	vpxor	xmm13,xmm13,xmm4
+	vpaddb	xmm1,xmm14,xmm2
+	vpxor	xmm14,xmm14,xmm4
+	jmp	NEAR $L$oop_ctr32
+
+ALIGN	16
+$L$oop_ctr32:
+	vaesenc	xmm9,xmm9,xmm15
+	vaesenc	xmm10,xmm10,xmm15
+	vaesenc	xmm11,xmm11,xmm15
+	vaesenc	xmm12,xmm12,xmm15
+	vaesenc	xmm13,xmm13,xmm15
+	vaesenc	xmm14,xmm14,xmm15
+	vmovups	xmm15,XMMWORD[r12]
+	lea	r12,[16+r12]
+	dec	r13d
+	jnz	NEAR $L$oop_ctr32
+
+	vmovdqu	xmm3,XMMWORD[r12]
+	vaesenc	xmm9,xmm9,xmm15
+	vpxor	xmm4,xmm3,XMMWORD[rdi]
+	vaesenc	xmm10,xmm10,xmm15
+	vpxor	xmm5,xmm3,XMMWORD[16+rdi]
+	vaesenc	xmm11,xmm11,xmm15
+	vpxor	xmm6,xmm3,XMMWORD[32+rdi]
+	vaesenc	xmm12,xmm12,xmm15
+	vpxor	xmm8,xmm3,XMMWORD[48+rdi]
+	vaesenc	xmm13,xmm13,xmm15
+	vpxor	xmm2,xmm3,XMMWORD[64+rdi]
+	vaesenc	xmm14,xmm14,xmm15
+	vpxor	xmm3,xmm3,XMMWORD[80+rdi]
+	lea	rdi,[96+rdi]
+
+	vaesenclast	xmm9,xmm9,xmm4
+	vaesenclast	xmm10,xmm10,xmm5
+	vaesenclast	xmm11,xmm11,xmm6
+	vaesenclast	xmm12,xmm12,xmm8
+	vaesenclast	xmm13,xmm13,xmm2
+	vaesenclast	xmm14,xmm14,xmm3
+	vmovups	XMMWORD[rsi],xmm9
+	vmovups	XMMWORD[16+rsi],xmm10
+	vmovups	XMMWORD[32+rsi],xmm11
+	vmovups	XMMWORD[48+rsi],xmm12
+	vmovups	XMMWORD[64+rsi],xmm13
+	vmovups	XMMWORD[80+rsi],xmm14
+	lea	rsi,[96+rsi]
+
+	DB	0F3h,0C3h		;repret
+ALIGN	32
+$L$handle_ctr32_2:
+	vpshufb	xmm6,xmm1,xmm0
+	vmovdqu	xmm5,XMMWORD[48+r11]
+	vpaddd	xmm10,xmm6,XMMWORD[64+r11]
+	vpaddd	xmm11,xmm6,xmm5
+	vpaddd	xmm12,xmm10,xmm5
+	vpshufb	xmm10,xmm10,xmm0
+	vpaddd	xmm13,xmm11,xmm5
+	vpshufb	xmm11,xmm11,xmm0
+	vpxor	xmm10,xmm10,xmm4
+	vpaddd	xmm14,xmm12,xmm5
+	vpshufb	xmm12,xmm12,xmm0
+	vpxor	xmm11,xmm11,xmm4
+	vpaddd	xmm1,xmm13,xmm5
+	vpshufb	xmm13,xmm13,xmm0
+	vpxor	xmm12,xmm12,xmm4
+	vpshufb	xmm14,xmm14,xmm0
+	vpxor	xmm13,xmm13,xmm4
+	vpshufb	xmm1,xmm1,xmm0
+	vpxor	xmm14,xmm14,xmm4
+	jmp	NEAR $L$oop_ctr32
+
+
+global	aesni_gcm_encrypt
+
+ALIGN	32
+aesni_gcm_encrypt:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_aesni_gcm_encrypt:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+	mov	r9,QWORD[48+rsp]
+
+
+	xor	r10,r10
+
+
+
+
+	cmp	rdx,0x60*3
+	jb	NEAR $L$gcm_enc_abort
+
+	lea	rax,[rsp]
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	lea	rsp,[((-168))+rsp]
+	movaps	XMMWORD[(-216)+rax],xmm6
+	movaps	XMMWORD[(-200)+rax],xmm7
+	movaps	XMMWORD[(-184)+rax],xmm8
+	movaps	XMMWORD[(-168)+rax],xmm9
+	movaps	XMMWORD[(-152)+rax],xmm10
+	movaps	XMMWORD[(-136)+rax],xmm11
+	movaps	XMMWORD[(-120)+rax],xmm12
+	movaps	XMMWORD[(-104)+rax],xmm13
+	movaps	XMMWORD[(-88)+rax],xmm14
+	movaps	XMMWORD[(-72)+rax],xmm15
+$L$gcm_enc_body:
+	vzeroupper
+
+	vmovdqu	xmm1,XMMWORD[r8]
+	add	rsp,-128
+	mov	ebx,DWORD[12+r8]
+	lea	r11,[$L$bswap_mask]
+	lea	r14,[((-128))+rcx]
+	mov	r15,0xf80
+	lea	rcx,[128+rcx]
+	vmovdqu	xmm0,XMMWORD[r11]
+	and	rsp,-128
+	mov	ebp,DWORD[((240-128))+rcx]
+
+	and	r14,r15
+	and	r15,rsp
+	sub	r15,r14
+	jc	NEAR $L$enc_no_key_aliasing
+	cmp	r15,768
+	jnc	NEAR $L$enc_no_key_aliasing
+	sub	rsp,r15
+$L$enc_no_key_aliasing:
+
+	lea	r14,[rsi]
+
+
+
+
+
+
+
+
+	lea	r15,[((-192))+rdx*1+rsi]
+
+	shr	rdx,4
+
+	call	_aesni_ctr32_6x
+	vpshufb	xmm8,xmm9,xmm0
+	vpshufb	xmm2,xmm10,xmm0
+	vmovdqu	XMMWORD[112+rsp],xmm8
+	vpshufb	xmm4,xmm11,xmm0
+	vmovdqu	XMMWORD[96+rsp],xmm2
+	vpshufb	xmm5,xmm12,xmm0
+	vmovdqu	XMMWORD[80+rsp],xmm4
+	vpshufb	xmm6,xmm13,xmm0
+	vmovdqu	XMMWORD[64+rsp],xmm5
+	vpshufb	xmm7,xmm14,xmm0
+	vmovdqu	XMMWORD[48+rsp],xmm6
+
+	call	_aesni_ctr32_6x
+
+	vmovdqu	xmm8,XMMWORD[r9]
+	lea	r9,[((32+32))+r9]
+	sub	rdx,12
+	mov	r10,0x60*2
+	vpshufb	xmm8,xmm8,xmm0
+
+	call	_aesni_ctr32_ghash_6x
+	vmovdqu	xmm7,XMMWORD[32+rsp]
+	vmovdqu	xmm0,XMMWORD[r11]
+	vmovdqu	xmm3,XMMWORD[((0-32))+r9]
+	vpunpckhqdq	xmm1,xmm7,xmm7
+	vmovdqu	xmm15,XMMWORD[((32-32))+r9]
+	vmovups	XMMWORD[(-96)+rsi],xmm9
+	vpshufb	xmm9,xmm9,xmm0
+	vpxor	xmm1,xmm1,xmm7
+	vmovups	XMMWORD[(-80)+rsi],xmm10
+	vpshufb	xmm10,xmm10,xmm0
+	vmovups	XMMWORD[(-64)+rsi],xmm11
+	vpshufb	xmm11,xmm11,xmm0
+	vmovups	XMMWORD[(-48)+rsi],xmm12
+	vpshufb	xmm12,xmm12,xmm0
+	vmovups	XMMWORD[(-32)+rsi],xmm13
+	vpshufb	xmm13,xmm13,xmm0
+	vmovups	XMMWORD[(-16)+rsi],xmm14
+	vpshufb	xmm14,xmm14,xmm0
+	vmovdqu	XMMWORD[16+rsp],xmm9
+	vmovdqu	xmm6,XMMWORD[48+rsp]
+	vmovdqu	xmm0,XMMWORD[((16-32))+r9]
+	vpunpckhqdq	xmm2,xmm6,xmm6
+	vpclmulqdq	xmm5,xmm7,xmm3,0x00
+	vpxor	xmm2,xmm2,xmm6
+	vpclmulqdq	xmm7,xmm7,xmm3,0x11
+	vpclmulqdq	xmm1,xmm1,xmm15,0x00
+
+	vmovdqu	xmm9,XMMWORD[64+rsp]
+	vpclmulqdq	xmm4,xmm6,xmm0,0x00
+	vmovdqu	xmm3,XMMWORD[((48-32))+r9]
+	vpxor	xmm4,xmm4,xmm5
+	vpunpckhqdq	xmm5,xmm9,xmm9
+	vpclmulqdq	xmm6,xmm6,xmm0,0x11
+	vpxor	xmm5,xmm5,xmm9
+	vpxor	xmm6,xmm6,xmm7
+	vpclmulqdq	xmm2,xmm2,xmm15,0x10
+	vmovdqu	xmm15,XMMWORD[((80-32))+r9]
+	vpxor	xmm2,xmm2,xmm1
+
+	vmovdqu	xmm1,XMMWORD[80+rsp]
+	vpclmulqdq	xmm7,xmm9,xmm3,0x00
+	vmovdqu	xmm0,XMMWORD[((64-32))+r9]
+	vpxor	xmm7,xmm7,xmm4
+	vpunpckhqdq	xmm4,xmm1,xmm1
+	vpclmulqdq	xmm9,xmm9,xmm3,0x11
+	vpxor	xmm4,xmm4,xmm1
+	vpxor	xmm9,xmm9,xmm6
+	vpclmulqdq	xmm5,xmm5,xmm15,0x00
+	vpxor	xmm5,xmm5,xmm2
+
+	vmovdqu	xmm2,XMMWORD[96+rsp]
+	vpclmulqdq	xmm6,xmm1,xmm0,0x00
+	vmovdqu	xmm3,XMMWORD[((96-32))+r9]
+	vpxor	xmm6,xmm6,xmm7
+	vpunpckhqdq	xmm7,xmm2,xmm2
+	vpclmulqdq	xmm1,xmm1,xmm0,0x11
+	vpxor	xmm7,xmm7,xmm2
+	vpxor	xmm1,xmm1,xmm9
+	vpclmulqdq	xmm4,xmm4,xmm15,0x10
+	vmovdqu	xmm15,XMMWORD[((128-32))+r9]
+	vpxor	xmm4,xmm4,xmm5
+
+	vpxor	xmm8,xmm8,XMMWORD[112+rsp]
+	vpclmulqdq	xmm5,xmm2,xmm3,0x00
+	vmovdqu	xmm0,XMMWORD[((112-32))+r9]
+	vpunpckhqdq	xmm9,xmm8,xmm8
+	vpxor	xmm5,xmm5,xmm6
+	vpclmulqdq	xmm2,xmm2,xmm3,0x11
+	vpxor	xmm9,xmm9,xmm8
+	vpxor	xmm2,xmm2,xmm1
+	vpclmulqdq	xmm7,xmm7,xmm15,0x00
+	vpxor	xmm4,xmm7,xmm4
+
+	vpclmulqdq	xmm6,xmm8,xmm0,0x00
+	vmovdqu	xmm3,XMMWORD[((0-32))+r9]
+	vpunpckhqdq	xmm1,xmm14,xmm14
+	vpclmulqdq	xmm8,xmm8,xmm0,0x11
+	vpxor	xmm1,xmm1,xmm14
+	vpxor	xmm5,xmm6,xmm5
+	vpclmulqdq	xmm9,xmm9,xmm15,0x10
+	vmovdqu	xmm15,XMMWORD[((32-32))+r9]
+	vpxor	xmm7,xmm8,xmm2
+	vpxor	xmm6,xmm9,xmm4
+
+	vmovdqu	xmm0,XMMWORD[((16-32))+r9]
+	vpxor	xmm9,xmm7,xmm5
+	vpclmulqdq	xmm4,xmm14,xmm3,0x00
+	vpxor	xmm6,xmm6,xmm9
+	vpunpckhqdq	xmm2,xmm13,xmm13
+	vpclmulqdq	xmm14,xmm14,xmm3,0x11
+	vpxor	xmm2,xmm2,xmm13
+	vpslldq	xmm9,xmm6,8
+	vpclmulqdq	xmm1,xmm1,xmm15,0x00
+	vpxor	xmm8,xmm5,xmm9
+	vpsrldq	xmm6,xmm6,8
+	vpxor	xmm7,xmm7,xmm6
+
+	vpclmulqdq	xmm5,xmm13,xmm0,0x00
+	vmovdqu	xmm3,XMMWORD[((48-32))+r9]
+	vpxor	xmm5,xmm5,xmm4
+	vpunpckhqdq	xmm9,xmm12,xmm12
+	vpclmulqdq	xmm13,xmm13,xmm0,0x11
+	vpxor	xmm9,xmm9,xmm12
+	vpxor	xmm13,xmm13,xmm14
+	vpalignr	xmm14,xmm8,xmm8,8
+	vpclmulqdq	xmm2,xmm2,xmm15,0x10
+	vmovdqu	xmm15,XMMWORD[((80-32))+r9]
+	vpxor	xmm2,xmm2,xmm1
+
+	vpclmulqdq	xmm4,xmm12,xmm3,0x00
+	vmovdqu	xmm0,XMMWORD[((64-32))+r9]
+	vpxor	xmm4,xmm4,xmm5
+	vpunpckhqdq	xmm1,xmm11,xmm11
+	vpclmulqdq	xmm12,xmm12,xmm3,0x11
+	vpxor	xmm1,xmm1,xmm11
+	vpxor	xmm12,xmm12,xmm13
+	vxorps	xmm7,xmm7,XMMWORD[16+rsp]
+	vpclmulqdq	xmm9,xmm9,xmm15,0x00
+	vpxor	xmm9,xmm9,xmm2
+
+	vpclmulqdq	xmm8,xmm8,XMMWORD[16+r11],0x10
+	vxorps	xmm8,xmm8,xmm14
+
+	vpclmulqdq	xmm5,xmm11,xmm0,0x00
+	vmovdqu	xmm3,XMMWORD[((96-32))+r9]
+	vpxor	xmm5,xmm5,xmm4
+	vpunpckhqdq	xmm2,xmm10,xmm10
+	vpclmulqdq	xmm11,xmm11,xmm0,0x11
+	vpxor	xmm2,xmm2,xmm10
+	vpalignr	xmm14,xmm8,xmm8,8
+	vpxor	xmm11,xmm11,xmm12
+	vpclmulqdq	xmm1,xmm1,xmm15,0x10
+	vmovdqu	xmm15,XMMWORD[((128-32))+r9]
+	vpxor	xmm1,xmm1,xmm9
+
+	vxorps	xmm14,xmm14,xmm7
+	vpclmulqdq	xmm8,xmm8,XMMWORD[16+r11],0x10
+	vxorps	xmm8,xmm8,xmm14
+
+	vpclmulqdq	xmm4,xmm10,xmm3,0x00
+	vmovdqu	xmm0,XMMWORD[((112-32))+r9]
+	vpxor	xmm4,xmm4,xmm5
+	vpunpckhqdq	xmm9,xmm8,xmm8
+	vpclmulqdq	xmm10,xmm10,xmm3,0x11
+	vpxor	xmm9,xmm9,xmm8
+	vpxor	xmm10,xmm10,xmm11
+	vpclmulqdq	xmm2,xmm2,xmm15,0x00
+	vpxor	xmm2,xmm2,xmm1
+
+	vpclmulqdq	xmm5,xmm8,xmm0,0x00
+	vpclmulqdq	xmm7,xmm8,xmm0,0x11
+	vpxor	xmm5,xmm5,xmm4
+	vpclmulqdq	xmm6,xmm9,xmm15,0x10
+	vpxor	xmm7,xmm7,xmm10
+	vpxor	xmm6,xmm6,xmm2
+
+	vpxor	xmm4,xmm7,xmm5
+	vpxor	xmm6,xmm6,xmm4
+	vpslldq	xmm1,xmm6,8
+	vmovdqu	xmm3,XMMWORD[16+r11]
+	vpsrldq	xmm6,xmm6,8
+	vpxor	xmm8,xmm5,xmm1
+	vpxor	xmm7,xmm7,xmm6
+
+	vpalignr	xmm2,xmm8,xmm8,8
+	vpclmulqdq	xmm8,xmm8,xmm3,0x10
+	vpxor	xmm8,xmm8,xmm2
+
+	vpalignr	xmm2,xmm8,xmm8,8
+	vpclmulqdq	xmm8,xmm8,xmm3,0x10
+	vpxor	xmm2,xmm2,xmm7
+	vpxor	xmm8,xmm8,xmm2
+	vpshufb	xmm8,xmm8,XMMWORD[r11]
+	vmovdqu	XMMWORD[(-64)+r9],xmm8
+
+	vzeroupper
+	movaps	xmm6,XMMWORD[((-216))+rax]
+	movaps	xmm7,XMMWORD[((-200))+rax]
+	movaps	xmm8,XMMWORD[((-184))+rax]
+	movaps	xmm9,XMMWORD[((-168))+rax]
+	movaps	xmm10,XMMWORD[((-152))+rax]
+	movaps	xmm11,XMMWORD[((-136))+rax]
+	movaps	xmm12,XMMWORD[((-120))+rax]
+	movaps	xmm13,XMMWORD[((-104))+rax]
+	movaps	xmm14,XMMWORD[((-88))+rax]
+	movaps	xmm15,XMMWORD[((-72))+rax]
+	mov	r15,QWORD[((-48))+rax]
+	mov	r14,QWORD[((-40))+rax]
+	mov	r13,QWORD[((-32))+rax]
+	mov	r12,QWORD[((-24))+rax]
+	mov	rbp,QWORD[((-16))+rax]
+	mov	rbx,QWORD[((-8))+rax]
+	lea	rsp,[rax]
+$L$gcm_enc_abort:
+	mov	rax,r10
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_aesni_gcm_encrypt:
+ALIGN	64
+$L$bswap_mask:
+DB	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+$L$poly:
+DB	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
+$L$one_msb:
+DB	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
+$L$two_lsb:
+DB	2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+$L$one_lsb:
+DB	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+DB	65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108
+DB	101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82
+DB	89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112
+DB	114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+ALIGN	64
+EXTERN	__imp_RtlVirtualUnwind
+
+ALIGN	16
+gcm_se_handler:
+	push	rsi
+	push	rdi
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	pushfq
+	sub	rsp,64
+
+	mov	rax,QWORD[120+r8]
+	mov	rbx,QWORD[248+r8]
+
+	mov	rsi,QWORD[8+r9]
+	mov	r11,QWORD[56+r9]
+
+	mov	r10d,DWORD[r11]
+	lea	r10,[r10*1+rsi]
+	cmp	rbx,r10
+	jb	NEAR $L$common_seh_tail
+
+	mov	rax,QWORD[152+r8]
+
+	mov	r10d,DWORD[4+r11]
+	lea	r10,[r10*1+rsi]
+	cmp	rbx,r10
+	jae	NEAR $L$common_seh_tail
+
+	mov	rax,QWORD[120+r8]
+
+	mov	r15,QWORD[((-48))+rax]
+	mov	r14,QWORD[((-40))+rax]
+	mov	r13,QWORD[((-32))+rax]
+	mov	r12,QWORD[((-24))+rax]
+	mov	rbp,QWORD[((-16))+rax]
+	mov	rbx,QWORD[((-8))+rax]
+	mov	QWORD[240+r8],r15
+	mov	QWORD[232+r8],r14
+	mov	QWORD[224+r8],r13
+	mov	QWORD[216+r8],r12
+	mov	QWORD[160+r8],rbp
+	mov	QWORD[144+r8],rbx
+
+	lea	rsi,[((-216))+rax]
+	lea	rdi,[512+r8]
+	mov	ecx,20
+	DD	0xa548f3fc
+
+$L$common_seh_tail:
+	mov	rdi,QWORD[8+rax]
+	mov	rsi,QWORD[16+rax]
+	mov	QWORD[152+r8],rax
+	mov	QWORD[168+r8],rsi
+	mov	QWORD[176+r8],rdi
+
+	mov	rdi,QWORD[40+r9]
+	mov	rsi,r8
+	mov	ecx,154
+	DD	0xa548f3fc
+
+	mov	rsi,r9
+	xor	rcx,rcx
+	mov	rdx,QWORD[8+rsi]
+	mov	r8,QWORD[rsi]
+	mov	r9,QWORD[16+rsi]
+	mov	r10,QWORD[40+rsi]
+	lea	r11,[56+rsi]
+	lea	r12,[24+rsi]
+	mov	QWORD[32+rsp],r10
+	mov	QWORD[40+rsp],r11
+	mov	QWORD[48+rsp],r12
+	mov	QWORD[56+rsp],rcx
+	call	QWORD[__imp_RtlVirtualUnwind]
+
+	mov	eax,1
+	add	rsp,64
+	popfq
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbp
+	pop	rbx
+	pop	rdi
+	pop	rsi
 	DB	0F3h,0C3h		;repret
 
+
+section	.pdata rdata align=4
+ALIGN	4
+	DD	$L$SEH_begin_aesni_gcm_decrypt wrt ..imagebase
+	DD	$L$SEH_end_aesni_gcm_decrypt wrt ..imagebase
+	DD	$L$SEH_gcm_dec_info wrt ..imagebase
+
+	DD	$L$SEH_begin_aesni_gcm_encrypt wrt ..imagebase
+	DD	$L$SEH_end_aesni_gcm_encrypt wrt ..imagebase
+	DD	$L$SEH_gcm_enc_info wrt ..imagebase
+section	.xdata rdata align=8
+ALIGN	8
+$L$SEH_gcm_dec_info:
+DB	9,0,0,0
+	DD	gcm_se_handler wrt ..imagebase
+	DD	$L$gcm_dec_body wrt ..imagebase,$L$gcm_dec_abort wrt ..imagebase
+$L$SEH_gcm_enc_info:
+DB	9,0,0,0
+	DD	gcm_se_handler wrt ..imagebase
+	DD	$L$gcm_enc_body wrt ..imagebase,$L$gcm_enc_abort wrt ..imagebase
diff --git a/third_party/boringssl/win-x86_64/crypto/modes/ghash-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/modes/ghash-x86_64.asm
index 5d8fadc..e5204bf 100644
--- a/third_party/boringssl/win-x86_64/crypto/modes/ghash-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/modes/ghash-x86_64.asm
@@ -1309,7 +1309,115 @@
 
 ALIGN	32
 gcm_init_avx:
-	jmp	NEAR $L$_init_clmul
+$L$SEH_begin_gcm_init_avx:
+
+DB	0x48,0x83,0xec,0x18
+DB	0x0f,0x29,0x34,0x24
+	vzeroupper
+
+	vmovdqu	xmm2,XMMWORD[rdx]
+	vpshufd	xmm2,xmm2,78
+
+
+	vpshufd	xmm4,xmm2,255
+	vpsrlq	xmm3,xmm2,63
+	vpsllq	xmm2,xmm2,1
+	vpxor	xmm5,xmm5,xmm5
+	vpcmpgtd	xmm5,xmm5,xmm4
+	vpslldq	xmm3,xmm3,8
+	vpor	xmm2,xmm2,xmm3
+
+
+	vpand	xmm5,xmm5,XMMWORD[$L$0x1c2_polynomial]
+	vpxor	xmm2,xmm2,xmm5
+
+	vpunpckhqdq	xmm6,xmm2,xmm2
+	vmovdqa	xmm0,xmm2
+	vpxor	xmm6,xmm6,xmm2
+	mov	r10,4
+	jmp	NEAR $L$init_start_avx
+ALIGN	32
+$L$init_loop_avx:
+	vpalignr	xmm5,xmm4,xmm3,8
+	vmovdqu	XMMWORD[(-16)+rcx],xmm5
+	vpunpckhqdq	xmm3,xmm0,xmm0
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm1,xmm0,xmm2,0x11
+	vpclmulqdq	xmm0,xmm0,xmm2,0x00
+	vpclmulqdq	xmm3,xmm3,xmm6,0x00
+	vpxor	xmm4,xmm1,xmm0
+	vpxor	xmm3,xmm3,xmm4
+
+	vpslldq	xmm4,xmm3,8
+	vpsrldq	xmm3,xmm3,8
+	vpxor	xmm0,xmm0,xmm4
+	vpxor	xmm1,xmm1,xmm3
+	vpsllq	xmm3,xmm0,57
+	vpsllq	xmm4,xmm0,62
+	vpxor	xmm4,xmm4,xmm3
+	vpsllq	xmm3,xmm0,63
+	vpxor	xmm4,xmm4,xmm3
+	vpslldq	xmm3,xmm4,8
+	vpsrldq	xmm4,xmm4,8
+	vpxor	xmm0,xmm0,xmm3
+	vpxor	xmm1,xmm1,xmm4
+
+	vpsrlq	xmm4,xmm0,1
+	vpxor	xmm1,xmm1,xmm0
+	vpxor	xmm0,xmm0,xmm4
+	vpsrlq	xmm4,xmm4,5
+	vpxor	xmm0,xmm0,xmm4
+	vpsrlq	xmm0,xmm0,1
+	vpxor	xmm0,xmm0,xmm1
+$L$init_start_avx:
+	vmovdqa	xmm5,xmm0
+	vpunpckhqdq	xmm3,xmm0,xmm0
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm1,xmm0,xmm2,0x11
+	vpclmulqdq	xmm0,xmm0,xmm2,0x00
+	vpclmulqdq	xmm3,xmm3,xmm6,0x00
+	vpxor	xmm4,xmm1,xmm0
+	vpxor	xmm3,xmm3,xmm4
+
+	vpslldq	xmm4,xmm3,8
+	vpsrldq	xmm3,xmm3,8
+	vpxor	xmm0,xmm0,xmm4
+	vpxor	xmm1,xmm1,xmm3
+	vpsllq	xmm3,xmm0,57
+	vpsllq	xmm4,xmm0,62
+	vpxor	xmm4,xmm4,xmm3
+	vpsllq	xmm3,xmm0,63
+	vpxor	xmm4,xmm4,xmm3
+	vpslldq	xmm3,xmm4,8
+	vpsrldq	xmm4,xmm4,8
+	vpxor	xmm0,xmm0,xmm3
+	vpxor	xmm1,xmm1,xmm4
+
+	vpsrlq	xmm4,xmm0,1
+	vpxor	xmm1,xmm1,xmm0
+	vpxor	xmm0,xmm0,xmm4
+	vpsrlq	xmm4,xmm4,5
+	vpxor	xmm0,xmm0,xmm4
+	vpsrlq	xmm0,xmm0,1
+	vpxor	xmm0,xmm0,xmm1
+	vpshufd	xmm3,xmm5,78
+	vpshufd	xmm4,xmm0,78
+	vpxor	xmm3,xmm3,xmm5
+	vmovdqu	XMMWORD[rcx],xmm5
+	vpxor	xmm4,xmm4,xmm0
+	vmovdqu	XMMWORD[16+rcx],xmm0
+	lea	rcx,[48+rcx]
+	sub	r10,1
+	jnz	NEAR $L$init_loop_avx
+
+	vpalignr	xmm5,xmm3,xmm4,8
+	vmovdqu	XMMWORD[(-16)+rcx],xmm5
+
+	vzeroupper
+	movaps	xmm6,XMMWORD[rsp]
+	lea	rsp,[24+rsp]
+$L$SEH_end_gcm_init_avx:
+	DB	0F3h,0C3h		;repret
 
 global	gcm_gmult_avx
 
@@ -1321,7 +1429,403 @@
 
 ALIGN	32
 gcm_ghash_avx:
-	jmp	NEAR $L$_ghash_clmul
+	lea	rax,[((-136))+rsp]
+$L$SEH_begin_gcm_ghash_avx:
+
+DB	0x48,0x8d,0x60,0xe0
+DB	0x0f,0x29,0x70,0xe0
+DB	0x0f,0x29,0x78,0xf0
+DB	0x44,0x0f,0x29,0x00
+DB	0x44,0x0f,0x29,0x48,0x10
+DB	0x44,0x0f,0x29,0x50,0x20
+DB	0x44,0x0f,0x29,0x58,0x30
+DB	0x44,0x0f,0x29,0x60,0x40
+DB	0x44,0x0f,0x29,0x68,0x50
+DB	0x44,0x0f,0x29,0x70,0x60
+DB	0x44,0x0f,0x29,0x78,0x70
+	vzeroupper
+
+	vmovdqu	xmm10,XMMWORD[rcx]
+	lea	r10,[$L$0x1c2_polynomial]
+	lea	rdx,[64+rdx]
+	vmovdqu	xmm13,XMMWORD[$L$bswap_mask]
+	vpshufb	xmm10,xmm10,xmm13
+	cmp	r9,0x80
+	jb	NEAR $L$short_avx
+	sub	r9,0x80
+
+	vmovdqu	xmm14,XMMWORD[112+r8]
+	vmovdqu	xmm6,XMMWORD[((0-64))+rdx]
+	vpshufb	xmm14,xmm14,xmm13
+	vmovdqu	xmm7,XMMWORD[((32-64))+rdx]
+
+	vpunpckhqdq	xmm9,xmm14,xmm14
+	vmovdqu	xmm15,XMMWORD[96+r8]
+	vpclmulqdq	xmm0,xmm14,xmm6,0x00
+	vpxor	xmm9,xmm9,xmm14
+	vpshufb	xmm15,xmm15,xmm13
+	vpclmulqdq	xmm1,xmm14,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((16-64))+rdx]
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vmovdqu	xmm14,XMMWORD[80+r8]
+	vpclmulqdq	xmm2,xmm9,xmm7,0x00
+	vpxor	xmm8,xmm8,xmm15
+
+	vpshufb	xmm14,xmm14,xmm13
+	vpclmulqdq	xmm3,xmm15,xmm6,0x00
+	vpunpckhqdq	xmm9,xmm14,xmm14
+	vpclmulqdq	xmm4,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((48-64))+rdx]
+	vpxor	xmm9,xmm9,xmm14
+	vmovdqu	xmm15,XMMWORD[64+r8]
+	vpclmulqdq	xmm5,xmm8,xmm7,0x10
+	vmovdqu	xmm7,XMMWORD[((80-64))+rdx]
+
+	vpshufb	xmm15,xmm15,xmm13
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm14,xmm6,0x00
+	vpxor	xmm4,xmm4,xmm1
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpclmulqdq	xmm1,xmm14,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((64-64))+rdx]
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm9,xmm7,0x00
+	vpxor	xmm8,xmm8,xmm15
+
+	vmovdqu	xmm14,XMMWORD[48+r8]
+	vpxor	xmm0,xmm0,xmm3
+	vpclmulqdq	xmm3,xmm15,xmm6,0x00
+	vpxor	xmm1,xmm1,xmm4
+	vpshufb	xmm14,xmm14,xmm13
+	vpclmulqdq	xmm4,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((96-64))+rdx]
+	vpxor	xmm2,xmm2,xmm5
+	vpunpckhqdq	xmm9,xmm14,xmm14
+	vpclmulqdq	xmm5,xmm8,xmm7,0x10
+	vmovdqu	xmm7,XMMWORD[((128-64))+rdx]
+	vpxor	xmm9,xmm9,xmm14
+
+	vmovdqu	xmm15,XMMWORD[32+r8]
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm14,xmm6,0x00
+	vpxor	xmm4,xmm4,xmm1
+	vpshufb	xmm15,xmm15,xmm13
+	vpclmulqdq	xmm1,xmm14,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((112-64))+rdx]
+	vpxor	xmm5,xmm5,xmm2
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpclmulqdq	xmm2,xmm9,xmm7,0x00
+	vpxor	xmm8,xmm8,xmm15
+
+	vmovdqu	xmm14,XMMWORD[16+r8]
+	vpxor	xmm0,xmm0,xmm3
+	vpclmulqdq	xmm3,xmm15,xmm6,0x00
+	vpxor	xmm1,xmm1,xmm4
+	vpshufb	xmm14,xmm14,xmm13
+	vpclmulqdq	xmm4,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((144-64))+rdx]
+	vpxor	xmm2,xmm2,xmm5
+	vpunpckhqdq	xmm9,xmm14,xmm14
+	vpclmulqdq	xmm5,xmm8,xmm7,0x10
+	vmovdqu	xmm7,XMMWORD[((176-64))+rdx]
+	vpxor	xmm9,xmm9,xmm14
+
+	vmovdqu	xmm15,XMMWORD[r8]
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm14,xmm6,0x00
+	vpxor	xmm4,xmm4,xmm1
+	vpshufb	xmm15,xmm15,xmm13
+	vpclmulqdq	xmm1,xmm14,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((160-64))+rdx]
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm9,xmm7,0x10
+
+	lea	r8,[128+r8]
+	cmp	r9,0x80
+	jb	NEAR $L$tail_avx
+
+	vpxor	xmm15,xmm15,xmm10
+	sub	r9,0x80
+	jmp	NEAR $L$oop8x_avx
+
+ALIGN	32
+$L$oop8x_avx:
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vmovdqu	xmm14,XMMWORD[112+r8]
+	vpxor	xmm3,xmm3,xmm0
+	vpxor	xmm8,xmm8,xmm15
+	vpclmulqdq	xmm10,xmm15,xmm6,0x00
+	vpshufb	xmm14,xmm14,xmm13
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm11,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((0-64))+rdx]
+	vpunpckhqdq	xmm9,xmm14,xmm14
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm12,xmm8,xmm7,0x00
+	vmovdqu	xmm7,XMMWORD[((32-64))+rdx]
+	vpxor	xmm9,xmm9,xmm14
+
+	vmovdqu	xmm15,XMMWORD[96+r8]
+	vpclmulqdq	xmm0,xmm14,xmm6,0x00
+	vpxor	xmm10,xmm10,xmm3
+	vpshufb	xmm15,xmm15,xmm13
+	vpclmulqdq	xmm1,xmm14,xmm6,0x11
+	vxorps	xmm11,xmm11,xmm4
+	vmovdqu	xmm6,XMMWORD[((16-64))+rdx]
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpclmulqdq	xmm2,xmm9,xmm7,0x00
+	vpxor	xmm12,xmm12,xmm5
+	vxorps	xmm8,xmm8,xmm15
+
+	vmovdqu	xmm14,XMMWORD[80+r8]
+	vpxor	xmm12,xmm12,xmm10
+	vpclmulqdq	xmm3,xmm15,xmm6,0x00
+	vpxor	xmm12,xmm12,xmm11
+	vpslldq	xmm9,xmm12,8
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm4,xmm15,xmm6,0x11
+	vpsrldq	xmm12,xmm12,8
+	vpxor	xmm10,xmm10,xmm9
+	vmovdqu	xmm6,XMMWORD[((48-64))+rdx]
+	vpshufb	xmm14,xmm14,xmm13
+	vxorps	xmm11,xmm11,xmm12
+	vpxor	xmm4,xmm4,xmm1
+	vpunpckhqdq	xmm9,xmm14,xmm14
+	vpclmulqdq	xmm5,xmm8,xmm7,0x10
+	vmovdqu	xmm7,XMMWORD[((80-64))+rdx]
+	vpxor	xmm9,xmm9,xmm14
+	vpxor	xmm5,xmm5,xmm2
+
+	vmovdqu	xmm15,XMMWORD[64+r8]
+	vpalignr	xmm12,xmm10,xmm10,8
+	vpclmulqdq	xmm0,xmm14,xmm6,0x00
+	vpshufb	xmm15,xmm15,xmm13
+	vpxor	xmm0,xmm0,xmm3
+	vpclmulqdq	xmm1,xmm14,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((64-64))+rdx]
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm1,xmm1,xmm4
+	vpclmulqdq	xmm2,xmm9,xmm7,0x00
+	vxorps	xmm8,xmm8,xmm15
+	vpxor	xmm2,xmm2,xmm5
+
+	vmovdqu	xmm14,XMMWORD[48+r8]
+	vpclmulqdq	xmm10,xmm10,XMMWORD[r10],0x10
+	vpclmulqdq	xmm3,xmm15,xmm6,0x00
+	vpshufb	xmm14,xmm14,xmm13
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm4,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((96-64))+rdx]
+	vpunpckhqdq	xmm9,xmm14,xmm14
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm5,xmm8,xmm7,0x10
+	vmovdqu	xmm7,XMMWORD[((128-64))+rdx]
+	vpxor	xmm9,xmm9,xmm14
+	vpxor	xmm5,xmm5,xmm2
+
+	vmovdqu	xmm15,XMMWORD[32+r8]
+	vpclmulqdq	xmm0,xmm14,xmm6,0x00
+	vpshufb	xmm15,xmm15,xmm13
+	vpxor	xmm0,xmm0,xmm3
+	vpclmulqdq	xmm1,xmm14,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((112-64))+rdx]
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm1,xmm1,xmm4
+	vpclmulqdq	xmm2,xmm9,xmm7,0x00
+	vpxor	xmm8,xmm8,xmm15
+	vpxor	xmm2,xmm2,xmm5
+	vxorps	xmm10,xmm10,xmm12
+
+	vmovdqu	xmm14,XMMWORD[16+r8]
+	vpalignr	xmm12,xmm10,xmm10,8
+	vpclmulqdq	xmm3,xmm15,xmm6,0x00
+	vpshufb	xmm14,xmm14,xmm13
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm4,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((144-64))+rdx]
+	vpclmulqdq	xmm10,xmm10,XMMWORD[r10],0x10
+	vxorps	xmm12,xmm12,xmm11
+	vpunpckhqdq	xmm9,xmm14,xmm14
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm5,xmm8,xmm7,0x10
+	vmovdqu	xmm7,XMMWORD[((176-64))+rdx]
+	vpxor	xmm9,xmm9,xmm14
+	vpxor	xmm5,xmm5,xmm2
+
+	vmovdqu	xmm15,XMMWORD[r8]
+	vpclmulqdq	xmm0,xmm14,xmm6,0x00
+	vpshufb	xmm15,xmm15,xmm13
+	vpclmulqdq	xmm1,xmm14,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((160-64))+rdx]
+	vpxor	xmm15,xmm15,xmm12
+	vpclmulqdq	xmm2,xmm9,xmm7,0x10
+	vpxor	xmm15,xmm15,xmm10
+
+	lea	r8,[128+r8]
+	sub	r9,0x80
+	jnc	NEAR $L$oop8x_avx
+
+	add	r9,0x80
+	jmp	NEAR $L$tail_no_xor_avx
+
+ALIGN	32
+$L$short_avx:
+	vmovdqu	xmm14,XMMWORD[((-16))+r9*1+r8]
+	lea	r8,[r9*1+r8]
+	vmovdqu	xmm6,XMMWORD[((0-64))+rdx]
+	vmovdqu	xmm7,XMMWORD[((32-64))+rdx]
+	vpshufb	xmm15,xmm14,xmm13
+
+	vmovdqa	xmm3,xmm0
+	vmovdqa	xmm4,xmm1
+	vmovdqa	xmm5,xmm2
+	sub	r9,0x10
+	jz	NEAR $L$tail_avx
+
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm15,xmm6,0x00
+	vpxor	xmm8,xmm8,xmm15
+	vmovdqu	xmm14,XMMWORD[((-32))+r8]
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm1,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((16-64))+rdx]
+	vpshufb	xmm15,xmm14,xmm13
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm8,xmm7,0x00
+	vpsrldq	xmm7,xmm7,8
+	sub	r9,0x10
+	jz	NEAR $L$tail_avx
+
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm15,xmm6,0x00
+	vpxor	xmm8,xmm8,xmm15
+	vmovdqu	xmm14,XMMWORD[((-48))+r8]
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm1,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((48-64))+rdx]
+	vpshufb	xmm15,xmm14,xmm13
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm8,xmm7,0x00
+	vmovdqu	xmm7,XMMWORD[((80-64))+rdx]
+	sub	r9,0x10
+	jz	NEAR $L$tail_avx
+
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm15,xmm6,0x00
+	vpxor	xmm8,xmm8,xmm15
+	vmovdqu	xmm14,XMMWORD[((-64))+r8]
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm1,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((64-64))+rdx]
+	vpshufb	xmm15,xmm14,xmm13
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm8,xmm7,0x00
+	vpsrldq	xmm7,xmm7,8
+	sub	r9,0x10
+	jz	NEAR $L$tail_avx
+
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm15,xmm6,0x00
+	vpxor	xmm8,xmm8,xmm15
+	vmovdqu	xmm14,XMMWORD[((-80))+r8]
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm1,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((96-64))+rdx]
+	vpshufb	xmm15,xmm14,xmm13
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm8,xmm7,0x00
+	vmovdqu	xmm7,XMMWORD[((128-64))+rdx]
+	sub	r9,0x10
+	jz	NEAR $L$tail_avx
+
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm15,xmm6,0x00
+	vpxor	xmm8,xmm8,xmm15
+	vmovdqu	xmm14,XMMWORD[((-96))+r8]
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm1,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((112-64))+rdx]
+	vpshufb	xmm15,xmm14,xmm13
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm8,xmm7,0x00
+	vpsrldq	xmm7,xmm7,8
+	sub	r9,0x10
+	jz	NEAR $L$tail_avx
+
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm15,xmm6,0x00
+	vpxor	xmm8,xmm8,xmm15
+	vmovdqu	xmm14,XMMWORD[((-112))+r8]
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm1,xmm15,xmm6,0x11
+	vmovdqu	xmm6,XMMWORD[((144-64))+rdx]
+	vpshufb	xmm15,xmm14,xmm13
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm8,xmm7,0x00
+	vmovq	xmm7,QWORD[((184-64))+rdx]
+	sub	r9,0x10
+	jmp	NEAR $L$tail_avx
+
+ALIGN	32
+$L$tail_avx:
+	vpxor	xmm15,xmm15,xmm10
+$L$tail_no_xor_avx:
+	vpunpckhqdq	xmm8,xmm15,xmm15
+	vpxor	xmm3,xmm3,xmm0
+	vpclmulqdq	xmm0,xmm15,xmm6,0x00
+	vpxor	xmm8,xmm8,xmm15
+	vpxor	xmm4,xmm4,xmm1
+	vpclmulqdq	xmm1,xmm15,xmm6,0x11
+	vpxor	xmm5,xmm5,xmm2
+	vpclmulqdq	xmm2,xmm8,xmm7,0x00
+
+	vmovdqu	xmm12,XMMWORD[r10]
+
+	vpxor	xmm10,xmm3,xmm0
+	vpxor	xmm11,xmm4,xmm1
+	vpxor	xmm5,xmm5,xmm2
+
+	vpxor	xmm5,xmm5,xmm10
+	vpxor	xmm5,xmm5,xmm11
+	vpslldq	xmm9,xmm5,8
+	vpsrldq	xmm5,xmm5,8
+	vpxor	xmm10,xmm10,xmm9
+	vpxor	xmm11,xmm11,xmm5
+
+	vpclmulqdq	xmm9,xmm10,xmm12,0x10
+	vpalignr	xmm10,xmm10,xmm10,8
+	vpxor	xmm10,xmm10,xmm9
+
+	vpclmulqdq	xmm9,xmm10,xmm12,0x10
+	vpalignr	xmm10,xmm10,xmm10,8
+	vpxor	xmm10,xmm10,xmm11
+	vpxor	xmm10,xmm10,xmm9
+
+	cmp	r9,0
+	jne	NEAR $L$short_avx
+
+	vpshufb	xmm10,xmm10,xmm13
+	vmovdqu	XMMWORD[rcx],xmm10
+	vzeroupper
+	movaps	xmm6,XMMWORD[rsp]
+	movaps	xmm7,XMMWORD[16+rsp]
+	movaps	xmm8,XMMWORD[32+rsp]
+	movaps	xmm9,XMMWORD[48+rsp]
+	movaps	xmm10,XMMWORD[64+rsp]
+	movaps	xmm11,XMMWORD[80+rsp]
+	movaps	xmm12,XMMWORD[96+rsp]
+	movaps	xmm13,XMMWORD[112+rsp]
+	movaps	xmm14,XMMWORD[128+rsp]
+	movaps	xmm15,XMMWORD[144+rsp]
+	lea	rsp,[168+rsp]
+$L$SEH_end_gcm_ghash_avx:
+	DB	0F3h,0C3h		;repret
 
 ALIGN	64
 $L$bswap_mask:
@@ -1478,6 +1982,13 @@
 	DD	$L$SEH_begin_gcm_ghash_clmul wrt ..imagebase
 	DD	$L$SEH_end_gcm_ghash_clmul wrt ..imagebase
 	DD	$L$SEH_info_gcm_ghash_clmul wrt ..imagebase
+	DD	$L$SEH_begin_gcm_init_avx wrt ..imagebase
+	DD	$L$SEH_end_gcm_init_avx wrt ..imagebase
+	DD	$L$SEH_info_gcm_init_clmul wrt ..imagebase
+
+	DD	$L$SEH_begin_gcm_ghash_avx wrt ..imagebase
+	DD	$L$SEH_end_gcm_ghash_avx wrt ..imagebase
+	DD	$L$SEH_info_gcm_ghash_clmul wrt ..imagebase
 section	.xdata rdata align=8
 ALIGN	8
 $L$SEH_info_gcm_gmult_4bit:
diff --git a/tools/gn/action_target_generator.cc b/tools/gn/action_target_generator.cc
index 6f962b6d..5c7cbf67 100644
--- a/tools/gn/action_target_generator.cc
+++ b/tools/gn/action_target_generator.cc
@@ -117,15 +117,32 @@
 bool ActionTargetGenerator::FillScriptArgs() {
   const Value* value = scope_->GetValue(variables::kArgs, true);
   if (!value)
-    return true;
-  return target_->action_values().args().Parse(*value, err_);
+    return true;  // Nothing to do.
+
+  if (!target_->action_values().args().Parse(*value, err_))
+    return false;
+  if (!EnsureValidSubstitutions(
+           target_->action_values().args().required_types(),
+           &IsValidScriptArgsSubstitution,
+           value->origin(), err_))
+    return false;
+
+  return true;
 }
 
 bool ActionTargetGenerator::FillResponseFileContents() {
   const Value* value = scope_->GetValue(variables::kResponseFileContents, true);
   if (!value)
-    return true;
-  return target_->action_values().rsp_file_contents().Parse(*value, err_);
+    return true;  // Nothing to do.
+
+  if (!target_->action_values().rsp_file_contents().Parse(*value, err_))
+    return false;
+  if (!EnsureValidSubstitutions(
+           target_->action_values().rsp_file_contents().required_types(),
+           &IsValidSourceSubstitution, value->origin(), err_))
+    return false;
+
+  return true;
 }
 
 bool ActionTargetGenerator::FillDepfile() {
diff --git a/tools/gn/action_target_generator_unittest.cc b/tools/gn/action_target_generator_unittest.cc
index 8f3e4d4..5a45932e 100644
--- a/tools/gn/action_target_generator_unittest.cc
+++ b/tools/gn/action_target_generator_unittest.cc
@@ -15,11 +15,11 @@
 
   // First test one with no substitutions, this should be valid.
   TestParseInput input_good(
-      "action(\"foo\") {\n"
-      "  script = \"//foo.py\"\n"
-      "  sources = [ \"//bar.txt\" ]\n"
-      "  outputs = [ \"//out/Debug/one.txt\" ]\n"
-      "}");
+      R"(action("foo") {
+           script = "//foo.py"
+           sources = [ "//bar.txt" ]
+           outputs = [ "//out/Debug/one.txt" ]
+         })");
   ASSERT_FALSE(input_good.has_error());
 
   // This should run fine.
@@ -29,14 +29,93 @@
 
   // Same thing with a pattern in the output should fail.
   TestParseInput input_bad(
-      "action(\"foo\") {\n"
-      "  script = \"//foo.py\"\n"
-      "  sources = [ \"//bar.txt\" ]\n"
-      "  outputs = [ \"//out/Debug/{{source_name_part}}.txt\" ]\n"
-      "}");
+      R"(action("foo") {
+           script = "//foo.py"
+           sources = [ "//bar.txt" ]
+           outputs = [ "//out/Debug/{{source_name_part}}.txt" ]
+         })");
   ASSERT_FALSE(input_bad.has_error());
 
   // This should run fine.
   input_bad.parsed()->Execute(setup.scope(), &err);
   ASSERT_TRUE(err.has_error());
 }
+
+// Tests that arg and response file substitutions are validated for
+// action_foreach targets.
+TEST(ActionTargetGenerator, ActionForeachSubstitutions) {
+  Scheduler scheduler;
+  TestWithScope setup;
+  Scope::ItemVector items_;
+  setup.scope()->set_item_collector(&items_);
+
+  // Args listing a response file but missing a response file definition should
+  // fail.
+  TestParseInput input_missing_resp_file(
+      R"(action_foreach("foo") {
+           script = "//foo.py"
+           sources = [ "//bar.txt" ]
+           outputs = [ "//out/Debug/{{source_name_part}}" ]
+           args = [ "{{response_file_name}}" ]
+         })");
+  ASSERT_FALSE(input_missing_resp_file.has_error());
+  Err err;
+  input_missing_resp_file.parsed()->Execute(setup.scope(), &err);
+  ASSERT_TRUE(err.has_error());
+
+  // Adding a response file definition should pass.
+  err = Err();
+  TestParseInput input_resp_file(
+      R"(action_foreach("foo") {
+           script = "//foo.py"
+           sources = [ "//bar.txt" ]
+           outputs = [ "//out/Debug/{{source_name_part}}" ]
+           args = [ "{{response_file_name}}" ]
+           response_file_contents = [ "{{source_name_part}}" ]
+         })");
+  ASSERT_FALSE(input_resp_file.has_error());
+  input_resp_file.parsed()->Execute(setup.scope(), &err);
+  ASSERT_FALSE(err.has_error()) << err.message();
+
+  // Defining a response file but not referencing it should fail.
+  err = Err();
+  TestParseInput input_missing_rsp_args(
+      R"(action_foreach("foo") {
+           script = "//foo.py"
+           sources = [ "//bar.txt" ]
+           outputs = [ "//out/Debug/{{source_name_part}}" ]
+           args = [ "{{source_name_part}}" ]
+           response_file_contents = [ "{{source_name_part}}" ]
+         })");
+  ASSERT_FALSE(input_missing_rsp_args.has_error());
+  input_missing_rsp_args.parsed()->Execute(setup.scope(), &err);
+  ASSERT_TRUE(err.has_error()) << err.message();
+
+  // Bad substitutions in args.
+  err = Err();
+  TestParseInput input_bad_args(
+      R"(action_foreach("foo") {
+           script = "//foo.py"
+           sources = [ "//bar.txt" ]
+           outputs = [ "//out/Debug/{{source_name_part}}" ]
+           args = [ "{{response_file_name}} {{ldflags}}" ]
+           response_file_contents = [ "{{source_name_part}}" ]
+         })");
+  ASSERT_FALSE(input_bad_args.has_error());
+  input_bad_args.parsed()->Execute(setup.scope(), &err);
+  ASSERT_TRUE(err.has_error()) << err.message();
+
+  // Bad substitutions in response file contents.
+  err = Err();
+  TestParseInput input_bad_rsp(
+      R"(action_foreach("foo") {
+           script = "//foo.py"
+           sources = [ "//bar.txt" ]
+           outputs = [ "//out/Debug/{{source_name_part}}" ]
+           args = [ "{{response_file_name}}" ]
+           response_file_contents = [ "{{source_name_part}} {{ldflags}}" ]
+         })");
+  ASSERT_FALSE(input_bad_rsp.has_error());
+  input_bad_rsp.parsed()->Execute(setup.scope(), &err);
+  ASSERT_TRUE(err.has_error()) << err.message();
+}
diff --git a/tools/gn/ninja_action_target_writer.cc b/tools/gn/ninja_action_target_writer.cc
index 77ee2b4..9e56362 100644
--- a/tools/gn/ninja_action_target_writer.cc
+++ b/tools/gn/ninja_action_target_writer.cc
@@ -180,7 +180,7 @@
 
     // The required types is the union of the args and response file. This
     // might theoretically duplicate a definition if the same substitution is
-    // used in both the args and the reponse file. However, this should be
+    // used in both the args and the response file. However, this should be
     // very unusual (normally the substitutions will go in one place or the
     // other) and the redundant assignment won't bother Ninja.
     SubstitutionWriter::WriteNinjaVariablesForSource(
diff --git a/tools/gn/substitution_type.cc b/tools/gn/substitution_type.cc
index c6ea3859..99b4e68 100644
--- a/tools/gn/substitution_type.cc
+++ b/tools/gn/substitution_type.cc
@@ -166,6 +166,11 @@
          type == SUBSTITUTION_SOURCE_TARGET_RELATIVE;
 }
 
+bool IsValidScriptArgsSubstitution(SubstitutionType type) {
+  return IsValidSourceSubstitution(type) ||
+      type == SUBSTITUTION_RSP_FILE_NAME;
+}
+
 bool IsValidToolSubstitution(SubstitutionType type) {
   return type == SUBSTITUTION_LITERAL ||
          type == SUBSTITUTION_OUTPUT ||
@@ -236,14 +241,14 @@
          type == SUBSTITUTION_BUNDLE_PRODUCT_TYPE;
 }
 
-bool EnsureValidSourcesSubstitutions(
-    const std::vector<SubstitutionType>& types,
-    const ParseNode* origin,
-    Err* err) {
-  for (size_t i = 0; i < types.size(); i++) {
-    if (!IsValidSourceSubstitution(types[i])) {
+bool EnsureValidSubstitutions(const std::vector<SubstitutionType>& types,
+                              bool (*is_valid_subst)(SubstitutionType),
+                              const ParseNode* origin,
+                              Err* err) {
+  for (SubstitutionType type : types) {
+    if (!is_valid_subst(type)) {
       *err = Err(origin, "Invalid substitution type.",
-          "The substitution " + std::string(kSubstitutionNames[types[i]]) +
+          "The substitution " + std::string(kSubstitutionNames[type]) +
           " isn't valid for something\n"
           "operating on a source file such as this.");
       return false;
diff --git a/tools/gn/substitution_type.h b/tools/gn/substitution_type.h
index 74ab507..df7f8b7a 100644
--- a/tools/gn/substitution_type.h
+++ b/tools/gn/substitution_type.h
@@ -118,6 +118,8 @@
 // Returns true if the given substitution is valid for the named purpose.
 bool IsValidBundleDataSubstitution(SubstitutionType type);
 bool IsValidSourceSubstitution(SubstitutionType type);
+bool IsValidScriptArgsSubstitution(SubstitutionType type);
+
 // Both compiler and linker tools.
 bool IsValidToolSubstitution(SubstitutionType type);
 bool IsValidCompilerSubstitution(SubstitutionType type);
@@ -128,10 +130,12 @@
 bool IsValidCopySubstitution(SubstitutionType type);
 bool IsValidCompileXCassetsSubstitution(SubstitutionType type);
 
-// Like the "IsValid..." version above but checks a list of types and sets a
-// an error blaming the given source if the test fails.
-bool EnsureValidSourcesSubstitutions(
+// Validates that each substitution type in the vector passes the given
+// is_valid_subst predicate. Returns true on success. On failure, fills in the
+// error object with an appropriate message and returns false.
+bool EnsureValidSubstitutions(
     const std::vector<SubstitutionType>& types,
+    bool (*is_valid_subst)(SubstitutionType),
     const ParseNode* origin,
     Err* err);
 
diff --git a/tools/gn/target_generator.cc b/tools/gn/target_generator.cc
index 7fe64fd..ca193b64 100644
--- a/tools/gn/target_generator.cc
+++ b/tools/gn/target_generator.cc
@@ -312,8 +312,9 @@
   }
 
   // Check the substitutions used are valid for this purpose.
-  if (!EnsureValidSourcesSubstitutions(outputs.required_types(),
-                                       value->origin(), err_))
+  if (!EnsureValidSubstitutions(outputs.required_types(),
+                                &IsValidSourceSubstitution,
+                                value->origin(), err_))
     return false;
 
   // Validate that outputs are in the output dir.
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 29aae712..4f39d80 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -65,6 +65,9 @@
         'android_ndk_next_release_bot_minimal_symbols_x64',
       'NDK Next x86 Builder':
         'android_ndk_next_release_bot_minimal_symbols_x86',
+      'x64 Device Tester': 'android_shared_release_bot_x64',
+      'x86 Cloud Tester': 'android_debug_static_bot_x86',
+      'x86 Emulator Tester': 'android_debug_static_bot_x86',
     },
 
     'chromium.chrome': {
@@ -93,13 +96,10 @@
 
     'chromium.fyi': {
       'Afl Upload Linux ASan': 'release_afl_asan',
-      'Android Cloud Tests': 'android_debug_static_bot_x86',
-      'Android Tests (x86 emulator)': 'android_debug_static_bot_x86',
       'Android Builder (dbg)': 'android_debug_static_bot_vr_shell',
       'Android Builder Goma Canary (dbg)': 'android_debug_bot',
       'Android deterministic': 'android_without_codecs_release_bot_minimal_symbols',
       'Android deterministic (dbg)': 'android_debug_bot',
-      'Android x64 Tests': 'android_shared_release_bot_x64',
       'Browser Side Navigation Linux': 'release_bot',
       'CFI Linux CF': 'cfi_full_cfi_diag_release_static',
       'CFI Linux ToT': 'cfi_full_clang_tot_release_static',
@@ -355,7 +355,9 @@
       'Chromium Win SyzyASAN': 'syzyasan_no_pch_release_x86',
       'Linux ASAN Builder': 'asan_lsan_release_bot',
       'Linux Debug Builder': 'debug_bot',
+      'Linux Release (NVIDIA)': 'gpu_tests_release_trybot',
       'Linux Snapshot Builder': 'release_bot',
+      'Mac Release (Intel)': 'gpu_tests_release_trybot',
       'V8 Android GN (dbg)': 'android_debug_bot',
       'V8 Linux GN': 'release_bot',
       'V8-Blink Linux 64': 'release_bot',
@@ -363,6 +365,7 @@
       'V8-Blink Linux 64 (dbg)': 'debug_bot',
       'V8-Blink Mac': 'release_bot',
       'V8-Blink Win': 'release_bot_x86',
+      'Win Release (NVIDIA)': 'gpu_tests_release_trybot_x86',
     },
 
     'chromium.webkit': {
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index c161f8a..e508c28 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -43069,6 +43069,14 @@
   </summary>
 </histogram>
 
+<histogram name="PageLoad.Clients.DocWrite.Block.Count" enum="Boolean">
+  <owner>bmcquade@chromium.org</owner>
+  <summary>
+    Counts the number of pages where a script loaded via document.write could
+    have been blocked.
+  </summary>
+</histogram>
+
 <histogram name="PageLoad.Clients.DocWrite.Block.ReloadCount">
   <owner>shivanisha@chromium.org</owner>
   <owner>bmcquade@chromium.org</owner>
@@ -89363,6 +89371,12 @@
       label="CSSSelectorInternalMediaControlsTextTrackListKindCaptions"/>
   <int value="1776"
       label="CSSSelectorInternalMediaControlsTextTrackListKindSubtitles"/>
+  <int value="1777" label="ScrollbarUseVerticalScrollbarButton"/>
+  <int value="1778" label="ScrollbarUseVerticalScrollbarThumb"/>
+  <int value="1779" label="ScrollbarUseVerticalScrollbarTrack"/>
+  <int value="1780" label="ScrollbarUseHorizontalScrollbarButton"/>
+  <int value="1781" label="ScrollbarUseHorizontalScrollbarThumb"/>
+  <int value="1782" label="ScrollbarUseHorizontalScrollbarTrack"/>
 </enum>
 
 <enum name="FetchRequestMode" type="int">
diff --git a/tools/perf/page_sets/tough_ad_cases.py b/tools/perf/page_sets/tough_ad_cases.py
index 68321d1..d9ea110c 100644
--- a/tools/perf/page_sets/tough_ad_cases.py
+++ b/tools/perf/page_sets/tough_ad_cases.py
@@ -189,8 +189,9 @@
         self, scroll=scroll))
     self.AddStory(AdPage('http://androidcentral.com', self, scroll=scroll,
         wait_for_interactive_or_better=True))
-    self.AddStory(AdPage('http://mashable.com', self, scroll=scroll,
-        y_scroll_distance_multiplier=0.25))
+    # Disabled: crbug.com/682349
+    #self.AddStory(AdPage('http://mashable.com', self, scroll=scroll,
+    #    y_scroll_distance_multiplier=0.25))
     self.AddStory(AdPage('http://www.androidauthority.com/'
         'reduce-data-use-turn-on-data-compression-in-chrome-630064/', self,
         scroll=scroll))
diff --git a/ui/events/keycodes/platform_key_map_win.cc b/ui/events/keycodes/platform_key_map_win.cc
index 439384c..32b544e3 100644
--- a/ui/events/keycodes/platform_key_map_win.cc
+++ b/ui/events/keycodes/platform_key_map_win.cc
@@ -286,6 +286,12 @@
 
 DomKey PlatformKeyMap::DomKeyFromKeyboardCodeImpl(KeyboardCode key_code,
                                                   int flags) const {
+  // Windows expresses right-Alt as VKEY_MENU with the extended flag set.
+  // This key should generate AltGraph under layouts which use that modifier.
+  if (key_code == VKEY_MENU && (flags & EF_IS_EXTENDED_KEY) && has_alt_graph_) {
+    return DomKey::ALT_GRAPH;
+  }
+
   DomKey key = NonPrintableKeyboardCodeToDomKey(key_code, keyboard_layout_);
   if (key != DomKey::NONE)
     return key;
@@ -346,6 +352,7 @@
   // TODO(chongz): Optimize layout switching (see crbug.com/587147).
   keyboard_layout_ = layout;
   printable_keycode_to_key_.clear();
+  has_alt_graph_ = false;
 
   // Map size for some sample keyboard layouts:
   // US: 476, French: 602, Persian: 482, Vietnamese: 1436
@@ -385,6 +392,11 @@
           printable_keycode_to_key_[std::make_pair(static_cast<int>(key_code),
                                                    flags)] =
               DomKey::FromCharacter(translated_chars[0]);
+
+          // Detect whether the layout makes use of AltGraph.
+          if (flags & EF_ALTGR_DOWN) {
+            has_alt_graph_ = true;
+          }
         } else {
           // Ignores legacy non-printable control characters.
         }
diff --git a/ui/events/keycodes/platform_key_map_win.h b/ui/events/keycodes/platform_key_map_win.h
index 541ab33..14315299 100644
--- a/ui/events/keycodes/platform_key_map_win.h
+++ b/ui/events/keycodes/platform_key_map_win.h
@@ -44,6 +44,9 @@
 
   HKL keyboard_layout_ = 0;
 
+  // True if |keyboard_layout_| makes use of the AltGraph modifier.
+  bool has_alt_graph_ = false;
+
   typedef std::pair<int /*KeyboardCode*/, int /*EventFlags*/>
       KeyboardCodeEventFlagsPair;
   typedef std::unordered_map<KeyboardCodeEventFlagsPair,
diff --git a/ui/events/keycodes/platform_key_map_win_unittest.cc b/ui/events/keycodes/platform_key_map_win_unittest.cc
index 98689d18..0de6e119 100644
--- a/ui/events/keycodes/platform_key_map_win_unittest.cc
+++ b/ui/events/keycodes/platform_key_map_win_unittest.cc
@@ -326,4 +326,21 @@
   }
 }
 
+TEST_F(PlatformKeyMapTest, AltGraph) {
+  PlatformKeyMap us_keymap(
+      GetPlatformKeyboardLayout(KEYBOARD_LAYOUT_ENGLISH_US));
+  EXPECT_EQ(DomKey::ALT,
+            DomKeyFromKeyboardCodeImpl(us_keymap, VKEY_MENU, EF_ALTGR_DOWN));
+  EXPECT_EQ(DomKey::ALT,
+            DomKeyFromKeyboardCodeImpl(us_keymap, VKEY_MENU,
+                                       EF_ALTGR_DOWN | EF_IS_EXTENDED_KEY));
+
+  PlatformKeyMap fr_keymap(GetPlatformKeyboardLayout(KEYBOARD_LAYOUT_FRENCH));
+  EXPECT_EQ(DomKey::ALT,
+            DomKeyFromKeyboardCodeImpl(fr_keymap, VKEY_MENU, EF_ALTGR_DOWN));
+  EXPECT_EQ(DomKey::ALT_GRAPH,
+            DomKeyFromKeyboardCodeImpl(fr_keymap, VKEY_MENU,
+                                       EF_ALTGR_DOWN | EF_IS_EXTENDED_KEY));
+}
+
 }  // namespace ui
diff --git a/ui/events/ozone/BUILD.gn b/ui/events/ozone/BUILD.gn
index 73d0195b..c409273a 100644
--- a/ui/events/ozone/BUILD.gn
+++ b/ui/events/ozone/BUILD.gn
@@ -99,6 +99,8 @@
       "evdev/keyboard_util_evdev.h",
       "evdev/mouse_button_map_evdev.cc",
       "evdev/mouse_button_map_evdev.h",
+      "evdev/scoped_input_device.cc",
+      "evdev/scoped_input_device.h",
       "evdev/tablet_event_converter_evdev.cc",
       "evdev/tablet_event_converter_evdev.h",
       "evdev/touch_evdev_debug_buffer.cc",
diff --git a/ui/events/ozone/evdev/event_converter_evdev.cc b/ui/events/ozone/evdev/event_converter_evdev.cc
index 42b48ea..e9da819 100644
--- a/ui/events/ozone/evdev/event_converter_evdev.cc
+++ b/ui/events/ozone/evdev/event_converter_evdev.cc
@@ -34,8 +34,6 @@
 EventConverterEvdev::~EventConverterEvdev() {
   DCHECK(!enabled_);
   DCHECK(!watching_);
-  if (fd_ >= 0)
-    close(fd_);
 }
 
 void EventConverterEvdev::Start() {
diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl.cc b/ui/events/ozone/evdev/event_converter_evdev_impl.cc
index 5da4f6b9..ca6fda5 100644
--- a/ui/events/ozone/evdev/event_converter_evdev_impl.cc
+++ b/ui/events/ozone/evdev/event_converter_evdev_impl.cc
@@ -15,6 +15,7 @@
 #include "ui/events/keycodes/dom/keycode_converter.h"
 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
 #include "ui/events/ozone/evdev/keyboard_util_evdev.h"
+#include "ui/events/ozone/evdev/scoped_input_device.h"
 
 namespace ui {
 
@@ -30,29 +31,28 @@
 }  // namespace
 
 EventConverterEvdevImpl::EventConverterEvdevImpl(
-    int fd,
+    ScopedInputDevice fd,
     base::FilePath path,
     int id,
     const EventDeviceInfo& devinfo,
     CursorDelegateEvdev* cursor,
     DeviceEventDispatcherEvdev* dispatcher)
-    : EventConverterEvdev(fd,
+    : EventConverterEvdev(fd.get(),
                           path,
                           id,
                           devinfo.device_type(),
                           devinfo.name(),
                           devinfo.vendor_id(),
                           devinfo.product_id()),
+      input_device_fd_(std::move(fd)),
       has_keyboard_(devinfo.HasKeyboard()),
       has_touchpad_(devinfo.HasTouchpad()),
       has_caps_lock_led_(devinfo.HasLedEvent(LED_CAPSL)),
       cursor_(cursor),
-      dispatcher_(dispatcher) {
-}
+      dispatcher_(dispatcher) {}
 
 EventConverterEvdevImpl::~EventConverterEvdevImpl() {
   DCHECK(!enabled_);
-  close(fd_);
 }
 
 void EventConverterEvdevImpl::OnFileCanReadWithoutBlocking(int fd) {
diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl.h b/ui/events/ozone/evdev/event_converter_evdev_impl.h
index 820554ec7..228d63c 100644
--- a/ui/events/ozone/evdev/event_converter_evdev_impl.h
+++ b/ui/events/ozone/evdev/event_converter_evdev_impl.h
@@ -19,6 +19,7 @@
 #include "ui/events/ozone/evdev/events_ozone_evdev_export.h"
 #include "ui/events/ozone/evdev/keyboard_evdev.h"
 #include "ui/events/ozone/evdev/mouse_button_map_evdev.h"
+#include "ui/events/ozone/evdev/scoped_input_device.h"
 
 struct input_event;
 
@@ -29,7 +30,7 @@
 class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdevImpl
     : public EventConverterEvdev {
  public:
-  EventConverterEvdevImpl(int fd,
+  EventConverterEvdevImpl(ScopedInputDevice fd,
                           base::FilePath path,
                           int id,
                           const EventDeviceInfo& info,
@@ -64,6 +65,9 @@
   // non-axis-aligned movement properly.
   void FlushEvents(const input_event& input);
 
+  // Input device file descriptor.
+  ScopedInputDevice input_device_fd_;
+
   // Input modalities for this device.
   bool has_keyboard_;
   bool has_touchpad_;
diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc b/ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc
index 406451f..720dfd5 100644
--- a/ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc
+++ b/ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc
@@ -22,6 +22,7 @@
 #include "ui/events/ozone/evdev/event_converter_test_util.h"
 #include "ui/events/ozone/evdev/event_factory_evdev.h"
 #include "ui/events/ozone/evdev/keyboard_evdev.h"
+#include "ui/events/ozone/evdev/scoped_input_device.h"
 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
 
 namespace ui {
@@ -30,10 +31,10 @@
 
 class MockEventConverterEvdevImpl : public EventConverterEvdevImpl {
  public:
-  MockEventConverterEvdevImpl(int fd,
+  MockEventConverterEvdevImpl(ScopedInputDevice fd,
                               CursorDelegateEvdev* cursor,
                               DeviceEventDispatcherEvdev* dispatcher)
-      : EventConverterEvdevImpl(fd,
+      : EventConverterEvdevImpl(std::move(fd),
                                 base::FilePath(kTestDevicePath),
                                 1,
                                 EventDeviceInfo(),
@@ -94,8 +95,8 @@
     int evdev_io[2];
     if (pipe(evdev_io))
       PLOG(FATAL) << "failed pipe";
-    events_in_ = evdev_io[0];
-    events_out_ = evdev_io[1];
+    ui::ScopedInputDevice events_in(evdev_io[0]);
+    events_out_.reset(evdev_io[1]);
 
     cursor_.reset(new ui::MockCursorEvdev());
 
@@ -107,15 +108,14 @@
                    base::Unretained(this)));
     dispatcher_ =
         ui::CreateDeviceEventDispatcherEvdevForTest(event_factory_.get());
-    device_.reset(new ui::MockEventConverterEvdevImpl(events_in_, cursor_.get(),
-                                                      dispatcher_.get()));
+    device_.reset(new ui::MockEventConverterEvdevImpl(
+        std::move(events_in), cursor_.get(), dispatcher_.get()));
   }
 
   void TearDown() override {
     device_.reset();
     cursor_.reset();
-    close(events_in_);
-    close(events_out_);
+    events_out_.reset();
   }
 
   ui::MockCursorEvdev* cursor() { return cursor_.get(); }
@@ -157,8 +157,7 @@
 
   std::vector<std::unique_ptr<ui::Event>> dispatched_events_;
 
-  int events_out_;
-  int events_in_;
+  ui::ScopedInputDevice events_out_;
 
   DISALLOW_COPY_AND_ASSIGN(EventConverterEvdevImplTest);
 };
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc
index dddfcbee..6812283 100644
--- a/ui/events/ozone/evdev/input_device_factory_evdev.cc
+++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -82,7 +82,7 @@
 
 std::unique_ptr<EventConverterEvdev> CreateConverter(
     const OpenInputDeviceParams& params,
-    int fd,
+    ScopedInputDevice fd,
     const EventDeviceInfo& devinfo) {
 #if defined(USE_EVDEV_GESTURES)
   // Touchpad or mouse: use gestures library.
@@ -92,16 +92,17 @@
         base::MakeUnique<GestureInterpreterLibevdevCros>(
             params.id, params.cursor, params.gesture_property_provider,
             params.dispatcher);
-    return base::MakeUnique<EventReaderLibevdevCros>(
-        fd, params.path, params.id, devinfo, std::move(gesture_interp));
+    return base::MakeUnique<EventReaderLibevdevCros>(std::move(fd), params.path,
+                                                     params.id, devinfo,
+                                                     std::move(gesture_interp));
   }
 #endif
 
   // Touchscreen: use TouchEventConverterEvdev.
   if (devinfo.HasTouchscreen()) {
     std::unique_ptr<TouchEventConverterEvdev> converter(
-        new TouchEventConverterEvdev(fd, params.path, params.id, devinfo,
-                                     params.dispatcher));
+        new TouchEventConverterEvdev(std::move(fd), params.path, params.id,
+                                     devinfo, params.dispatcher));
     converter->Initialize(devinfo);
     return std::move(converter);
   }
@@ -109,11 +110,13 @@
   // Graphics tablet
   if (devinfo.HasTablet())
     return base::WrapUnique<EventConverterEvdev>(new TabletEventConverterEvdev(
-        fd, params.path, params.id, params.cursor, devinfo, params.dispatcher));
+        std::move(fd), params.path, params.id, params.cursor, devinfo,
+        params.dispatcher));
 
   // Everything else: use EventConverterEvdevImpl.
-  return base::WrapUnique<EventConverterEvdevImpl>(new EventConverterEvdevImpl(
-      fd, params.path, params.id, devinfo, params.cursor, params.dispatcher));
+  return base::WrapUnique<EventConverterEvdevImpl>(
+      new EventConverterEvdevImpl(std::move(fd), params.path, params.id,
+                                  devinfo, params.cursor, params.dispatcher));
 }
 
 // Open an input device and construct an EventConverterEvdev.
@@ -122,8 +125,8 @@
   const base::FilePath& path = params.path;
   TRACE_EVENT1("evdev", "OpenInputDevice", "path", path.value());
 
-  int fd = open(path.value().c_str(), O_RDWR | O_NONBLOCK);
-  if (fd < 0) {
+  ScopedInputDevice fd(open(path.value().c_str(), O_RDWR | O_NONBLOCK));
+  if (fd.get() < 0) {
     PLOG(ERROR) << "Cannot open " << path.value();
     return nullptr;
   }
@@ -132,17 +135,16 @@
   // expects event timestamps to correlate to the monotonic clock
   // (base::TimeTicks).
   unsigned int clk = CLOCK_MONOTONIC;
-  if (ioctl(fd, EVIOCSCLOCKID, &clk))
+  if (ioctl(fd.get(), EVIOCSCLOCKID, &clk))
     PLOG(ERROR) << "failed to set CLOCK_MONOTONIC";
 
   EventDeviceInfo devinfo;
-  if (!devinfo.Initialize(fd, path)) {
+  if (!devinfo.Initialize(fd.get(), path)) {
     LOG(ERROR) << "Failed to get device information for " << path.value();
-    close(fd);
     return nullptr;
   }
 
-  return CreateConverter(params, fd, devinfo);
+  return CreateConverter(params, std::move(fd), devinfo);
 }
 
 }  // namespace
diff --git a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc
index b1d46ce..5914791 100644
--- a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc
+++ b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc
@@ -28,12 +28,12 @@
 }  // namespace
 
 EventReaderLibevdevCros::EventReaderLibevdevCros(
-    int fd,
+    ScopedInputDevice fd,
     const base::FilePath& path,
     int id,
     const EventDeviceInfo& devinfo,
     std::unique_ptr<Delegate> delegate)
-    : EventConverterEvdev(fd,
+    : EventConverterEvdev(fd.get(),
                           path,
                           id,
                           devinfo.device_type(),
@@ -53,7 +53,7 @@
   evdev_.log_udata = this;
   evdev_.syn_report = OnSynReport;
   evdev_.syn_report_udata = this;
-  evdev_.fd = fd;
+  evdev_.fd = fd.release();
 
   memset(&evstate_, 0, sizeof(evstate_));
   evdev_.evstate = &evstate_;
@@ -67,7 +67,6 @@
 EventReaderLibevdevCros::~EventReaderLibevdevCros() {
   DCHECK(!watching_);
   EvdevClose(&evdev_);
-  fd_ = -1;
 }
 
 EventReaderLibevdevCros::Delegate::~Delegate() {}
diff --git a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h
index ba55e85..b4480152 100644
--- a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h
+++ b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h
@@ -14,6 +14,7 @@
 #include "base/message_loop/message_loop.h"
 #include "ui/events/ozone/evdev/event_converter_evdev.h"
 #include "ui/events/ozone/evdev/event_device_info.h"
+#include "ui/events/ozone/evdev/scoped_input_device.h"
 
 namespace ui {
 
@@ -42,7 +43,7 @@
     virtual void OnLibEvdevCrosStopped(Evdev* evdev, EventStateRec* state) = 0;
   };
 
-  EventReaderLibevdevCros(int fd,
+  EventReaderLibevdevCros(ScopedInputDevice fd,
                           const base::FilePath& path,
                           int id,
                           const EventDeviceInfo& devinfo,
diff --git a/ui/events/ozone/evdev/scoped_input_device.cc b/ui/events/ozone/evdev/scoped_input_device.cc
new file mode 100644
index 0000000..3f8f62bd
--- /dev/null
+++ b/ui/events/ozone/evdev/scoped_input_device.cc
@@ -0,0 +1,31 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/ozone/evdev/scoped_input_device.h"
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "base/debug/alias.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+
+namespace ui {
+namespace internal {
+
+// static
+void ScopedInputDeviceCloseTraits::Free(int fd) {
+  // It's important to crash here.
+  // There are security implications to not closing a file descriptor
+  // properly. As file descriptors are "capabilities", keeping them open
+  // would make the current process keep access to a resource. Much of
+  // Chrome relies on being able to "drop" such access.
+  // It's especially problematic on Linux with the setuid sandbox, where
+  // a single open directory would bypass the entire security model.
+  int ret = IGNORE_EINTR(close(fd));
+  PCHECK(0 == ret || errno != EBADF);
+}
+
+}  // namespace internal
+}  // namespace ui
diff --git a/ui/events/ozone/evdev/scoped_input_device.h b/ui/events/ozone/evdev/scoped_input_device.h
new file mode 100644
index 0000000..24d8aa58
--- /dev/null
+++ b/ui/events/ozone/evdev/scoped_input_device.h
@@ -0,0 +1,25 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_OZONE_EVDEV_SCOPED_INPUT_DEVICE_H_
+#define UI_EVENTS_OZONE_EVDEV_SCOPED_INPUT_DEVICE_H_
+
+#include "base/scoped_generic.h"
+
+namespace ui {
+namespace internal {
+
+struct ScopedInputDeviceCloseTraits {
+  static int InvalidValue() { return -1; }
+  static void Free(int fd);
+};
+
+}  // namespace internal
+
+typedef base::ScopedGeneric<int, internal::ScopedInputDeviceCloseTraits>
+    ScopedInputDevice;
+
+}  // namespace ui
+
+#endif  // UI_EVENTS_OZONE_EVDEV_SCOPED_INPUT_DEVICE_H_
diff --git a/ui/events/ozone/evdev/tablet_event_converter_evdev.cc b/ui/events/ozone/evdev/tablet_event_converter_evdev.cc
index 869520f2..ef021d3 100644
--- a/ui/events/ozone/evdev/tablet_event_converter_evdev.cc
+++ b/ui/events/ozone/evdev/tablet_event_converter_evdev.cc
@@ -31,19 +31,20 @@
 }  // namespace
 
 TabletEventConverterEvdev::TabletEventConverterEvdev(
-    int fd,
+    ScopedInputDevice fd,
     base::FilePath path,
     int id,
     CursorDelegateEvdev* cursor,
     const EventDeviceInfo& info,
     DeviceEventDispatcherEvdev* dispatcher)
-    : EventConverterEvdev(fd,
+    : EventConverterEvdev(fd.get(),
                           path,
                           id,
                           info.device_type(),
                           info.name(),
                           info.vendor_id(),
                           info.product_id()),
+      input_device_fd_(std::move(fd)),
       cursor_(cursor),
       dispatcher_(dispatcher) {
   x_abs_min_ = info.GetAbsMinimum(ABS_X);
diff --git a/ui/events/ozone/evdev/tablet_event_converter_evdev.h b/ui/events/ozone/evdev/tablet_event_converter_evdev.h
index b8c528d..11e9e34 100644
--- a/ui/events/ozone/evdev/tablet_event_converter_evdev.h
+++ b/ui/events/ozone/evdev/tablet_event_converter_evdev.h
@@ -14,6 +14,7 @@
 #include "ui/events/ozone/evdev/event_device_info.h"
 #include "ui/events/ozone/evdev/event_modifiers_evdev.h"
 #include "ui/events/ozone/evdev/events_ozone_evdev_export.h"
+#include "ui/events/ozone/evdev/scoped_input_device.h"
 
 struct input_event;
 
@@ -24,7 +25,7 @@
 class EVENTS_OZONE_EVDEV_EXPORT TabletEventConverterEvdev
     : public EventConverterEvdev {
  public:
-  TabletEventConverterEvdev(int fd,
+  TabletEventConverterEvdev(ScopedInputDevice fd,
                             base::FilePath path,
                             int id,
                             CursorDelegateEvdev* cursor,
@@ -48,6 +49,9 @@
   // non-axis-aligned movement properly.
   void FlushEvents(const input_event& input);
 
+  // Input device file descriptor.
+  ScopedInputDevice input_device_fd_;
+
   // Controller for watching the input fd.
   base::MessagePumpLibevent::FileDescriptorWatcher controller_;
 
diff --git a/ui/events/ozone/evdev/tablet_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/tablet_event_converter_evdev_unittest.cc
index b049287..30bd240 100644
--- a/ui/events/ozone/evdev/tablet_event_converter_evdev_unittest.cc
+++ b/ui/events/ozone/evdev/tablet_event_converter_evdev_unittest.cc
@@ -78,7 +78,7 @@
 
 class MockTabletEventConverterEvdev : public TabletEventConverterEvdev {
  public:
-  MockTabletEventConverterEvdev(int fd,
+  MockTabletEventConverterEvdev(ScopedInputDevice fd,
                                 base::FilePath path,
                                 CursorDelegateEvdev* cursor,
                                 const EventDeviceInfo& devinfo,
@@ -131,12 +131,12 @@
 };
 
 MockTabletEventConverterEvdev::MockTabletEventConverterEvdev(
-    int fd,
+    ScopedInputDevice fd,
     base::FilePath path,
     CursorDelegateEvdev* cursor,
     const EventDeviceInfo& devinfo,
     DeviceEventDispatcherEvdev* dispatcher)
-    : TabletEventConverterEvdev(fd,
+    : TabletEventConverterEvdev(std::move(fd),
                                 path,
                                 1,
                                 cursor,
@@ -173,13 +173,6 @@
 
   // Overridden from testing::Test:
   void SetUp() override {
-    // Set up pipe to satisfy message pump (unused).
-    int evdev_io[2];
-    if (pipe(evdev_io))
-      PLOG(FATAL) << "failed pipe";
-    events_in_ = evdev_io[0];
-    events_out_ = evdev_io[1];
-
     cursor_.reset(new ui::MockTabletCursorEvdev());
     device_manager_ = ui::CreateDeviceManagerForTest();
     event_factory_ = ui::CreateEventFactoryEvdevForTest(
@@ -197,11 +190,18 @@
 
   ui::MockTabletEventConverterEvdev* CreateDevice(
       const ui::DeviceCapabilities& caps) {
+    // Set up pipe to satisfy message pump (unused).
+    int evdev_io[2];
+    if (pipe(evdev_io))
+      PLOG(FATAL) << "failed pipe";
+    ui::ScopedInputDevice events_in(evdev_io[0]);
+    events_out_.reset(evdev_io[1]);
+
     ui::EventDeviceInfo devinfo;
     CapabilitiesToDeviceInfo(caps, &devinfo);
     return new ui::MockTabletEventConverterEvdev(
-        events_in_, base::FilePath(kTestDevicePath), cursor_.get(), devinfo,
-        dispatcher_.get());
+        std::move(events_in), base::FilePath(kTestDevicePath), cursor_.get(),
+        devinfo, dispatcher_.get());
   }
 
   ui::CursorDelegateEvdev* cursor() { return cursor_.get(); }
@@ -227,8 +227,7 @@
 
   std::vector<std::unique_ptr<ui::Event>> dispatched_events_;
 
-  int events_out_;
-  int events_in_;
+  ui::ScopedInputDevice events_out_;
 
   DISALLOW_COPY_AND_ASSIGN(TabletEventConverterEvdevTest);
 };
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
index c46608d..dc88e3c 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
@@ -96,18 +96,19 @@
 namespace ui {
 
 TouchEventConverterEvdev::TouchEventConverterEvdev(
-    int fd,
+    ScopedInputDevice fd,
     base::FilePath path,
     int id,
     const EventDeviceInfo& devinfo,
     DeviceEventDispatcherEvdev* dispatcher)
-    : EventConverterEvdev(fd,
+    : EventConverterEvdev(fd.get(),
                           path,
                           id,
                           devinfo.device_type(),
                           devinfo.name(),
                           devinfo.vendor_id(),
                           devinfo.product_id()),
+      input_device_fd_(std::move(fd)),
       dispatcher_(dispatcher) {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kExtraTouchNoiseFiltering)) {
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h
index 45ceb653..26a557d 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.h
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -19,6 +19,7 @@
 #include "ui/events/ozone/evdev/event_converter_evdev.h"
 #include "ui/events/ozone/evdev/event_device_info.h"
 #include "ui/events/ozone/evdev/events_ozone_evdev_export.h"
+#include "ui/events/ozone/evdev/scoped_input_device.h"
 #include "ui/events/ozone/evdev/touch_evdev_debug_buffer.h"
 
 namespace ui {
@@ -30,7 +31,7 @@
 class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev
     : public EventConverterEvdev {
  public:
-  TouchEventConverterEvdev(int fd,
+  TouchEventConverterEvdev(ScopedInputDevice fd,
                            base::FilePath path,
                            int id,
                            const EventDeviceInfo& devinfo,
@@ -88,6 +89,9 @@
 
   int NextTrackingId();
 
+  // Input device file descriptor.
+  ScopedInputDevice input_device_fd_;
+
   // Dispatcher for events.
   DeviceEventDispatcherEvdev* dispatcher_;
 
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
index 3b0ed67..c8b24a9 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -80,7 +80,7 @@
 
 class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
  public:
-  MockTouchEventConverterEvdev(int fd,
+  MockTouchEventConverterEvdev(ScopedInputDevice fd,
                                base::FilePath path,
                                const EventDeviceInfo& devinfo,
                                DeviceEventDispatcherEvdev* dispatcher);
@@ -158,15 +158,11 @@
 };
 
 MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(
-    int fd,
+    ScopedInputDevice fd,
     base::FilePath path,
     const EventDeviceInfo& devinfo,
     DeviceEventDispatcherEvdev* dispatcher)
-    : TouchEventConverterEvdev(fd,
-                               path,
-                               1,
-                               devinfo,
-                               dispatcher) {
+    : TouchEventConverterEvdev(std::move(fd), path, 1, devinfo, dispatcher) {
   int fds[2];
 
   if (pipe(fds))
@@ -211,8 +207,8 @@
     int evdev_io[2];
     if (pipe(evdev_io))
       PLOG(FATAL) << "failed pipe";
-    events_in_ = evdev_io[0];
-    events_out_ = evdev_io[1];
+    ScopedInputDevice events_in(evdev_io[0]);
+    events_out_.reset(evdev_io[1]);
 
     // Device creation happens on a worker thread since it may involve blocking
     // operations. Simulate that by creating it before creating a UI message
@@ -222,7 +218,7 @@
         base::Bind(&TouchEventConverterEvdevTest::DispatchCallback,
                    base::Unretained(this))));
     device_.reset(new ui::MockTouchEventConverterEvdev(
-        events_in_, base::FilePath(kTestDevicePath), devinfo,
+        std::move(events_in), base::FilePath(kTestDevicePath), devinfo,
         dispatcher_.get()));
     loop_ = new base::MessageLoopForUI;
 
@@ -264,8 +260,7 @@
   std::unique_ptr<ui::MockTouchEventConverterEvdev> device_;
   std::unique_ptr<ui::MockDeviceEventDispatcherEvdev> dispatcher_;
 
-  int events_out_;
-  int events_in_;
+  ScopedInputDevice events_out_;
 
   void DispatchCallback(const GenericEventParams& params) {
     dispatched_events_.push_back(params);
diff --git a/ui/file_manager/image_loader/background_scripts.js b/ui/file_manager/image_loader/background_scripts.js
index e9b28a0..e395e9e 100644
--- a/ui/file_manager/image_loader/background_scripts.js
+++ b/ui/file_manager/image_loader/background_scripts.js
@@ -9,6 +9,7 @@
 // <include src="../file_manager/foreground/js/metadata/image_orientation.js">
 // <include src="cache.js">
 // <include src="image_loader.js">
+// <include src="image_loader_util.js">
 // <include src="piex_loader.js">
 // <include src="request.js">
 // <include src="scheduler.js">
diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn
index 3226e6fa..6a5101ab 100644
--- a/ui/keyboard/BUILD.gn
+++ b/ui/keyboard/BUILD.gn
@@ -166,6 +166,7 @@
     "//ui/gfx",
     "//ui/gfx/geometry",
     "//ui/gl:test_support",
+    "//ui/resources:ui_test_pak",
     "//ui/wm",
   ]
 }
diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc
index 147c6df0..fa58eb457 100644
--- a/ui/keyboard/keyboard_controller_unittest.cc
+++ b/ui/keyboard/keyboard_controller_unittest.cc
@@ -64,6 +64,33 @@
   }
 }
 
+class ScopedTouchKeyboardEnabler {
+ public:
+  ScopedTouchKeyboardEnabler() : enabled_(keyboard::GetTouchKeyboardEnabled()) {
+    keyboard::SetTouchKeyboardEnabled(true);
+  }
+
+  ~ScopedTouchKeyboardEnabler() { keyboard::SetTouchKeyboardEnabled(enabled_); }
+
+ private:
+  const bool enabled_;
+};
+
+class ScopedAccessibilityKeyboardEnabler {
+ public:
+  ScopedAccessibilityKeyboardEnabler()
+      : enabled_(keyboard::GetAccessibilityKeyboardEnabled()) {
+    keyboard::SetAccessibilityKeyboardEnabled(true);
+  }
+
+  ~ScopedAccessibilityKeyboardEnabler() {
+    keyboard::SetAccessibilityKeyboardEnabled(enabled_);
+  }
+
+ private:
+  const bool enabled_;
+};
+
 // An event handler that focuses a window when it is clicked/touched on. This is
 // used to match the focus manger behaviour in ash and views.
 class TestFocusController : public ui::EventHandler {
@@ -375,7 +402,7 @@
 
 // Tests that tapping/clicking inside the keyboard does not give it focus.
 TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) {
-  keyboard::SetAccessibilityKeyboardEnabled(true);
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
   const gfx::Rect& root_bounds = root_window()->bounds();
   aura::test::EventCountDelegate delegate;
   std::unique_ptr<aura::Window> window(new aura::Window(&delegate));
@@ -416,11 +443,10 @@
   generator.ClickLeftButton();
   EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset());
   keyboard_container->RemovePreTargetHandler(&observer);
-  keyboard::SetAccessibilityKeyboardEnabled(false);
 }
 
 TEST_F(KeyboardControllerTest, VisibilityChangeWithTextInputTypeChange) {
-  keyboard::SetAccessibilityKeyboardEnabled(true);
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
   ui::DummyTextInputClient input_client_0(ui::TEXT_INPUT_TYPE_TEXT);
   ui::DummyTextInputClient input_client_1(ui::TEXT_INPUT_TYPE_TEXT);
   ui::DummyTextInputClient input_client_2(ui::TEXT_INPUT_TYPE_TEXT);
@@ -457,7 +483,6 @@
 
   EXPECT_FALSE(WillHideKeyboard());
   EXPECT_TRUE(keyboard_container->IsVisible());
-  keyboard::SetAccessibilityKeyboardEnabled(false);
 }
 
 // Test to prevent spurious overscroll boxes when changing tabs during keyboard
@@ -470,7 +495,7 @@
   root_window()->AddChild(keyboard_container);
 
   // Enable touch keyboard / overscroll mode to test insets.
-  keyboard::SetTouchKeyboardEnabled(true);
+  ScopedTouchKeyboardEnabler scoped_keyboard_enabler;
   EXPECT_TRUE(keyboard::IsKeyboardOverscrollEnabled());
 
   SetFocus(&input_client);
@@ -487,7 +512,7 @@
 // Verify switch to FLOATING mode will reset the overscroll or resize and when
 // in FLOATING mode, overscroll or resize wont be triggered.
 TEST_F(KeyboardControllerTest, FloatingKeyboardDontOverscrollOrResize) {
-  keyboard::SetAccessibilityKeyboardEnabled(true);
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
   ui::DummyTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT);
   ui::DummyTextInputClient no_input_client(ui::TEXT_INPUT_TYPE_NONE);
 
@@ -497,7 +522,7 @@
   std::unique_ptr<KeyboardContainerObserver> keyboard_container_observer(
       new KeyboardContainerObserver(container, &run_loop));
   gfx::Rect screen_bounds = root_window()->bounds();
-  keyboard::SetTouchKeyboardEnabled(true);
+  ScopedTouchKeyboardEnabler scoped_touch_keyboard_enabler;
 
   SetFocus(&input_client);
   gfx::Rect expected_bounds(
@@ -519,18 +544,17 @@
   // In FLOATING mode, no overscroll or resize should be triggered.
   EXPECT_EQ(3, number_of_calls());
   EXPECT_EQ(gfx::Rect(), controller()->current_keyboard_bounds());
-  keyboard::SetAccessibilityKeyboardEnabled(false);
 }
 
 // Verify switch to FULL_WIDTH mode will move virtual keyboard to the right
 // place and sets the correct overscroll.
 TEST_F(KeyboardControllerTest, SwitchToFullWidthVirtualKeyboard) {
+  ScopedTouchKeyboardEnabler scoped_keyboard_enabler;
   ui::DummyTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT);
 
   aura::Window* container(controller()->GetContainerWindow());
   root_window()->AddChild(container);
   gfx::Rect screen_bounds = root_window()->bounds();
-  keyboard::SetTouchKeyboardEnabled(true);
   SetFocus(&input_client);
 
   controller()->SetKeyboardMode(FLOATING);
@@ -546,7 +570,7 @@
 }
 
 TEST_F(KeyboardControllerTest, AlwaysVisibleWhenLocked) {
-  keyboard::SetAccessibilityKeyboardEnabled(true);
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
   ui::DummyTextInputClient input_client_0(ui::TEXT_INPUT_TYPE_TEXT);
   ui::DummyTextInputClient input_client_1(ui::TEXT_INPUT_TYPE_TEXT);
   ui::DummyTextInputClient no_input_client_0(ui::TEXT_INPUT_TYPE_NONE);
@@ -583,12 +607,11 @@
   // Wait for hide keyboard to finish.
   run_loop.Run();
   EXPECT_FALSE(keyboard_container->IsVisible());
-  keyboard::SetAccessibilityKeyboardEnabled(false);
 }
 
 // Tests that deactivates keyboard will get closed event.
 TEST_F(KeyboardControllerTest, CloseKeyboard) {
-  keyboard::SetAccessibilityKeyboardEnabled(true);
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
   aura::Window* keyboard_container(controller()->GetContainerWindow());
   root_window()->AddChild(keyboard_container);
   keyboard_container->Show();
@@ -600,7 +623,6 @@
   root_window()->RemoveChild(keyboard_container);
   ResetController();
   EXPECT_TRUE(IsKeyboardClosed());
-  keyboard::SetAccessibilityKeyboardEnabled(false);
 }
 
 class KeyboardControllerAnimationTest : public KeyboardControllerTest {
@@ -639,8 +661,8 @@
 
 // Tests virtual keyboard has correct show and hide animation.
 TEST_F(KeyboardControllerAnimationTest, ContainerAnimation) {
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
   ui::Layer* layer = keyboard_container()->layer();
-  keyboard::SetAccessibilityKeyboardEnabled(true);
   ShowKeyboard();
 
   // Keyboard container and window should immediately become visible before
@@ -681,14 +703,13 @@
   EXPECT_GT(hide_start_opacity, hide_end_opacity);
   EXPECT_EQ(transform, layer->transform());
   EXPECT_EQ(gfx::Rect(), notified_bounds());
-  keyboard::SetAccessibilityKeyboardEnabled(false);
 }
 
 // Show keyboard during keyboard hide animation should abort the hide animation
 // and the keyboard should animate in.
 // Test for crbug.com/333284.
 TEST_F(KeyboardControllerAnimationTest, ContainerShowWhileHide) {
-  keyboard::SetAccessibilityKeyboardEnabled(true);
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
   ui::Layer* layer = keyboard_container()->layer();
   ShowKeyboard();
   RunAnimationForLayer(layer);
@@ -701,16 +722,15 @@
   EXPECT_TRUE(keyboard_window()->IsVisible());
   EXPECT_EQ(1.0, layer->opacity());
   EXPECT_EQ(gfx::Transform(), layer->transform());
-  keyboard::SetAccessibilityKeyboardEnabled(false);
 }
 
 // Test for crbug.com/568274.
 TEST_F(KeyboardControllerTest, FloatingKeyboardShowOnFirstTap) {
+  ScopedTouchKeyboardEnabler scoped_keyboard_enabler;
   aura::Window* container(controller()->GetContainerWindow());
   aura::Window* keyboard(ui()->GetKeyboardWindow());
   root_window()->AddChild(container);
 
-  keyboard::SetTouchKeyboardEnabled(true);
   controller()->SetKeyboardMode(FLOATING);
   container->AddChild(keyboard);
   // Mock focus on an input field.
@@ -725,12 +745,12 @@
 }
 
 TEST_F(KeyboardControllerTest, DisplayChangeShouldNotifyBoundsChange) {
+  ScopedTouchKeyboardEnabler scoped_keyboard_enabler;
   ui::DummyTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT);
 
   aura::Window* container(controller()->GetContainerWindow());
   root_window()->AddChild(container);
 
-  keyboard::SetTouchKeyboardEnabled(true);
   controller()->SetKeyboardMode(FULL_WIDTH);
   SetFocus(&input_client);
   gfx::Rect new_bounds(0, 0, 1280, 800);
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd
index abe7398..44d685e 100644
--- a/ui/strings/ui_strings.grd
+++ b/ui/strings/ui_strings.grd
@@ -619,8 +619,8 @@
         <message name="IDS_MESSAGE_CENTER_NOTIFICATION_BUTTON_COPY_SCREENSHOT_TO_CLIPBOARD" desc="The button label for the screenshot notification which copies the screenshot image to clipboard on click.">
           Copy to clipboard
         </message>
-        <message name="IDS_MESSAGE_CENTER_NOTIFICATION_BUTTON_ANNOTATE_SCREENSHOT" desc="The label for the screenshot notification button that opens Google Keep to annotate the screenhsot.">
-          Annotate in Google Keep
+        <message name="IDS_MESSAGE_CENTER_NOTIFICATION_BUTTON_ANNOTATE_SCREENSHOT" desc="The label for the screenshot notification button that opens the note-taking app to annotate the screenhsot.">
+          Annotate image
         </message>
         <message name="IDS_MESSAGE_CENTER_NOTIFIER_HATS_NAME" desc="The name of hats notifier that is a system component">
           Hats
diff --git a/ui/views/animation/flood_fill_ink_drop_ripple.cc b/ui/views/animation/flood_fill_ink_drop_ripple.cc
index 5ed22814..e542679 100644
--- a/ui/views/animation/flood_fill_ink_drop_ripple.cc
+++ b/ui/views/animation/flood_fill_ink_drop_ripple.cc
@@ -209,7 +209,8 @@
       }
       break;
     case InkDropState::ACTION_PENDING: {
-      DCHECK(old_ink_drop_state == InkDropState::HIDDEN);
+      DCHECK_EQ(InkDropState::HIDDEN, old_ink_drop_state)
+          << " old_ink_drop_state=" << ToString(old_ink_drop_state);
 
       AnimateToOpacity(visible_opacity_,
                        GetAnimationDuration(ACTION_PENDING_FADE_IN),
@@ -228,7 +229,8 @@
     }
     case InkDropState::ACTION_TRIGGERED: {
       DCHECK(old_ink_drop_state == InkDropState::HIDDEN ||
-             old_ink_drop_state == InkDropState::ACTION_PENDING);
+             old_ink_drop_state == InkDropState::ACTION_PENDING)
+          << " old_ink_drop_state=" << ToString(old_ink_drop_state);
       if (old_ink_drop_state == InkDropState::HIDDEN) {
         AnimateStateChange(old_ink_drop_state, InkDropState::ACTION_PENDING,
                            animation_observer);
@@ -240,7 +242,8 @@
       break;
     }
     case InkDropState::ALTERNATE_ACTION_PENDING: {
-      DCHECK(old_ink_drop_state == InkDropState::ACTION_PENDING);
+      DCHECK_EQ(InkDropState::ACTION_PENDING, old_ink_drop_state)
+          << " old_ink_drop_state=" << ToString(old_ink_drop_state);
       AnimateToOpacity(visible_opacity_,
                        GetAnimationDuration(ALTERNATE_ACTION_PENDING),
                        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
@@ -252,7 +255,8 @@
       break;
     }
     case InkDropState::ALTERNATE_ACTION_TRIGGERED:
-      DCHECK(old_ink_drop_state == InkDropState::ALTERNATE_ACTION_PENDING);
+      DCHECK_EQ(InkDropState::ALTERNATE_ACTION_PENDING, old_ink_drop_state)
+          << " old_ink_drop_state=" << ToString(old_ink_drop_state);
       AnimateToOpacity(kHiddenOpacity, GetAnimationDuration(
                                            ALTERNATE_ACTION_TRIGGERED_FADE_OUT),
                        ui::LayerAnimator::ENQUEUE_NEW_ANIMATION,
diff --git a/ui/views/animation/square_ink_drop_ripple.cc b/ui/views/animation/square_ink_drop_ripple.cc
index 64def33..6a635a5 100644
--- a/ui/views/animation/square_ink_drop_ripple.cc
+++ b/ui/views/animation/square_ink_drop_ripple.cc
@@ -280,7 +280,9 @@
       }
       break;
     case InkDropState::ACTION_PENDING:
-      DCHECK(old_ink_drop_state == InkDropState::HIDDEN);
+      DCHECK_EQ(InkDropState::HIDDEN, old_ink_drop_state)
+          << " old_ink_drop_state=" << ToString(old_ink_drop_state);
+      ;
       AnimateToOpacity(visible_opacity_,
                        GetAnimationDuration(ACTION_PENDING_FADE_IN),
                        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
@@ -301,7 +303,8 @@
       break;
     case InkDropState::ACTION_TRIGGERED: {
       DCHECK(old_ink_drop_state == InkDropState::HIDDEN ||
-             old_ink_drop_state == InkDropState::ACTION_PENDING);
+             old_ink_drop_state == InkDropState::ACTION_PENDING)
+          << " old_ink_drop_state=" << ToString(old_ink_drop_state);
       if (old_ink_drop_state == InkDropState::HIDDEN) {
         AnimateStateChange(old_ink_drop_state, InkDropState::ACTION_PENDING,
                            animation_observer);
@@ -323,7 +326,8 @@
       break;
     }
     case InkDropState::ALTERNATE_ACTION_PENDING:
-      DCHECK(old_ink_drop_state == InkDropState::ACTION_PENDING);
+      DCHECK_EQ(InkDropState::ACTION_PENDING, old_ink_drop_state)
+          << " old_ink_drop_state=" << ToString(old_ink_drop_state);
       AnimateToOpacity(visible_opacity_,
                        GetAnimationDuration(ALTERNATE_ACTION_PENDING),
                        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
@@ -339,7 +343,8 @@
                          gfx::Tween::EASE_IN, animation_observer);
       break;
     case InkDropState::ALTERNATE_ACTION_TRIGGERED: {
-      DCHECK(old_ink_drop_state == InkDropState::ALTERNATE_ACTION_PENDING);
+      DCHECK_EQ(InkDropState::ALTERNATE_ACTION_PENDING, old_ink_drop_state)
+          << " old_ink_drop_state=" << ToString(old_ink_drop_state);
       base::TimeDelta visible_duration =
           GetAnimationDuration(ALTERNATE_ACTION_TRIGGERED_TRANSFORM) -
           GetAnimationDuration(ALTERNATE_ACTION_TRIGGERED_FADE_OUT);
diff --git a/url/gurl.cc b/url/gurl.cc
index c0e4a68..43f3052 100644
--- a/url/gurl.cc
+++ b/url/gurl.cc
@@ -108,9 +108,6 @@
 template<typename STR>
 void GURL::InitCanonical(base::BasicStringPiece<STR> input_spec,
                          bool trim_path_end) {
-  // Reserve enough room in the output for the input, plus some extra so that
-  // we have room if we have to escape a few things without reallocating.
-  spec_.reserve(input_spec.size() + 32);
   url::StdStringCanonOutput output(&spec_);
   is_valid_ = url::Canonicalize(
       input_spec.data(), static_cast<int>(input_spec.length()), trim_path_end,
@@ -198,12 +195,7 @@
     return GURL();
 
   GURL result;
-
-  // Reserve enough room in the output for the input, plus some extra so that
-  // we have room if we have to escape a few things without reallocating.
-  result.spec_.reserve(spec_.size() + 32);
   url::StdStringCanonOutput output(&result.spec_);
-
   if (!url::ResolveRelative(spec_.data(), static_cast<int>(spec_.length()),
                             parsed_, relative.data(),
                             static_cast<int>(relative.length()),
@@ -229,12 +221,7 @@
     return GURL();
 
   GURL result;
-
-  // Reserve enough room in the output for the input, plus some extra so that
-  // we have room if we have to escape a few things without reallocating.
-  result.spec_.reserve(spec_.size() + 32);
   url::StdStringCanonOutput output(&result.spec_);
-
   if (!url::ResolveRelative(spec_.data(), static_cast<int>(spec_.length()),
                             parsed_, relative.data(),
                             static_cast<int>(relative.length()),
@@ -262,11 +249,7 @@
   if (!is_valid_)
     return GURL();
 
-  // Reserve enough room in the output for the input, plus some extra so that
-  // we have room if we have to escape a few things without reallocating.
-  result.spec_.reserve(spec_.size() + 32);
   url::StdStringCanonOutput output(&result.spec_);
-
   result.is_valid_ = url::ReplaceComponents(
       spec_.data(), static_cast<int>(spec_.length()), parsed_, replacements,
       NULL, &output, &result.parsed_);
@@ -289,11 +272,7 @@
   if (!is_valid_)
     return GURL();
 
-  // Reserve enough room in the output for the input, plus some extra so that
-  // we have room if we have to escape a few things without reallocating.
-  result.spec_.reserve(spec_.size() + 32);
   url::StdStringCanonOutput output(&result.spec_);
-
   result.is_valid_ = url::ReplaceComponents(
       spec_.data(), static_cast<int>(spec_.length()), parsed_, replacements,
       NULL, &output, &result.parsed_);
diff --git a/url/url_canon.h b/url/url_canon.h
index c4852e490..ff66c6e3 100644
--- a/url/url_canon.h
+++ b/url/url_canon.h
@@ -117,6 +117,11 @@
     cur_len_ += str_len;
   }
 
+  void ReserveSizeIfNeeded(int estimated_size) {
+    if (estimated_size > buffer_len_)
+      Resize(estimated_size);
+  }
+
  protected:
   // Grows the given buffer so that it can fit at least |min_additional|
   // characters. Returns true if the buffer could be resized, false on OOM.
diff --git a/url/url_canon_relative.cc b/url/url_canon_relative.cc
index e34ea2f..8259056 100644
--- a/url/url_canon_relative.cc
+++ b/url/url_canon_relative.cc
@@ -4,6 +4,8 @@
 
 // Canonicalizer functions for working with and resolving relative URLs.
 
+#include <algorithm>
+
 #include "base/logging.h"
 #include "url/url_canon.h"
 #include "url/url_canon_internal.h"
@@ -264,7 +266,7 @@
 #endif  // WIN32
 
 // A subroutine of DoResolveRelativeURL, this resolves the URL knowning that
-// the input is a relative path or less (qyuery or ref).
+// the input is a relative path or less (query or ref).
 template<typename CHAR>
 bool DoResolveRelativePath(const char* base_url,
                            const Parsed& base_parsed,
@@ -280,7 +282,13 @@
   // also know we have a path so can copy up to there.
   Component path, query, ref;
   ParsePathInternal(relative_url, relative_component, &path, &query, &ref);
-  // Canonical URLs always have a path, so we can use that offset.
+
+  // Canonical URLs always have a path, so we can use that offset. Reserve
+  // enough room for the base URL, the new path, and some extra bytes for
+  // possible escaped characters.
+  output->ReserveSizeIfNeeded(
+      base_parsed.path.begin +
+      std::max(path.end(), std::max(query.end(), ref.end())) + 8);
   output->Append(base_url, base_parsed.path.begin);
 
   if (path.len > 0) {
@@ -394,6 +402,11 @@
   replacements.SetQuery(relative_url, relative_parsed.query);
   replacements.SetRef(relative_url, relative_parsed.ref);
 
+  // Length() does not include the old scheme, so make sure to add it from the
+  // base URL.
+  output->ReserveSizeIfNeeded(
+      replacements.components().Length() +
+      base_parsed.CountCharactersBefore(Parsed::USERNAME, false) + 8);
   return ReplaceStandardURL(base_url, base_parsed, replacements,
                             query_converter, output, out_parsed);
 }
diff --git a/url/url_util.cc b/url/url_util.cc
index b3e3604..f98f4b8 100644
--- a/url/url_util.cc
+++ b/url/url_util.cc
@@ -169,6 +169,10 @@
                     CharsetConverter* charset_converter,
                     CanonOutput* output,
                     Parsed* output_parsed) {
+  // Reserve enough room in the output for the input, plus some extra so that
+  // we have room if we have to escape a few things without reallocating.
+  output->ReserveSizeIfNeeded(spec_len + 8);
+
   // Remove any whitespace from the middle of the relative URL if necessary.
   // Possibly this will result in copying to the new buffer.
   RawCanonOutputT<CHAR> whitespace_buffer;
@@ -278,6 +282,9 @@
     return false;
   }
 
+  // Don't reserve buffer space here. Instead, reserve in DoCanonicalize and
+  // ReserveRelativeURL, to enable more accurate buffer sizes.
+
   // Pretend for a moment that |base_spec| is a standard URL. Normally
   // non-standard URLs are treated as PathURLs, but if the base has an
   // authority we would like to preserve it.
@@ -380,6 +387,12 @@
                                charset_converter, output, out_parsed);
   }
 
+  // TODO(csharrison): We could be smarter about size to reserve if this is done
+  // in callers below, and the code checks to see which components are being
+  // replaced, and with what length. If this ends up being a hot spot it should
+  // be changed.
+  output->ReserveSizeIfNeeded(spec_len + 8);
+
   // If we get here, then we know the scheme doesn't need to be replaced, so can
   // just key off the scheme in the spec to know how to do the replacements.
   if (DoCompareSchemeComponent(spec, parsed.scheme, url::kFileScheme)) {