diff --git a/DEPS b/DEPS
index ebec986..c32122a 100644
--- a/DEPS
+++ b/DEPS
@@ -78,7 +78,7 @@
   # 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': '8bc327bffb7ae7d10b93ee75c3d207caeb37f93b',
+  'skia_revision': '03a527c718edc3b39331437822f7131aec71ed0b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -643,7 +643,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd458ada06171a85af00367251a4ed55db7fe2018',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '1e53f8ad040ad8e614c0d1205cff070a8a03bf44', # commit position 20628
+    Var('webrtc_git') + '/src.git' + '@' + '5ec7e1276029f63ab6aaa244d402c3cf10011151', # commit position 20628
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index fdf77fd..d8f880de 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -180,13 +180,13 @@
 #endif  // USE_AURA
 
 const FeatureEntry::Choice kTouchEventFeatureDetectionChoices[] = {
-    {flags_ui::kGenericExperimentChoiceAutomatic, "", ""},
+    {flags_ui::kGenericExperimentChoiceDisabled, "", ""},
     {flags_ui::kGenericExperimentChoiceEnabled,
      switches::kTouchEventFeatureDetection,
      switches::kTouchEventFeatureDetectionEnabled},
-    {flags_ui::kGenericExperimentChoiceDisabled,
+    {flags_ui::kGenericExperimentChoiceAutomatic,
      switches::kTouchEventFeatureDetection,
-     switches::kTouchEventFeatureDetectionDisabled}};
+     switches::kTouchEventFeatureDetectionAuto}};
 
 #if defined(USE_AURA)
 const FeatureEntry::Choice kOverscrollHistoryNavigationChoices[] = {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 8b66159f..fcd95a0 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1427,7 +1427,7 @@
 const char kTouchEventsDescription[] =
     "Force Touch Events API feature detection to always be enabled or "
     "disabled, or to be enabled when a touchscreen is detected on startup "
-    "(Automatic, the default).";
+    "(Automatic).";
 
 const char kTouchSelectionStrategyName[] = "Touch text selection strategy";
 const char kTouchSelectionStrategyDescription[] =
diff --git a/chrome/browser/prefs/chrome_pref_service_unittest.cc b/chrome/browser/prefs/chrome_pref_service_unittest.cc
index c89dc7e..8c47ccb1 100644
--- a/chrome/browser/prefs/chrome_pref_service_unittest.cc
+++ b/chrome/browser/prefs/chrome_pref_service_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
 #include "chrome/browser/prefs/chrome_command_line_pref_store.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -99,4 +100,11 @@
   EXPECT_EQ(base::ASCIIToUTF16(kDefaultFont),
             webkit_prefs.standard_font_family_map[prefs::kWebKitCommonScript]);
   EXPECT_TRUE(webkit_prefs.javascript_enabled);
+
+#if defined(OS_ANDROID)
+  // Touch event enabled only on Android.
+  EXPECT_TRUE(webkit_prefs.touch_event_feature_detection_enabled);
+#else
+  EXPECT_FALSE(webkit_prefs.touch_event_feature_detection_enabled);
+#endif
 }
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 2a1da429..c7c70cc 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -734,12 +734,6 @@
   return dict_value;
 }
 
-bool PrerenderContents::IsCrossSiteNavigationPending() const {
-  return prerender_contents_ &&
-         prerender_contents_->GetSiteInstance() !=
-             prerender_contents_->GetPendingSiteInstance();
-}
-
 void PrerenderContents::PrepareForUse() {
   SetFinalStatus(FINAL_STATUS_USED);
 
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index 33c9adc1..305e97b 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -226,11 +226,6 @@
 
   std::unique_ptr<base::DictionaryValue> GetAsValue() const;
 
-  // Returns whether a pending cross-site navigation is happening.
-  // This could happen with renderer-issued navigations, such as a
-  // MouseEvent being dispatched by a link to a website installed as an app.
-  bool IsCrossSiteNavigationPending() const;
-
   // Marks prerender as used and releases any throttled resource requests.
   void PrepareForUse();
 
diff --git a/chrome/browser/prerender/prerender_final_status.h b/chrome/browser/prerender/prerender_final_status.h
index 48b2904..d2bc4549 100644
--- a/chrome/browser/prerender/prerender_final_status.h
+++ b/chrome/browser/prerender/prerender_final_status.h
@@ -46,7 +46,7 @@
   FINAL_STATUS_CACHE_OR_HISTORY_CLEARED = 31,
   FINAL_STATUS_CANCELLED = 32,
   FINAL_STATUS_SSL_ERROR = 33,
-  FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING = 34,
+  // Obsolete: FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING = 34,
   FINAL_STATUS_DEVTOOLS_ATTACHED = 35,
   // Obsolete: FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH = 36,
   // Obsolete: FINAL_STATUS_NO_USE_GROUP = 37,
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index e66b5209..d3ed8fb 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -403,16 +403,6 @@
     return nullptr;
   }
 
-  // If the prerendered page is in the middle of a cross-site navigation,
-  // don't swap it in because there isn't a good way to merge histories.
-  if (prerender_data->contents()->IsCrossSiteNavigationPending()) {
-    histograms_->RecordFinalStatus(prerender_data->contents()->origin(),
-                                   FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING);
-    prerender_data->contents()->Destroy(
-        FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING);
-    return nullptr;
-  }
-
   // At this point, we've determined that we will use the prerender.
   content::RenderProcessHost* process_host =
       prerender_data->contents()->GetRenderViewHost()->GetProcess();
diff --git a/chrome/test/mini_installer/config/chrome_beta_not_installed.prop b/chrome/test/mini_installer/config/chrome_beta_not_installed.prop
index 459610e..5dc7686 100644
--- a/chrome/test/mini_installer/config/chrome_beta_not_installed.prop
+++ b/chrome/test/mini_installer/config/chrome_beta_not_installed.prop
@@ -14,8 +14,20 @@
       "exists": "forbidden",
       "wow_key": "KEY_WOW64_32KEY"
     },
+    "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_HTML_PROG_ID_BETA$USER_SPECIFIC_REGISTRY_SUFFIX": {
+      "exists": "forbidden"
+    },
     "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_BETA$USER_SPECIFIC_REGISTRY_SUFFIX": {
       "exists": "forbidden"
+    },
+    "HKEY_CURRENT_USER\\Software\\Clients\\StartMenuInternet\\$CHROME_SHORT_NAME_BETA$USER_SPECIFIC_REGISTRY_SUFFIX": {
+      "exists": "forbidden"
+    },
+    "HKEY_CURRENT_USER\\Software\\RegisteredApplications": {
+      "exists": "optional",
+      "values": {
+        "$CHROME_LONG_NAME_BETA$USER_SPECIFIC_REGISTRY_SUFFIX": {}
+      }
     }
   }
 }
diff --git a/chrome/test/mini_installer/config/chrome_canary_not_installed.prop b/chrome/test/mini_installer/config/chrome_canary_not_installed.prop
index 3984f76..01cdf7bf 100644
--- a/chrome/test/mini_installer/config/chrome_canary_not_installed.prop
+++ b/chrome/test/mini_installer/config/chrome_canary_not_installed.prop
@@ -14,8 +14,20 @@
       "exists": "forbidden",
       "wow_key": "KEY_WOW64_32KEY"
     },
+    "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_HTML_PROG_ID_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": {
+      "exists": "forbidden"
+    },
     "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": {
       "exists": "forbidden"
+    },
+    "HKEY_CURRENT_USER\\Software\\Clients\\StartMenuInternet\\$CHROME_SHORT_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": {
+      "exists": "forbidden"
+    },
+    "HKEY_CURRENT_USER\\Software\\RegisteredApplications": {
+      "exists": "optional",
+      "values": {
+        "$CHROME_LONG_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": {}
+      }
     }
   }
 }
diff --git a/chrome/test/mini_installer/config/chrome_dev_not_installed.prop b/chrome/test/mini_installer/config/chrome_dev_not_installed.prop
index 43241c1c..2decdad 100644
--- a/chrome/test/mini_installer/config/chrome_dev_not_installed.prop
+++ b/chrome/test/mini_installer/config/chrome_dev_not_installed.prop
@@ -14,8 +14,20 @@
       "exists": "forbidden",
       "wow_key": "KEY_WOW64_32KEY"
     },
+    "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_HTML_PROG_ID_DEV$USER_SPECIFIC_REGISTRY_SUFFIX": {
+      "exists": "forbidden"
+    },
     "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_DEV$USER_SPECIFIC_REGISTRY_SUFFIX": {
       "exists": "forbidden"
+    },
+    "HKEY_CURRENT_USER\\Software\\Clients\\StartMenuInternet\\$CHROME_SHORT_NAME_DEV$USER_SPECIFIC_REGISTRY_SUFFIX": {
+      "exists": "forbidden"
+    },
+    "HKEY_CURRENT_USER\\Software\\RegisteredApplications": {
+      "exists": "optional",
+      "values": {
+        "$CHROME_LONG_NAME_DEV$USER_SPECIFIC_REGISTRY_SUFFIX": {}
+      }
     }
   }
 }
diff --git a/chrome/test/mini_installer/config/chrome_system_not_installed.prop b/chrome/test/mini_installer/config/chrome_system_not_installed.prop
index 6573d5da..4238ece 100644
--- a/chrome/test/mini_installer/config/chrome_system_not_installed.prop
+++ b/chrome/test/mini_installer/config/chrome_system_not_installed.prop
@@ -20,8 +20,20 @@
       "exists": "forbidden",
       "wow_key": "KEY_WOW64_32KEY"
     },
+    "HKEY_LOCAL_MACHINE\\Software\\Classes\\$CHROME_HTML_PROG_ID": {
+      "exists": "forbidden"
+    },
     "HKEY_LOCAL_MACHINE\\Software\\Classes\\$CHROME_SHORT_NAME": {
       "exists": "forbidden"
+    },
+    "HKEY_LOCAL_MACHINE\\Software\\Clients\\StartMenuInternet\\$CHROME_SHORT_NAME": {
+      "exists": "forbidden"
+    },
+    "HKEY_LOCAL_MACHINE\\Software\\RegisteredApplications": {
+      "exists": "optional",
+      "values": {
+        "$CHROME_LONG_NAME": {}
+      }
     }
   }
 }
diff --git a/chrome/test/mini_installer/config/chrome_user_not_installed.prop b/chrome/test/mini_installer/config/chrome_user_not_installed.prop
index 4008722..07c372b 100644
--- a/chrome/test/mini_installer/config/chrome_user_not_installed.prop
+++ b/chrome/test/mini_installer/config/chrome_user_not_installed.prop
@@ -20,8 +20,20 @@
       "exists": "forbidden",
       "wow_key": "KEY_WOW64_32KEY"
     },
+    "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_HTML_PROG_ID$USER_SPECIFIC_REGISTRY_SUFFIX": {
+      "exists": "forbidden"
+    },
     "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": {
       "exists": "forbidden"
+    },
+    "HKEY_CURRENT_USER\\Software\\Clients\\StartMenuInternet\\$CHROME_SHORT_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": {
+      "exists": "forbidden"
+    },
+    "HKEY_CURRENT_USER\\Software\\RegisteredApplications": {
+      "exists": "optional",
+      "values": {
+        "$CHROME_LONG_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": {}
+      }
     }
   }
 }
diff --git a/chrome/test/mini_installer/registry_verifier.py b/chrome/test/mini_installer/registry_verifier.py
index 0e8f57b..5fa1fb29 100644
--- a/chrome/test/mini_installer/registry_verifier.py
+++ b/chrome/test/mini_installer/registry_verifier.py
@@ -65,13 +65,15 @@
               'required', 'optional', or 'forbidden'. Values are not checked if
               an 'optional' key is not present in the registry.
           'values' (optional) a dictionary where each key is a registry value
-              and its associated value is a dictionary with the following key
-              and values:
+              (which is expanded using Expand) and its associated value is a
+              dictionary with the following key and values:
                   'type' (optional) a string indicating the type of the registry
                       value. If not present, the corresponding value is expected
                       to be absent in the registry.
-                  'data' the associated data of the registry value if 'type' is
-                      specified. If it is a string, it is expanded using Expand.
+                  'data' (optional) the associated data of the registry value if
+                      'type' is specified. If it is a string, it is expanded
+                      using Expand. If not present, only the value's type is
+                      verified.
           'wow_key' (optional) a string indicating whether the view of the
               registry is KEY_WOW64_32KEY or KEY_WOW64_64KEY. If not present,
               the view of registry is determined by the bitness of the installer
@@ -107,6 +109,7 @@
     for value, value_expectation in expectation['values'].iteritems():
       # Query the value. It will throw a WindowsError if the value doesn't
       # exist.
+      value = variable_expander.Expand(value)
       try:
         data, value_type = _winreg.QueryValueEx(key_handle, value)
       except WindowsError:
@@ -124,6 +127,9 @@
           "Value '%s' of registry key %s has unexpected type '%s'" % (
               value, key, expected_value_type)
 
+      if 'data' not in value_expectation:
+        return
+
       # Verify the associated data of the value.
       expected_data = value_expectation['data']
       if isinstance(expected_data, basestring):
diff --git a/chrome/test/mini_installer/variable_expander.py b/chrome/test/mini_installer/variable_expander.py
index e6e2841e..98b1d35 100644
--- a/chrome/test/mini_installer/variable_expander.py
+++ b/chrome/test/mini_installer/variable_expander.py
@@ -152,6 +152,9 @@
             '{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}'),
           'CHROME_DIR': 'Google\\Chrome',
           'CHROME_HTML_PROG_ID': 'ChromeHTML',
+          'CHROME_HTML_PROG_ID_BETA': 'ChromeBHTML',
+          'CHROME_HTML_PROG_ID_DEV': 'ChromeDHTML',
+          'CHROME_HTML_PROG_ID_SXS': 'ChromeSSHTM',
           'CHROME_LONG_NAME': 'Google Chrome',
           'CHROME_SHORT_NAME': 'Chrome',
           'CHROME_UPDATE_REGISTRY_SUBKEY': (
diff --git a/components/viz/service/surfaces/surface_hittest.cc b/components/viz/service/surfaces/surface_hittest.cc
index 52990c3c..9ba95d4 100644
--- a/components/viz/service/surfaces/surface_hittest.cc
+++ b/components/viz/service/surfaces/surface_hittest.cc
@@ -25,16 +25,25 @@
 SurfaceId SurfaceHittest::GetTargetSurfaceAtPoint(
     const SurfaceId& root_surface_id,
     const gfx::Point& point,
-    gfx::Transform* transform) {
+    gfx::Transform* transform,
+    bool* out_query_renderer) {
   SurfaceId out_surface_id = root_surface_id;
 
   // Reset the output transform to identity.
   if (transform)
     *transform = gfx::Transform();
 
+  *out_query_renderer = false;
+
   std::set<const RenderPass*> referenced_passes;
   GetTargetSurfaceAtPointInternal(root_surface_id, 0, point, &referenced_passes,
-                                  &out_surface_id, transform);
+                                  &out_surface_id, transform,
+                                  out_query_renderer);
+  // Any point that hits an OOPIF can defer to renderer-based hit testing
+  // in order to check whether there might be transparent elements
+  // occluding it. Such elements would not have DrawQuads present here.
+  if (root_surface_id != out_surface_id)
+    *out_query_renderer = true;
 
   return out_surface_id;
 }
@@ -82,7 +91,8 @@
     const gfx::Point& point_in_root_target,
     std::set<const RenderPass*>* referenced_passes,
     SurfaceId* out_surface_id,
