diff --git a/DEPS b/DEPS
index af04d62..e0ced88 100644
--- a/DEPS
+++ b/DEPS
@@ -397,7 +397,7 @@
 
     # For Linux and Chromium OS.
     'src/third_party/cros_system_api':
-      Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '4489d28f1ec210c840d4f4827f8210ab27141f2d',
+      Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '0995a6af616cd4ef0e94d278ecc92aa2537b16c3',
 
     # Note that this is different from Android's freetype repo.
     'src/third_party/freetype2/src':
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index c088556a1..01065487 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -974,6 +974,12 @@
       cflags += [ "-Wpartial-availability" ]
     }
 
+    if (is_ios) {
+      # When compiling Objective-C, warns if a selector named via @selector has
+      # not been defined in any visible interface.
+      cflags += [ "-Wundeclared-selector" ]
+    }
+
     # Suppress warnings about ABI changes on ARM (Clang doesn't give this
     # warning).
     if (current_cpu == "arm" && !is_clang) {
diff --git a/chrome/browser/net/resource_prefetch_predictor_observer.cc b/chrome/browser/net/resource_prefetch_predictor_observer.cc
index d1517f1..b8925160a 100644
--- a/chrome/browser/net/resource_prefetch_predictor_observer.cc
+++ b/chrome/browser/net/resource_prefetch_predictor_observer.cc
@@ -70,7 +70,9 @@
     return false;
   *navigation_id =
       predictors::NavigationID(web_contents, main_frame_url, creation_time);
-  return true;
+  // A WebContents might be associated with something that is not a tab.
+  // In this case tab_id will be -1 and is_valid() will return false.
+  return navigation_id->is_valid();
 }
 
 }  // namespace
diff --git a/chrome/browser/password_manager/credential_manager_browsertest.cc b/chrome/browser/password_manager/credential_manager_browsertest.cc
index f7d3a22..d10b3634 100644
--- a/chrome/browser/password_manager/credential_manager_browsertest.cc
+++ b/chrome/browser/password_manager/credential_manager_browsertest.cc
@@ -214,10 +214,9 @@
   // Wait for the password store before checking the prompt because it pops up
   // after the store replies.
   WaitForPasswordStore();
-  std::unique_ptr<BubbleObserver> prompt_observer(
-      new BubbleObserver(WebContents()));
-  EXPECT_FALSE(prompt_observer->IsShowingSavePrompt());
-  EXPECT_FALSE(prompt_observer->IsShowingUpdatePrompt());
+  BubbleObserver prompt_observer(WebContents());
+  EXPECT_FALSE(prompt_observer.IsShowingSavePrompt());
+  EXPECT_FALSE(prompt_observer.IsShowingUpdatePrompt());
 
   // There should be an entry for both psl.example.com and www.example.com.
   password_manager::TestPasswordStore::PasswordMap passwords =
@@ -263,11 +262,10 @@
   observer.SetPathToWaitFor("/password/done.html");
   observer.Wait();
 
-  std::unique_ptr<BubbleObserver> prompt_observer(
-      new BubbleObserver(WebContents()));
+  BubbleObserver prompt_observer(WebContents());
   // The autofill password manager shouldn't react to the successful login
   // because it was suppressed when the site got the credential back.
-  EXPECT_FALSE(prompt_observer->IsShowingSavePrompt());
+  EXPECT_FALSE(prompt_observer.IsShowingSavePrompt());
 }
 
 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, SaveViaAPIAndAutofill) {
@@ -291,10 +289,9 @@
   form_submit_observer.Wait();
 
   WaitForPasswordStore();
-  std::unique_ptr<BubbleObserver> prompt_observer(
-      new BubbleObserver(WebContents()));
-  ASSERT_TRUE(prompt_observer->IsShowingSavePrompt());
-  prompt_observer->AcceptSavePrompt();
+  BubbleObserver prompt_observer(WebContents());
+  ASSERT_TRUE(prompt_observer.IsShowingSavePrompt());
+  prompt_observer.AcceptSavePrompt();
 
   WaitForPasswordStore();
   password_manager::TestPasswordStore::PasswordMap stored =
@@ -350,10 +347,9 @@
   // Wait for the password store before checking the prompt because it pops up
   // after the store replies.
   WaitForPasswordStore();
-  std::unique_ptr<BubbleObserver> prompt_observer(
-      new BubbleObserver(WebContents()));
-  EXPECT_FALSE(prompt_observer->IsShowingSavePrompt());
-  EXPECT_FALSE(prompt_observer->IsShowingUpdatePrompt());
+  BubbleObserver prompt_observer(WebContents());
+  EXPECT_FALSE(prompt_observer.IsShowingSavePrompt());
+  EXPECT_FALSE(prompt_observer.IsShowingUpdatePrompt());
   signin_form.skip_zero_click = false;
   signin_form.times_used = 1;
   signin_form.password_value = base::ASCIIToUTF16("API");
diff --git a/chrome/browser/predictors/resource_prefetch_common.cc b/chrome/browser/predictors/resource_prefetch_common.cc
index d2654aa..174848d 100644
--- a/chrome/browser/predictors/resource_prefetch_common.cc
+++ b/chrome/browser/predictors/resource_prefetch_common.cc
@@ -10,11 +10,10 @@
 #include "base/command_line.h"
 #include "chrome/browser/net/prediction_options.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
 
 namespace predictors {
@@ -76,52 +75,38 @@
   return false;
 }
 
-NavigationID::NavigationID()
-    : render_process_id(-1),
-      render_frame_id(-1) {
-}
+NavigationID::NavigationID() : tab_id(-1) {}
 
 NavigationID::NavigationID(const NavigationID& other)
-    : render_process_id(other.render_process_id),
-      render_frame_id(other.render_frame_id),
+    : tab_id(other.tab_id),
       main_frame_url(other.main_frame_url),
-      creation_time(other.creation_time) {
-}
+      creation_time(other.creation_time) {}
 
 NavigationID::NavigationID(content::WebContents* web_contents)
-    : render_process_id(web_contents->GetRenderProcessHost()->GetID()),
-      render_frame_id(web_contents->GetMainFrame()->GetRoutingID()),
-      main_frame_url(web_contents->GetURL()) {
-}
+    : tab_id(SessionTabHelper::IdForTab(web_contents)),
+      main_frame_url(web_contents->GetLastCommittedURL()),
+      creation_time(base::TimeTicks::Now()) {}
 
 NavigationID::NavigationID(content::WebContents* web_contents,
                            const GURL& main_frame_url,
                            const base::TimeTicks& creation_time)
-    : render_process_id(web_contents->GetRenderProcessHost()->GetID()),
-      render_frame_id(web_contents->GetMainFrame()->GetRoutingID()),
+    : tab_id(SessionTabHelper::IdForTab(web_contents)),
       main_frame_url(main_frame_url),
       creation_time(creation_time) {}
 
 bool NavigationID::is_valid() const {
-  return render_process_id != -1 && render_frame_id != -1 &&
-      !main_frame_url.is_empty();
+  return tab_id != -1 && !main_frame_url.is_empty();
 }
 
 bool NavigationID::operator<(const NavigationID& rhs) const {
   DCHECK(is_valid() && rhs.is_valid());
-  return std::tie(render_process_id, render_frame_id, main_frame_url) <
-    std::tie(rhs.render_process_id, rhs.render_frame_id, rhs.main_frame_url);
+  return std::tie(tab_id, main_frame_url) <
+         std::tie(rhs.tab_id, rhs.main_frame_url);
 }
 
 bool NavigationID::operator==(const NavigationID& rhs) const {
   DCHECK(is_valid() && rhs.is_valid());
-  return IsSameRenderer(rhs) && main_frame_url == rhs.main_frame_url;
-}
-
-bool NavigationID::IsSameRenderer(const NavigationID& other) const {
-  DCHECK(is_valid() && other.is_valid());
-  return render_process_id == other.render_process_id &&
-      render_frame_id == other.render_frame_id;
+  return tab_id == rhs.tab_id && main_frame_url == rhs.main_frame_url;
 }
 
 ResourcePrefetchPredictorConfig::ResourcePrefetchPredictorConfig()
diff --git a/chrome/browser/predictors/resource_prefetch_common.h b/chrome/browser/predictors/resource_prefetch_common.h
index afbd9240..46e9707 100644
--- a/chrome/browser/predictors/resource_prefetch_common.h
+++ b/chrome/browser/predictors/resource_prefetch_common.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include "base/time/time.h"
+#include "components/sessions/core/session_id.h"
 #include "url/gurl.h"
 
 class Profile;
@@ -43,17 +44,14 @@
                const GURL& main_frame_url,
                const base::TimeTicks& creation_time);
   NavigationID(const NavigationID& other);
+
   bool operator<(const NavigationID& rhs) const;
   bool operator==(const NavigationID& rhs) const;
 
-  bool IsSameRenderer(const NavigationID& other) const;
-
-  // Returns true iff the render_process_id_, render_frame_id_ and
-  // frame_url_ has been set correctly.
+  // Returns true iff the tab_id is valid and the Main frame URL is set.
   bool is_valid() const;
 
-  int render_process_id;
-  int render_frame_id;
+  SessionID::id_type tab_id;
   GURL main_frame_url;
 
   // NOTE: Even though we store the creation time here, it is not used during
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc
index 310aee3..f333d10 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
@@ -715,7 +715,7 @@
   base::TimeTicks time_now = base::TimeTicks::Now();
   for (NavigationMap::iterator it = inflight_navigations_.begin();
        it != inflight_navigations_.end();) {
-    if (it->first.IsSameRenderer(navigation_id) ||
+    if ((it->first.tab_id == navigation_id.tab_id) ||
         (time_now - it->first.creation_time > max_navigation_age)) {
       inflight_navigations_.erase(it++);
     } else {
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
index 7b292b3..1994b6501 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <stddef.h>
+
+#include <set>
+
 #include "base/command_line.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
@@ -15,8 +19,8 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/render_process_host.h"
+#include "net/base/host_port_pair.h"
+#include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -26,6 +30,9 @@
 
 namespace {
 
+const char kFooHost[] = "foo.com";
+const char kBarHost[] = "bar.com";
+
 const char kImageMime[] = "image/png";
 const char kStyleMime[] = "text/css";
 const char kJavascriptMime[] = "application/javascript";
@@ -132,8 +139,7 @@
 // Fill a NavigationID with "empty" data that does not trigger
 // the is_valid DCHECK(). Allows comparing.
 void SetValidNavigationID(NavigationID* navigation_id) {
-  navigation_id->render_process_id = 0;
-  navigation_id->render_frame_id = 0;
+  navigation_id->tab_id = 0;
   navigation_id->main_frame_url = GURL("http://127.0.0.1");
 }
 
@@ -192,6 +198,8 @@
     EXPECT_EQ(url_visit_count, url_visit_count_);
     EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url);
     EXPECT_EQ(summary.initial_url, summary_.initial_url);
+    for (const auto& resource : summary.subresource_requests)
+      current_navigation_ids_.insert(resource.navigation_id);
     CompareSubresources(summary.subresource_requests,
                         summary_.subresource_requests, match_navigation_id_);
     run_loop_.Quit();
@@ -199,11 +207,16 @@
 
   void Wait() { run_loop_.Run(); }
 
+  std::set<NavigationID>& current_navigation_ids() {
+    return current_navigation_ids_;
+  }
+
  private:
   base::RunLoop run_loop_;
   size_t url_visit_count_;
   PageRequestSummary summary_;
   bool match_navigation_id_;
+  std::set<NavigationID> current_navigation_ids_;
 
   DISALLOW_COPY_AND_ASSIGN(LearningObserver);
 };
@@ -247,6 +260,9 @@
   }
 
   void SetUpOnMainThread() override {
+    // Resolving all hosts to local allows us to have
+    // cross domains navigations (matching url_visit_count_, etc).
+    host_resolver()->AddRule("*", "127.0.0.1");
     embedded_test_server()->RegisterRequestHandler(
         base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest,
                    base::Unretained(this)));
@@ -284,11 +300,15 @@
       url_request_summaries.push_back(
           GetURLRequestSummaryForResource(endpoint_url, kv.second));
     }
+
+    bool match_navigation_id =
+        disposition == WindowOpenDisposition::CURRENT_TAB;
+
     LearningObserver observer(
         predictor_, UpdateAndGetVisitCount(main_frame_url),
         CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(),
                                  url_request_summaries),