-    gfx::Transform* out_transform) {
+    gfx::Transform* out_transform,
+    bool* out_query_renderer) {
   const RenderPass* render_pass =
       GetRenderPassForSurfaceById(surface_id, render_pass_id);
   if (!render_pass)
@@ -105,6 +115,7 @@
 
   gfx::Point point_in_render_pass_space(point_in_root_target);
   transform_from_root_target.TransformPoint(&point_in_render_pass_space);
+  bool non_surface_was_hit = false;
 
   for (const DrawQuad* quad : render_pass->quad_list) {
     gfx::Transform target_to_quad_transform;
@@ -114,57 +125,88 @@
       continue;
     }
 
-    if (quad->material == DrawQuad::SURFACE_CONTENT) {
-      // We've hit a SurfaceDrawQuad, we need to recurse into this
-      // Surface.
-      const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
+    switch (quad->material) {
+      case DrawQuad::SURFACE_CONTENT: {
+        // We've hit a SurfaceDrawQuad, we need to recurse into this
+        // Surface.
+        const SurfaceDrawQuad* surface_quad =
+            SurfaceDrawQuad::MaterialCast(quad);
 
-      if (delegate_ &&
-          delegate_->RejectHitTarget(surface_quad, point_in_quad_space)) {
-        continue;
+        if (delegate_ &&
+            delegate_->RejectHitTarget(surface_quad, point_in_quad_space)) {
+          continue;
+        }
+
+        // If a point hits a Surface after hitting a non-Surface quad, we should
+        // defer to the renderer. Some DrawQuads are not valid hit test targets
+        // and information needed to distinguish them is not available here.
+        if (non_surface_was_hit) {
+          *out_query_renderer = true;
+          return true;
+        }
+
+        gfx::Transform transform_to_child_space;
+        if (GetTargetSurfaceAtPointInternal(
+                surface_quad->primary_surface_id, 0, point_in_quad_space,
+                referenced_passes, out_surface_id, &transform_to_child_space,
+                out_query_renderer)) {
+          *out_transform = transform_to_child_space * target_to_quad_transform *
+                           transform_from_root_target;
+          return true;
+        } else if (delegate_ && delegate_->AcceptHitTarget(
+                                    surface_quad, point_in_quad_space)) {
+          *out_surface_id = surface_quad->primary_surface_id;
+          *out_transform = transform_to_child_space * target_to_quad_transform *
+                           transform_from_root_target;
+          return true;
+        }
+        break;
       }
 
-      gfx::Transform transform_to_child_space;
-      if (GetTargetSurfaceAtPointInternal(
-              surface_quad->primary_surface_id, 0, point_in_quad_space,
-              referenced_passes, out_surface_id, &transform_to_child_space)) {
-        *out_transform = transform_to_child_space * target_to_quad_transform *
-                         transform_from_root_target;
-        return true;
-      } else if (delegate_ && delegate_->AcceptHitTarget(surface_quad,
-                                                         point_in_quad_space)) {
-        *out_surface_id = surface_quad->primary_surface_id;
-        *out_transform = transform_to_child_space * target_to_quad_transform *
-                         transform_from_root_target;
-        return true;
+      case DrawQuad::RENDER_PASS: {
+        // We've hit a RenderPassDrawQuad, we need to recurse into this
+        // RenderPass.
+        const RenderPassDrawQuad* render_quad =
+            RenderPassDrawQuad::MaterialCast(quad);
+
+        SurfaceId out_surface_id_candidate;
+        gfx::Transform transform_to_child_space;
+
+        if (GetTargetSurfaceAtPointInternal(
+                surface_id, render_quad->render_pass_id, point_in_root_target,
+                referenced_passes, &out_surface_id_candidate,
+                &transform_to_child_space, out_query_renderer)) {
+          // If |non_surface_was_hit| is set, then the above call was only for
+          // the purpose of potentially setting |out_query_renderer|.
+          if (!non_surface_was_hit) {
+            *out_transform = transform_to_child_space;
+            *out_surface_id = out_surface_id_candidate;
+            if (surface_id == out_surface_id_candidate) {
+              // Don't return here even though we hit a viable target, in order
+              // to continue looking for occluded surfaces that might be
+              // underneath.
+              non_surface_was_hit = true;
+            } else {
+              return true;
+            }
+          }
+        }
+        break;
       }
 
-      continue;
+      default: {
+        // We've hit a different type of quad in the current Surface. Typically
+        // this quad will receive the event, but continue iterating to look for
+        // occluded surface quads.
+        *out_surface_id = surface_id;
+        non_surface_was_hit = true;
+      }
     }
-
-    if (quad->material == DrawQuad::RENDER_PASS) {
-      // We've hit a RenderPassDrawQuad, we need to recurse into this
-      // RenderPass.
-      const RenderPassDrawQuad* render_quad =
-          RenderPassDrawQuad::MaterialCast(quad);
-
-      gfx::Transform transform_to_child_space;
-      if (GetTargetSurfaceAtPointInternal(
-              surface_id, render_quad->render_pass_id, point_in_root_target,
-              referenced_passes, out_surface_id, &transform_to_child_space)) {
-        *out_transform = transform_to_child_space;
-        return true;
-      }
-
-      continue;
-    }
-
-    // We've hit a different type of quad in the current Surface. There's no
-    // need to iterate anymore, this is the quad that receives the event.
-    *out_surface_id = surface_id;
-    return true;
   }
 
+  if (non_surface_was_hit)
+    return true;
+
   // No quads were found beneath the provided |point|.
   return false;
 }
diff --git a/components/viz/service/surfaces/surface_hittest.h b/components/viz/service/surfaces/surface_hittest.h
index f8550309..c297e04c 100644
--- a/components/viz/service/surfaces/surface_hittest.h
+++ b/components/viz/service/surfaces/surface_hittest.h
@@ -33,11 +33,18 @@
   ~SurfaceHittest();
 
   // Returns the target surface that falls underneath the provided |point|.
+  // |out_query_renderer| is set to true if the result is not high confidence,
+  // which means that there could be a different result when hit testing is
+  // performed in the renderer process. In that case the returned SurfaceId and
+  // Transform should be ignored.
+  // When |out_query_renderer| is set to false the returned SurfaceId and
+  // Transform can be taken as correct without further verification.
   // Also returns the |transform| to convert the |point| to the target surface's
   // space.
   SurfaceId GetTargetSurfaceAtPoint(const SurfaceId& root_surface_id,
                                     const gfx::Point& point,
-                                    gfx::Transform* transform);
+                                    gfx::Transform* transform,
+                                    bool* out_query_renderer);
 
   // Returns whether the target surface falls inside the provide root surface.
   // Returns the |transform| to convert points from the root surface coordinate
@@ -61,7 +68,8 @@
       const gfx::Point& point_in_root_target,
       std::set<const RenderPass*>* referenced_passes,
       SurfaceId* out_surface_id,
-      gfx::Transform* out_transform);
+      gfx::Transform* out_transform,
+      bool* out_query_renderer);
 
   bool GetTransformToTargetSurfaceInternal(
       const SurfaceId& root_surface_id,
diff --git a/components/viz/service/surfaces/surface_hittest_unittest.cc b/components/viz/service/surfaces/surface_hittest_unittest.cc
index 76fbf553..3411980 100644
--- a/components/viz/service/surfaces/surface_hittest_unittest.cc
+++ b/components/viz/service/surfaces/surface_hittest_unittest.cc
@@ -34,6 +34,7 @@
   gfx::Point input_point;
   SurfaceId expected_layer_tree_frame_sink_id;
   gfx::Point expected_output_point;
+  bool query_renderer;
 };
 
 void RunTests(SurfaceHittestDelegate* delegate,
@@ -41,15 +42,17 @@
               TestCase* tests,
               size_t test_count) {
   SurfaceHittest hittest(delegate, manager);
+  bool query_renderer;
   for (size_t i = 0; i < test_count; ++i) {
     const TestCase& test = tests[i];
     gfx::Point point(test.input_point);
     gfx::Transform transform;
     EXPECT_EQ(test.expected_layer_tree_frame_sink_id,
               hittest.GetTargetSurfaceAtPoint(test.input_surface_id, point,
-                                              &transform));
+                                              &transform, &query_renderer));
     transform.TransformPoint(&point);
     EXPECT_EQ(test.expected_output_point, point);
+    EXPECT_EQ(test.query_renderer, query_renderer);
 
     // Verify that GetTransformToTargetSurface returns true and returns the same
     // transform as returned by GetTargetSurfaceAtPoint.
@@ -127,9 +130,10 @@
     SurfaceHittest hittest(nullptr, surface_manager());
     // It is expected this test will complete without crashes.
     gfx::Transform transform;
-    EXPECT_EQ(root_surface_id,
-              hittest.GetTargetSurfaceAtPoint(
-                  root_surface_id, gfx::Point(100, 100), &transform));
+    bool query_renderer;
+    EXPECT_EQ(root_surface_id, hittest.GetTargetSurfaceAtPoint(
+                                   root_surface_id, gfx::Point(100, 100),
+                                   &transform, &query_renderer));
   }
 
   root_support().EvictCurrentSurface();
@@ -149,7 +153,7 @@
                                        std::move(root_frame));
   TestCase tests[] = {
       {root_surface_id, gfx::Point(100, 100), root_surface_id,
-       gfx::Point(100, 100)},
+       gfx::Point(100, 100), false},
   };
 
   RunTests(nullptr, surface_manager(), tests, arraysize(tests));
@@ -198,17 +202,17 @@
                                         std::move(child_frame));
 
   TestCase tests[] = {{root_surface_id, gfx::Point(10, 10), root_surface_id,
-                       gfx::Point(10, 10)},
+                       gfx::Point(10, 10), false},
                       {root_surface_id, gfx::Point(99, 99), root_surface_id,
-                       gfx::Point(99, 99)},
+                       gfx::Point(99, 99), false},
                       {root_surface_id, gfx::Point(100, 100), child_surface_id,
-                       gfx::Point(50, 50)},
+                       gfx::Point(50, 50), true},
                       {root_surface_id, gfx::Point(199, 199), child_surface_id,
-                       gfx::Point(149, 149)},
+                       gfx::Point(149, 149), true},
                       {root_surface_id, gfx::Point(200, 200), root_surface_id,
-                       gfx::Point(200, 200)},
+                       gfx::Point(200, 200), false},
                       {root_surface_id, gfx::Point(290, 290), root_surface_id,
-                       gfx::Point(290, 290)}};
+                       gfx::Point(290, 290), false}};
 
   RunTests(nullptr, surface_manager(), tests, arraysize(tests));
 
@@ -229,10 +233,13 @@
 
     gfx::Point point(100, 100);
     gfx::Transform transform;
-    EXPECT_EQ(root_surface_id, hittest.GetTargetSurfaceAtPoint(
-                                   root_surface_id, point, &transform));
+    bool query_renderer;
+    EXPECT_EQ(root_surface_id,
+              hittest.GetTargetSurfaceAtPoint(root_surface_id, point,
+                                              &transform, &query_renderer));
     transform.TransformPoint(&point);
     EXPECT_EQ(gfx::Point(100, 100), point);
+    EXPECT_EQ(query_renderer, false);
 
     gfx::Point point_in_target_space(100, 100);
     gfx::Transform target_transform;
@@ -247,6 +254,73 @@
   child_support().EvictCurrentSurface();
 }
 
+TEST_F(SurfaceHittestTest, Hittest_OccludedChildSurface) {
+  // Creates a root surface.
+  gfx::Rect root_rect(300, 300);
+  RenderPass* root_pass = nullptr;
+  CompositorFrame root_frame = CreateCompositorFrame(root_rect, &root_pass);
+
+  // Add a solid quad to the root surface, occluding the child surface.
+  gfx::Rect root_solid_quad_rect(100, 100);
+  CreateSolidColorDrawQuad(
+      root_pass,
+      gfx::Transform(1.0f, 0.0f, 0.0f, 50.0f, 0.0f, 1.0f, 0.0f, 50.0f, 0.0f,
+                     0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f),
+      root_rect, root_solid_quad_rect);
+
+  // Add a reference to the child surface on the root surface.
+  ParentLocalSurfaceIdAllocator child_allocator;
+  LocalSurfaceId child_local_surface_id = child_allocator.GenerateId();
+  SurfaceId child_surface_id(kChildFrameSink, child_local_surface_id);
+  gfx::Rect child_rect(200, 200);
+  CreateSurfaceDrawQuad(
+      root_pass,
+      gfx::Transform(1.0f, 0.0f, 0.0f, 50.0f, 0.0f, 1.0f, 0.0f, 50.0f, 0.0f,
+                     0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f),
+      root_rect, child_rect, child_surface_id);
+
+  // Submit the root frame.
+  ParentLocalSurfaceIdAllocator root_allocator;
+  LocalSurfaceId root_local_surface_id = root_allocator.GenerateId();
+  SurfaceId root_surface_id(kRootFrameSink, root_local_surface_id);
+  root_support().SubmitCompositorFrame(root_local_surface_id,
+                                       std::move(root_frame));
+
+  // Creates a child surface.
+  RenderPass* child_pass = nullptr;
+  CompositorFrame child_frame = CreateCompositorFrame(child_rect, &child_pass);
+
+  // Add a solid quad in the child surface.
+  gfx::Rect child_solid_quad_rect(100, 100);
+  CreateSolidColorDrawQuad(
+      child_pass,
+      gfx::Transform(1.0f, 0.0f, 0.0f, 50.0f, 0.0f, 1.0f, 0.0f, 50.0f, 0.0f,
+                     0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f),
+      root_rect, child_solid_quad_rect);
+
+  // Submit the frame.
+  child_support().SubmitCompositorFrame(child_local_surface_id,
+                                        std::move(child_frame));
+
+  TestCase tests[] = {{root_surface_id, gfx::Point(10, 10), root_surface_id,
+                       gfx::Point(10, 10), false},
+                      {root_surface_id, gfx::Point(99, 99), root_surface_id,
+                       gfx::Point(99, 99), true},
+                      {root_surface_id, gfx::Point(100, 100), root_surface_id,
+                       gfx::Point(100, 100), true},
+                      {root_surface_id, gfx::Point(199, 199), child_surface_id,
+                       gfx::Point(149, 149), true},
+                      {root_surface_id, gfx::Point(200, 200), root_surface_id,
+                       gfx::Point(200, 200), false},
+                      {root_surface_id, gfx::Point(290, 290), root_surface_id,
+                       gfx::Point(290, 290), false}};
+
+  RunTests(nullptr, surface_manager(), tests, arraysize(tests));
+
+  root_support().EvictCurrentSurface();
+  child_support().EvictCurrentSurface();
+}
+
 // This test verifies that hit testing will progress to the next quad if it
 // encounters an invalid RenderPassDrawQuad for whatever reason.
 TEST_F(SurfaceHittestTest, Hittest_InvalidRenderPassDrawQuad) {
@@ -295,17 +369,17 @@
                                         std::move(child_frame));
 
   TestCase tests[] = {{root_surface_id, gfx::Point(10, 10), root_surface_id,
-                       gfx::Point(10, 10)},
+                       gfx::Point(10, 10), false},
                       {root_surface_id, gfx::Point(99, 99), root_surface_id,
-                       gfx::Point(99, 99)},
+                       gfx::Point(99, 99), false},
                       {root_surface_id, gfx::Point(100, 100), child_surface_id,
-                       gfx::Point(50, 50)},
+                       gfx::Point(50, 50), true},
                       {root_surface_id, gfx::Point(199, 199), child_surface_id,
-                       gfx::Point(149, 149)},
+                       gfx::Point(149, 149), true},
                       {root_surface_id, gfx::Point(200, 200), root_surface_id,
-                       gfx::Point(200, 200)},
+                       gfx::Point(200, 200), false},
                       {root_surface_id, gfx::Point(290, 290), root_surface_id,
-                       gfx::Point(290, 290)}};
+                       gfx::Point(290, 290), false}};
 
   RunTests(nullptr, surface_manager(), tests, arraysize(tests));
 
@@ -355,21 +429,21 @@
 
   TestCase tests[] = {// These tests just miss the RenderPassDrawQuad.
                       {root_surface_id, gfx::Point(49, 49), root_surface_id,
-                       gfx::Point(49, 49)},
+                       gfx::Point(49, 49), false},
                       {root_surface_id, gfx::Point(150, 150), root_surface_id,
-                       gfx::Point(150, 150)},
+                       gfx::Point(150, 150), false},
                       // These tests just hit the boundaries of the
                       // RenderPassDrawQuad.
                       {root_surface_id, gfx::Point(50, 50), root_surface_id,
-                       gfx::Point(50, 50)},
+                       gfx::Point(50, 50), false},
                       {root_surface_id, gfx::Point(149, 149), root_surface_id,
-                       gfx::Point(149, 149)},
+                       gfx::Point(149, 149), false},
                       // These tests fall somewhere in the center of the
                       // RenderPassDrawQuad.
                       {root_surface_id, gfx::Point(99, 99), root_surface_id,
-                       gfx::Point(99, 99)},
+                       gfx::Point(99, 99), false},
                       {root_surface_id, gfx::Point(100, 100), root_surface_id,
-                       gfx::Point(100, 100)}};
+                       gfx::Point(100, 100), false}};
 
   RunTests(nullptr, surface_manager(), tests, arraysize(tests));
 
@@ -417,17 +491,18 @@
                                         std::move(child_frame));
 
   TestCase test_expectations_without_insets[] = {
-      {root_surface_id, gfx::Point(55, 55), child_surface_id, gfx::Point(5, 5)},
+      {root_surface_id, gfx::Point(55, 55), child_surface_id, gfx::Point(5, 5),
+       true},
       {root_surface_id, gfx::Point(60, 60), child_surface_id,
-       gfx::Point(10, 10)},
+       gfx::Point(10, 10), true},
       {root_surface_id, gfx::Point(239, 239), child_surface_id,
-       gfx::Point(189, 189)},
+       gfx::Point(189, 189), true},
       {root_surface_id, gfx::Point(244, 244), child_surface_id,
-       gfx::Point(194, 194)},
-      {root_surface_id, gfx::Point(50, 50), root_surface_id,
-       gfx::Point(50, 50)},
+       gfx::Point(194, 194), true},
+      {root_surface_id, gfx::Point(50, 50), root_surface_id, gfx::Point(50, 50),
+       false},
       {root_surface_id, gfx::Point(249, 249), root_surface_id,
-       gfx::Point(249, 249)},
+       gfx::Point(249, 249), false},
   };
 
   TestSurfaceHittestDelegate empty_delegate;
@@ -441,22 +516,22 @@
   TestCase test_expectations_with_reject_insets[] = {
       // Point (55, 55) falls outside the child surface due to the insets
       // introduced above.
-      {root_surface_id, gfx::Point(55, 55), root_surface_id,
-       gfx::Point(55, 55)},
+      {root_surface_id, gfx::Point(55, 55), root_surface_id, gfx::Point(55, 55),
+       false},
       // These two points still fall within the child surface.
       {root_surface_id, gfx::Point(60, 60), child_surface_id,
-       gfx::Point(10, 10)},
+       gfx::Point(10, 10), true},
       {root_surface_id, gfx::Point(239, 239), child_surface_id,
-       gfx::Point(189, 189)},
+       gfx::Point(189, 189), true},
       // Point (244, 244) falls outside the child surface due to the insets
       // introduced above.
       {root_surface_id, gfx::Point(244, 244), root_surface_id,
-       gfx::Point(244, 244)},
+       gfx::Point(244, 244), false},
       // Next two points also fall within within the insets indroduced above.
-      {root_surface_id, gfx::Point(50, 50), root_surface_id,
-       gfx::Point(50, 50)},
+      {root_surface_id, gfx::Point(50, 50), root_surface_id, gfx::Point(50, 50),
+       false},
       {root_surface_id, gfx::Point(249, 249), root_surface_id,
-       gfx::Point(249, 249)},
+       gfx::Point(249, 249), false},
   };
 
   TestSurfaceHittestDelegate reject_delegate;
@@ -471,17 +546,19 @@
   EXPECT_EQ(0, reject_delegate.accept_target_overrides());
 
   TestCase test_expectations_with_accept_insets[] = {
-      {root_surface_id, gfx::Point(55, 55), child_surface_id, gfx::Point(5, 5)},
+      {root_surface_id, gfx::Point(55, 55), child_surface_id, gfx::Point(5, 5),
+       true},
       {root_surface_id, gfx::Point(60, 60), child_surface_id,
-       gfx::Point(10, 10)},
+       gfx::Point(10, 10), true},
       {root_surface_id, gfx::Point(239, 239), child_surface_id,
-       gfx::Point(189, 189)},
+       gfx::Point(189, 189), true},
       {root_surface_id, gfx::Point(244, 244), child_surface_id,
-       gfx::Point(194, 194)},
+       gfx::Point(194, 194), true},
       // Next two points fall within within the insets indroduced above.
-      {root_surface_id, gfx::Point(50, 50), child_surface_id, gfx::Point(0, 0)},
+      {root_surface_id, gfx::Point(50, 50), child_surface_id, gfx::Point(0, 0),
+       true},
       {root_surface_id, gfx::Point(249, 249), child_surface_id,
-       gfx::Point(199, 199)},
+       gfx::Point(199, 199), true},
   };
 
   TestSurfaceHittestDelegate accept_delegate;
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index 848871c..82c02db 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -1032,11 +1032,9 @@
 
   RenderFrameHostManager* manager = frame_tree_node_->render_manager();
   RenderFrameHostImpl* current = manager->current_frame_host();
-  RenderFrameHostImpl* pending = manager->pending_frame_host();
   RenderFrameHostImpl* speculative = manager->speculative_frame_host();
-  RenderFrameHostImpl* host =
-      IsBrowserSideNavigationEnabled() ? frame_host_ : handlers_frame_host_;
-  return host == current || host == pending || host == speculative;
+  RenderFrameHostImpl* host = frame_host_;
+  return host == current || host == speculative;
 }
 
 #if defined(OS_ANDROID)
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc
index 30b4494..f22d52b 100644
--- a/content/browser/frame_host/frame_tree_node.cc
+++ b/content/browser/frame_host/frame_tree_node.cc
@@ -424,23 +424,16 @@
 bool FrameTreeNode::IsLoading() const {
   RenderFrameHostImpl* current_frame_host =
       render_manager_.current_frame_host();
-  RenderFrameHostImpl* pending_frame_host =
-      render_manager_.pending_frame_host();
 
   DCHECK(current_frame_host);
 
-  if (IsBrowserSideNavigationEnabled()) {
-    if (navigation_request_)
-      return true;
+  if (navigation_request_)
+    return true;
 
-    RenderFrameHostImpl* speculative_frame_host =
-        render_manager_.speculative_frame_host();
-    if (speculative_frame_host && speculative_frame_host->is_loading())
-      return true;
-  } else {
-    if (pending_frame_host && pending_frame_host->is_loading())
-      return true;
-  }
+  RenderFrameHostImpl* speculative_frame_host =
+      render_manager_.speculative_frame_host();
+  if (speculative_frame_host && speculative_frame_host->is_loading())
+    return true;
   return current_frame_host->is_loading();
 }
 
@@ -630,22 +623,15 @@
   DCHECK(current_frame_host);
   current_frame_host->ResetLoadingState();
 
-  if (IsBrowserSideNavigationEnabled()) {
-    RenderFrameHostImpl* speculative_frame_host =
-        render_manager_.speculative_frame_host();
-    if (speculative_frame_host)
-      speculative_frame_host->ResetLoadingState();
-    // Note: there is no need to set an error code on the NavigationHandle here
-    // as it has not been created yet. It is only created when the
-    // BeforeUnloadACK is received.
-    if (navigation_request_)
-      ResetNavigationRequest(false, true);
-  } else {
-    RenderFrameHostImpl* pending_frame_host =
-        render_manager_.pending_frame_host();
-    if (pending_frame_host)
-      pending_frame_host->ResetLoadingState();
-  }
+  RenderFrameHostImpl* speculative_frame_host =
+      render_manager_.speculative_frame_host();
+  if (speculative_frame_host)
+    speculative_frame_host->ResetLoadingState();
+  // Note: there is no need to set an error code on the NavigationHandle here
+  // as it has not been created yet. It is only created when the
+  // BeforeUnloadACK is received.
+  if (navigation_request_)
+    ResetNavigationRequest(false, true);
 }
 
 void FrameTreeNode::OnSetHasReceivedUserGesture() {
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc
index 32b5215e..67f268d 100644
--- a/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -119,7 +119,6 @@
   EXPECT_EQ(NavigationRequest::STARTED, request->state());
   ASSERT_TRUE(GetLoaderForNavigationRequest(request));
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
 
   // Have the current RenderFrameHost commit the navigation.
   scoped_refptr<ResourceResponse> response(new ResourceResponse);
@@ -135,7 +134,6 @@
   EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl),
             main_test_rfh()->GetSiteInstance()->GetSiteURL());
   EXPECT_EQ(kUrl, contents()->GetLastCommittedURL());
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
 
   // The main RenderFrameHost should not have been changed, and the renderer
   // should have been initialized.
@@ -145,9 +143,6 @@
   // After a navigation is finished no speculative RenderFrameHost should
   // exist.
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
-
-  // With PlzNavigate enabled a pending RenderFrameHost should never exist.
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
 }
 
 // PlzNavigate: Test a complete renderer-initiated same-site navigation.
@@ -195,7 +190,6 @@
             main_test_rfh()->GetSiteInstance()->GetSiteURL());
   EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
 }
 
 // PlzNavigate: Test a complete renderer-initiated navigation that should be
@@ -250,7 +244,6 @@
   EXPECT_TRUE(main_test_rfh()->is_active());
   EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
 
   // The SiteInstance did not change unless site-per-process is enabled.
   if (AreAllSitesIsolatedForTesting()) {
@@ -403,7 +396,6 @@
   // was aborted.
   EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
   EXPECT_FALSE(node->navigation_request());
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
 
   // Now, repeat the test with 205 Reset Content.
@@ -429,7 +421,6 @@
   // was aborted.
   EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
   EXPECT_FALSE(node->navigation_request());
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
 }
 
@@ -904,7 +895,6 @@
   EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
   EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl),
             speculative_rfh->GetSiteInstance()->GetSiteURL());
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
   int32_t site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
 
   // Ask Navigator to commit the navigation by simulating a call to
@@ -915,13 +905,11 @@
   EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
   EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
   EXPECT_EQ(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
 
   // Invoke DidCommitProvisionalLoad.
   speculative_rfh->SendNavigate(entry_id, true, kUrl);
   EXPECT_EQ(site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
-  EXPECT_FALSE(node->render_manager()->pending_frame_host());
 }
 
 // PlzNavigate: Confirm that a speculative RenderFrameHost is thrown away when
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index c4aefcbc..31562f3 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1426,11 +1426,7 @@
   // A Javascript navigation interrupted the initial history load.  Check if an
   // initial subframe cross-process navigation needs to be canceled as a result.
   // TODO(creis, clamy): Cancel any cross-process navigation.
-  if (GetParent() && !frame_tree_node_->has_committed_real_load() &&
-      frame_tree_node_->render_manager()->pending_frame_host()) {
-    frame_tree_node_->render_manager()->CancelPendingIfNecessary(
-        frame_tree_node_->render_manager()->pending_frame_host());
-  }
+  NOTIMPLEMENTED();
 }
 
 void RenderFrameHostImpl::OnDocumentOnLoadCompleted(
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index d5b588a..a1673d3 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -45,7 +45,6 @@
 #include "content/public/browser/render_process_host_observer.h"
 #include "content/public/browser/render_widget_host_iterator.h"
 #include "content/public/browser/render_widget_host_view.h"
-#include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/referrer.h"
 #include "content/public/common/url_constants.h"
@@ -67,9 +66,6 @@
 }
 
 RenderFrameHostManager::~RenderFrameHostManager() {
-  if (pending_render_frame_host_)
-    UnsetPendingRenderFrameHost();
-
   if (speculative_render_frame_host_)
     UnsetSpeculativeRenderFrameHost();
 
@@ -115,20 +111,9 @@
   return render_frame_host_->render_view_host();
 }
 
-RenderViewHostImpl* RenderFrameHostManager::pending_render_view_host() const {
-  if (!pending_render_frame_host_)
-    return nullptr;
-  return pending_render_frame_host_->render_view_host();
-}
-
 WebUIImpl* RenderFrameHostManager::GetNavigatingWebUI() const {
-  if (IsBrowserSideNavigationEnabled()) {
-    if (speculative_render_frame_host_)
-      return speculative_render_frame_host_->web_ui();
-  } else {
-    if (pending_render_frame_host_)
-      return pending_render_frame_host_->web_ui();
-  }
+  if (speculative_render_frame_host_)
+    return speculative_render_frame_host_->web_ui();
   return render_frame_host_->pending_web_ui();
 }
 
@@ -199,110 +184,19 @@
       outer_delegate_frame_tree_node);
 }
 