-        true);  // Matching navigation id by default
+        match_navigation_id);
     ui_test_utils::NavigateToURLWithDisposition(
         browser(), main_frame_url, disposition,
         ui_test_utils::BROWSER_TEST_NONE);
@@ -297,6 +317,8 @@
       if (!kv.second.is_no_store && kv.second.should_be_recorded)
         kv.second.request.was_cached = true;
     }
+    for (const auto& nav : observer.current_navigation_ids())
+      navigation_id_history_.insert(nav);
   }
 
   void PrefetchURL(const GURL& main_frame_url) {
@@ -352,6 +374,8 @@
     }
   }
 
+  void ClearResources() { resources_.clear(); }
+
   void ClearCache() {
     BrowsingDataRemover* remover =
         BrowsingDataRemoverFactory::GetForBrowserContext(browser()->profile());
@@ -393,6 +417,10 @@
 
   net::EmbeddedTestServer* https_server() { return https_server_.get(); }
 
+  size_t navigation_ids_history_size() const {
+    return navigation_id_history_.size();
+  }
+
  private:
   // ResourcePrefetchPredictor needs to be initialized before the navigation
   // happens otherwise this navigation will be ignored by predictor.
@@ -416,10 +444,8 @@
     URLRequestSummary summary(resource_summary.request);
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    int process_id = web_contents->GetRenderProcessHost()->GetID();
-    int frame_id = web_contents->GetMainFrame()->GetRoutingID();
     summary.navigation_id =
-        CreateNavigationID(process_id, frame_id, main_frame_url.spec());
+        NavigationID(web_contents, main_frame_url, base::TimeTicks::Now());
     return summary;
   }
 
@@ -436,7 +462,21 @@
 
   std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest(
       const net::test_server::HttpRequest& request) const {
-    auto resource_it = resources_.find(request.GetURL());
+    GURL resource_url = request.GetURL();
+    // Retrieve the host that was used in the request because
+    // resource_url contains a resolved host (e.g. 127.0.0.1).
+    if (request.headers.find("Host") != request.headers.end()) {
+      auto host_port_pair =
+          net::HostPortPair::FromString(request.headers.at("Host"));
+      GURL::Replacements replace_host;
+      replace_host.SetHostStr(host_port_pair.host());
+      resource_url = resource_url.ReplaceComponents(replace_host);
+    } else {
+      ADD_FAILURE() << "Host header was not found in a HttpRequest to url: "
+                    << resource_url.spec();
+    }
+
+    auto resource_it = resources_.find(resource_url);
     if (resource_it == resources_.end())
       return nullptr;
 
@@ -487,6 +527,7 @@
   std::map<GURL, ResourceSummary> resources_;
   std::map<GURL, RedirectEdge> redirects_;
   std::map<GURL, size_t> visit_count_;
+  std::set<NavigationID> navigation_id_history_;
 };
 
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Simple) {
@@ -528,7 +569,7 @@
 }
 
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
-                       LearningAfterHttpToHttpsRedirect) {
+                       HttpToHttpsRedirect) {
   EnableHttpsServer();
   AddRedirectChain(GetURL(kRedirectPath),
                    {{net::HTTP_MOVED_PERMANENTLY,
@@ -541,9 +582,7 @@
               content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
   AddResource(https_server()->GetURL(kFontPath),
               content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST);
-  NavigateToURLAndCheckSubresources(GetURL(kRedirectPath));
-  // TODO(alexilin): Test learning and prefetching once crbug.com/650246 is
-  // fixed.
+  TestLearningAndPrefetching(GetURL(kRedirectPath));
 }
 
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
@@ -619,4 +658,63 @@
   TestLearningAndPrefetching(GetURL(kHtmlIframePath));
 }
 
+IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
+                       CrossSiteNavigation) {
+  AddResource(embedded_test_server()->GetURL(kFooHost, kImagePath),
+              content::RESOURCE_TYPE_IMAGE, net::LOWEST);
+  AddResource(embedded_test_server()->GetURL(kFooHost, kStylePath),
+              content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST);
+  AddResource(embedded_test_server()->GetURL(kFooHost, kScriptPath),
+              content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
+  AddResource(embedded_test_server()->GetURL(kFooHost, kFontPath),
+              content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST);
+  TestLearningAndPrefetching(
+      embedded_test_server()->GetURL(kFooHost, kHtmlSubresourcesPath));
+  ClearResources();
+
+  AddResource(embedded_test_server()->GetURL(kBarHost, kImagePath),
+              content::RESOURCE_TYPE_IMAGE, net::LOWEST);
+  AddResource(embedded_test_server()->GetURL(kBarHost, kStylePath),
+              content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST);
+  AddResource(embedded_test_server()->GetURL(kBarHost, kScriptPath),
+              content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
+  AddResource(embedded_test_server()->GetURL(kBarHost, kFontPath),
+              content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST);
+  // Navigating to kBarHost, although done in the same tab, will generate a new
+  // process.
+  TestLearningAndPrefetching(
+      embedded_test_server()->GetURL(kBarHost, kHtmlSubresourcesPath));
+}
+
+// In this test we are trying to assess if :
+// - Reloading in the same tab is using the same NavigationID.
+// - Navigation into a new tab, window or popup yields different NavigationID's.
+// - Navigating twice to a new browser/popup yields different NavigationID's.
+IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
+                       TabIdBehavingAsExpected) {
+  AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST);
+  AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET,
+              net::HIGHEST);
+  AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
+  AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE,
+              net::HIGHEST);
+  NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath));
+  EXPECT_EQ(navigation_ids_history_size(), 1U);
+  ClearCache();
+  NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath));
+  EXPECT_EQ(navigation_ids_history_size(), 1U);
+  ClearCache();
+  NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath),
+                                    WindowOpenDisposition::NEW_BACKGROUND_TAB);
+  EXPECT_EQ(navigation_ids_history_size(), 2U);
+  ClearCache();
+  NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath),
+                                    WindowOpenDisposition::NEW_WINDOW);
+  EXPECT_EQ(navigation_ids_history_size(), 3U);
+  ClearCache();
+  NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath),
+                                    WindowOpenDisposition::NEW_POPUP);
+  EXPECT_EQ(navigation_ids_history_size(), 4U);
+}
+
 }  // namespace predictors
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc b/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc
index fc73ff3..805d04b 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc
@@ -60,12 +60,10 @@
   return data;
 }
 
-NavigationID CreateNavigationID(int process_id,
-                                int render_frame_id,
+NavigationID CreateNavigationID(SessionID::id_type tab_id,
                                 const std::string& main_frame_url) {
   NavigationID navigation_id;
-  navigation_id.render_process_id = process_id;
-  navigation_id.render_frame_id = render_frame_id;
+  navigation_id.tab_id = tab_id;
   navigation_id.main_frame_url = GURL(main_frame_url);
   navigation_id.creation_time = base::TimeTicks::Now();
   return navigation_id;
@@ -82,8 +80,7 @@
   return summary;
 }
 
-URLRequestSummary CreateURLRequestSummary(int process_id,
-                                          int render_frame_id,
+URLRequestSummary CreateURLRequestSummary(SessionID::id_type tab_id,
                                           const std::string& main_frame_url,
                                           const std::string& resource_url,
                                           content::ResourceType resource_type,
@@ -94,8 +91,7 @@
                                           bool has_validators,
                                           bool always_revalidate) {
   URLRequestSummary summary;
-  summary.navigation_id =
-      CreateNavigationID(process_id, render_frame_id, main_frame_url);
+  summary.navigation_id = CreateNavigationID(tab_id, main_frame_url);
   summary.resource_url =
       resource_url.empty() ? GURL(main_frame_url) : GURL(resource_url);
   summary.resource_type = resource_type;
@@ -158,9 +154,7 @@
 }
 
 std::ostream& operator<<(std::ostream& os, const NavigationID& navigation_id) {
-  return os << navigation_id.render_process_id << ","
-            << navigation_id.render_frame_id << ","
-            << navigation_id.main_frame_url;
+  return os << navigation_id.tab_id << "," << navigation_id.main_frame_url;
 }
 
 bool operator==(const PrefetchData& lhs, const PrefetchData& rhs) {
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_test_util.h b/chrome/browser/predictors/resource_prefetch_predictor_test_util.h
index bd72225..4f12990 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_test_util.h
+++ b/chrome/browser/predictors/resource_prefetch_predictor_test_util.h
@@ -9,6 +9,7 @@
 
 #include "chrome/browser/predictors/resource_prefetch_predictor.h"
 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
+#include "components/sessions/core/session_id.h"
 
 namespace predictors {
 
@@ -34,8 +35,7 @@
 RedirectData CreateRedirectData(const std::string& primary_key,
                                 uint64_t last_visit_time = 0);
 
-NavigationID CreateNavigationID(int process_id,
-                                int render_frame_id,
+NavigationID CreateNavigationID(SessionID::id_type tab_id,
                                 const std::string& main_frame_url);
 
 ResourcePrefetchPredictor::PageRequestSummary CreatePageRequestSummary(
@@ -45,8 +45,7 @@
         subresource_requests);
 
 ResourcePrefetchPredictor::URLRequestSummary CreateURLRequestSummary(
-    int process_id,
-    int render_frame_id,
+    SessionID::id_type tab_id,
     const std::string& main_frame_url,
     const std::string& resource_url = std::string(),
     content::ResourceType resource_type = content::RESOURCE_TYPE_MAIN_FRAME,
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
index 62b0eff..ffadf01 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -18,6 +18,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_types.h"
+#include "components/sessions/core/session_id.h"
 #include "content/public/browser/resource_request_info.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "net/http/http_response_headers.h"
@@ -189,12 +190,11 @@
   }
 
   URLRequestSummary CreateRedirectRequestSummary(
-      int process_id,
-      int render_frame_id,
+      SessionID::id_type session_id,
       const std::string& main_frame_url,
       const std::string& redirect_url) {
     URLRequestSummary summary =
-        CreateURLRequestSummary(process_id, render_frame_id, main_frame_url);
+        CreateURLRequestSummary(session_id, main_frame_url);
     summary.redirect_url = GURL(redirect_url);
     return summary;
   }
@@ -203,16 +203,14 @@
       const GURL& url,
       net::RequestPriority priority,
       content::ResourceType resource_type,
-      int render_process_id,
-      int render_frame_id,
       bool is_main_frame) {
     std::unique_ptr<net::URLRequest> request =
         url_request_context_.CreateRequest(url, priority,
                                            &url_request_delegate_);
     request->set_first_party_for_cookies(url);
     content::ResourceRequestInfo::AllocateForTesting(
-        request.get(), resource_type, nullptr, render_process_id, -1,
-        render_frame_id, is_main_frame, false, false, true, false);
+        request.get(), resource_type, nullptr, -1, -1, -1, is_main_frame, false,
+        false, true, false);
     request->Start();
     return request;
   }
@@ -475,27 +473,27 @@
   AddUrlToHistory("https://www.google.com", kVisitCount);
 
   URLRequestSummary main_frame =
-      CreateURLRequestSummary(1, 1, "http://www.google.com");
+      CreateURLRequestSummary(1, "http://www.google.com");
   predictor_->RecordURLRequest(main_frame);
   EXPECT_EQ(1U, predictor_->inflight_navigations_.size());
 
   URLRequestSummary main_frame_redirect = CreateRedirectRequestSummary(
-      1, 1, "http://www.google.com", "https://www.google.com");
+      1, "http://www.google.com", "https://www.google.com");
   predictor_->RecordURLRedirect(main_frame_redirect);
   EXPECT_EQ(1U, predictor_->inflight_navigations_.size());
-  main_frame = CreateURLRequestSummary(1, 1, "https://www.google.com");
+  main_frame = CreateURLRequestSummary(1, "https://www.google.com");
 
   // Now add a few subresources.
   URLRequestSummary resource1 = CreateURLRequestSummary(
-      1, 1, "https://www.google.com", "https://google.com/style1.css",
+      1, "https://www.google.com", "https://google.com/style1.css",
       content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false);
   predictor_->RecordURLResponse(resource1);
   URLRequestSummary resource2 = CreateURLRequestSummary(
-      1, 1, "https://www.google.com", "https://google.com/script1.js",
+      1, "https://www.google.com", "https://google.com/script1.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
   predictor_->RecordURLResponse(resource2);
   URLRequestSummary resource3 = CreateURLRequestSummary(
-      1, 1, "https://www.google.com", "https://google.com/script2.js",
+      1, "https://www.google.com", "https://google.com/script2.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
   predictor_->RecordURLResponse(resource3);
 
@@ -534,37 +532,37 @@
   AddUrlToHistory("http://www.google.com", kVisitCount);
 
   URLRequestSummary main_frame =
-      CreateURLRequestSummary(1, 1, "http://www.google.com");
+      CreateURLRequestSummary(1, "http://www.google.com");
   predictor_->RecordURLRequest(main_frame);
   EXPECT_EQ(1U, predictor_->inflight_navigations_.size());
 
   std::vector<URLRequestSummary> resources;
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/style1.css",
+      1, "http://www.google.com", "http://google.com/style1.css",
       content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/script1.js",
+      1, "http://www.google.com", "http://google.com/script1.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/script2.js",
+      1, "http://www.google.com", "http://google.com/script2.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/script1.js",
+      1, "http://www.google.com", "http://google.com/script1.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/image1.png",
+      1, "http://www.google.com", "http://google.com/image1.png",
       content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/image2.png",
+      1, "http://www.google.com", "http://google.com/image2.png",
       content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/style2.css",
+      1, "http://www.google.com", "http://google.com/style2.css",
       content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true));
   predictor_->RecordURLResponse(resources.back());
 
@@ -624,38 +622,38 @@
   EXPECT_EQ(2U, predictor_->host_table_cache_->size());
 
   URLRequestSummary main_frame = CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://www.google.com",
+      1, "http://www.google.com", "http://www.google.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
   predictor_->RecordURLRequest(main_frame);
   EXPECT_EQ(1U, predictor_->inflight_navigations_.size());
 
   std::vector<URLRequestSummary> resources;
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/style1.css",
+      1, "http://www.google.com", "http://google.com/style1.css",
       content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/script1.js",
+      1, "http://www.google.com", "http://google.com/script1.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/script2.js",
+      1, "http://www.google.com", "http://google.com/script2.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/script1.js",
+      1, "http://www.google.com", "http://google.com/script1.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/image1.png",
+      1, "http://www.google.com", "http://google.com/image1.png",
       content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/image2.png",
+      1, "http://www.google.com", "http://google.com/image2.png",
       content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false));
   predictor_->RecordURLResponse(resources.back());
   resources.push_back(CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/style2.css",
+      1, "http://www.google.com", "http://google.com/style2.css",
       content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true));
   predictor_->RecordURLResponse(resources.back());
 