-RenderFrameHostImpl* RenderFrameHostManager::Navigate(
-    const GURL& dest_url,
-    const FrameNavigationEntry& frame_entry,
-    const NavigationEntryImpl& entry,
-    bool is_reload) {
-  TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate",
-               "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
-  // Create a pending RenderFrameHost to use for the navigation.
-  RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate(
-      dest_url, frame_entry.source_site_instance(), frame_entry.site_instance(),
-      entry.GetTransitionType(), entry.restore_type() != RestoreType::NONE,
-      entry.IsViewSourceMode(), entry.transferred_global_request_id(),
-      entry.bindings(), is_reload);
-  if (!dest_render_frame_host)
-    return nullptr;  // We weren't able to create a pending render frame host.
-
-  // If the renderer isn't live, then try to create a new one to satisfy this
-  // navigation request.
-  if (!dest_render_frame_host->IsRenderFrameLive()) {
-    // Instruct the destination render frame host to set up a Mojo connection
-    // with the new render frame if necessary.  Note that this call needs to
-    // occur before initializing the RenderView; the flow of creating the
-    // RenderView can cause browser-side code to execute that expects the this
-    // RFH's service_manager::InterfaceRegistry to be initialized (e.g., if the
-    // site is a
-    // WebUI site that is handled via Mojo, then Mojo WebUI code in //chrome
-    // will add an interface to this RFH's InterfaceRegistry).
-    dest_render_frame_host->SetUpMojoIfNeeded();
-
-    if (!ReinitializeRenderFrame(dest_render_frame_host))
-      return nullptr;
-
-    if (GetNavigatingWebUI()) {
-      // A new RenderFrame was created and there is a navigating WebUI which
-      // never interacted with it. So notify the WebUI using
-      // RenderFrameCreated.
-      GetNavigatingWebUI()->RenderFrameCreated(dest_render_frame_host);
-    }
-
-    // Now that we've created a new renderer, be sure to hide it if it isn't
-    // our primary one.  Otherwise, we might crash if we try to call Show()
-    // on it later.
-    if (dest_render_frame_host != render_frame_host_.get()) {
-      if (dest_render_frame_host->GetView())
-        dest_render_frame_host->GetView()->Hide();
-    } else {
-      EnsureRenderFrameHostVisibilityConsistent();
-      EnsureRenderFrameHostPageFocusConsistent();
-      // TODO(nasko): This is a very ugly hack. The Chrome extensions process
-      // manager still uses NotificationService and expects to see a
-      // RenderViewHost changed notification after WebContents and
-      // RenderFrameHostManager are completely initialized. This should be
-      // removed once the process manager moves away from NotificationService.
-      // See https://crbug.com/462682.
-      delegate_->NotifyMainFrameSwappedFromRenderManager(
-          nullptr, render_frame_host_->render_view_host());
-    }
-  }
-
-  // If entry includes the request ID of a request that is being transferred,
-  // the destination render frame will take ownership, so release ownership of
-  // the transferring NavigationHandle.
-  if (transfer_navigation_handle_.get() &&
-      transfer_navigation_handle_->GetGlobalRequestID() ==
-          entry.transferred_global_request_id()) {
-    // The navigating RenderFrameHost should take ownership of the
-    // NavigationHandle that came from the transferring RenderFrameHost.
-    dest_render_frame_host->SetNavigationHandle(
-        std::move(transfer_navigation_handle_));
-
-    dest_render_frame_host->navigation_handle()->set_render_frame_host(
-        dest_render_frame_host);
-  }
-
-  return dest_render_frame_host;
-}
-
 void RenderFrameHostManager::Stop() {
   render_frame_host_->Stop();
 
-  // If a cross-process navigation is happening, the pending RenderFrameHost
-  // should stop. This will lead to a DidFailProvisionalLoad, which will
-  // properly destroy it.
-  if (pending_render_frame_host_) {
-    pending_render_frame_host_->Send(new FrameMsg_Stop(
-        pending_render_frame_host_->GetRoutingID()));
-  }
-
-  // PlzNavigate: a loading speculative RenderFrameHost should also stop.
-  if (IsBrowserSideNavigationEnabled()) {
-    if (speculative_render_frame_host_ &&
-        speculative_render_frame_host_->is_loading()) {
-      speculative_render_frame_host_->Send(
-          new FrameMsg_Stop(speculative_render_frame_host_->GetRoutingID()));
-    }
+  // A loading speculative RenderFrameHost should also stop.
+  if (speculative_render_frame_host_ &&
+      speculative_render_frame_host_->is_loading()) {
+    speculative_render_frame_host_->Send(
+        new FrameMsg_Stop(speculative_render_frame_host_->GetRoutingID()));
   }
 }
 
 void RenderFrameHostManager::SetIsLoading(bool is_loading) {
   render_frame_host_->render_view_host()->GetWidget()->SetIsLoading(is_loading);
-  if (pending_render_frame_host_) {
-    pending_render_frame_host_->render_view_host()->GetWidget()->SetIsLoading(
-        is_loading);
-  }
 }
 
 void RenderFrameHostManager::OnBeforeUnloadACK(
@@ -313,14 +207,9 @@
                                                 &proceed_to_fire_unload);
 
   if (proceed_to_fire_unload) {
-    // If we're about to close the tab and there's a pending RFH, cancel it.
-    // Otherwise, if the navigation in the pending RFH completes before the
+    // If we're about to close the tab and there's a speculative RFH, cancel it.
+    // Otherwise, if the navigation in the speculative RFH completes before the
     // close in the current RFH, we'll lose the tab close.
-    if (pending_render_frame_host_) {
-      CancelPending();
-    }
-
-    // Clean up the speculative RenderFrameHost if there is one.
     if (speculative_render_frame_host_)
       CleanUpNavigation();
 
@@ -341,9 +230,9 @@
 void RenderFrameHostManager::CommitPendingIfNecessary(
     RenderFrameHostImpl* render_frame_host,
     bool was_caused_by_user_gesture) {
-  if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
-    // There's no pending/speculative RenderFrameHost so it must be that the
-    // current renderer process completed a navigation.
+  if (!speculative_render_frame_host_) {
+    // There's no speculative RenderFrameHost so it must be that the current
+    // renderer process completed a navigation.
 
     // We should only hear this from our current renderer.
     DCHECK_EQ(render_frame_host_.get(), render_frame_host);
@@ -357,15 +246,13 @@
     return;
   }
 
-  if (render_frame_host == pending_render_frame_host_.get() ||
-      render_frame_host == speculative_render_frame_host_.get()) {
+  if (render_frame_host == speculative_render_frame_host_.get()) {
     // A cross-process navigation completed, so show the new renderer. If a
     // same-process navigation is also ongoing, it will be canceled when the
-    // pending/speculative RenderFrameHost replaces the current one in the
-    // commit call below.
+    // speculative RenderFrameHost replaces the current one in the commit call
+    // below.
     CommitPending();
-    if (IsBrowserSideNavigationEnabled())
-      frame_tree_node_->ResetNavigationRequest(false, true);
+    frame_tree_node_->ResetNavigationRequest(false, true);
   } else if (render_frame_host == render_frame_host_.get()) {
     // A same-process navigation committed while a simultaneous cross-process
     // navigation is still ongoing.
@@ -374,17 +261,13 @@
     if (render_frame_host_->pending_web_ui())
       CommitPendingWebUI();
 
-    // A navigation in the original page has taken place.  Cancel the pending
+    // A navigation in the original page has taken place. Cancel the speculative
     // one. Only do it for user gesture originated navigations to prevent page
     // doing any shenanigans to prevent user from navigating.  See
     // https://code.google.com/p/chromium/issues/detail?id=75195
     if (was_caused_by_user_gesture) {
-      if (IsBrowserSideNavigationEnabled()) {
-        frame_tree_node_->ResetNavigationRequest(false, true);
-        CleanUpNavigation();
-      } else {
-        CancelPending();
-      }
+      frame_tree_node_->ResetNavigationRequest(false, true);
+      CleanUpNavigation();
     }
   } else {
     // No one else should be sending us DidNavigate in this state.
@@ -419,14 +302,8 @@
   if (render_frame_host_->GetSiteInstance() != source_site_instance)
     render_frame_host_->UpdateOpener();
 
-  // Notify the pending and speculative RenderFrameHosts as well.  This is
-  // necessary in case a process swap has started while the message was in
-  // flight.
-  if (pending_render_frame_host_ &&
-      pending_render_frame_host_->GetSiteInstance() != source_site_instance) {
-    pending_render_frame_host_->UpdateOpener();
-  }
-
+  // Notify the speculative RenderFrameHosts as well.  This is necessary in case
+  // a process swap has started while the message was in flight.
   if (speculative_render_frame_host_ &&
       speculative_render_frame_host_->GetSiteInstance() !=
           source_site_instance) {
@@ -581,17 +458,12 @@
 
 void RenderFrameHostManager::ClearWebUIInstances() {
   current_frame_host()->ClearAllWebUI();
-  if (pending_render_frame_host_)
-    pending_render_frame_host_->ClearAllWebUI();
-  // PlzNavigate
   if (speculative_render_frame_host_)
     speculative_render_frame_host_->ClearAllWebUI();
 }
 
-// PlzNavigate
 void RenderFrameHostManager::DidCreateNavigationRequest(
     NavigationRequest* request) {
-  CHECK(IsBrowserSideNavigationEnabled());
   RenderFrameHostImpl* dest_rfh = GetFrameHostForNavigation(*request);
   DCHECK(dest_rfh);
   request->set_associated_site_instance_type(
@@ -600,10 +472,8 @@
           : NavigationRequest::AssociatedSiteInstanceType::SPECULATIVE);
 }
 
-// PlzNavigate
 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
     const NavigationRequest& request) {
-  CHECK(IsBrowserSideNavigationEnabled());
   DCHECK(!request.common_params().url.SchemeIs(url::kJavaScriptScheme))
       << "Don't call this method for JavaScript URLs as those create a "
          "temporary  NavigationRequest and we don't want to reset an ongoing "
@@ -759,9 +629,7 @@
   return navigation_rfh;
 }
 
-// PlzNavigate
 void RenderFrameHostManager::CleanUpNavigation() {
-  CHECK(IsBrowserSideNavigationEnabled());
   if (speculative_render_frame_host_) {
     // If the speculative RenderFrameHost is trying to commit a navigation,
     // inform the NavigationController that the load of the corresponding
@@ -778,10 +646,8 @@
   }
 }
 
-// PlzNavigate
 std::unique_ptr<RenderFrameHostImpl>
 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() {
-  CHECK(IsBrowserSideNavigationEnabled());
   speculative_render_frame_host_->GetProcess()->RemovePendingView();
   return std::move(speculative_render_frame_host_);
 }
@@ -903,9 +769,7 @@
 
 void RenderFrameHostManager::CancelPendingIfNecessary(
     RenderFrameHostImpl* render_frame_host) {
-  if (render_frame_host == pending_render_frame_host_.get())
-    CancelPending();
-  else if (render_frame_host == speculative_render_frame_host_.get()) {
+  if (render_frame_host == speculative_render_frame_host_.get()) {
     // TODO(nasko, clamy): This should just clean up the speculative RFH
     // without canceling the request.  See https://crbug.com/636119.
     if (frame_tree_node_->navigation_request() &&
@@ -1596,32 +1460,6 @@
   return false;
 }
 
-void RenderFrameHostManager::CreatePendingRenderFrameHost(
-    SiteInstance* old_instance,
-    SiteInstance* new_instance) {
-  if (pending_render_frame_host_)
-    CancelPending();
-
-  // The process for the new SiteInstance may (if we're sharing a process with
-  // another host that already initialized it) or may not (we have our own
-  // process or the existing process crashed) have been initialized. Calling
-  // Init multiple times will be ignored, so this is safe.
-  if (!new_instance->GetProcess()->Init())
-    return;
-
-  CreateProxiesForNewRenderFrameHost(old_instance, new_instance);
-
-  pending_render_frame_host_ =
-      CreateRenderFrame(new_instance, delegate_->IsHidden(), nullptr);
-
-  // If RenderViewHost was created along with the pending RenderFrameHost,
-  // ensure that RenderViewCreated is fired for it.  It is important to do this
-  // after pending_render_frame_host_ is assigned, so that observers processing
-  // RenderViewCreated can find it via RenderViewHostImpl::GetMainFrame().
-  if (pending_render_frame_host_)
-    pending_render_frame_host_->render_view_host()->DispatchRenderViewCreated();
-}
-
 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
     SiteInstance* old_instance,
     SiteInstance* new_instance) {
@@ -1708,7 +1546,6 @@
       widget_routing_id, hidden, renderer_initiated_creation);
 }
 
-// PlzNavigate
 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
     SiteInstance* old_instance,
     SiteInstance* new_instance) {
@@ -2115,7 +1952,7 @@
 void RenderFrameHostManager::CommitPending() {
   TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
                "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
-  DCHECK(pending_render_frame_host_ || speculative_render_frame_host_);
+  DCHECK(speculative_render_frame_host_);
 
   bool is_main_frame = frame_tree_node_->IsMainFrame();
 
@@ -2140,16 +1977,9 @@
   // Swap in the pending or speculative frame and make it active. Also ensure
   // the FrameTree stays in sync.
   std::unique_ptr<RenderFrameHostImpl> old_render_frame_host;
-  if (!IsBrowserSideNavigationEnabled()) {
-    DCHECK(!speculative_render_frame_host_);
-    old_render_frame_host =
-        SetRenderFrameHost(std::move(pending_render_frame_host_));
-  } else {
-    // PlzNavigate
-    DCHECK(speculative_render_frame_host_);
-    old_render_frame_host =
-        SetRenderFrameHost(std::move(speculative_render_frame_host_));
-  }
+  DCHECK(speculative_render_frame_host_);
+  old_render_frame_host =
+      SetRenderFrameHost(std::move(speculative_render_frame_host_));
 
   // Save off the old background color before possibly deleting the
   // old RenderWidgetHostView.
@@ -2261,131 +2091,6 @@
   CHECK(!GetRenderFrameProxyHost(render_frame_host_->GetSiteInstance()));
 }
 
-// TODO(clamy): Remove this function.
-RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
-    const GURL& dest_url,
-    SiteInstance* source_instance,
-    SiteInstance* dest_instance,
-    ui::PageTransition transition,
-    bool dest_is_restore,
-    bool dest_is_view_source_mode,
-    const GlobalRequestID& transferred_request_id,
-    int bindings,
-    bool is_reload) {
-  SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
-  bool was_server_redirect = transfer_navigation_handle_ &&
-                             transfer_navigation_handle_->WasServerRedirect();
-  scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
-      dest_url, source_instance, dest_instance, nullptr, transition,
-      dest_is_restore, dest_is_view_source_mode, was_server_redirect);
-
-  // Note: Do not add code here to determine whether the subframe should swap
-  // or not. Add it to CanSubframeSwapProcess instead.
-  bool allowed_to_swap_process =
-      frame_tree_node_->IsMainFrame() ||
-      CanSubframeSwapProcess(dest_url, source_instance, dest_instance,
-                             was_server_redirect);
-
-  // If we are currently navigating cross-process to a pending RFH for a
-  // different SiteInstance, we want to get back to normal and then navigate as
-  // usual.  We will reuse the pending RFH below if it matches the destination
-  // SiteInstance.
-  if (pending_render_frame_host_) {
-    if (pending_render_frame_host_->GetSiteInstance() != new_instance) {
-      CancelPending();
-    } else {
-      // When a pending RFH is reused, it should always be live, since it is
-      // cleared whenever a process dies.
-      CHECK(pending_render_frame_host_->IsRenderFrameLive());
-    }
-  }
-
-  if (new_instance.get() != current_instance && allowed_to_swap_process) {
-    TRACE_EVENT_INSTANT2(
-        "navigation",
-        "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
-        TRACE_EVENT_SCOPE_THREAD,
-        "current_instance id", current_instance->GetId(),
-        "new_instance id", new_instance->GetId());
-
-    // New SiteInstance: create a pending RFH to navigate.
-
-    if (!pending_render_frame_host_)
-      CreatePendingRenderFrameHost(current_instance, new_instance.get());
-    DCHECK(pending_render_frame_host_);
-    if (!pending_render_frame_host_)
-      return nullptr;
-    DCHECK_EQ(new_instance, pending_render_frame_host_->GetSiteInstance());
-
-    pending_render_frame_host_->UpdatePendingWebUI(dest_url, bindings);
-    pending_render_frame_host_->CommitPendingWebUI();
-    DCHECK_EQ(GetNavigatingWebUI(), pending_render_frame_host_->web_ui());
-
-    // If a WebUI exists in the pending RenderFrameHost it was just created, as
-    // well as the RenderFrame, and they never interacted. So notify the WebUI
-    // using RenderFrameCreated.
-    if (pending_render_frame_host_->web_ui()) {
-      pending_render_frame_host_->web_ui()->RenderFrameCreated(
-          pending_render_frame_host_.get());
-    }
-
-    // Check if our current RFH is live before we set up a transition.
-    if (!render_frame_host_->IsRenderFrameLive()) {
-      // The current RFH is not live.  There's no reason to sit around with a
-      // sad tab or a newly created RFH while we wait for the pending RFH to
-      // navigate.  Just switch to the pending RFH now and go back to normal.
-      // (Note that we don't care about on{before}unload handlers if the current
-      // RFH isn't live.)
-      //
-      // If the corresponding RenderFrame is currently associated with a proxy,
-      // send a SwapIn message to ensure that the RenderFrame swaps into the
-      // frame tree and replaces that proxy on the renderer side.  Normally
-      // this happens at navigation commit time, but in this case this must be
-      // done earlier to keep browser and renderer state in sync.  This is
-      // important to do before CommitPending(), which destroys the
-      // corresponding proxy. See https://crbug.com/487872.
-      if (GetRenderFrameProxyHost(new_instance.get())) {
-        pending_render_frame_host_->Send(
-            new FrameMsg_SwapIn(pending_render_frame_host_->GetRoutingID()));
-      }
-      CommitPending();
-      return render_frame_host_.get();
-    }
-    // Otherwise, it's safe to treat this as a pending cross-process transition.
-
-    bool is_transfer = transferred_request_id != GlobalRequestID();
-    if (is_transfer) {
-      // We don't need to stop the old renderer or run beforeunload/unload
-      // handlers, because those have already been done.
-      DCHECK(transfer_navigation_handle_ &&
-             transfer_navigation_handle_->GetGlobalRequestID() ==
-                 transferred_request_id);
-    }
-    return pending_render_frame_host_.get();
-  }
-
-  // Otherwise the same SiteInstance can be used.  Navigate render_frame_host_.
-
-  // It's possible to swap out the current RFH and then decide to navigate in it
-  // anyway (e.g., a cross-process navigation that redirects back to the
-  // original site).  In that case, we have a proxy for the current RFH but
-  // haven't deleted it yet.  The new navigation will swap it back in, so we can
-  // delete the proxy.
-  DeleteRenderFrameProxyHost(new_instance.get());
-
-  UpdatePendingWebUIOnCurrentFrameHost(dest_url, bindings);
-
-  // The renderer can exit view source mode when any error or cancellation
-  // happen. We must overwrite to recover the mode.
-  if (dest_is_view_source_mode) {
-    DCHECK(!render_frame_host_->GetParent());
-    render_frame_host_->Send(
-        new FrameMsg_EnableViewSourceMode(render_frame_host_->GetRoutingID()));
-  }
-
-  return render_frame_host_.get();
-}
-
 void RenderFrameHostManager::UpdatePendingWebUIOnCurrentFrameHost(
     const GURL& dest_url,
     int entry_bindings) {
@@ -2415,33 +2120,6 @@
   }
 }
 
-void RenderFrameHostManager::CancelPending() {
-  CHECK(pending_render_frame_host_);
-  TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending",
-               "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
-  render_frame_host_->ClearPendingWebUI();
-
-  bool pending_was_loading = pending_render_frame_host_->is_loading();
-  DiscardUnusedFrame(UnsetPendingRenderFrameHost());
-  if (pending_was_loading)
-    frame_tree_node_->DidStopLoading();
-}
-
-std::unique_ptr<RenderFrameHostImpl>
-RenderFrameHostManager::UnsetPendingRenderFrameHost() {
-  std::unique_ptr<RenderFrameHostImpl> pending_render_frame_host =
-      std::move(pending_render_frame_host_);
-
-  RenderFrameDevToolsAgentHost::OnCancelPendingNavigation(
-      pending_render_frame_host.get(),
-      render_frame_host_.get());
-
-  // We no longer need to prevent the process from exiting.
-  pending_render_frame_host->GetProcess()->RemovePendingView();
-
-  return pending_render_frame_host;
-}
-
 std::unique_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
     std::unique_ptr<RenderFrameHostImpl> render_frame_host) {
   // Swap the two.
@@ -2637,10 +2315,6 @@
     send_msg(speculative_render_frame_host_.get(),
              speculative_render_frame_host_->GetRoutingID(), msg,
              speculative_render_frame_host_->GetSiteInstance());
-  } else if (pending_render_frame_host_) {
-    send_msg(pending_render_frame_host_.get(),
-             pending_render_frame_host_->GetRoutingID(), msg,
-             pending_render_frame_host_->GetSiteInstance());
   }
 
   if (render_frame_host_->GetSiteInstance() != instance_to_skip) {
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h
index 628c24c3..24af2ffb 100644
--- a/content/browser/frame_host/render_frame_host_manager.h
+++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -27,13 +27,10 @@
 
 namespace content {
 class BrowserContext;
-class FrameNavigationEntry;
 class FrameTreeNode;
 class InterstitialPageImpl;
 class NavigationControllerImpl;
 class NavigationEntry;
-class NavigationEntryImpl;
-class NavigationHandleImpl;
 class NavigationRequest;
 class NavigatorTestWithBrowserSideNavigation;
 class RenderFrameHostDelegate;
@@ -108,11 +105,6 @@
   // There is additional complexity that some of the functions we need in
   // WebContentsImpl are inherited and non-virtual. These are named with
   // "RenderManager" so that the duplicate implementation of them will be clear.
-  //
-  // Functions and parameters whose description are prefixed by PlzNavigate are
-  // part of a navigation refactoring project, currently behind the
-  // enable-browser-side-navigation flag. The idea is to move the logic behind
-  // driving navigations from the renderer to the browser.
   class CONTENT_EXPORT Delegate {
    public:
     // Initializes the given renderer if necessary and creates the view ID
@@ -246,36 +238,17 @@
   // somehwere else.
   void RemoveOuterDelegateFrame();
 
-  // Returns the pending RenderFrameHost, or null if there is no pending one.
-  RenderFrameHostImpl* pending_frame_host() const {
-    return pending_render_frame_host_.get();
-  }
-
   // Returns the speculative RenderFrameHost, or null if there is no speculative
   // one.
   RenderFrameHostImpl* speculative_frame_host() const {
     return speculative_render_frame_host_.get();
   }
 
-  // TODO(creis): Remove this when we no longer use RVH for navigation.
-  RenderViewHostImpl* pending_render_view_host() const;
-
   // Returns the WebUI associated with the ongoing navigation, it being either
   // the active or the pending one from the navigating RenderFrameHost. Returns
   // null if there's no ongoing navigation or if no WebUI applies.
   WebUIImpl* GetNavigatingWebUI() const;
 
-  // Called when we want to instruct the renderer to navigate to the given
-  // navigation entry. It may create a new RenderFrameHost or re-use an existing
-  // one. The RenderFrameHost to navigate will be returned. Returns NULL if one
-  // could not be created. |dest_url| takes precedence over the |frame_entry|'s
-  // url (this is necessary because ReloadOriginalRequest navigates to a
-  // different URL than the last committed entry, without modifying it).
-  RenderFrameHostImpl* Navigate(const GURL& dest_url,
-                                const FrameNavigationEntry& frame_entry,
-                                const NavigationEntryImpl& entry,
-                                bool is_reload);
-
   // Instructs the various live views to stop. Called when the user directed the
   // page to stop loading.
   void Stop();
@@ -360,13 +333,11 @@
   // RenderFrameHostManager. Returns MSG_ROUTING_NONE if none is found.
   int GetRoutingIdForSiteInstance(SiteInstance* site_instance);
 
-  // PlzNavigate
   // Notifies the RenderFrameHostManager that a new NavigationRequest has been
   // created and set in the FrameTreeNode so that it can speculatively create a
   // new RenderFrameHost (and potentially a new process) if needed.
   void DidCreateNavigationRequest(NavigationRequest* request);
 
-  // PlzNavigate
   // Called (possibly several times) during a navigation to select or create an
   // appropriate RenderFrameHost for the provided URL. The returned pointer will
   // be for the current or the speculative RenderFrameHost and the instance is
@@ -374,11 +345,9 @@
   RenderFrameHostImpl* GetFrameHostForNavigation(
       const NavigationRequest& request);
 
-  // PlzNavigate
   // Clean up any state for any ongoing navigation.
   void CleanUpNavigation();
 
-  // PlzNavigate
   // Clears the speculative members, returning the RenderFrameHost to the caller
   // for disposal.
   std::unique_ptr<RenderFrameHostImpl> UnsetSpeculativeRenderFrameHost();
@@ -632,12 +601,6 @@
   bool IsCurrentlySameSite(RenderFrameHostImpl* candidate,
                            const GURL& dest_url);
 
-  // Creates a new RenderFrameHostImpl for the |new_instance| and assign it to
-  // |pending_render_frame_host_| while respecting the opener route if needed
-  // and stores it in pending_render_frame_host_.
-  void CreatePendingRenderFrameHost(SiteInstance* old_instance,
-                                    SiteInstance* new_instance);
-
   // Ensure that we have created all needed proxies for a new RFH with
   // SiteInstance |new_instance|: (1) create swapped-out RVHs and proxies for
   // the new RFH's opener chain if we are staying in the same BrowsingInstance;
@@ -674,7 +637,6 @@
       bool hidden,
       bool renderer_initiated_creation);
 
-  // PlzNavigate
   // Create and initialize a speculative RenderFrameHost for an ongoing
   // navigation. It might be destroyed and re-created later if the navigation
   // is redirected to a different SiteInstance.
@@ -694,10 +656,8 @@
   // when the current RenderFrameHost commits and it has a pending WebUI.
   void CommitPendingWebUI();
 
-  // Sets the pending RenderFrameHost to be the active one. Call when the
+  // Sets the speculative RenderFrameHost to be the active one. Called when the
   // pending RenderFrameHost commits.
-  // If PlzNavigate is enabled the method will set the speculative (not pending)
-  // RenderFrameHost to be the active one.
   void CommitPending();
 
   // Helper to call CommitPending() in all necessary cases.
@@ -718,28 +678,11 @@
   void DiscardUnusedFrame(
       std::unique_ptr<RenderFrameHostImpl> render_frame_host);
 
-  // Terminates and deletes the pending RenderFrameHost.
-  void CancelPending();
-
-  // Clears pending_render_frame_host_, returning it to the caller for disposal.
-  std::unique_ptr<RenderFrameHostImpl> UnsetPendingRenderFrameHost();
-
   // Helper method to set the active RenderFrameHost. Returns the old
   // RenderFrameHost and updates counts.
   std::unique_ptr<RenderFrameHostImpl> SetRenderFrameHost(
       std::unique_ptr<RenderFrameHostImpl> render_frame_host);
 
-  RenderFrameHostImpl* UpdateStateForNavigate(
-      const GURL& dest_url,
-      SiteInstance* source_instance,
-      SiteInstance* dest_instance,
-      ui::PageTransition transition,
-      bool dest_is_restore,
-      bool dest_is_view_source_mode,
-      const GlobalRequestID& transferred_request_id,
-      int bindings,
-      bool is_reload);
-
   // Updates the pending WebUI of the current RenderFrameHost for a same-site
   // navigation.
   void UpdatePendingWebUIOnCurrentFrameHost(const GURL& dest_url,
@@ -777,19 +720,6 @@
   // Eventually, RenderViewHost will be replaced with a page context.
   std::unique_ptr<RenderFrameHostImpl> render_frame_host_;
 
-  // A RenderFrameHost used to load a cross-site page. This remains hidden
-  // while a cross-site request is pending until it calls DidNavigate.
-  // Note: This member is not used in PlzNavigate.
-  std::unique_ptr<RenderFrameHostImpl> pending_render_frame_host_;
-
-  // This is used to temporarily store the NavigationHandle during
-  // transferring navigations. The handle needs to be stored because the old
-  // RenderFrameHost may be discarded before a new RenderFrameHost is created
-  // for the navigation.
-  // PlzNavigate: this will never be set since there are no transferring
-  // navigations in PlzNavigate.
-  std::unique_ptr<NavigationHandleImpl> transfer_navigation_handle_;
-
   // Proxy hosts, indexed by site instance ID.
   std::unordered_map<int32_t, std::unique_ptr<RenderFrameProxyHost>>
       proxy_hosts_;
@@ -798,15 +728,12 @@
   using RFHPendingDeleteList = std::list<std::unique_ptr<RenderFrameHostImpl>>;
   RFHPendingDeleteList pending_delete_hosts_;
 
-  // PlzNavigate
   // Stores a speculative RenderFrameHost which is created early in a navigation
   // so a renderer process can be started in parallel, if needed.
   // This is purely a performance optimization and is not required for correct
   // behavior. The speculative RenderFrameHost might be discarded later on if
   // the final URL's SiteInstance isn't compatible with the one used to create
   // it.
-  // Note: PlzNavigate only uses the speculative RenderFrameHost, not the
-  // pending one.
   std::unique_ptr<RenderFrameHostImpl> speculative_render_frame_host_;
 
   base::WeakPtrFactory<RenderFrameHostManager> weak_factory_;
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
index bc9d0c4..bbbb46bf 100644
--- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -303,10 +303,6 @@
 
   // Wait for the cross-site transition in the new tab to finish.
   WaitForLoadStop(new_shell->web_contents());
-  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
-      new_shell->web_contents());
-  EXPECT_FALSE(web_contents->GetRenderManagerForTesting()->
-      pending_render_view_host());
 
   // Should have a new SiteInstance.
   scoped_refptr<SiteInstance> noref_blank_site_instance(
@@ -349,10 +345,6 @@
 
   // Wait for the cross-site transition in the new tab to finish.
   WaitForLoadStop(new_shell->web_contents());
-  WebContentsImpl* web_contents =
-      static_cast<WebContentsImpl*>(new_shell->web_contents());
-  EXPECT_FALSE(
-      web_contents->GetRenderManagerForTesting()->pending_render_view_host());
 
   // Check that the referrer is set correctly.
   std::string expected_referrer =
@@ -399,10 +391,6 @@
 
   // Wait for the cross-site transition in the new tab to finish.
   WaitForLoadStop(new_shell->web_contents());
-  WebContentsImpl* web_contents =
-      static_cast<WebContentsImpl*>(new_shell->web_contents());
-  EXPECT_FALSE(
-      web_contents->GetRenderManagerForTesting()->pending_render_view_host());
 
   EXPECT_EQ("/title2.html",
             new_shell->web_contents()->GetLastCommittedURL().path());
@@ -469,10 +457,6 @@
 
   // Wait for the cross-site transition in the new tab to finish.
   WaitForLoadStop(new_shell->web_contents());
-  WebContentsImpl* web_contents =
-      static_cast<WebContentsImpl*>(new_shell->web_contents());
-  EXPECT_FALSE(
-      web_contents->GetRenderManagerForTesting()->pending_render_view_host());
 
   // Should have a new SiteInstance (in a new BrowsingInstance).
   scoped_refptr<SiteInstance> noref_blank_site_instance(
@@ -518,10 +502,6 @@
 
   // Wait for the cross-site transition in the new tab to finish.
   WaitForLoadStop(new_shell->web_contents());
-  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
-      new_shell->web_contents());
-  EXPECT_FALSE(web_contents->GetRenderManagerForTesting()->
-      pending_render_view_host());
 
   // Should have a new SiteInstance (in a new BrowsingInstance).
   scoped_refptr<SiteInstance> noref_blank_site_instance(
@@ -2931,33 +2911,21 @@
   WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
       shell()->web_contents());
   RenderFrameHostImpl* next_rfh =
-      IsBrowserSideNavigationEnabled()
-          ? web_contents->GetRenderManagerForTesting()->speculative_frame_host()
-          : web_contents->GetRenderManagerForTesting()->pending_frame_host();
+      web_contents->GetRenderManagerForTesting()->speculative_frame_host();
   ASSERT_TRUE(next_rfh);
 
   // Navigate to the same new site and verify that we commit in the same RFH.
   GURL cross_site_url2(embedded_test_server()->GetURL("b.com", "/title2.html"));
   TestNavigationObserver navigation_observer(web_contents, 1);
   shell()->LoadURL(cross_site_url2);
-  if (IsBrowserSideNavigationEnabled()) {
-    EXPECT_EQ(
-        next_rfh,
-        web_contents->GetRenderManagerForTesting()->speculative_frame_host());
-  } else {
-    EXPECT_EQ(next_rfh,
-              web_contents->GetRenderManagerForTesting()->pending_frame_host());
-  }
+  EXPECT_EQ(
+      next_rfh,
+      web_contents->GetRenderManagerForTesting()->speculative_frame_host());
   navigation_observer.Wait();
   EXPECT_EQ(cross_site_url2, web_contents->GetLastCommittedURL());
   EXPECT_EQ(next_rfh, web_contents->GetMainFrame());
-  if (IsBrowserSideNavigationEnabled()) {
-    EXPECT_FALSE(
-        web_contents->GetRenderManagerForTesting()->speculative_frame_host());
-  } else {
-    EXPECT_FALSE(
-        web_contents->GetRenderManagerForTesting()->pending_frame_host());
-  }
+  EXPECT_FALSE(
+      web_contents->GetRenderManagerForTesting()->speculative_frame_host());
 
   ResourceDispatcherHost::Get()->SetDelegate(nullptr);
 }
@@ -3251,13 +3219,10 @@
   RenderFrameDeletedObserver deleted_observer(rfh_a);
   shell()->LoadURL(url_b);
 
-  // The pending RFH shouln't have a last committed origin (the default value
-  // is a unique origin). The current RFH shouldn't change its last committed
-  // origin before commit.
-  RenderFrameHostImpl* rfh_b =
-      IsBrowserSideNavigationEnabled()
-          ? root->render_manager()->speculative_frame_host()
-          : root->render_manager()->pending_frame_host();
+  // The speculative RFH shouln't have a last committed origin (the default
+  // value is a unique origin). The current RFH shouldn't change its last
+  // committed origin before commit.
+  RenderFrameHostImpl* rfh_b = root->render_manager()->speculative_frame_host();
   EXPECT_EQ("null", rfh_b->GetLastCommittedOrigin().Serialize());
   EXPECT_EQ(url::Origin::Create(url_a), rfh_a->GetLastCommittedOrigin());
 
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 7e52bb8..6886275 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -436,52 +436,43 @@
 
   // Returns the RenderFrameHost that should be used in the navigation to
   // |entry|.
-  RenderFrameHostImpl* NavigateToEntry(
-      RenderFrameHostManager* manager,
-      const NavigationEntryImpl& entry) {
+  RenderFrameHostImpl* NavigateToEntry(RenderFrameHostManager* manager,
+                                       const NavigationEntryImpl& entry) {
     // Tests currently only navigate using main frame FrameNavigationEntries.
     FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
-    if (IsBrowserSideNavigationEnabled()) {
-      NavigationControllerImpl* controller =
-          static_cast<NavigationControllerImpl*>(manager->current_frame_host()
-                                                     ->frame_tree_node()
-                                                     ->navigator()
-                                                     ->GetController());
-      FrameMsg_Navigate_Type::Value navigate_type =
-          entry.restore_type() == RestoreType::NONE
-              ? FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT
-              : FrameMsg_Navigate_Type::RESTORE;
-      std::unique_ptr<NavigationRequest> navigation_request =
-          NavigationRequest::CreateBrowserInitiated(
-              manager->frame_tree_node_, frame_entry->url(),
-              frame_entry->referrer(), *frame_entry, entry, navigate_type,
-              PREVIEWS_UNSPECIFIED, false, false, nullptr,
-              base::TimeTicks::Now(), controller);
+    NavigationControllerImpl* controller =
+        static_cast<NavigationControllerImpl*>(manager->current_frame_host()
+                                                   ->frame_tree_node()
+                                                   ->navigator()
+                                                   ->GetController());
+    FrameMsg_Navigate_Type::Value navigate_type =
+        entry.restore_type() == RestoreType::NONE
+            ? FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT
+            : FrameMsg_Navigate_Type::RESTORE;
+    std::unique_ptr<NavigationRequest> navigation_request =
+        NavigationRequest::CreateBrowserInitiated(
+            manager->frame_tree_node_, frame_entry->url(),
+            frame_entry->referrer(), *frame_entry, entry, navigate_type,
+            PREVIEWS_UNSPECIFIED, false, false, nullptr, base::TimeTicks::Now(),
+            controller);
 
-      // Simulates request creation that triggers the 1st internal call to
-      // GetFrameHostForNavigation.
-      manager->DidCreateNavigationRequest(navigation_request.get());
+    // Simulates request creation that triggers the 1st internal call to
+    // GetFrameHostForNavigation.
+    manager->DidCreateNavigationRequest(navigation_request.get());
 
-      // And also simulates the 2nd and final call to GetFrameHostForNavigation
-      // that determines the final frame that will commit the navigation.
-      TestRenderFrameHost* frame_host = static_cast<TestRenderFrameHost*>(
-          manager->GetFrameHostForNavigation(*navigation_request));
-      CHECK(frame_host);
-      frame_host->set_pending_commit(true);
-      return frame_host;
-    }
-
-    return manager->Navigate(frame_entry->url(), *frame_entry, entry, false);
+    // And also simulates the 2nd and final call to GetFrameHostForNavigation
+    // that determines the final frame that will commit the navigation.
+    TestRenderFrameHost* frame_host = static_cast<TestRenderFrameHost*>(
+        manager->GetFrameHostForNavigation(*navigation_request));
+    CHECK(frame_host);
+    frame_host->set_pending_commit(true);
+    return frame_host;
   }
 
-  // Returns the pending RenderFrameHost.
-  // PlzNavigate: returns the speculative RenderFrameHost.
+  // Returns the speculative RenderFrameHost.
   RenderFrameHostImpl* GetPendingFrameHost(
       RenderFrameHostManager* manager) {
-    if (IsBrowserSideNavigationEnabled())
-      return manager->speculative_render_frame_host_.get();
-
-    return manager->pending_frame_host();
+    return manager->speculative_render_frame_host_.get();
   }
 
   // Exposes RenderFrameHostManager::CollectOpenerFrameTrees for testing.
@@ -913,7 +904,6 @@
   EXPECT_EQ(web_contents.get(), rvh->GetDelegate());
   EXPECT_EQ(web_contents.get(), rfh->delegate());
   EXPECT_TRUE(manager->GetRenderWidgetHostView());
-  EXPECT_FALSE(manager->pending_render_view_host());
 }
 
 // Tests the Navigate function. We navigate three sites consecutively and check
@@ -1155,105 +1145,6 @@
   EXPECT_FALSE(main_test_rfh()->web_ui());
 }
 
-// Tests that we don't end up in an inconsistent state if a page does a back and
-// then reload. http://crbug.com/51680
-// Also tests that only user-gesture navigations can interrupt cross-process
-// navigations. http://crbug.com/75195
-TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) {
-  if (IsBrowserSideNavigationEnabled()) {
-    // PlzNavigate uses a significantly different logic for renderer initiated
-    // navigations and navigation cancellation. Adapting this test would make it
-    // full of special cases and almost unreadable.
-    // There are tests that exercise these concerns for PlzNavigate, all from
-    // NavigatorTestWithBrowserSideNavigation:
-    // - BrowserInitiatedNavigationCancel
-    // - RendererUserInitiatedNavigationCancel
-    // - RendererNonUserInitiatedNavigationDoesntCancelRendererUserInitiated
-    // - RendererNonUserInitiatedNavigationDoesntCancelBrowserInitiated
-    // - RendererNonUserInitiatedNavigationCancelSimilarNavigation
-    SUCCEED() << "Test is not applicable with browser side navigation enabled";
-    return;
-  }
-  const GURL kUrl1("http://www.google.com/");
-  const GURL kUrl2("http://www.evil-site.com/");
-
-  // Navigate to a safe site, then an evil site.
-  // This will switch RenderFrameHosts.  We cannot assert that the first and
-  // second RFHs are different, though, because the first one may be promptly
-  // deleted.
-  contents()->NavigateAndCommit(kUrl1);
-  contents()->NavigateAndCommit(kUrl2);
-  TestRenderFrameHost* evil_rfh = contents()->GetMainFrame();
-
-  // Now let's simulate the evil page calling history.back().
-  contents()->OnGoToEntryAtOffset(evil_rfh->GetRenderViewHost(), -1);
-  contents()->GetMainFrame()->PrepareForCommit();
-  // We should have a new pending RFH.
-  // Note that in this case, the navigation has not committed, so evil_rfh will
-  // not be deleted yet.
-  EXPECT_NE(evil_rfh, contents()->GetPendingMainFrame());
-  EXPECT_NE(evil_rfh->GetRenderViewHost(),
-            contents()->GetPendingMainFrame()->GetRenderViewHost());
-
-  // Before that RFH has committed, the evil page reloads itself.
-  FrameHostMsg_DidCommitProvisionalLoad_Params params;
-  params.nav_entry_id = 0;
-  params.did_create_new_entry = false;
-  params.url = kUrl2;
-  params.transition = ui::PAGE_TRANSITION_CLIENT_REDIRECT;
-  params.should_update_history = false;
-  params.gesture = NavigationGestureAuto;
-  params.was_within_same_document = false;
-  params.method = "GET";
-  params.page_state = PageState::CreateFromURL(kUrl2);
-
-  evil_rfh->SimulateNavigationStart(kUrl2);
-  evil_rfh->SendNavigateWithParams(&params);
-  evil_rfh->SimulateNavigationStop();
-
-  // That should NOT have cancelled the pending RFH, because the reload did
-  // not have a user gesture. Thus, the pending back navigation will still
-  // eventually commit.
-  EXPECT_TRUE(
-      contents()->GetRenderManagerForTesting()->pending_render_view_host() !=
-      nullptr);
-  EXPECT_TRUE(contents()->GetRenderManagerForTesting()->pending_frame_host() !=
-              nullptr);
-  EXPECT_EQ(evil_rfh,
-            contents()->GetRenderManagerForTesting()->current_frame_host());
-  EXPECT_EQ(evil_rfh->GetRenderViewHost(),
-            contents()->GetRenderManagerForTesting()->current_host());
-
-  // Also we should not have a pending navigation entry.
-  EXPECT_TRUE(contents()->GetController().GetPendingEntry() == nullptr);
-  NavigationEntry* entry = contents()->GetController().GetVisibleEntry();
-  ASSERT_TRUE(entry != nullptr);
-  EXPECT_EQ(kUrl2, entry->GetURL());
-
-  // Now do the same but as a user gesture.
-  params.gesture = NavigationGestureUser;
-  evil_rfh->SimulateNavigationStart(kUrl2);
-  evil_rfh->SendNavigateWithParams(&params);
-  evil_rfh->SimulateNavigationStop();
-
-  // User navigation should have cancelled the pending RFH.
-  EXPECT_TRUE(
-      contents()->GetRenderManagerForTesting()->pending_render_view_host() ==
-      nullptr);
-  EXPECT_TRUE(contents()->GetRenderManagerForTesting()->pending_frame_host() ==
-              nullptr);
-  EXPECT_EQ(evil_rfh,
-            contents()->GetRenderManagerForTesting()->current_frame_host());
-  EXPECT_EQ(evil_rfh->GetRenderViewHost(),
-            contents()->GetRenderManagerForTesting()->current_host());
-
-  // Also we should not have a pending navigation entry.
-  EXPECT_TRUE(contents()->GetController().GetPendingEntry() == nullptr);
-  entry = contents()->GetController().GetVisibleEntry();
-  ASSERT_TRUE(entry != nullptr);
-  EXPECT_EQ(kUrl2, entry->GetURL());
-}
-
 // Ensure that we can go back and forward even if a SwapOut ACK isn't received.
 // See http://crbug.com/93427.
 TEST_F(RenderFrameHostManagerTest, NavigateAfterMissingSwapOutACK) {
@@ -1631,7 +1522,7 @@
 
   // The RenderFrameHost created in Init will be reused.
   EXPECT_TRUE(host == manager->current_frame_host());
-  EXPECT_FALSE(manager->pending_frame_host());
+  EXPECT_FALSE(manager->speculative_frame_host());
   EXPECT_EQ(manager->current_frame_host()->GetSiteInstance(), instance);
 
   // Commit.
@@ -1653,7 +1544,7 @@
 
   // The RenderFrameHost created in Init will be reused.
   EXPECT_EQ(host, manager->current_frame_host());
-  EXPECT_FALSE(manager->pending_frame_host());
+  EXPECT_FALSE(manager->speculative_frame_host());
 
   // Commit.
   manager->DidNavigateFrame(host, true);
@@ -3165,46 +3056,6 @@
   EXPECT_FALSE(main_test_rfh()->frame_tree_node()->navigation_request());
 }
 
-// Tests that a DidStartProvisionalLoad IPC from a no longer active RFH is
-// ignored.
-TEST_F(RenderFrameHostManagerTest,
-       DidStartProvisionalLoadIgnoredWhenNotActive) {
-  if (IsBrowserSideNavigationEnabled()) {
-    SUCCEED() << "This test is not applicable to browser side navigation. See "
-                 "RenderFrameHostManagerTestWithBrowserSideNavigation."
-                 "BeginNavigationIgnoredWhenNotActive for a similar case when "
-                 "PlzNavigate is enabled.";
-    return;
-  }
-  const GURL kUrl1("http://www.google.com");
-  const GURL kUrl2("http://www.chromium.org");
-  const GURL kUrl3("http://foo.com");
-
-  contents()->NavigateAndCommit(kUrl1);
-
-  TestRenderFrameHost* initial_rfh = main_test_rfh();
-  RenderViewHostDeletedObserver delete_observer(
-      initial_rfh->GetRenderViewHost());
-
-  // Navigate cross-site but don't simulate the swap out ACK. The initial RFH
-  // should be pending delete.
-  RenderFrameHostManager* manager =
-      main_test_rfh()->frame_tree_node()->render_manager();
-  auto navigation =
-      NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
-  navigation->ReadyToCommit();
-  static_cast<TestRenderFrameHost*>(manager->pending_frame_host())
-      ->SimulateNavigationCommit(kUrl2);
-  EXPECT_NE(initial_rfh, main_test_rfh());
-  ASSERT_FALSE(delete_observer.deleted());
-  EXPECT_FALSE(initial_rfh->is_active());
-
-  // The initial RFH receives a DidStartProvisionalLoad IPC. It should not
-  // create a NavigationHandle.
-  initial_rfh->SimulateNavigationStart(kUrl3);
-  EXPECT_FALSE(initial_rfh->navigation_handle());
-}
-
 // Tests that sandbox flags received after a navigation away has started do not
 // affect the document being navigated to.
 TEST_F(RenderFrameHostManagerTest, ReceivedFramePolicyAfterNavigationStarted) {
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index 6337629..88c140b 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -202,7 +202,8 @@
 viz::SurfaceId DelegatedFrameHost::SurfaceIdAtPoint(
     viz::SurfaceHittestDelegate* delegate,
     const gfx::PointF& point,
-    gfx::PointF* transformed_point) {
+    gfx::PointF* transformed_point,
+    bool* out_query_renderer) {
   *transformed_point = point;
   viz::SurfaceId surface_id(frame_sink_id_, local_surface_id_);
   if (!surface_id.is_valid() || enable_viz_)
@@ -210,8 +211,9 @@
   viz::SurfaceHittest hittest(delegate,
                               GetFrameSinkManager()->surface_manager());
   gfx::Transform target_transform;
-  viz::SurfaceId target_local_surface_id = hittest.GetTargetSurfaceAtPoint(
-      surface_id, gfx::ToFlooredPoint(point), &target_transform);
+  viz::SurfaceId target_local_surface_id =
+      hittest.GetTargetSurfaceAtPoint(surface_id, gfx::ToFlooredPoint(point),
+                                      &target_transform, out_query_renderer);
   if (target_local_surface_id.is_valid())
     target_transform.TransformPoint(transformed_point);
   return target_local_surface_id;
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h
index 963f76e..8e5b197 100644
--- a/content/browser/renderer_host/delegated_frame_host.h
+++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -168,7 +168,8 @@
   // a compositor Surface.
   viz::SurfaceId SurfaceIdAtPoint(viz::SurfaceHittestDelegate* delegate,
                                   const gfx::PointF& point,
-                                  gfx::PointF* transformed_point);
+                                  gfx::PointF* transformed_point,
+                                  bool* out_query_renderer);
 
   // Given the SurfaceID of a Surface that is contained within this class'
   // Surface, find the relative transform between the Surfaces and apply it
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 4908f01..f3e0d62 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -441,11 +441,18 @@
     NOTREACHED();
   }
 
+  // On Android, Touch event feature detection is enabled by default,
+  // Otherwise default is disabled.
+  std::string touch_enabled_default_switch =
+      switches::kTouchEventFeatureDetectionDisabled;
+#if defined(OS_ANDROID)
+  touch_enabled_default_switch = switches::kTouchEventFeatureDetectionEnabled;
+#endif  // defined(OS_ANDROID)
   const std::string touch_enabled_switch =
       command_line.HasSwitch(switches::kTouchEventFeatureDetection)
           ? command_line.GetSwitchValueASCII(
                 switches::kTouchEventFeatureDetection)
-          : switches::kTouchEventFeatureDetectionAuto;
+          : touch_enabled_default_switch;
   prefs.touch_event_feature_detection_enabled =
       (touch_enabled_switch == switches::kTouchEventFeatureDetectionAuto)
           ? (ui::GetTouchScreensAvailability() ==
@@ -453,6 +460,7 @@
           : (touch_enabled_switch.empty() ||
              touch_enabled_switch ==
                  switches::kTouchEventFeatureDetectionEnabled);
+
   std::tie(prefs.available_pointer_types, prefs.available_hover_types) =
       ui::GetAvailablePointerAndHoverTypes();
   prefs.primary_pointer_type =
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index 2b812822..a261ebdc 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -289,12 +289,17 @@
     // hittesting data send by the renderer.
     HittestDelegate delegate(hittest_data_);
 
+    // TODO(kenrb, sadrul): If this is set to true by FrameSinkIdAtPoint,
+    // invoke the InputTargetClient interface on the root view's frame (and on
+    // any OOPIFs also, if any are hit).
+    bool query_renderer = false;
+
     // The conversion of point to transform_point is done over the course of the
     // hit testing, and reflect transformations that would normally be applied
     // in the renderer process if the event was being routed between frames
     // within a single process with only one RenderWidgetHost.
-    frame_sink_id =
-        root_view->FrameSinkIdAtPoint(&delegate, point, transformed_point);
+    frame_sink_id = root_view->FrameSinkIdAtPoint(
+        &delegate, point, transformed_point, &query_renderer);
   }
 
   // TODO(kenrb): There should be a better way to handle hit tests to surfaces
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
index 19fcbc6..17d922e6 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
@@ -61,7 +61,8 @@
 
   viz::FrameSinkId FrameSinkIdAtPoint(viz::SurfaceHittestDelegate*,
                                       const gfx::PointF&,
-                                      gfx::PointF*) override {
+                                      gfx::PointF*,
+                                      bool*) override {
     return frame_sink_id_map_[current_hittest_result_];
   }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 382cae4..23feea8 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -853,7 +853,8 @@
 viz::FrameSinkId RenderWidgetHostViewAndroid::FrameSinkIdAtPoint(
     viz::SurfaceHittestDelegate* delegate,
     const gfx::PointF& point,
-    gfx::PointF* transformed_point) {
+    gfx::PointF* transformed_point,
+    bool* out_query_renderer) {
   if (!delegated_frame_host_)
     return viz::FrameSinkId();
 
@@ -869,7 +870,8 @@
                                 GetFrameSinkManager()->surface_manager());
     gfx::Transform target_transform;
     surface_id = hittest.GetTargetSurfaceAtPoint(
-        surface_id, gfx::ToFlooredPoint(point_in_pixels), &target_transform);
+        surface_id, gfx::ToFlooredPoint(point_in_pixels), &target_transform,
+        out_query_renderer);
     *transformed_point = point_in_pixels;
     if (surface_id.is_valid())
       target_transform.TransformPoint(transformed_point);
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 94bf0418..bd18984 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -174,7 +174,8 @@
   viz::FrameSinkId GetFrameSinkId() override;
   viz::FrameSinkId FrameSinkIdAtPoint(viz::SurfaceHittestDelegate* delegate,
                                       const gfx::PointF& point,
-                                      gfx::PointF* transformed_point) override;
+                                      gfx::PointF* transformed_point,
+                                      bool* out_query_renderer) override;
   bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
                                        const viz::SurfaceId& original_surface,
                                        gfx::PointF* transformed_point) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 5f24ca9..fe662b3 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1655,7 +1655,8 @@
 viz::FrameSinkId RenderWidgetHostViewAura::FrameSinkIdAtPoint(
     viz::SurfaceHittestDelegate* delegate,
     const gfx::PointF& point,
-    gfx::PointF* transformed_point) {
+    gfx::PointF* transformed_point,
+    bool* out_query_renderer) {
   DCHECK(device_scale_factor_ != 0.0f);
 
   // TODO: this shouldn't be used with aura-mus, so that the null check so
@@ -1670,7 +1671,7 @@
   gfx::PointF point_in_pixels =
       gfx::ConvertPointToPixel(device_scale_factor_, point);
   viz::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint(
-      delegate, point_in_pixels, transformed_point);
+      delegate, point_in_pixels, transformed_point, out_query_renderer);
   *transformed_point =
       gfx::ConvertPointToDIP(device_scale_factor_, *transformed_point);
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 91fff1b4..ab61c8a 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -189,7 +189,8 @@
   viz::LocalSurfaceId GetLocalSurfaceId() const override;
   viz::FrameSinkId FrameSinkIdAtPoint(viz::SurfaceHittestDelegate* delegate,
                                       const gfx::PointF& point,
-                                      gfx::PointF* transformed_point) override;
+                                      gfx::PointF* transformed_point,
+                                      bool* out_query_renderer) override;
   bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
                                        const viz::SurfaceId& original_surface,
                                        gfx::PointF* transformed_point) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index 95c399e..07364f0 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -435,7 +435,8 @@
 viz::FrameSinkId RenderWidgetHostViewBase::FrameSinkIdAtPoint(
     viz::SurfaceHittestDelegate* delegate,
     const gfx::PointF& point,
-    gfx::PointF* transformed_point) {
+    gfx::PointF* transformed_point,
+    bool* out_query_renderer) {
   NOTREACHED();
   return viz::FrameSinkId();
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 8e25605..ca1e9a83 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -296,10 +296,15 @@
   // methods are invoked on the RenderWidgetHostView that should be able to
   // properly handle the event (i.e. it has focus for keyboard events, or has
   // been identified by hit testing mouse, touch or gesture events).
+  // |out_query_renderer| is set if there is low confidence in the hit test
+  // result which means that renderer process hit testing could potentially
+  // give a different result. In that case the returned FrameSinkId and
+  // transformed point should be ignored.
   virtual viz::FrameSinkId FrameSinkIdAtPoint(
       viz::SurfaceHittestDelegate* delegate,
       const gfx::PointF& point,
-      gfx::PointF* transformed_point);
+      gfx::PointF* transformed_point,
+      bool* out_query_renderer);
 
   virtual void PreProcessMouseEvent(const blink::WebMouseEvent& event) {}
   virtual void PreProcessTouchEvent(const blink::WebTouchEvent& event) {}
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h
index dd15337..9b7f340 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -358,7 +358,8 @@
   viz::LocalSurfaceId GetLocalSurfaceId() const override;
   viz::FrameSinkId FrameSinkIdAtPoint(viz::SurfaceHittestDelegate* delegate,
                                       const gfx::PointF& point,
-                                      gfx::PointF* transformed_point) override;
+                                      gfx::PointF* transformed_point,
+                                      bool* out_query_renderer) override;
   // Returns true when we can do SurfaceHitTesting for the event type.
   bool ShouldRouteEvent(const blink::WebInputEvent& event) const;
   // This method checks |event| to see if a GesturePinch event can be routed
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index f231744..eaaf27f 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1538,14 +1538,15 @@
 viz::FrameSinkId RenderWidgetHostViewMac::FrameSinkIdAtPoint(
     viz::SurfaceHittestDelegate* delegate,
     const gfx::PointF& point,
-    gfx::PointF* transformed_point) {
+    gfx::PointF* transformed_point,
+    bool* out_query_renderer) {
   // The surface hittest happens in device pixels, so we need to convert the
   // |point| from DIPs to pixels before hittesting.
   float scale_factor = ui::GetScaleFactorForNativeView(cocoa_view_);
   gfx::PointF point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
   viz::SurfaceId id =
       browser_compositor_->GetDelegatedFrameHost()->SurfaceIdAtPoint(
-          delegate, point_in_pixels, transformed_point);
+          delegate, point_in_pixels, transformed_point, out_query_renderer);
   *transformed_point = gfx::ConvertPointToDIP(scale_factor, *transformed_point);
 
   // It is possible that the renderer has not yet produced a surface, in which
diff --git a/content/browser/screen_orientation/screen_orientation_browsertest.cc b/content/browser/screen_orientation/screen_orientation_browsertest.cc
index a461bd2..e3f6275 100644
--- a/content/browser/screen_orientation/screen_orientation_browsertest.cc
+++ b/content/browser/screen_orientation/screen_orientation_browsertest.cc
@@ -389,9 +389,7 @@
 
   FrameTreeNode* root = web_contents()->GetFrameTree()->root();
   RenderFrameHostImpl* pending_rfh =
-      IsBrowserSideNavigationEnabled()
-          ? root->render_manager()->speculative_frame_host()
-          : root->render_manager()->pending_frame_host();
+      root->render_manager()->speculative_frame_host();
 
   // Send the orientation change to the pending RFH's widget.
   pending_rfh->GetRenderWidgetHost()->Send(new ViewMsg_Resize(
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index 9d81c70..4b84db0d 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -108,11 +108,8 @@
   // Since the navigation above requires a cross-process swap, there will be a
   // speculative/pending RenderFrameHost. Ensure it exists and is in a different
   // process than the initial page.
-  RenderFrameHostImpl* next_rfh;
-  if (IsBrowserSideNavigationEnabled())
-    next_rfh = wc->GetRenderManagerForTesting()->speculative_frame_host();
-  else
-    next_rfh = wc->GetRenderManagerForTesting()->pending_frame_host();
+  RenderFrameHostImpl* next_rfh =
+      wc->GetRenderManagerForTesting()->speculative_frame_host();
 
   EXPECT_TRUE(next_rfh);
   EXPECT_NE(shell->web_contents()->GetMainFrame()->GetProcess()->GetID(),
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 8cd4f4e..8f648a4 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -3930,9 +3930,7 @@
   // message loop, so no IPCs that alter the frame tree can be processed.
   FrameTreeNode* child = root->child_at(1);
   SiteInstance* site = nullptr;
-  bool browser_side_navigation = IsBrowserSideNavigationEnabled();
-  std::string cross_site_rfh_type =
-      browser_side_navigation ? "speculative" : "pending";
+  std::string cross_site_rfh_type = "speculative";
   {
     TestNavigationObserver observer(shell()->web_contents());
     TestFrameNavigationObserver navigation_observer(child);
@@ -3941,13 +3939,7 @@
     params.frame_tree_node_id = child->frame_tree_node_id();
     child->navigator()->GetController()->LoadURLWithParams(params);
 
-    if (browser_side_navigation) {
-      site = child->render_manager()
-                 ->speculative_frame_host()
-                 ->GetSiteInstance();
-    } else {
-      site = child->render_manager()->pending_frame_host()->GetSiteInstance();
-    }
+    site = child->render_manager()->speculative_frame_host()->GetSiteInstance();
     EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site);
 
     std::string tree = base::StringPrintf(
@@ -3965,7 +3957,6 @@
     // Now that the verification is done, run the message loop and wait for the
     // navigation to complete.
     navigation_observer.Wait();
-    EXPECT_FALSE(child->render_manager()->pending_frame_host());
     EXPECT_TRUE(observer.last_navigation_succeeded());
     EXPECT_EQ(cross_site_url, observer.last_navigation_url());
 
@@ -3994,14 +3985,8 @@
     params.frame_tree_node_id = child->frame_tree_node_id();
     child->navigator()->GetController()->LoadURLWithParams(params);
 
-    SiteInstance* site2;
-    if (browser_side_navigation) {
-      site2 = child->render_manager()
-                  ->speculative_frame_host()
-                  ->GetSiteInstance();
-    } else {
-      site2 = child->render_manager()->pending_frame_host()->GetSiteInstance();
-    }
+    SiteInstance* site2 =
+        child->render_manager()->speculative_frame_host()->GetSiteInstance();
     EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site2);
     EXPECT_NE(site, site2);
 
@@ -5992,9 +5977,7 @@
   TestNavigationObserver navigation_observer(shell()->web_contents());
   shell()->LoadURL(a_url);
   RenderViewHostImpl* pending_rvh =
-      IsBrowserSideNavigationEnabled()
-          ? root->render_manager()->speculative_frame_host()->render_view_host()
-          : root->render_manager()->pending_render_view_host();
+      root->render_manager()->speculative_frame_host()->render_view_host();
   EXPECT_EQ(site_instance, pending_rvh->GetSiteInstance());
   EXPECT_FALSE(rvh_routing_id == pending_rvh->GetRoutingID() &&
                rvh_process_id == pending_rvh->GetProcess()->GetID());
@@ -7819,15 +7802,11 @@
   // observer to ensure there is no crash when a new RenderFrame creation is
   // attempted.
   RenderProcessHost* process =
-      IsBrowserSideNavigationEnabled()
-          ? node->render_manager()->speculative_frame_host()->GetProcess()
-          : node->render_manager()->pending_frame_host()->GetProcess();
+      node->render_manager()->speculative_frame_host()->GetProcess();
   RenderProcessHostWatcher watcher(
       process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   int frame_routing_id =
-      IsBrowserSideNavigationEnabled()
-          ? node->render_manager()->speculative_frame_host()->GetRoutingID()
-          : node->render_manager()->pending_frame_host()->GetRoutingID();
+      node->render_manager()->speculative_frame_host()->GetRoutingID();
   int proxy_routing_id =
       node->render_manager()->GetProxyToParent()->GetRoutingID();
 
@@ -9996,9 +9975,7 @@
 
   // The pending RFH should be in the same process as the popup.
   RenderFrameHostImpl* pending_rfh =
-      IsBrowserSideNavigationEnabled()
-          ? root->render_manager()->speculative_frame_host()
-          : root->render_manager()->pending_frame_host();
+      root->render_manager()->speculative_frame_host();
   RenderProcessHost* pending_process = pending_rfh->GetProcess();
   EXPECT_EQ(pending_process,
             popup_shell->web_contents()->GetMainFrame()->GetProcess());
@@ -10014,9 +9991,7 @@
   // be reused while it's not live in the next navigation.
   {
     RenderFrameHostImpl* pending_rfh =
-        IsBrowserSideNavigationEnabled()
-            ? root->render_manager()->speculative_frame_host()
-            : root->render_manager()->pending_frame_host();
+        root->render_manager()->speculative_frame_host();
     EXPECT_FALSE(pending_rfh);
   }
 
@@ -11326,7 +11301,7 @@
   GURL frame_url(
       embedded_test_server()->GetURL("a.com", "/cross-site/b.com/title2.html"));
   NavigateIframeToURL(shell()->web_contents(), "child-0", frame_url);
-  EXPECT_FALSE(root->child_at(0)->render_manager()->pending_frame_host());
+  EXPECT_FALSE(root->child_at(0)->render_manager()->speculative_frame_host());
   GURL redirected_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
   EXPECT_EQ(root->child_at(0)->current_url(), redirected_url);
   EXPECT_EQ(b_site_instance,
@@ -11334,7 +11309,7 @@
 
   // Try the same navigation, but use the browser-initiated path.
   NavigateFrameToURL(root->child_at(0), frame_url);
-  EXPECT_FALSE(root->child_at(0)->render_manager()->pending_frame_host());
+  EXPECT_FALSE(root->child_at(0)->render_manager()->speculative_frame_host());
   EXPECT_EQ(root->child_at(0)->current_url(), redirected_url);
   EXPECT_EQ(b_site_instance,
             root->child_at(0)->current_frame_host()->GetSiteInstance());
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 17dc389..5c7d67f5 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -648,11 +648,6 @@
   // destroyed.
   RenderFrameHostManager* root = GetRenderManager();
 
-  if (root->pending_frame_host()) {
-    root->pending_frame_host()->SetRenderFrameCreated(false);
-    root->pending_frame_host()->SetNavigationHandle(
-        std::unique_ptr<NavigationHandleImpl>());
-  }
   root->current_frame_host()->SetRenderFrameCreated(false);
   root->current_frame_host()->SetNavigationHandle(
       std::unique_ptr<NavigationHandleImpl>());
@@ -677,11 +672,6 @@
   for (auto& observer : observers_)
     observer.FrameDeleted(root->current_frame_host());
 
-  if (root->pending_render_view_host()) {
-    for (auto& observer : observers_)
-      observer.RenderViewDeleted(root->pending_render_view_host());
-  }
-
   for (auto& observer : observers_)
     observer.RenderViewDeleted(root->current_host());
 
@@ -1075,13 +1065,8 @@
 
   for (FrameTreeNode* node : frame_tree_.Nodes()) {
     UpdateAccessibilityModeOnFrame(node->current_frame_host());
-    // Also update accessibility mode on the pending RenderFrameHost for this
-    // FrameTreeNode, if one exists.  speculative_frame_host() is used with
-    // PlzNavigate, and pending_frame_host() is used without it.
-    RenderFrameHost* pending_frame_host =
-        node->render_manager()->pending_frame_host();
-    if (pending_frame_host)
-      UpdateAccessibilityModeOnFrame(pending_frame_host);
+    // Also update accessibility mode on the speculative RenderFrameHost for
+    // this FrameTreeNode, if one exists.
     RenderFrameHost* speculative_frame_host =
         node->render_manager()->speculative_frame_host();
     if (speculative_frame_host)
@@ -1310,14 +1295,6 @@
   return GetRenderManager()->current_host()->GetSiteInstance();
 }
 
-SiteInstanceImpl* WebContentsImpl::GetPendingSiteInstance() const {
-  RenderViewHostImpl* dest_rvh =
-      GetRenderManager()->pending_render_view_host() ?
-          GetRenderManager()->pending_render_view_host() :
-          GetRenderManager()->current_host();
-  return dest_rvh->GetSiteInstance();
-}
-
 bool WebContentsImpl::IsLoading() const {
   return frame_tree_.IsLoading() &&
          !(ShowingInterstitialPage() && interstitial_page_->pause_throbber());
@@ -4787,9 +4764,7 @@
 }
 
 RenderFrameHost* WebContentsImpl::GetPendingMainFrame() {
-  if (IsBrowserSideNavigationEnabled())
-    return GetRenderManager()->speculative_frame_host();
-  return GetRenderManager()->pending_frame_host();
+  return GetRenderManager()->speculative_frame_host();
 }
 
 bool WebContentsImpl::HasActiveEffectivelyFullscreenVideo() const {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 681b80ad..c17ad4b 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -331,7 +331,6 @@
   void UpdateTitleForEntry(NavigationEntry* entry,
                            const base::string16& title) override;
   SiteInstanceImpl* GetSiteInstance() const override;
-  SiteInstanceImpl* GetPendingSiteInstance() const override;
   bool IsLoading() const override;
   bool IsLoadingToDifferentDocument() const override;
   bool IsWaitingForResponse() const override;
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 21044ad3..3003cc14 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -353,10 +353,6 @@
   // Returns the SiteInstance associated with the current page.
   virtual SiteInstance* GetSiteInstance() const = 0;
 
-  // Returns the SiteInstance for the pending navigation, if any.  Otherwise
-  // returns the current SiteInstance.
-  virtual SiteInstance* GetPendingSiteInstance() const = 0;
-
   // Returns whether this WebContents is loading a resource.
   virtual bool IsLoading() const = 0;
 
diff --git a/content/public/test/test_renderer_host.cc b/content/public/test/test_renderer_host.cc
index b4acef4..9fba244 100644
--- a/content/public/test/test_renderer_host.cc
+++ b/content/public/test/test_renderer_host.cc
@@ -83,11 +83,8 @@
 
   WebContentsImpl* web_contents =
       static_cast<WebContentsImpl*>(controller->GetWebContents());
-  RenderFrameHost* pending_rfh =
-      IsBrowserSideNavigationEnabled()
-          ? web_contents->GetRenderManagerForTesting()
-                ->speculative_render_frame_host_.get()
-          : web_contents->GetRenderManagerForTesting()->pending_frame_host();
+  RenderFrameHost* pending_rfh = web_contents->GetRenderManagerForTesting()
+                                     ->speculative_render_frame_host_.get();
 
   // Commit on the pending_rfh, if one exists.
   RenderFrameHost* test_rfh = pending_rfh ? pending_rfh : old_rfh;
diff --git a/content/test/content_browser_test_utils_internal.cc b/content/test/content_browser_test_utils_internal.cc
index 1f755a3..f76e12fe6 100644
--- a/content/test/content_browser_test_utils_internal.cc
+++ b/content/test/content_browser_test_utils_internal.cc
@@ -92,10 +92,7 @@
       to_explore.push(node->child_at(i));
     }
 
-    RenderFrameHost* pending = node->render_manager()->pending_frame_host();
     RenderFrameHost* spec = node->render_manager()->speculative_frame_host();
-    if (pending)
-      legend[GetName(pending->GetSiteInstance())] = pending->GetSiteInstance();
     if (spec)
       legend[GetName(spec->GetSiteInstance())] = spec->GetSiteInstance();
   }
@@ -170,14 +167,9 @@
     // RenderFrameHost, and show any exceptional state of the node, like a
     // pending or speculative RenderFrameHost.
     RenderFrameHost* current = node->render_manager()->current_frame_host();
-    RenderFrameHost* pending = node->render_manager()->pending_frame_host();
     RenderFrameHost* spec = node->render_manager()->speculative_frame_host();
     base::StringAppendF(&line, "Site %s",
                         GetName(current->GetSiteInstance()).c_str());
-    if (pending) {
-      base::StringAppendF(&line, " (%s pending)",
-                          GetName(pending->GetSiteInstance()).c_str());
-    }
     if (spec) {
       base::StringAppendF(&line, " (%s speculative)",
                           GetName(spec->GetSiteInstance()).c_str());
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc
index 727bd32..0b698b7 100644
--- a/content/test/test_web_contents.cc
+++ b/content/test/test_web_contents.cc
@@ -189,10 +189,7 @@
 }
 
 bool TestWebContents::CrossProcessNavigationPending() {
-  if (IsBrowserSideNavigationEnabled()) {
-    return GetRenderManager()->speculative_render_frame_host_ != nullptr;
-  }
-  return GetRenderManager()->pending_frame_host() != nullptr;
+  return GetRenderManager()->speculative_render_frame_host_ != nullptr;
 }
 
 bool TestWebContents::CreateRenderViewForRenderManager(
@@ -237,18 +234,11 @@
       DCHECK(current_frame_host);
       current_frame_host->ResetLoadingState();
 
-      if (IsBrowserSideNavigationEnabled()) {
-        RenderFrameHostImpl* speculative_frame_host =
-            node->render_manager()->speculative_frame_host();
-        if (speculative_frame_host)
-          speculative_frame_host->ResetLoadingState();
-        node->ResetNavigationRequest(false, true);
-      } else {
-        RenderFrameHostImpl* pending_frame_host =
-            node->render_manager()->pending_frame_host();
-        if (pending_frame_host)
-          pending_frame_host->ResetLoadingState();
-      }
+      RenderFrameHostImpl* speculative_frame_host =
+          node->render_manager()->speculative_frame_host();
+      if (speculative_frame_host)
+        speculative_frame_host->ResetLoadingState();
+      node->ResetNavigationRequest(false, true);
     }
   }
 }
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn
index b977500..6683d8d 100644
--- a/ios/chrome/browser/ui/BUILD.gn
+++ b/ios/chrome/browser/ui/BUILD.gn
@@ -512,6 +512,7 @@
     "//ios/chrome/browser/tabs:tabs_internal",
     "//ios/chrome/browser/ui/omnibox:omnibox_internal",
     "//ios/chrome/browser/ui/toolbar",
+    "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/web_state_list",
     "//ios/chrome/browser/web_state_list:test_support",
     "//ios/chrome/test/base:perf_test_support",
diff --git a/ios/chrome/browser/ui/omnibox_perftest.mm b/ios/chrome/browser/ui/omnibox_perftest.mm
index c1e9d12..50dbec6 100644
--- a/ios/chrome/browser/ui/omnibox_perftest.mm
+++ b/ios/chrome/browser/ui/omnibox_perftest.mm
@@ -18,6 +18,7 @@
 #include "ios/chrome/browser/ui/toolbar/toolbar_model_impl_ios.h"
 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
 #import "ios/chrome/browser/ui/toolbar/web_toolbar_delegate.h"
+#import "ios/chrome/browser/ui/util/named_guide.h"
 #include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h"
 #include "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/web_state_list/web_state_opener.h"
@@ -119,6 +120,8 @@
     toolbarView.frame = toolbarFrame;
     // Add toolbar to window.
     [window_ addSubview:toolbarView];
+    AddNamedGuide(kOmniboxGuide, window_);
+    [toolbar_ didMoveToParentViewController:nil];
     base::test::ios::WaitUntilCondition(^bool() {
       return IsToolbarLoaded(window_);
     });
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 69e2852..c909329 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -228,10 +228,6 @@
 #define SK_SUPPORT_LEGACY_TILED_BITMAPS
 #endif
 
-#ifndef SK_SUPPORT_LEGACY_ADOBE_XYZ
-#define SK_SUPPORT_LEGACY_ADOBE_XYZ
-#endif
-
 // remove after rebaselining svg layout tests
 #ifndef SK_SUPPORT_LEGACY_SVG_ARC_TO
 #define SK_SUPPORT_LEGACY_SVG_ARC_TO
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-munsell-adobe-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/images/color-profile-munsell-adobe-to-srgb-expected.txt
index 44eb3b02..33aac4f 100644
--- a/third_party/WebKit/LayoutTests/images/color-profile-munsell-adobe-to-srgb-expected.txt
+++ b/third_party/WebKit/LayoutTests/images/color-profile-munsell-adobe-to-srgb-expected.txt
@@ -20,7 +20,7 @@
 Red           177,45,56     177,44,56     1
 Yellow        239,200,27    238,200,27    1
 Magenta       187,82,147    187,82,148    1
-Cyan (*)      0,135,166     0,135,166     0
+Cyan (*)      0,135,165     0,135,166     1
 --------------------------------------------
 White         243,242,236   243,242,237   1
 Neutral 8     202,202,200   201,201,201   2
@@ -30,7 +30,7 @@
 Black         50,50,50      50,49,50      1
 --------------------------------------------
 
-Result: total RMS color error: 1.04
+Result: total RMS color error: 1.06
  * Munsell Cyan is outside 255 sRGB gamut
 
   
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png
index 1e52af5..9cbf418 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
index d88c9d2..04513cd 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png
index 511f4a47..00038947 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png
index 2152282b..81ed3529 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
index 45860fd2..be03ed5a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/media/mq-color-gamut-picture-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/media/mq-color-gamut-picture-expected.png
index 32968d8..4b244ad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/media/mq-color-gamut-picture-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/media/mq-color-gamut-picture-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png
index 522c84c..e271aa1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
index eecdc6c..7f4acd95 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/media/mq-color-gamut-picture-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/media/mq-color-gamut-picture-expected.png
index 1fce168..b027ad2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/media/mq-color-gamut-picture-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/media/mq-color-gamut-picture-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png
index d246ff28..adc1e7e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
index e7e62743..4510056d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png
index 86e6b38..967edf0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png
Binary files differ
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.cpp b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
index 32890c6a..0461a9a 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.cpp
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
@@ -112,12 +112,6 @@
   DCHECK(runner_);
 }
 
-void WebTaskRunner::PostDelayedTask(const base::Location& location,
-                                    CrossThreadClosure task,
-                                    TimeDelta delay) {
-  PostDelayedCrossThreadTask(*this, location, std::move(task), delay);
-}
-
 void WebTaskRunner::PostTask(const base::Location& location,
                              base::OnceClosure task) {
   PostDelayedTask(location, std::move(task), base::TimeDelta());
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.h b/third_party/WebKit/Source/platform/WebTaskRunner.h
index 9d4e00e..3c017aad 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.h
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.h
@@ -70,12 +70,6 @@
 
   // Helpers for posting bound functions as tasks.
 
-  // Deprecated. Use namespace-level Post(Delayed)CrossThreadTask() defined
-  // below.
-  void PostDelayedTask(const base::Location&,
-                       CrossThreadClosure,
-                       TimeDelta delay);
-
   // For same-thread posting. Must be called from the associated WebThread.
   void PostTask(const base::Location&, base::OnceClosure);
 
diff --git a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
index fb516850..2008f1a0 100644
--- a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
+++ b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
@@ -53,8 +53,8 @@
   void PostDelayedTask(const base::Location& location,
                        CrossThreadClosure task,
                        TimeDelta delay) {
-    thread_->GetWebTaskRunner()->PostDelayedTask(location, std::move(task),
-                                                 delay);
+    PostDelayedCrossThreadTask(*thread_->GetWebTaskRunner(), location,
+                               std::move(task), delay);
   }
 
   bool IsCurrentThread() const { return thread_->IsCurrentThread(); }
diff --git a/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp b/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp
index 85c5568c..00f87d1 100644
--- a/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp
+++ b/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp
@@ -57,8 +57,8 @@
     ++counter_;
     RunTask();
     if (elapsed_ms_ < duration_ms_) {
-      client_thread_->GetWebTaskRunner()->PostDelayedTask(
-          FROM_HERE,
+      PostDelayedCrossThreadTask(
+          *client_thread_->GetWebTaskRunner(), FROM_HERE,
           CrossThreadBind(&FIFOClient::RunTaskOnOwnThread,
                           CrossThreadUnretained(this)),
           TimeDelta::FromMillisecondsD(interval_with_jitter));
diff --git a/third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h b/third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h
index c422d31..03b4e17b 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h
+++ b/third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h
@@ -31,6 +31,7 @@
   // instances of HeapTerminatedArray and manage their lifetimes.
   struct Allocator final {
     STATIC_ONLY(Allocator);
+    using BackendAllocator = HeapAllocator;
     using PassPtr = HeapTerminatedArray*;
     using Ptr = Member<HeapTerminatedArray>;
 
diff --git a/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp b/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp
index 48a82d5..32cf15d 100644
--- a/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp
@@ -9,6 +9,8 @@
 #include "platform/heap/GarbageCollected.h"
 #include "platform/heap/Heap.h"
 #include "platform/heap/HeapAllocator.h"
+#include "platform/heap/HeapTerminatedArray.h"
+#include "platform/heap/HeapTerminatedArrayBuilder.h"
 #include "platform/heap/IncrementalMarkingFlag.h"
 #include "platform/heap/Member.h"
 #include "platform/heap/ThreadState.h"
@@ -809,6 +811,47 @@
   }
 }
 
+// =============================================================================
+// HeapTerminatedArray support. ================================================
+// =============================================================================
+
+namespace {
+
+class TerminatedArrayNode {
+  DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+
+ public:
+  TerminatedArrayNode(Object* obj) : obj_(obj), is_last_in_array_(false) {}
+
+  // TerminatedArray support.
+  bool IsLastInArray() const { return is_last_in_array_; }
+  void SetLastInArray(bool flag) { is_last_in_array_ = flag; }
+
+  void Trace(blink::Visitor* visitor) { visitor->Trace(obj_); }
+
+ private:
+  Member<Object> obj_;
+  bool is_last_in_array_;
+};
+
+}  // namespace
+
+TEST(IncrementalMarkingTest, HeapTerminatedArrayBuilder) {
+  Object* obj = Object::Create();
+  HeapTerminatedArray<TerminatedArrayNode>* array = nullptr;
+  {
+    // The builder allocates the backing store on Oilpans heap, effectively
+    // triggering a write barrier.
+    HeapTerminatedArrayBuilder<TerminatedArrayNode> builder(array);
+    builder.Grow(1);
+    {
+      ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj});
+      builder.Append(TerminatedArrayNode(obj));
+    }
+    array = builder.Release();
+  }
+}
+
 }  // namespace incremental_marking_test
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
index 7c9ea2d..69ad1912 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
@@ -151,8 +151,9 @@
   thread_->PostIdleTask(
       FROM_HERE, base::BindOnce(&MockIdleTask::Run, WTF::Unretained(&task)));
   // We need to post a wake-up task or idle work will never happen.