@@ -729,17 +727,17 @@
   EXPECT_EQ(2U, predictor_->host_table_cache_->size());
 
   URLRequestSummary main_frame = CreateURLRequestSummary(
-      1, 1, "http://www.nike.com", "http://www.nike.com",
+      1, "http://www.nike.com", "http://www.nike.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
   predictor_->RecordURLRequest(main_frame);
   EXPECT_EQ(1U, predictor_->inflight_navigations_.size());
 
   URLRequestSummary resource1 = CreateURLRequestSummary(
-      1, 1, "http://www.nike.com", "http://nike.com/style1.css",
+      1, "http://www.nike.com", "http://nike.com/style1.css",
       content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false);
   predictor_->RecordURLResponse(resource1);
   URLRequestSummary resource2 = CreateURLRequestSummary(
-      1, 1, "http://www.nike.com", "http://nike.com/image2.png",
+      1, "http://www.nike.com", "http://nike.com/image2.png",
       content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false);
   predictor_->RecordURLResponse(resource2);
 
@@ -783,17 +781,17 @@
   const int kVisitCount = 4;
   AddUrlToHistory("https://facebook.com/google", kVisitCount);
 
-  URLRequestSummary fb1 = CreateURLRequestSummary(1, 1, "http://fb.com/google");
+  URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google");
   predictor_->RecordURLRequest(fb1);
   EXPECT_EQ(1U, predictor_->inflight_navigations_.size());
 
   URLRequestSummary fb2 = CreateRedirectRequestSummary(
-      1, 1, "http://fb.com/google", "http://facebook.com/google");
+      1, "http://fb.com/google", "http://facebook.com/google");
   predictor_->RecordURLRedirect(fb2);
   URLRequestSummary fb3 = CreateRedirectRequestSummary(
-      1, 1, "http://facebook.com/google", "https://facebook.com/google");
+      1, "http://facebook.com/google", "https://facebook.com/google");
   predictor_->RecordURLRedirect(fb3);
-  NavigationID fb_end = CreateNavigationID(1, 1, "https://facebook.com/google");
+  NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google");
 
   StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(
       predictor_.get());
@@ -848,17 +846,17 @@
   EXPECT_EQ(3U, predictor_->url_redirect_table_cache_->size());
   EXPECT_EQ(2U, predictor_->host_redirect_table_cache_->size());
 
-  URLRequestSummary fb1 = CreateURLRequestSummary(1, 1, "http://fb.com/google");
+  URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google");
   predictor_->RecordURLRequest(fb1);
   EXPECT_EQ(1U, predictor_->inflight_navigations_.size());
 
   URLRequestSummary fb2 = CreateRedirectRequestSummary(
-      1, 1, "http://fb.com/google", "http://facebook.com/google");
+      1, "http://fb.com/google", "http://facebook.com/google");
   predictor_->RecordURLRedirect(fb2);
   URLRequestSummary fb3 = CreateRedirectRequestSummary(
-      1, 1, "http://facebook.com/google", "https://facebook.com/google");
+      1, "http://facebook.com/google", "https://facebook.com/google");
   predictor_->RecordURLRedirect(fb3);
-  NavigationID fb_end = CreateNavigationID(1, 1, "https://facebook.com/google");
+  NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google");
 
   StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(
       predictor_.get());