-  thread_->GetWebTaskRunner()->PostDelayedTask(
-      FROM_HERE, CrossThreadBind([] {}), TimeDelta::FromMilliseconds(50));
+  PostDelayedCrossThreadTask(*thread_->GetWebTaskRunner(), FROM_HERE,
+                             CrossThreadBind([] {}),
+                             TimeDelta::FromMilliseconds(50));
 
   completion.Wait();
 }
@@ -189,8 +190,8 @@
   PostCrossThreadTask(
       *thread_->GetWebTaskRunner(), FROM_HERE,
       CrossThreadBind(&MockTask::Run, WTF::CrossThreadUnretained(&task)));
-  thread_->GetWebTaskRunner()->PostDelayedTask(
-      FROM_HERE,
+  PostDelayedCrossThreadTask(
+      *thread_->GetWebTaskRunner(), FROM_HERE,
       CrossThreadBind(&MockTask::Run,
                       WTF::CrossThreadUnretained(&delayed_task)),
       TimeDelta::FromMilliseconds(50));
diff --git a/third_party/WebKit/Source/platform/wtf/TerminatedArray.h b/third_party/WebKit/Source/platform/wtf/TerminatedArray.h
index b119962..ea368adb 100644
--- a/third_party/WebKit/Source/platform/wtf/TerminatedArray.h
+++ b/third_party/WebKit/Source/platform/wtf/TerminatedArray.h
@@ -91,6 +91,7 @@
   // of TerminateArray and manage their lifetimes.
   struct Allocator {
     STATIC_ONLY(Allocator);
+    using BackendAllocator = PartitionAllocator;
     using PassPtr = std::unique_ptr<TerminatedArray>;
     using Ptr = std::unique_ptr<TerminatedArray>;
 
diff --git a/third_party/WebKit/Source/platform/wtf/TerminatedArrayBuilder.h b/third_party/WebKit/Source/platform/wtf/TerminatedArrayBuilder.h
index ea2b9b4..b663c371 100644
--- a/third_party/WebKit/Source/platform/wtf/TerminatedArrayBuilder.h
+++ b/third_party/WebKit/Source/platform/wtf/TerminatedArrayBuilder.h
@@ -6,6 +6,7 @@
 
 #include "base/macros.h"
 #include "platform/wtf/Allocator.h"
+#include "platform/wtf/ConstructTraits.h"
 
 namespace WTF {
 
@@ -44,6 +45,8 @@
     CHECK_LT(count_, capacity_);
     DCHECK(!item.IsLastInArray());
     array_->at(count_++) = item;
+    ConstructTraits<T, typename ArrayType<T>::Allocator::BackendAllocator>::
+        NotifyNewElements(&array_->at(count_ - 1), 1);
     if (count_ == capacity_)
       array_->at(capacity_ - 1).SetLastInArray(true);
   }
diff --git a/tools/cygprofile/delayed_dumper.cc b/tools/cygprofile/delayed_dumper.cc
index c2d60b4..513b6a5 100644
--- a/tools/cygprofile/delayed_dumper.cc
+++ b/tools/cygprofile/delayed_dumper.cc
@@ -8,10 +8,7 @@
 #include <thread>
 
 #include "base/android/library_loader/anchor_functions.h"
-#include "base/files/file.h"
-#include "base/format_macros.h"
 #include "base/logging.h"
-#include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "tools/cygprofile/lightweight_cygprofile.h"
 
@@ -34,19 +31,19 @@
       PLOG(FATAL) << "clock_gettime.";
     uint64_t start_ns_since_epoch =
         static_cast<uint64_t>(ts.tv_sec) * 1000 * 1000 * 1000 + ts.tv_nsec;
+    int pid = getpid();
 
-    std::thread([start_ns_since_epoch]() {
-      sleep(kDelayInSeconds);
-      auto path = base::StringPrintf(
-          "/data/local/tmp/chrome/cyglog/"
-          "cygprofile-instrumented-code-hitmap-%d-%" PRIu64 ".txt",
-          getpid(), start_ns_since_epoch);
-      StopAndDumpToFile(base::FilePath(path));
+    std::thread([pid, start_ns_since_epoch]() {
+      sleep(kInitialDelayInSeconds);
+      while (!SwitchToNextPhaseOrDump(pid, start_ns_since_epoch))
+        sleep(kDelayInSeconds);
     })
         .detach();
   }
 
   static constexpr int kDelayInSeconds = 30;
+  static constexpr int kInitialDelayInSeconds =
+      kPhases == 1 ? kDelayInSeconds : 5;
 };
 
 // Static initializer on purpose. Will disable instrumentation after
diff --git a/tools/cygprofile/lightweight_cygprofile.cc b/tools/cygprofile/lightweight_cygprofile.cc
index d57a5fa..7d2cd930 100644
--- a/tools/cygprofile/lightweight_cygprofile.cc
+++ b/tools/cygprofile/lightweight_cygprofile.cc
@@ -32,6 +32,16 @@
 constexpr size_t kMaxTextSizeInBytes = kBitfieldSize * (4 * 32);
 constexpr size_t kMaxElements = 1 << 20;
 
+// Data required to log reached offsets.
+struct LogData {
+  std::atomic<uint32_t> offsets[kBitfieldSize];
+  std::atomic<size_t> ordered_offsets[kMaxElements];
+  std::atomic<size_t> index;
+};
+
+LogData g_data[kPhases];
+std::atomic<int> g_data_index;
+
 // |RecordAddress()| adds an element to a concurrent bitset and to a concurrent
 // append-only list of offsets.
 //
@@ -52,28 +62,13 @@
 // - Capacity of the set is limited by |kMaxElements|.
 // - Some insertions at the end of collection may be lost.
 
-// |g_offsets| and |g_ordered_offsets| are allocated in .bss, as
-// std::atomic<uint32_t> and std::atomic<size_t> are guarangeed to behave like
-// their respective template type parameters with respect to size and
-// initialization.
-// Having these arrays in .bss simplifies initialization.
-std::atomic<uint32_t> g_offsets[kBitfieldSize];
-// Non-null iff collection is enabled. Also use to as the pointer to the offset
-// array to save a global load in the instrumentation.
-std::atomic<std::atomic<uint32_t>*> g_enabled_and_offsets = {g_offsets};
-
-// Ordered list of recorded offsets.
-std::atomic<size_t> g_ordered_offsets[kMaxElements];
-// Next free slot.
-std::atomic<size_t> g_ordered_offsets_index;
-
 // Records that |address| has been reached, if recording is enabled.
 // To avoid any risk of infinite recursion, this *must* *never* call any
 // instrumented function.
 template <bool for_testing>
 void RecordAddress(size_t address) {
-  auto* offsets = g_enabled_and_offsets.load(std::memory_order_relaxed);
-  if (!offsets)
+  int index = g_data_index.load(std::memory_order_relaxed);
+  if (index == kPhases)
     return;
 
   const size_t start =
@@ -89,14 +84,15 @@
   size_t offset = address - start;
   static_assert(sizeof(int) == 4,
                 "Collection and processing code assumes that sizeof(int) == 4");
-  size_t index = offset / 4;
+  size_t offset_index = offset / 4;
 
+  auto* offsets = g_data[index].offsets;
   // Atomically set the corresponding bit in the array.
-  std::atomic<uint32_t>* element = offsets + (index / 32);
+  std::atomic<uint32_t>* element = offsets + (offset_index / 32);
   // First, a racy check. This saves a CAS if the bit is already set, and
   // allows the cache line to remain shared acoss CPUs in this case.
   uint32_t value = element->load(std::memory_order_relaxed);
-  uint32_t mask = 1 << (index % 32);
+  uint32_t mask = 1 << (offset_index % 32);
   if (value & mask)
     return;
 
@@ -108,20 +104,57 @@
   // elements list.
   // Use relaxed ordering, as the value is not published, or used for
   // synchronization.
-  size_t ordered_offsets_index =
-      g_ordered_offsets_index.fetch_add(1, std::memory_order_relaxed);
-  if (UNLIKELY(ordered_offsets_index >= kMaxElements)) {
+  auto* ordered_offsets = g_data[index].ordered_offsets;
+  auto& ordered_offsets_index = g_data[index].index;
+  size_t insertion_index =
+      ordered_offsets_index.fetch_add(1, std::memory_order_relaxed);
+  if (UNLIKELY(insertion_index >= kMaxElements)) {
     Disable();
     LOG(FATAL) << "Too many reached offsets";
   }
-  g_ordered_offsets[ordered_offsets_index].store(offset,
-                                                 std::memory_order_relaxed);
+  ordered_offsets[insertion_index].store(offset, std::memory_order_relaxed);
+}
+
+void DumpToFile(const base::FilePath& path, const LogData& data) {
+  auto file =
+      base::File(path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+  if (!file.IsValid()) {
+    PLOG(ERROR) << "Could not open " << path;
+    return;
+  }
+
+  size_t count = data.index - 1;
+  for (size_t i = 0; i < count; i++) {
+    // |g_ordered_offsets| is initialized to 0, so a 0 in the middle of it
+    // indicates a case where the index was incremented, but the write is not
+    // visible in this thread yet. Safe to skip, also because the function at
+    // the start of text is never called.
+    auto offset = data.ordered_offsets[i].load(std::memory_order_relaxed);
+    if (!offset)
+      continue;
+    auto offset_str = base::StringPrintf("%" PRIuS "\n", offset);
+    file.WriteAtCurrentPos(offset_str.c_str(),
+                           static_cast<int>(offset_str.size()));
+  }
+}
+
+// Stops recording, and outputs the data to |path|.
+void StopAndDumpToFile(int pid, uint64_t start_ns_since_epoch) {
+  Disable();
+
+  for (int phase = 0; phase < kPhases; phase++) {
+    auto path = base::StringPrintf(
+        "/data/local/tmp/chrome/cyglog/"
+        "cygprofile-instrumented-code-hitmap-%d-%" PRIu64 ".txt_%d",
+        pid, start_ns_since_epoch, phase);
+    DumpToFile(base::FilePath(path), g_data[phase]);
+  }
 }
 
 }  // namespace
 
 void Disable() {
-  g_enabled_and_offsets.store(nullptr, std::memory_order_relaxed);
+  g_data_index.store(kPhases, std::memory_order_relaxed);
   std::atomic_thread_fence(std::memory_order_seq_cst);
 }
 
@@ -131,41 +164,25 @@
   base::android::CheckOrderingSanity();
 }
 
-// Stops recording, and outputs the data to |path|.
-void StopAndDumpToFile(const base::FilePath& path) {
-  Disable();
-  auto file = base::File(base::FilePath(path), base::File::FLAG_CREATE_ALWAYS |
-                                                   base::File::FLAG_WRITE);
-  if (!file.IsValid()) {
-    PLOG(ERROR) << "Could not open " << path;
-    return;
+bool SwitchToNextPhaseOrDump(int pid, uint64_t start_ns_since_epoch) {
+  int before = g_data_index.fetch_add(1, std::memory_order_relaxed);
+  if (before + 1 == kPhases) {
+    StopAndDumpToFile(pid, start_ns_since_epoch);
+    return true;
   }
-
-  std::atomic_thread_fence(std::memory_order_seq_cst);
-  // |g_ordered_offset_index| is the index of the next insertion.
-  size_t count = g_ordered_offsets_index.load(std::memory_order_relaxed) - 1;
-  for (size_t i = 0; i < count; i++) {
-    // |g_ordered_offsets| is initialized to 0, so a 0 in the middle of it
-    // indicates a case where the index was incremented, but the write is not
-    // visible in this thread yet. Safe to skip, also because the function at
-    // the start of text is never called.
-    auto offset = g_ordered_offsets[i].load(std::memory_order_relaxed);
-    if (!offset)
-      continue;
-    auto offset_str = base::StringPrintf("%" PRIuS "\n", offset);
-    file.WriteAtCurrentPos(offset_str.c_str(),
-                           static_cast<int>(offset_str.size()));
-  }
+  return false;
 }
 
 void ResetForTesting() {
   Disable();
-  g_ordered_offsets_index = 0;
-  memset(reinterpret_cast<uint32_t*>(g_offsets), 0,
-         sizeof(uint32_t) * kBitfieldSize);
-  memset(reinterpret_cast<size_t*>(g_ordered_offsets), 0,
-         sizeof(size_t) * kMaxElements);
-  g_enabled_and_offsets.store(g_offsets);
+  g_data_index = 0;
+  for (int i = 0; i < kPhases; i++) {
+    memset(reinterpret_cast<uint32_t*>(g_data[i].offsets), 0,
+           sizeof(uint32_t) * kBitfieldSize);
+    memset(reinterpret_cast<uint32_t*>(g_data[i].ordered_offsets), 0,
+           sizeof(uint32_t) * kMaxElements);
+    g_data[i].index.store(0);
+  }
 }
 
 void RecordAddressForTesting(size_t address) {
@@ -174,10 +191,9 @@
 
 std::vector<size_t> GetOrderedOffsetsForTesting() {
   std::vector<size_t> result;
-
-  size_t max_index = g_ordered_offsets_index.load(std::memory_order_relaxed);
+  size_t max_index = g_data[0].index.load(std::memory_order_relaxed);
   for (size_t i = 0; i < max_index; ++i) {
-    auto value = g_ordered_offsets[i].load(std::memory_order_relaxed);
+    auto value = g_data[0].ordered_offsets[i].load(std::memory_order_relaxed);
     if (value)
       result.push_back(value);
   }
diff --git a/tools/cygprofile/lightweight_cygprofile.h b/tools/cygprofile/lightweight_cygprofile.h
index 5db222a7..2cabd2a 100644
--- a/tools/cygprofile/lightweight_cygprofile.h
+++ b/tools/cygprofile/lightweight_cygprofile.h
@@ -8,11 +8,8 @@
 #include <cstdint>
 #include <vector>
 
-namespace base {
-class FilePath;
-}
-
 namespace cygprofile {
+constexpr int kPhases = 1;
 constexpr size_t kStartOfTextForTesting = 1000;
 constexpr size_t kEndOfTextForTesting = kStartOfTextForTesting + 1000 * 1000;
 
@@ -22,8 +19,10 @@
 // CHECK()s that the offsets are correctly set up.
 void SanityChecks();
 
-// Stops recording, and dump the results to |path|.
-void StopAndDumpToFile(const base::FilePath& path);
+// Switches to the next recording phase. If called from the last phase, dumps
+// the data to disk, and returns |true|. |pid| is the current process pid, and
+// |start_ns_since_epoch| the process start timestamp.
+bool SwitchToNextPhaseOrDump(int pid, uint64_t start_ns_since_epoch);
 
 // Record an |address|, if recording is enabled. Only for testing.
 void RecordAddressForTesting(size_t address);
diff --git a/tools/cygprofile/process_profiles.py b/tools/cygprofile/process_profiles.py
index 87a0fefd4..22e66ca 100755
--- a/tools/cygprofile/process_profiles.py
+++ b/tools/cygprofile/process_profiles.py
@@ -234,10 +234,11 @@
   reached_symbols = GetReachedSymbolsFromDumpsAndMaybeWriteOffsets(
       sorted_dumps, instrumented_native_lib, args.offsets_output)
   logging.info('Reached Symbols = %d', len(reached_symbols))
-  total_size = sum(s.size for s in reached_symbols)
-  logging.info('Total reached size = %d', total_size)
   matched_in_regular_build = MatchSymbolsInRegularBuild(reached_symbols,
                                                         regular_native_lib)
+  total_size = sum(s.size for s in matched_in_regular_build)
+  logging.info('Total reached size = %d', total_size)
+
   with open(args.output, 'w') as f:
     for s in matched_in_regular_build:
       f.write(s.name + '\n')