@@ -982,13 +980,13 @@
 
 TEST_F(ResourcePrefetchPredictorTest, OnMainFrameRequest) {
   URLRequestSummary summary1 = CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://www.google.com",
+      1, "http://www.google.com", "http://www.google.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
   URLRequestSummary summary2 = CreateURLRequestSummary(
-      1, 2, "http://www.google.com", "http://www.google.com",
+      2, "http://www.google.com", "http://www.google.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
   URLRequestSummary summary3 = CreateURLRequestSummary(
-      2, 1, "http://www.yahoo.com", "http://www.yahoo.com",
+      3, "http://www.yahoo.com", "http://www.yahoo.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
 
   predictor_->OnMainFrameRequest(summary1);
@@ -1000,10 +998,10 @@
 
   // Insert another with same navigation id. It should replace.
   URLRequestSummary summary4 = CreateURLRequestSummary(
-      1, 1, "http://www.nike.com", "http://www.nike.com",
+      1, "http://www.nike.com", "http://www.nike.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
   URLRequestSummary summary5 = CreateURLRequestSummary(
-      1, 2, "http://www.google.com", "http://www.google.com",
+      2, "http://www.google.com", "http://www.google.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
 
   predictor_->OnMainFrameRequest(summary4);
@@ -1016,7 +1014,7 @@
   EXPECT_EQ(3U, predictor_->inflight_navigations_.size());
 
   URLRequestSummary summary6 = CreateURLRequestSummary(
-      3, 1, "http://www.shoes.com", "http://www.shoes.com",
+      4, "http://www.shoes.com", "http://www.shoes.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
   predictor_->OnMainFrameRequest(summary6);
   EXPECT_EQ(3U, predictor_->inflight_navigations_.size());
@@ -1030,36 +1028,35 @@
 }
 
 TEST_F(ResourcePrefetchPredictorTest, OnMainFrameRedirect) {
-  URLRequestSummary yahoo = CreateURLRequestSummary(1, 1, "http://yahoo.com");
+  URLRequestSummary yahoo = CreateURLRequestSummary(1, "http://yahoo.com");
 
-  URLRequestSummary bbc1 = CreateURLRequestSummary(2, 2, "http://bbc.com");
-  URLRequestSummary bbc2 = CreateRedirectRequestSummary(2, 2, "http://bbc.com",
-                                                        "https://www.bbc.com");
-  NavigationID bbc_end = CreateNavigationID(2, 2, "https://www.bbc.com");
+  URLRequestSummary bbc1 = CreateURLRequestSummary(2, "http://bbc.com");
+  URLRequestSummary bbc2 =
+      CreateRedirectRequestSummary(2, "http://bbc.com", "https://www.bbc.com");
+  NavigationID bbc_end = CreateNavigationID(2, "https://www.bbc.com");
 
-  URLRequestSummary youtube1 =
-      CreateURLRequestSummary(1, 2, "http://youtube.com");
+  URLRequestSummary youtube1 = CreateURLRequestSummary(3, "http://youtube.com");
   URLRequestSummary youtube2 = CreateRedirectRequestSummary(
-      1, 2, "http://youtube.com", "https://youtube.com");
-  NavigationID youtube_end = CreateNavigationID(1, 2, "https://youtube.com");
+      3, "http://youtube.com", "https://youtube.com");
+  NavigationID youtube_end = CreateNavigationID(3, "https://youtube.com");
 
-  URLRequestSummary nyt1 = CreateURLRequestSummary(2, 1, "http://nyt.com");
-  URLRequestSummary nyt2 = CreateRedirectRequestSummary(2, 1, "http://nyt.com",
-                                                        "http://nytimes.com");
-  URLRequestSummary nyt3 = CreateRedirectRequestSummary(
-      2, 1, "http://nytimes.com", "http://m.nytimes.com");
-  NavigationID nyt_end = CreateNavigationID(2, 1, "http://m.nytimes.com");
+  URLRequestSummary nyt1 = CreateURLRequestSummary(4, "http://nyt.com");
+  URLRequestSummary nyt2 =
+      CreateRedirectRequestSummary(4, "http://nyt.com", "http://nytimes.com");
+  URLRequestSummary nyt3 = CreateRedirectRequestSummary(4, "http://nytimes.com",
+                                                        "http://m.nytimes.com");
+  NavigationID nyt_end = CreateNavigationID(4, "http://m.nytimes.com");
 
-  URLRequestSummary fb1 = CreateURLRequestSummary(1, 3, "http://fb.com");
-  URLRequestSummary fb2 = CreateRedirectRequestSummary(1, 3, "http://fb.com",
-                                                       "http://facebook.com");
-  URLRequestSummary fb3 = CreateRedirectRequestSummary(
-      1, 3, "http://facebook.com", "https://facebook.com");
+  URLRequestSummary fb1 = CreateURLRequestSummary(5, "http://fb.com");
+  URLRequestSummary fb2 =
+      CreateRedirectRequestSummary(5, "http://fb.com", "http://facebook.com");
+  URLRequestSummary fb3 = CreateRedirectRequestSummary(5, "http://facebook.com",
+                                                       "https://facebook.com");
   URLRequestSummary fb4 = CreateRedirectRequestSummary(
-      1, 3, "https://facebook.com",
+      5, "https://facebook.com",
       "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr");
   NavigationID fb_end = CreateNavigationID(
-      1, 3,
+      5,
       "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr");
 
   // Redirect with empty redirect_url will be deleted.
@@ -1107,24 +1104,24 @@
 TEST_F(ResourcePrefetchPredictorTest, OnSubresourceResponse) {
   // If there is no inflight navigation, nothing happens.
   URLRequestSummary resource1 = CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/style1.css",
+      1, "http://www.google.com", "http://google.com/style1.css",
       content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false);
   predictor_->OnSubresourceResponse(resource1);
   EXPECT_TRUE(predictor_->inflight_navigations_.empty());
 
   // Add an inflight navigation.
   URLRequestSummary main_frame1 = CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://www.google.com",
+      1, "http://www.google.com", "http://www.google.com",
       content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
   predictor_->OnMainFrameRequest(main_frame1);
   EXPECT_EQ(1U, predictor_->inflight_navigations_.size());
 
   // Now add a few subresources.
   URLRequestSummary resource2 = CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/script1.js",
+      1, "http://www.google.com", "http://google.com/script1.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
   URLRequestSummary resource3 = CreateURLRequestSummary(
-      1, 1, "http://www.google.com", "http://google.com/script2.js",
+      1, "http://www.google.com", "http://google.com/script2.js",
       content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
   predictor_->OnSubresourceResponse(resource1);
   predictor_->OnSubresourceResponse(resource2);
@@ -1174,19 +1171,19 @@
 TEST_F(ResourcePrefetchPredictorTest, ShouldRecordRequestMainFrame) {
   std::unique_ptr<net::URLRequest> http_request =
       CreateURLRequest(GURL("http://www.google.com"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, true);
+                       content::RESOURCE_TYPE_IMAGE, true);
   EXPECT_TRUE(ResourcePrefetchPredictor::ShouldRecordRequest(
       http_request.get(), content::RESOURCE_TYPE_MAIN_FRAME));
 
   std::unique_ptr<net::URLRequest> https_request =
       CreateURLRequest(GURL("https://www.google.com"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, true);
+                       content::RESOURCE_TYPE_IMAGE, true);
   EXPECT_TRUE(ResourcePrefetchPredictor::ShouldRecordRequest(
       https_request.get(), content::RESOURCE_TYPE_MAIN_FRAME));
 
   std::unique_ptr<net::URLRequest> file_request =
       CreateURLRequest(GURL("file://www.google.com"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, true);
+                       content::RESOURCE_TYPE_IMAGE, true);
   EXPECT_FALSE(ResourcePrefetchPredictor::ShouldRecordRequest(
       file_request.get(), content::RESOURCE_TYPE_MAIN_FRAME));
 }
@@ -1194,19 +1191,19 @@
 TEST_F(ResourcePrefetchPredictorTest, ShouldRecordRequestSubResource) {
   std::unique_ptr<net::URLRequest> http_request =
       CreateURLRequest(GURL("http://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, false);
+                       content::RESOURCE_TYPE_IMAGE, false);
   EXPECT_FALSE(ResourcePrefetchPredictor::ShouldRecordRequest(
       http_request.get(), content::RESOURCE_TYPE_IMAGE));
 
   std::unique_ptr<net::URLRequest> https_request =
       CreateURLRequest(GURL("https://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, false);
+                       content::RESOURCE_TYPE_IMAGE, false);
   EXPECT_FALSE(ResourcePrefetchPredictor::ShouldRecordRequest(
       https_request.get(), content::RESOURCE_TYPE_IMAGE));
 
   std::unique_ptr<net::URLRequest> file_request =
       CreateURLRequest(GURL("file://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, false);
+                       content::RESOURCE_TYPE_IMAGE, false);
   EXPECT_FALSE(ResourcePrefetchPredictor::ShouldRecordRequest(
       file_request.get(), content::RESOURCE_TYPE_IMAGE));
 }
@@ -1218,19 +1215,19 @@
 
   std::unique_ptr<net::URLRequest> http_request =
       CreateURLRequest(GURL("http://www.google.com"), net::MEDIUM,
-                       content::RESOURCE_TYPE_MAIN_FRAME, 1, 1, true);
+                       content::RESOURCE_TYPE_MAIN_FRAME, true);
   EXPECT_TRUE(
       ResourcePrefetchPredictor::ShouldRecordResponse(http_request.get()));
 
   std::unique_ptr<net::URLRequest> https_request =
       CreateURLRequest(GURL("https://www.google.com"), net::MEDIUM,
-                       content::RESOURCE_TYPE_MAIN_FRAME, 1, 1, true);
+                       content::RESOURCE_TYPE_MAIN_FRAME, true);
   EXPECT_TRUE(
       ResourcePrefetchPredictor::ShouldRecordResponse(https_request.get()));
 
   std::unique_ptr<net::URLRequest> file_request =
       CreateURLRequest(GURL("file://www.google.com"), net::MEDIUM,
-                       content::RESOURCE_TYPE_MAIN_FRAME, 1, 1, true);
+                       content::RESOURCE_TYPE_MAIN_FRAME, true);
   EXPECT_FALSE(
       ResourcePrefetchPredictor::ShouldRecordResponse(file_request.get()));
 }
@@ -1245,32 +1242,32 @@
   // Protocol.
   std::unique_ptr<net::URLRequest> http_image_request =
       CreateURLRequest(GURL("http://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, true);
+                       content::RESOURCE_TYPE_IMAGE, true);
   EXPECT_TRUE(ResourcePrefetchPredictor::ShouldRecordResponse(
       http_image_request.get()));
 
   std::unique_ptr<net::URLRequest> https_image_request =
       CreateURLRequest(GURL("https://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, true);
+                       content::RESOURCE_TYPE_IMAGE, true);
   EXPECT_TRUE(ResourcePrefetchPredictor::ShouldRecordResponse(
       https_image_request.get()));
 
   std::unique_ptr<net::URLRequest> file_image_request =
       CreateURLRequest(GURL("file://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_IMAGE, 1, 1, true);
+                       content::RESOURCE_TYPE_IMAGE, true);
   EXPECT_FALSE(ResourcePrefetchPredictor::ShouldRecordResponse(
       file_image_request.get()));
 
   // ResourceType.
   std::unique_ptr<net::URLRequest> sub_frame_request =
       CreateURLRequest(GURL("http://www.google.com/frame.html"), net::MEDIUM,
-                       content::RESOURCE_TYPE_SUB_FRAME, 1, 1, true);
+                       content::RESOURCE_TYPE_SUB_FRAME, true);
   EXPECT_FALSE(
       ResourcePrefetchPredictor::ShouldRecordResponse(sub_frame_request.get()));
 
-  std::unique_ptr<net::URLRequest> font_request = CreateURLRequest(
-      GURL("http://www.google.com/comic-sans-ms.woff"), net::MEDIUM,
-      content::RESOURCE_TYPE_FONT_RESOURCE, 1, 1, true);
+  std::unique_ptr<net::URLRequest> font_request =
+      CreateURLRequest(GURL("http://www.google.com/comic-sans-ms.woff"),
+                       net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, true);
   EXPECT_TRUE(
       ResourcePrefetchPredictor::ShouldRecordResponse(font_request.get()));
 
@@ -1278,36 +1275,35 @@
   url_request_job_factory_.set_mime_type("image/png");
   std::unique_ptr<net::URLRequest> prefetch_image_request =
       CreateURLRequest(GURL("http://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_PREFETCH, 1, 1, true);
+                       content::RESOURCE_TYPE_PREFETCH, true);
   EXPECT_TRUE(ResourcePrefetchPredictor::ShouldRecordResponse(
       prefetch_image_request.get()));
 
   url_request_job_factory_.set_mime_type("image/my-wonderful-format");
   std::unique_ptr<net::URLRequest> prefetch_unknown_image_request =
       CreateURLRequest(GURL("http://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_PREFETCH, 1, 1, true);
+                       content::RESOURCE_TYPE_PREFETCH, true);
   EXPECT_FALSE(ResourcePrefetchPredictor::ShouldRecordResponse(
       prefetch_unknown_image_request.get()));
 
   url_request_job_factory_.set_mime_type("font/woff");
-  std::unique_ptr<net::URLRequest> prefetch_font_request = CreateURLRequest(
-      GURL("http://www.google.com/comic-sans-ms.woff"), net::MEDIUM,
-      content::RESOURCE_TYPE_PREFETCH, 1, 1, true);
+  std::unique_ptr<net::URLRequest> prefetch_font_request =
+      CreateURLRequest(GURL("http://www.google.com/comic-sans-ms.woff"),
+                       net::MEDIUM, content::RESOURCE_TYPE_PREFETCH, true);
   EXPECT_TRUE(ResourcePrefetchPredictor::ShouldRecordResponse(
       prefetch_font_request.get()));
 
   url_request_job_factory_.set_mime_type("font/woff-woff");
   std::unique_ptr<net::URLRequest> prefetch_unknown_font_request =
       CreateURLRequest(GURL("http://www.google.com/comic-sans-ms.woff"),
-                       net::MEDIUM, content::RESOURCE_TYPE_PREFETCH, 1, 1,
-                       true);
+                       net::MEDIUM, content::RESOURCE_TYPE_PREFETCH, true);
   EXPECT_FALSE(ResourcePrefetchPredictor::ShouldRecordResponse(
       prefetch_unknown_font_request.get()));
 
   // Not main frame.
   std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest(
       GURL("http://www.google.com/comic-sans-ms.woff"), net::MEDIUM,
-      content::RESOURCE_TYPE_FONT_RESOURCE, 1, 1, false);
+      content::RESOURCE_TYPE_FONT_RESOURCE, false);
   EXPECT_FALSE(ResourcePrefetchPredictor::ShouldRecordResponse(
       font_request_sub_frame.get()));
 }
@@ -1320,8 +1316,8 @@
   url_request_job_factory_.set_response_info(response_info);
 
   GURL url("http://www.google.com/cat.png");
-  std::unique_ptr<net::URLRequest> request = CreateURLRequest(
-      url, net::MEDIUM, content::RESOURCE_TYPE_IMAGE, 1, 1, true);
+  std::unique_ptr<net::URLRequest> request =
+      CreateURLRequest(url, net::MEDIUM, content::RESOURCE_TYPE_IMAGE, true);
   URLRequestSummary summary;
   EXPECT_TRUE(URLRequestSummary::SummarizeResponse(*request, &summary));
   EXPECT_EQ(url, summary.resource_url);
@@ -1331,8 +1327,7 @@
   EXPECT_FALSE(summary.always_revalidate);
 
   // Navigation_id elements should be unset by default.
-  EXPECT_EQ(-1, summary.navigation_id.render_process_id);
-  EXPECT_EQ(-1, summary.navigation_id.render_frame_id);
+  EXPECT_EQ(-1, summary.navigation_id.tab_id);
   EXPECT_EQ(GURL(), summary.navigation_id.main_frame_url);
 }
 
@@ -1347,7 +1342,7 @@
 
   std::unique_ptr<net::URLRequest> request =
       CreateURLRequest(GURL("http://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_PREFETCH, 1, 1, true);
+                       content::RESOURCE_TYPE_PREFETCH, true);
   URLRequestSummary summary;
   EXPECT_TRUE(URLRequestSummary::SummarizeResponse(*request, &summary));
   EXPECT_EQ(content::RESOURCE_TYPE_IMAGE, summary.resource_type);
@@ -1362,7 +1357,7 @@
 
   std::unique_ptr<net::URLRequest> request_no_validators =
       CreateURLRequest(GURL("http://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_PREFETCH, 1, 1, true);
+                       content::RESOURCE_TYPE_PREFETCH, true);
 
   URLRequestSummary summary;
   EXPECT_TRUE(
@@ -1376,7 +1371,7 @@
   url_request_job_factory_.set_response_info(response_info);
   std::unique_ptr<net::URLRequest> request_etag =
       CreateURLRequest(GURL("http://www.google.com/cat.png"), net::MEDIUM,
-                       content::RESOURCE_TYPE_PREFETCH, 1, 1, true);
+                       content::RESOURCE_TYPE_PREFETCH, true);
   EXPECT_TRUE(URLRequestSummary::SummarizeResponse(*request_etag, &summary));
   EXPECT_TRUE(summary.has_validators);
   EXPECT_TRUE(summary.always_revalidate);
diff --git a/chrome/browser/predictors/resource_prefetcher_unittest.cc b/chrome/browser/predictors/resource_prefetcher_unittest.cc
index 2cc5711c..80631b9 100644
--- a/chrome/browser/predictors/resource_prefetcher_unittest.cc
+++ b/chrome/browser/predictors/resource_prefetcher_unittest.cc
@@ -165,7 +165,7 @@
                             GURL("http://yahoo.com/resource4.png"),
                             GURL("http://yahoo.com/resource5.png")};
 
-  NavigationID navigation_id = CreateNavigationID(1, 2, main_frame_url.spec());
+  NavigationID navigation_id = CreateNavigationID(1, main_frame_url.spec());
 
   prefetcher_.reset(new TestResourcePrefetcher(&prefetcher_delegate_, config_,
                                                main_frame_url, urls));
@@ -237,7 +237,7 @@
                             GURL("http://yahoo.com/resource3.png"),
                             GURL("http://m.google.com/resource1.jpg")};
 
-  NavigationID navigation_id = CreateNavigationID(1, 2, main_frame_url.spec());
+  NavigationID navigation_id = CreateNavigationID(1, main_frame_url.spec());
 
   prefetcher_.reset(new TestResourcePrefetcher(&prefetcher_delegate_, config_,
                                                main_frame_url, urls));
diff --git a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java
index 7ff1ee0..7df0402 100644
--- a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java
+++ b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java
@@ -12,7 +12,6 @@
 import android.test.MoreAsserts;
 
 import org.chromium.base.annotations.SuppressFBWarnings;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 
 import java.io.File;
@@ -402,7 +401,6 @@
      */
     @SmallTest
     @Feature({"Android-AppBase"})
-    @DisabledTest(message = "crbug.com/676429")
     public void testMinidumpStorageRestrictionsGlobal() throws IOException {
         testMinidumpStorageRestrictions(false /* perUid */);
     }
@@ -441,17 +439,10 @@
         int minidumpLimit = perUid ? CrashFileManager.MAX_CRASH_REPORTS_TO_UPLOAD_PER_UID
                                    : CrashFileManager.MAX_CRASH_REPORTS_TO_UPLOAD;
         for (int n = 0; n < minidumpLimit; n++) {
-            ParcelFileDescriptor minidumpFd =
-                    ParcelFileDescriptor.open(minidumpToCopy, ParcelFileDescriptor.MODE_READ_ONLY);
-            try {
-                // If we are testing the app-throttling we want to use the same uid for each
-                // minidump, otherwise use a different one for each minidump.
-                int currentUid = perUid ? 1 : n;
-                assertNotNull(fileManager.copyMinidumpFromFD(
-                        minidumpFd.getFileDescriptor(), tmpCopyDir, currentUid));
-            } finally {
-                minidumpFd.close();
-            }
+            // If we are testing the app-throttling we want to use the same uid for each
+            // minidump, otherwise use a different one for each minidump.
+            createFdForandCopyFile(fileManager, minidumpToCopy, tmpCopyDir,
+                    perUid ? 1 : n /* uid */, true /* shouldSucceed */);
         }
 
         // Update time-stamps of copied files.
@@ -471,15 +462,37 @@
 
         // Now the crash directory is full - so copying a new minidump should cause the oldest
         // existing minidump to be deleted.
-        ParcelFileDescriptor minidumpFd =
-                ParcelFileDescriptor.open(minidumpToCopy, ParcelFileDescriptor.MODE_READ_ONLY);
-        fileManager.copyMinidumpFromFD(minidumpFd.getFileDescriptor(), tmpCopyDir, 1 /* uid */);
-        assertEquals(minidumpLimit, fileManager.getAllMinidumpFiles(10000 /* maxTries */).length);
+        createFdForandCopyFile(fileManager, minidumpToCopy, tmpCopyDir, 1 /* uid */,
+                true /* shouldSucceed */);
+        assertEquals(minidumpLimit,
+                fileManager.getAllMinidumpFiles(10000 /* maxTries */).length);
         // Ensure we removed the oldest file.
         assertFalse(oldestMinidump.exists());
     }
 
     /**
+     * Utility method that creates (and closes) a file descriptor to {@param minidumpToCopy} and
+     * calls CrashFileManager.copyMinidumpFromFD.
+     */
+    private static void createFdForandCopyFile(CrashFileManager fileManager, File minidumpToCopy,
+            File tmpCopyDir, int uid, boolean shouldSucceed) throws IOException {
+        ParcelFileDescriptor minidumpFd = null;
+        try {
+            minidumpFd =
+                    ParcelFileDescriptor.open(minidumpToCopy, ParcelFileDescriptor.MODE_READ_ONLY);
+            File copiedFile =
+                    fileManager.copyMinidumpFromFD(minidumpFd.getFileDescriptor(), tmpCopyDir, uid);
+            if (shouldSucceed) {
+                assertNotNull(copiedFile);
+            } else {
+                assertNull(copiedFile);
+            }
+        } finally {
+            if (minidumpFd != null) minidumpFd.close();
+        }
+    }
+
+    /**
      * Returns the oldest file in the set of files {@param files}.
      */
     private static File getOldestFile(File[] files) {
@@ -523,10 +536,8 @@
         } finally {
             minidumpOutputStream.close();
         }
-        ParcelFileDescriptor minidumpFd =
-                ParcelFileDescriptor.open(minidumpToCopy, ParcelFileDescriptor.MODE_READ_ONLY);
-        assertNull(fileManager.copyMinidumpFromFD(
-                minidumpFd.getFileDescriptor(), tmpCopyDir, 0 /* uid */));
+        createFdForandCopyFile(fileManager, minidumpToCopy, tmpCopyDir, 0 /* uid */,
+                false /* shouldSucceed */);
         assertEquals(0, tmpCopyDir.listFiles().length);
         assertEquals(0, fileManager.getAllMinidumpFiles(10000 /* maxTries */).length);
     }
diff --git a/headless/README.md b/headless/README.md
index 9e98dae..bf4d301 100644
--- a/headless/README.md
+++ b/headless/README.md
@@ -1,17 +1,37 @@
 # Headless Chromium
 
-Headless Chromium is a library for running Chromium in a headless/server
-environment. Expected use cases include loading web pages, extracting metadata
-(e.g., the DOM) and generating bitmaps from page contents -- using all the
-modern web platform features provided by Chromium and Blink.
+Headless Chromium allows running Chromium in a headless/server environment.
+Expected use cases include loading web pages, extracting metadata (e.g., the
+DOM) and generating bitmaps from page contents -- using all the modern web
+platform features provided by Chromium and Blink.
 
-See the [architecture design doc](https://docs.google.com/document/d/11zIkKkLBocofGgoTeeyibB2TZ_k7nR78v7kNelCatUE)
-for more information.
+There are two ways to use Headless Chromium:
 
-## Headless shell
+## Usage via the DevTools remote debugging protocol
 
-The headless shell is a sample application which demonstrates the use of the
-headless API. To run it, first initialize a headless build configuration:
+1. Start a normal Chrome binary with the `--headless` command line flag
+(Linux-only for now):
+
+```
+$ chrome --headless --remote-debugging-port=9222 https://chromium.org
+```
+
+Currently you'll also need to use `--disable-gpu` to avoid an error from a
+missing Mesa library.
+
+2. Navigate to `http://localhost:9222` in another browser to open the
+[DevTools](https://developer.chrome.com/devtools) interface or use a tool such
+as [Selenium](http://www.seleniumhq.org/) to drive the headless browser.
+
+## Usage as a C++ library
+
+Headless Chromium can be built as a library for embedding into a C++
+application. This approach is otherwise similar to controlling the browser over
+a DevTools connection, but it provides more customization points, e.g., for
+networking and [mojo services](https://docs.google.com/document/d/1Fr6_DJH6OK9rG3-ibMvRPTNnHsAXPk0VzxxiuJDSK3M/edit#heading=h.qh0udvlk963d).
+
+Headless Shell is a sample application which demonstrates the use of the
+headless C++ API. To run it, first initialize a headless build configuration:
 
 ```
 $ mkdir -p out/Debug
@@ -25,8 +45,7 @@
 $ ninja -C out/Debug headless_shell
 ```
 
-After the build completes, the headless shell can be run with the following
-command:
+After the build completes, Headless Shell can be run with the following command:
 
 ```
 $ out/Debug/headless_shell https://www.google.com
@@ -39,7 +58,7 @@
 $ out/Debug/headless_shell --remote-debugging-port=9222 https://youtube.com
 ```
 
-Then navigate to `http://127.0.0.1:9222` with your browser.
+Then navigate to `http://localhost:9222` with your browser.
 
 ## Embedder API
 
@@ -67,7 +86,10 @@
   See the [client API documentation](https://docs.google.com/document/d/1rlqcp8nk-ZQvldNJWdbaMbwfDbJoOXvahPCDoPGOwhQ/edit#)
   for more information.
 
-## Documentation
+## Resources and Documentation
+
+Mailing list: [headless-dev@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/headless-dev)
+Bug tracker: [Proj=Headless](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=Proj%3DHeadless)
 
 * [Runtime headless mode for Chrome](https://docs.google.com/document/d/1aIJUzQr3eougZQp90bp4mqGr5gY6hdUice8UPa-Ys90/edit#)
 * [Virtual Time in Blink](https://docs.google.com/document/d/1y9kdt_zezt7pbey6uzvt1dgklwc1ob_vy4nzo1zbqmo/edit#heading=h.tn3gd1y9ifml)
@@ -78,3 +100,4 @@
 * [Controlling BeginFrame through DevTools](https://docs.google.com/document/d/1LVMYDkfjrrX9PNkrD8pJH5-Np_XUTQHIuJ8IEOirQH4/edit?ts=57d96dbd#heading=h.ndv831lc9uf0)
 * [Viewport bounds and scale for screenshots](https://docs.google.com/document/d/1VTcYz4q_x0f1O5IVrvRX4u1DVd_K34IVUl1VULLTCWw/edit#heading=h.ndv831lc9uf0)
 * [BlinkOn 6 presentation slides](https://docs.google.com/presentation/d/1gqK9F4lGAY3TZudAtdcxzMQNEE7PcuQrGu83No3l0lw/edit#slide=id.p)
+* [Architecture design doc](https://docs.google.com/document/d/11zIkKkLBocofGgoTeeyibB2TZ_k7nR78v7kNelCatUE)
diff --git a/ios/chrome/app/application_delegate/metrics_mediator_testing.h b/ios/chrome/app/application_delegate/metrics_mediator_testing.h
index 81791a6..1e470ef 100644
--- a/ios/chrome/app/application_delegate/metrics_mediator_testing.h
+++ b/ios/chrome/app/application_delegate/metrics_mediator_testing.h
@@ -13,6 +13,8 @@
 - (void)setBreakpadUploadingEnabled:(BOOL)enableUploading;
 - (void)setReporting:(BOOL)enableReporting;
 - (BOOL)isMetricsReportingEnabledWifiOnly;
++ (void)recordNumTabAtStartup:(int)numTabs;
++ (void)recordNumTabAtResume:(int)numTabs;
 @end
 
 #endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_METRICS_MEDIATOR_TESTING_H_
diff --git a/ios/chrome/app/safe_mode/safe_mode_egtest.mm b/ios/chrome/app/safe_mode/safe_mode_egtest.mm
index 88925df..5962693 100644
--- a/ios/chrome/app/safe_mode/safe_mode_egtest.mm
+++ b/ios/chrome/app/safe_mode/safe_mode_egtest.mm
@@ -55,6 +55,13 @@
 
 }  // namespace
 
+// Expose internal class methods for swizzling.
+@interface SafeModeViewController (Testing)
++ (BOOL)detectedThirdPartyMods;
++ (BOOL)hasReportToUpload;
+- (NSArray*)startupCrashModules;
+@end
+
 // Tests the display of Safe Mode Controller under different error states of
 // jailbroken-ness and whether a crash dump was saved.
 @interface SafeModeTestCase : ChromeTestCase
diff --git a/ios/chrome/browser/memory/memory_debugger.mm b/ios/chrome/browser/memory/memory_debugger.mm
index da304df0..6d41fbe5 100644
--- a/ios/chrome/browser/memory/memory_debugger.mm
+++ b/ios/chrome/browser/memory/memory_debugger.mm
@@ -119,10 +119,13 @@
 // TODO(lliabraa): Figure out how to support memory warnings (or something
 // like them) in official builds.
 #if CHROMIUM_BUILD
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
   [self addButtonWithTitle:@"Trigger Memory Warning"
                     target:[UIApplication sharedApplication]
                     action:@selector(_performMemoryWarning)
                 withOrigin:[self originForSubviewAtIndex:index++]];
+#pragma clang diagnostic pop
 #endif  // CHROMIUM_BUILD
 
   // Display a text input to set the amount of artificial memory bloat and a
@@ -504,12 +507,15 @@
   }
   // If a valid value was found have the timer start triggering continuous
   // memory warnings.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
   _memoryWarningTimer.reset(
       [[NSTimer scheduledTimerWithTimeInterval:timerValue
                                         target:[UIApplication sharedApplication]
                                       selector:@selector(_performMemoryWarning)
                                       userInfo:nil
                                        repeats:YES] retain]);
+#pragma clang diagnostic push
 }
 #endif  // CHROMIUM_BUILD
 
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
index f5b33efe..1e33eb0 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
+++ b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
@@ -199,8 +199,11 @@
   void TriggerMemoryWarning() {
     // _performMemoryWarning is a private API and must not be compiled into
     // official builds.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
     [[UIApplication sharedApplication]
         performSelector:@selector(_performMemoryWarning)];
+#pragma clang diagnostic pop
   }
 
   web::TestWebThreadBundle thread_bundle_;
diff --git a/ios/chrome/browser/sync/sync_observer_bridge.mm b/ios/chrome/browser/sync/sync_observer_bridge.mm
index 52cb5040..ec4f248 100644
--- a/ios/chrome/browser/sync/sync_observer_bridge.mm
+++ b/ios/chrome/browser/sync/sync_observer_bridge.mm
@@ -27,6 +27,6 @@
 }
 
 void SyncObserverBridge::OnSyncConfigurationCompleted() {
-  if ([delegate_ respondsToSelector:@selector(onSyncConfigurationCompleted:)])
+  if ([delegate_ respondsToSelector:@selector(onSyncConfigurationCompleted)])
     [delegate_ onSyncConfigurationCompleted];
 }
diff --git a/ios/chrome/browser/ui/find_bar/find_bar_view.mm b/ios/chrome/browser/ui/find_bar/find_bar_view.mm
index 443c7e39..62099301 100644
--- a/ios/chrome/browser/ui/find_bar/find_bar_view.mm
+++ b/ios/chrome/browser/ui/find_bar/find_bar_view.mm
@@ -6,6 +6,7 @@
 
 #include "base/mac/scoped_nsobject.h"
 #include "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #import "ios/chrome/browser/ui/commands/ios_command_ids.h"
 #import "ios/chrome/browser/ui/find_bar/find_bar_touch_forwarding_view.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/omnibox/location_bar_view_ios.mm b/ios/chrome/browser/ui/omnibox/location_bar_view_ios.mm
index e57613e..123669e 100644
--- a/ios/chrome/browser/ui/omnibox/location_bar_view_ios.mm
+++ b/ios/chrome/browser/ui/omnibox/location_bar_view_ios.mm
@@ -14,6 +14,7 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/chrome/browser/experimental_flags.h"
+#include "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
 #include "ios/chrome/browser/ui/omnibox/location_bar_view_ios.h"
 #import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h"
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
index a386973..d6cfabf 100644
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
@@ -90,7 +90,7 @@
         [PasswordDetailsCollectionViewController simplifyOrigin:origin];
     NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
     [defaultCenter addObserver:self
-                      selector:@selector(hidePassword:)
+                      selector:@selector(hidePassword)
                           name:UIApplicationDidEnterBackgroundNotification
                         object:nil];
 
diff --git a/ios/chrome/browser/ui/toolbar/new_tab_button.mm b/ios/chrome/browser/ui/toolbar/new_tab_button.mm
index 29994c28..bde38a0e 100644
--- a/ios/chrome/browser/ui/toolbar/new_tab_button.mm
+++ b/ios/chrome/browser/ui/toolbar/new_tab_button.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/ui/toolbar/new_tab_button.h"
 
 #include "base/logging.h"
+#import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
 #import "ios/chrome/browser/ui/image_util.h"
 #import "ios/chrome/browser/ui/rtl_geometry.h"
diff --git a/ios/web/test/wk_web_view_crash_utils.mm b/ios/web/test/wk_web_view_crash_utils.mm
index 4657d62..a8bf8c6 100644
--- a/ios/web/test/wk_web_view_crash_utils.mm
+++ b/ios/web/test/wk_web_view_crash_utils.mm
@@ -39,7 +39,10 @@
   if ([webView.navigationDelegate respondsToSelector:selector]) {
     [webView.navigationDelegate performSelector:selector withObject:webView];
   }
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
   [webView performSelector:@selector(_processDidExit)];
+#pragma clang diagnostic pop
 }
 
 WKWebView* BuildTerminatedWKWebView() {
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index f2e9226..3debdc7 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -3968,9 +3968,11 @@
   if (!_placeholderOverlayView || _overlayPreviewMode)
     return;
 
-  [NSObject cancelPreviousPerformRequestsWithTarget:self
-                                           selector:@selector(removeOverlay)
-                                             object:nil];
+  [NSObject
+      cancelPreviousPerformRequestsWithTarget:self
+                                     selector:@selector(
+                                                  removePlaceholderOverlay)
+                                       object:nil];
   // Remove overlay with transition.
   [UIView animateWithDuration:kSnapshotOverlayTransition
       animations:^{
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter
index 6f36796..e16994cb 100644
--- a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter
+++ b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter
@@ -11,10 +11,6 @@
 -PageLoadMetricsBrowserTest.Ignore204Pages
 -PageLoadMetricsBrowserTest.IgnoreDownloads
 
-# https://crbug.com/650246: ResourcePrefetchPredictor doesn't work correctly yet
-# with PlzNavigate
--ResourcePrefetchPredictorBrowserTest.*
-
 # https://crbug.com/668714: Allow setting net/ flags for NavigationHandle
 -NoStatePrefetchBrowserTest.PrefetchLoadFlag
 -NoStatePrefetchBrowserTest.Prefetch301LoadFlags
diff --git a/third_party/WebKit/Source/core/svg/BUILD.gn b/third_party/WebKit/Source/core/svg/BUILD.gn
index 8cebdb2..64ac7d1 100644
--- a/third_party/WebKit/Source/core/svg/BUILD.gn
+++ b/third_party/WebKit/Source/core/svg/BUILD.gn
@@ -43,8 +43,6 @@
     "SVGAnimatedPath.cpp",
     "SVGAnimatedString.cpp",
     "SVGAnimatedString.h",
-    "SVGAnimatedTypeAnimator.cpp",
-    "SVGAnimatedTypeAnimator.h",
     "SVGAnimationElement.cpp",
     "SVGAnimationElement.h",
     "SVGBoolean.cpp",
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp b/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
index 67e710b..ee425ba 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
@@ -27,6 +27,12 @@
 #include "core/dom/Document.h"
 #include "core/dom/QualifiedName.h"
 #include "core/dom/StyleChangeReason.h"
+#include "core/svg/SVGAnimatedColor.h"
+#include "core/svg/SVGLength.h"
+#include "core/svg/SVGLengthList.h"
+#include "core/svg/SVGNumber.h"
+#include "core/svg/SVGString.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
 #include "core/svg/properties/SVGProperty.h"
 
 namespace blink {
@@ -68,7 +74,8 @@
 SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName,
                                      Document& document)
     : SVGAnimationElement(tagName, document),
-      m_animator(this),
+      m_type(AnimatedUnknown),
+      m_cssPropertyId(CSSPropertyInvalid),
       m_fromPropertyValueType(RegularPropertyValue),
       m_toPropertyValueType(RegularPropertyValue),
       m_attributeType(AttributeTypeAuto),
@@ -120,12 +127,40 @@
   SVGAnimationElement::svgAttributeChanged(attrName);
 }
 
+void SVGAnimateElement::resolveTargetProperty() {
+  DCHECK(targetElement());
+  m_targetProperty = targetElement()->propertyFromAttribute(attributeName());
+  if (m_targetProperty) {
+    m_type = m_targetProperty->type();
+    m_cssPropertyId = m_targetProperty->cssPropertyId();
+
+    // Only <animateTransform> is allowed to animate AnimatedTransformList.
+    // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
+    if (m_type == AnimatedTransformList) {
+      m_type = AnimatedUnknown;
+      m_cssPropertyId = CSSPropertyInvalid;
+    }
+  } else {
+    m_type = SVGElement::animatedPropertyTypeForCSSAttribute(attributeName());
+    m_cssPropertyId = m_type != AnimatedUnknown
+                          ? cssPropertyID(attributeName().localName())
+                          : CSSPropertyInvalid;
+  }
+  DCHECK(m_type != AnimatedPoint && m_type != AnimatedStringList &&
+         m_type != AnimatedTransform && m_type != AnimatedTransformList);
+}
+
+void SVGAnimateElement::clearTargetProperty() {
+  m_targetProperty = nullptr;
+  m_type = AnimatedUnknown;
+  m_cssPropertyId = CSSPropertyInvalid;
+}
+
 AnimatedPropertyType SVGAnimateElement::animatedPropertyType() {
   if (!targetElement())
     return AnimatedUnknown;
-
-  m_animator.reset(*targetElement());
-  return m_animator.type();
+  resolveTargetProperty();
+  return m_type;
 }
 
 bool SVGAnimateElement::hasValidTarget() {
@@ -160,6 +195,81 @@
   return getAttributeType() != AttributeTypeCSS;
 }
 
+SVGPropertyBase* SVGAnimateElement::createPropertyForAttributeAnimation(
+    const String& value) const {
+  // SVG DOM animVal animation code-path.
+  // TransformList must be animated via <animateTransform>, and its
+  // {from,by,to} attribute values needs to be parsed w.r.t. its "type"
+  // attribute. Spec:
+  // http://www.w3.org/TR/SVG/single-page.html#animate-AnimateTransformElement
+  DCHECK_NE(m_type, AnimatedTransformList);
+  DCHECK(m_targetProperty);
+  return m_targetProperty->currentValueBase()->cloneForAnimation(value);
+}
+
+SVGPropertyBase* SVGAnimateElement::createPropertyForCSSAnimation(
+    const String& value) const {
+  // CSS properties animation code-path.
+  // Create a basic instance of the corresponding SVG property.
+  // The instance will not have full context info. (e.g. SVGLengthMode)
+  switch (m_type) {
+    case AnimatedColor:
+      return SVGColorProperty::create(value);
+    case AnimatedNumber: {
+      SVGNumber* property = SVGNumber::create();
+      property->setValueAsString(value);
+      return property;
+    }
+    case AnimatedLength: {
+      SVGLength* property = SVGLength::create();
+      property->setValueAsString(value);
+      return property;
+    }
+    case AnimatedLengthList: {
+      SVGLengthList* property = SVGLengthList::create();
+      property->setValueAsString(value);
+      return property;
+    }
+    case AnimatedString: {
+      SVGString* property = SVGString::create();
+      property->setValueAsString(value);
+      return property;
+    }
+    // These types don't appear in the table in
+    // SVGElement::animatedPropertyTypeForCSSAttribute() and thus don't need
+    // support.
+    case AnimatedAngle:
+    case AnimatedBoolean:
+    case AnimatedEnumeration:
+    case AnimatedInteger:
+    case AnimatedIntegerOptionalInteger:
+    case AnimatedNumberList:
+    case AnimatedNumberOptionalNumber:
+    case AnimatedPath:
+    case AnimatedPoint:
+    case AnimatedPoints:
+    case AnimatedPreserveAspectRatio:
+    case AnimatedRect:
+    case AnimatedStringList:
+    case AnimatedTransform:
+    case AnimatedTransformList:
+    case AnimatedUnknown:
+      break;
+    default:
+      break;
+  }
+  NOTREACHED();
+  return nullptr;
+}
+
+SVGPropertyBase* SVGAnimateElement::createPropertyForAnimation(
+    const String& value) const {
+  if (isAnimatingSVGDom())
+    return createPropertyForAttributeAnimation(value);
+  DCHECK(isAnimatingCSSProperty());
+  return createPropertyForCSSAnimation(value);
+}
+
 SVGPropertyBase* SVGAnimateElement::adjustForInheritance(
     SVGPropertyBase* propertyValue,
     AnimatedPropertyValueType valueType) const {
@@ -174,8 +284,8 @@
     return propertyValue;
   SVGElement* svgParent = toSVGElement(parent);
   // Replace 'inherit' by its computed property value.
-  String value = computeCSSPropertyValue(svgParent, m_animator.cssProperty());
-  return m_animator.createPropertyForAnimation(value);
+  String value = computeCSSPropertyValue(svgParent, m_cssPropertyId);
+  return createPropertyForAnimation(value);
 }
 
 void SVGAnimateElement::calculateAnimatedValue(float percentage,
@@ -186,19 +296,17 @@
   if (!isSVGAnimateElement(*resultElement))
     return;
 
-  ASSERT(percentage >= 0 && percentage <= 1);
-  ASSERT(animatedPropertyType() != AnimatedTransformList ||
-         isSVGAnimateTransformElement(*this));
-  ASSERT(animatedPropertyType() != AnimatedUnknown);
-  ASSERT(m_fromProperty);
-  ASSERT(m_fromProperty->type() == animatedPropertyType());
-  ASSERT(m_toProperty);
+  DCHECK(percentage >= 0 && percentage <= 1);
+  DCHECK_NE(animatedPropertyType(), AnimatedUnknown);
+  DCHECK(m_fromProperty);
+  DCHECK_EQ(m_fromProperty->type(), animatedPropertyType());
+  DCHECK(m_toProperty);
 
   SVGAnimateElement* resultAnimationElement =
       toSVGAnimateElement(resultElement);
-  ASSERT(resultAnimationElement->m_animatedProperty);
-  ASSERT(resultAnimationElement->animatedPropertyType() ==
-         animatedPropertyType());
+  DCHECK(resultAnimationElement->m_animatedValue);
+  DCHECK_EQ(resultAnimationElement->animatedPropertyType(),
+            animatedPropertyType());
 
   if (isSVGSetElement(*this))
     percentage = 1;
@@ -211,7 +319,7 @@
 
   // Values-animation accumulates using the last values entry corresponding to
   // the end of duration time.
-  SVGPropertyBase* animatedValue = resultAnimationElement->m_animatedProperty;
+  SVGPropertyBase* animatedValue = resultAnimationElement->m_animatedValue;
   SVGPropertyBase* toAtEndOfDurationValue =
       m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty : m_toProperty;
   SVGPropertyBase* fromValue =
@@ -232,16 +340,16 @@
   if (toAtEndOfDurationString.isEmpty())
     return false;
   m_toAtEndOfDurationProperty =
-      m_animator.createPropertyForAnimation(toAtEndOfDurationString);
+      createPropertyForAnimation(toAtEndOfDurationString);
   return true;
 }
 
 bool SVGAnimateElement::calculateFromAndToValues(const String& fromString,
                                                  const String& toString) {
   DCHECK(targetElement());
-  m_fromProperty = m_animator.createPropertyForAnimation(fromString);
+  m_fromProperty = createPropertyForAnimation(fromString);
   m_fromPropertyValueType = propertyValueType(attributeName(), fromString);
-  m_toProperty = m_animator.createPropertyForAnimation(toString);
+  m_toProperty = createPropertyForAnimation(toString);
   m_toPropertyValueType = propertyValueType(attributeName(), toString);
   return true;
 }
@@ -261,41 +369,41 @@
 
   DCHECK(!isSVGSetElement(*this));
 
-  m_fromProperty = m_animator.createPropertyForAnimation(fromString);
+  m_fromProperty = createPropertyForAnimation(fromString);
   m_fromPropertyValueType = propertyValueType(attributeName(), fromString);
-  m_toProperty = m_animator.createPropertyForAnimation(byString);
+  m_toProperty = createPropertyForAnimation(byString);
   m_toPropertyValueType = propertyValueType(attributeName(), byString);
   m_toProperty->add(m_fromProperty, targetElement());
   return true;
 }
 
 void SVGAnimateElement::resetAnimatedType() {
+  resolveTargetProperty();
+
   SVGElement* targetElement = this->targetElement();
   const QualifiedName& attributeName = this->attributeName();
 
-  m_animator.reset(*targetElement);
-
   if (!shouldApplyAnimation(*targetElement, attributeName))
     return;
-  if (m_animator.isAnimatingSVGDom()) {
+  if (isAnimatingSVGDom()) {
     // SVG DOM animVal animation code-path.
-    m_animatedProperty = m_animator.createAnimatedValue();
-    targetElement->setAnimatedAttribute(attributeName, m_animatedProperty);
+    m_animatedValue = m_targetProperty->createAnimatedValue();
+    DCHECK_EQ(m_animatedValue->type(), m_type);
+    targetElement->setAnimatedAttribute(attributeName, m_animatedValue);
     return;
   }
-  DCHECK(m_animator.isAnimatingCSSProperty());
+  DCHECK(isAnimatingCSSProperty());
   // Presentation attributes which has an SVG DOM representation should use the
   // "SVG DOM" code-path (above.)
   DCHECK(SVGElement::isAnimatableCSSProperty(attributeName));
 
   // CSS properties animation code-path.
-  String baseValue =
-      computeCSSPropertyValue(targetElement, m_animator.cssProperty());
-  m_animatedProperty = m_animator.createPropertyForAnimation(baseValue);
+  String baseValue = computeCSSPropertyValue(targetElement, m_cssPropertyId);
+  m_animatedValue = createPropertyForAnimation(baseValue);
 }
 
 void SVGAnimateElement::clearAnimatedType() {
-  if (!m_animatedProperty)
+  if (!m_animatedValue)
     return;
 
   // The animated property lock is held for the "result animation" (see
@@ -306,42 +414,40 @@
 
   SVGElement* targetElement = this->targetElement();
   if (!targetElement) {
-    m_animatedProperty.clear();
+    m_animatedValue.clear();
     return;
   }
 
   bool shouldApply = shouldApplyAnimation(*targetElement, attributeName());
-  if (m_animator.isAnimatingCSSProperty()) {
+  if (isAnimatingCSSProperty()) {
     // CSS properties animation code-path.
     if (shouldApply) {
       MutableStylePropertySet* propertySet =
           targetElement->ensureAnimatedSMILStyleProperties();
-      if (propertySet->removeProperty(m_animator.cssProperty())) {
+      if (propertySet->removeProperty(m_cssPropertyId)) {
         targetElement->setNeedsStyleRecalc(
             LocalStyleChange,
             StyleChangeReasonForTracing::create(StyleChangeReason::Animation));
       }
     }
   }
-  if (m_animator.isAnimatingSVGDom()) {
+  if (isAnimatingSVGDom()) {
     // SVG DOM animVal animation code-path.
     targetElement->clearAnimatedAttribute(attributeName());
     if (shouldApply)
       targetElement->invalidateAnimatedAttribute(attributeName());
   }
 
-  m_animatedProperty.clear();
-  m_animator.clear();
+  m_animatedValue.clear();
+  clearTargetProperty();
 }
 
 void SVGAnimateElement::applyResultsToTarget() {
-  ASSERT(animatedPropertyType() != AnimatedTransformList ||
-         isSVGAnimateTransformElement(*this));
-  ASSERT(animatedPropertyType() != AnimatedUnknown);
+  DCHECK_NE(animatedPropertyType(), AnimatedUnknown);
 
   // Early exit if our animated type got destructed by a previous
   // endedActiveInterval().
-  if (!m_animatedProperty)
+  if (!m_animatedValue)
     return;
 
   if (!shouldApplyAnimation(*targetElement(), attributeName()))
@@ -349,22 +455,22 @@
 
   // We do update the style and the animation property independent of each
   // other.
-  if (m_animator.isAnimatingCSSProperty()) {
+  if (isAnimatingCSSProperty()) {
     // CSS properties animation code-path.
     // Convert the result of the animation to a String and apply it as CSS
     // property on the target.
     MutableStylePropertySet* propertySet =
         targetElement()->ensureAnimatedSMILStyleProperties();
     if (propertySet
-            ->setProperty(m_animator.cssProperty(),
-                          m_animatedProperty->valueAsString(), false, 0)
+            ->setProperty(m_cssPropertyId, m_animatedValue->valueAsString(),
+                          false, 0)
             .didChange) {
       targetElement()->setNeedsStyleRecalc(
           LocalStyleChange,
           StyleChangeReasonForTracing::create(StyleChangeReason::Animation));
     }
   }
-  if (m_animator.isAnimatingSVGDom()) {
+  if (isAnimatingSVGDom()) {
     // SVG DOM animVal animation code-path.
     // At this point the SVG DOM values are already changed, unlike for CSS.
     // We only have to trigger update notifications here.
@@ -401,9 +507,8 @@
   DCHECK(targetElement());
   // FIXME: A return value of float is not enough to support paced animations on
   // lists.
-  SVGPropertyBase* fromValue =
-      m_animator.createPropertyForAnimation(fromString);
-  SVGPropertyBase* toValue = m_animator.createPropertyForAnimation(toString);
+  SVGPropertyBase* fromValue = createPropertyForAnimation(fromString);
+  SVGPropertyBase* toValue = createPropertyForAnimation(toString);
   return fromValue->calculateDistance(toValue, targetElement());
 }
 
@@ -451,19 +556,19 @@
 }
 
 void SVGAnimateElement::resetAnimatedPropertyType() {
-  ASSERT(!m_animatedProperty);
+  DCHECK(!m_animatedValue);
   m_fromProperty.clear();
   m_toProperty.clear();
   m_toAtEndOfDurationProperty.clear();
-  m_animator.clear();
+  clearTargetProperty();
 }
 
 DEFINE_TRACE(SVGAnimateElement) {
   visitor->trace(m_fromProperty);
   visitor->trace(m_toProperty);
   visitor->trace(m_toAtEndOfDurationProperty);
-  visitor->trace(m_animatedProperty);
-  visitor->trace(m_animator);
+  visitor->trace(m_animatedValue);
+  visitor->trace(m_targetProperty);
   SVGAnimationElement::trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimateElement.h b/third_party/WebKit/Source/core/svg/SVGAnimateElement.h
index 2325e52..87c38eab9 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimateElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGAnimateElement.h
@@ -23,9 +23,9 @@
 #ifndef SVGAnimateElement_h
 #define SVGAnimateElement_h
 
+#include "core/CSSPropertyNames.h"
 #include "core/CoreExport.h"
 #include "core/SVGNames.h"
-#include "core/svg/SVGAnimatedTypeAnimator.h"
 #include "core/svg/SVGAnimationElement.h"
 #include "platform/heap/Handle.h"
 #include <base/gtest_prod_util.h>
@@ -101,16 +101,32 @@
   bool hasValidAttributeName() const;
   virtual bool hasValidAttributeType();
 
+  virtual void resolveTargetProperty();
+  void clearTargetProperty();
+
+  virtual SVGPropertyBase* createPropertyForAnimation(const String&) const;
+  SVGPropertyBase* createPropertyForAttributeAnimation(const String&) const;
+  SVGPropertyBase* createPropertyForCSSAnimation(const String&) const;
+
   SVGPropertyBase* adjustForInheritance(SVGPropertyBase*,
                                         AnimatedPropertyValueType) const;
 
   Member<SVGPropertyBase> m_fromProperty;
   Member<SVGPropertyBase> m_toProperty;
   Member<SVGPropertyBase> m_toAtEndOfDurationProperty;
-  Member<SVGPropertyBase> m_animatedProperty;
+  Member<SVGPropertyBase> m_animatedValue;
 
-  SVGAnimatedTypeAnimator m_animator;
+ protected:
+  Member<SVGAnimatedPropertyBase> m_targetProperty;
+  AnimatedPropertyType m_type;
+  CSSPropertyID m_cssPropertyId;
 
+  bool isAnimatingSVGDom() const { return m_targetProperty; }
+  bool isAnimatingCSSProperty() const {
+    return m_cssPropertyId != CSSPropertyInvalid;
+  }
+
+ private:
   AnimatedPropertyValueType m_fromPropertyValueType;
   AnimatedPropertyValueType m_toPropertyValueType;
   AttributeType m_attributeType;
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp b/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp
index 07a673b7..7707935 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp
@@ -24,13 +24,14 @@
 
 #include "core/SVGNames.h"
 #include "core/svg/SVGTransformList.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
 
 namespace blink {
 
 inline SVGAnimateTransformElement::SVGAnimateTransformElement(
     Document& document)
     : SVGAnimateElement(SVGNames::animateTransformTag, document),
-      m_type(kSvgTransformUnknown) {}
+      m_transformType(kSvgTransformUnknown) {}
 
 DEFINE_NODE_FACTORY(SVGAnimateTransformElement)
 
@@ -45,13 +46,35 @@
   return animatedPropertyType() == AnimatedTransformList;
 }
 
+void SVGAnimateTransformElement::resolveTargetProperty() {
+  DCHECK(targetElement());
+  m_targetProperty = targetElement()->propertyFromAttribute(attributeName());
+  m_type = m_targetProperty ? m_targetProperty->type() : AnimatedUnknown;
+  // <animateTransform> only animates AnimatedTransformList.
+  // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
+  if (m_type != AnimatedTransformList)
+    m_type = AnimatedUnknown;
+  // Because of the syntactic mismatch between the CSS and SVGProperty
+  // representations, disallow CSS animations of transforms. Support for that
+  // is better added to the <animate> element since the <animateTransform>
+  // element is deprecated and quirky. (We also reject this case via
+  // hasValidAttributeType above.)
+  m_cssPropertyId = CSSPropertyInvalid;
+}
+
+SVGPropertyBase* SVGAnimateTransformElement::createPropertyForAnimation(
+    const String& value) const {
+  DCHECK(isAnimatingSVGDom());
+  return SVGTransformList::create(m_transformType, value);
+}
+
 void SVGAnimateTransformElement::parseAttribute(const QualifiedName& name,
                                                 const AtomicString& oldValue,
                                                 const AtomicString& value) {
   if (name == SVGNames::typeAttr) {
-    m_type = parseTransformType(value);
-    if (m_type == kSvgTransformMatrix)
-      m_type = kSvgTransformUnknown;
+    m_transformType = parseTransformType(value);
+    if (m_transformType == kSvgTransformMatrix)
+      m_transformType = kSvgTransformUnknown;
     return;
   }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h b/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h
index ad3bd3c..094b43a4 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h
@@ -34,8 +34,6 @@
  public:
   DECLARE_NODE_FACTORY(SVGAnimateTransformElement);
 
-  SVGTransformType transformType() const { return m_type; }
-
  private:
   explicit SVGAnimateTransformElement(Document&);
 
@@ -45,7 +43,10 @@
                       const AtomicString&,
                       const AtomicString&) override;
 
-  SVGTransformType m_type;
+  void resolveTargetProperty() override;
+  SVGPropertyBase* createPropertyForAnimation(const String&) const override;
+
+  SVGTransformType m_transformType;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp b/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp
deleted file mode 100644
index f31c0741..0000000
--- a/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011-2012. All rights reserved.
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-
-#include "core/svg/SVGAnimateTransformElement.h"
-#include "core/svg/SVGAnimatedColor.h"
-#include "core/svg/SVGAnimationElement.h"
-#include "core/svg/SVGLength.h"
-#include "core/svg/SVGLengthList.h"
-#include "core/svg/SVGNumber.h"
-#include "core/svg/SVGString.h"
-#include "core/svg/SVGTransformList.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-
-namespace blink {
-
-SVGAnimatedTypeAnimator::SVGAnimatedTypeAnimator(
-    SVGAnimationElement* animationElement)
-    : m_animationElement(animationElement),
-      m_type(AnimatedUnknown),
-      m_cssProperty(CSSPropertyInvalid) {
-  DCHECK(m_animationElement);
-}
-
-void SVGAnimatedTypeAnimator::clear() {
-  m_animatedProperty = nullptr;
-  m_type = AnimatedUnknown;
-  m_cssProperty = CSSPropertyInvalid;
-}
-
-void SVGAnimatedTypeAnimator::reset(const SVGElement& contextElement) {
-  const QualifiedName& attributeName = m_animationElement->attributeName();
-  m_animatedProperty = contextElement.propertyFromAttribute(attributeName);
-  if (m_animatedProperty) {
-    m_type = m_animatedProperty->type();
-    m_cssProperty = m_animatedProperty->cssPropertyId();
-
-    if (m_type == AnimatedTransformList) {
-      // Only <animateTransform> is allowed to animate AnimatedTransformList.
-      // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
-      if (!isSVGAnimateTransformElement(*m_animationElement))
-        m_type = AnimatedUnknown;
-      // Because of the syntactic mismatch between the CSS and SVGProperty
-      // representations, disallow CSS animations of transform list for
-      // now. (We also reject this case via
-      // SVGAnimateTransformElement::hasValidAttributeType ATM.)
-      m_cssProperty = CSSPropertyInvalid;
-    }
-  } else {
-    m_type = SVGElement::animatedPropertyTypeForCSSAttribute(attributeName);
-    m_cssProperty = m_type != AnimatedUnknown
-                        ? cssPropertyID(attributeName.localName())
-                        : CSSPropertyInvalid;
-    DCHECK_NE(m_type, AnimatedTransformList);
-  }
-
-  DCHECK(m_type != AnimatedPoint && m_type != AnimatedStringList &&
-         m_type != AnimatedTransform);
-}
-
-SVGPropertyBase* SVGAnimatedTypeAnimator::createPropertyForAttributeAnimation(
-    const String& value) const {
-  // SVG DOM animVal animation code-path.
-  if (m_type == AnimatedTransformList) {
-    // TransformList must be animated via <animateTransform>, and its
-    // {from,by,to} attribute values needs to be parsed w.r.t. its "type"
-    // attribute.  Spec:
-    // http://www.w3.org/TR/SVG/single-page.html#animate-AnimateTransformElement
-    DCHECK(m_animationElement);
-    SVGTransformType transformType =
-        toSVGAnimateTransformElement(m_animationElement)->transformType();
-    return SVGTransformList::create(transformType, value);
-  }
-  DCHECK(m_animatedProperty);
-  return m_animatedProperty->currentValueBase()->cloneForAnimation(value);
-}
-
-SVGPropertyBase* SVGAnimatedTypeAnimator::createPropertyForCSSAnimation(
-    const String& value) const {
-  // CSS properties animation code-path.
-  // Create a basic instance of the corresponding SVG property.
-  // The instance will not have full context info. (e.g. SVGLengthMode)
-  switch (m_type) {
-    case AnimatedColor:
-      return SVGColorProperty::create(value);
-    case AnimatedNumber: {
-      SVGNumber* property = SVGNumber::create();
-      property->setValueAsString(value);
-      return property;
-    }
-    case AnimatedLength: {
-      SVGLength* property = SVGLength::create();
-      property->setValueAsString(value);
-      return property;
-    }
-    case AnimatedLengthList: {
-      SVGLengthList* property = SVGLengthList::create();
-      property->setValueAsString(value);
-      return property;
-    }
-    case AnimatedString: {
-      SVGString* property = SVGString::create();
-      property->setValueAsString(value);
-      return property;
-    }
-    // These types don't appear in the table in
-    // SVGElement::animatedPropertyTypeForCSSAttribute() and thus don't need
-    // support.
-    case AnimatedAngle:
-    case AnimatedBoolean:
-    case AnimatedEnumeration:
-    case AnimatedInteger:
-    case AnimatedIntegerOptionalInteger:
-    case AnimatedNumberList:
-    case AnimatedNumberOptionalNumber:
-    case AnimatedPath:
-    case AnimatedPoint:
-    case AnimatedPoints:
-    case AnimatedPreserveAspectRatio:
-    case AnimatedRect:
-    case AnimatedStringList:
-    case AnimatedTransform:
-    case AnimatedTransformList:
-    case AnimatedUnknown:
-      break;
-    default:
-      break;
-  }
-  NOTREACHED();
-  return nullptr;
-}
-
-SVGPropertyBase* SVGAnimatedTypeAnimator::createPropertyForAnimation(
-    const String& value) const {
-  if (isAnimatingSVGDom())
-    return createPropertyForAttributeAnimation(value);
-  DCHECK(isAnimatingCSSProperty());
-  return createPropertyForCSSAnimation(value);
-}
-
-SVGPropertyBase* SVGAnimatedTypeAnimator::createAnimatedValue() const {
-  DCHECK(isAnimatingSVGDom());
-  SVGPropertyBase* animatedValue = m_animatedProperty->createAnimatedValue();
-  DCHECK_EQ(animatedValue->type(), m_type);
-  return animatedValue;
-}
-
-DEFINE_TRACE(SVGAnimatedTypeAnimator) {
-  visitor->trace(m_animationElement);
-  visitor->trace(m_animatedProperty);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.h b/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.h
deleted file mode 100644
index 2bea1a7..0000000
--- a/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011-2012. All rights reserved.
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedTypeAnimator_h
-#define SVGAnimatedTypeAnimator_h
-
-#include "core/CSSPropertyNames.h"
-#include "core/svg/properties/SVGPropertyInfo.h"
-#include "platform/heap/Handle.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-
-class SVGAnimatedPropertyBase;
-class SVGPropertyBase;
-class SVGElement;
-class SVGAnimationElement;
-
-class SVGAnimatedTypeAnimator final {
-  DISALLOW_NEW();
-
- public:
-  SVGAnimatedTypeAnimator(SVGAnimationElement*);
-
-  void clear();
-  void reset(const SVGElement&);
-
-  SVGPropertyBase* createAnimatedValue() const;
-  SVGPropertyBase* createPropertyForAnimation(const String&) const;
-
-  AnimatedPropertyType type() const { return m_type; }
-  CSSPropertyID cssProperty() const { return m_cssProperty; }
-
-  bool isAnimatingSVGDom() const { return m_animatedProperty; }
-  bool isAnimatingCSSProperty() const {
-    return m_cssProperty != CSSPropertyInvalid;
-  }
-
-  DECLARE_TRACE();
-
- private:
-  SVGPropertyBase* createPropertyForAttributeAnimation(const String&) const;
-  SVGPropertyBase* createPropertyForCSSAnimation(const String&) const;
-
-  Member<SVGAnimationElement> m_animationElement;
-  Member<SVGAnimatedPropertyBase> m_animatedProperty;
-  AnimatedPropertyType m_type;
-  CSSPropertyID m_cssProperty;
-};
-
-}  // namespace blink
-
-#endif  // SVGAnimatedTypeAnimator_h
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp b/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
index cb2e4aa..10150ac 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
@@ -467,12 +467,8 @@
   CalcMode calcMode = this->getCalcMode();
   if (isSVGAnimateElement(*this)) {
     SVGAnimateElement& animateElement = toSVGAnimateElement(*this);
-    if (!animateElement.animatedPropertyTypeSupportsAddition()) {
-      ASSERT(animateElement.animatedPropertyType() != AnimatedTransformList ||
-             isSVGAnimateTransformElement(*this));
-      ASSERT(animateElement.animatedPropertyType() != AnimatedUnknown);
+    if (!animateElement.animatedPropertyTypeSupportsAddition())
       calcMode = CalcModeDiscrete;
-    }
   }
   if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced)
     return currentValuesFromKeyPoints(percent, effectivePercent, from, to);
diff --git a/third_party/WebKit/Source/platform/heap/GarbageCollected.h b/third_party/WebKit/Source/platform/heap/GarbageCollected.h
index 58c9313c..79a37b3 100644
--- a/third_party/WebKit/Source/platform/heap/GarbageCollected.h
+++ b/third_party/WebKit/Source/platform/heap/GarbageCollected.h
@@ -242,8 +242,6 @@
  public:
   static const bool value = false;
 };
-template <typename T>
-const bool NeedsAdjustAndMark<T, true>::value;
 
 template <typename T>
 class NeedsAdjustAndMark<T, false> {
@@ -253,8 +251,6 @@
   static const bool value =
       IsGarbageCollectedMixin<typename std::remove_const<T>::type>::value;
 };
-template <typename T>
-const bool NeedsAdjustAndMark<T, false>::value;
 
 template <typename T,
           bool = std::is_base_of<TraceWrapperBase,
@@ -268,8 +264,6 @@
  public:
   static const bool value = true;
 };
-template <typename T>
-const bool CanTraceWrappers<T, true>::value;
 
 template <typename T>
 class CanTraceWrappers<T, false> {
@@ -278,8 +272,6 @@
  public:
   static const bool value = false;
 };
-template <typename T>
-const bool CanTraceWrappers<T, false>::value;
 
 // TODO(sof): migrate to wtf/TypeTraits.h
 template <typename T>
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index 1310bac..fc3d4ad 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -4843,16 +4843,22 @@
 
 TEST(HeapTest, NeedsAdjustAndMark) {
   // class Mixin : public GarbageCollectedMixin {};
-  EXPECT_TRUE(NeedsAdjustAndMark<Mixin>::value);
-  EXPECT_TRUE(NeedsAdjustAndMark<const Mixin>::value);
+  static_assert(NeedsAdjustAndMark<Mixin>::value,
+                "A Mixin pointer needs adjustment");
+  static_assert(NeedsAdjustAndMark<Mixin>::value,
+                "A const Mixin pointer needs adjustment");
 
   // class SimpleObject : public GarbageCollected<SimpleObject> {};
-  EXPECT_FALSE(NeedsAdjustAndMark<SimpleObject>::value);
-  EXPECT_FALSE(NeedsAdjustAndMark<const SimpleObject>::value);
+  static_assert(!NeedsAdjustAndMark<SimpleObject>::value,
+                "A SimpleObject pointer does not need adjustment");
+  static_assert(!NeedsAdjustAndMark<const SimpleObject>::value,
+                "A const SimpleObject pointer does not need adjustment");
 
   // class UseMixin : public SimpleObject, public Mixin {};
-  EXPECT_FALSE(NeedsAdjustAndMark<UseMixin>::value);
-  EXPECT_FALSE(NeedsAdjustAndMark<const UseMixin>::value);
+  static_assert(!NeedsAdjustAndMark<UseMixin>::value,
+                "A UseMixin pointer does not need adjustment");
+  static_assert(!NeedsAdjustAndMark<const UseMixin>::value,
+                "A const UseMixin pointer does not need adjustment");
 }
 
 template <typename Set>
diff --git a/third_party/ocmock/BUILD.gn b/third_party/ocmock/BUILD.gn
index 7d9f702..22c1a545 100644
--- a/third_party/ocmock/BUILD.gn
+++ b/third_party/ocmock/BUILD.gn
@@ -10,7 +10,10 @@
 
 config("ocmock_warnings") {
   # NSInvocation+OCMAdditions.m has some `- (void) foo; {...`
-  cflags = [ "-Wno-semicolon-before-method-body" ]
+  cflags = [
+    "-Wno-semicolon-before-method-body",
+    "-Wno-undeclared-selector",
+  ]
 }
 
 source_set("ocmock") {