diff --git a/DEPS b/DEPS
index 1296d791..767f180 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'f5d4746ad73ef5eabc927d3d988bb9ee97c77921',
+  'skia_revision': '03762fea75b0fe34ac0375407b83b6ae52e453b4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -275,7 +275,7 @@
 
   'src/third_party/catapult':
     Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' +
-    'dd5b026ac253edbcdb3be08a12eef1d03b796b35',
+    '017a5a5670fb0d56233a84700a50238f01e43c8f',
 
   'src/third_party/openh264/src':
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index fdaa46b..de43123 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -610,7 +610,7 @@
 }
 
 // static
-FilePath FilePath::FromUTF8Unsafe(const std::string& utf8) {
+FilePath FilePath::FromUTF8Unsafe(StringPiece utf8) {
 #if defined(SYSTEM_NATIVE_UTF8)
   return FilePath(utf8);
 #else
@@ -619,11 +619,11 @@
 }
 
 // static
-FilePath FilePath::FromUTF16Unsafe(const string16& utf16) {
+FilePath FilePath::FromUTF16Unsafe(StringPiece16 utf16) {
 #if defined(SYSTEM_NATIVE_UTF8)
   return FilePath(UTF16ToUTF8(utf16));
 #else
-  return FilePath(SysWideToNativeMB(UTF16ToWide(utf16)));
+  return FilePath(SysWideToNativeMB(UTF16ToWide(utf16.as_string())));
 #endif
 }
 
@@ -647,12 +647,12 @@
 }
 
 // static
-FilePath FilePath::FromUTF8Unsafe(const std::string& utf8) {
+FilePath FilePath::FromUTF8Unsafe(StringPiece utf8) {
   return FilePath(UTF8ToWide(utf8));
 }
 
 // static
-FilePath FilePath::FromUTF16Unsafe(const string16& utf16) {
+FilePath FilePath::FromUTF16Unsafe(StringPiece16 utf16) {
   return FilePath(utf16);
 }
 #endif
diff --git a/base/files/file_path.h b/base/files/file_path.h
index 4eb712a..3234df7bf 100644
--- a/base/files/file_path.h
+++ b/base/files/file_path.h
@@ -373,10 +373,10 @@
   // internally calls SysWideToNativeMB() on POSIX systems other than Mac
   // and Chrome OS, to mitigate the encoding issue. See the comment at
   // AsUTF8Unsafe() for details.
-  static FilePath FromUTF8Unsafe(const std::string& utf8);
+  static FilePath FromUTF8Unsafe(StringPiece utf8);
 
   // Similar to FromUTF8Unsafe, but accepts UTF-16 instead.
-  static FilePath FromUTF16Unsafe(const string16& utf16);
+  static FilePath FromUTF16Unsafe(StringPiece16 utf16);
 
   void GetSizeForPickle(PickleSizer* sizer) const;
   void WriteToPickle(Pickle* pickle) const;
diff --git a/base/third_party/nspr/prtime.cc b/base/third_party/nspr/prtime.cc
index e7c202f..c125160 100644
--- a/base/third_party/nspr/prtime.cc
+++ b/base/third_party/nspr/prtime.cc
@@ -75,16 +75,6 @@
 #include <time.h>
 
 /*
- * Long-long (64-bit signed integer type) support macros used by
- * PR_ImplodeTime().
- * See http://lxr.mozilla.org/nspr/source/pr/include/prlong.h
- */
-#define LL_I2L(l, i) ((l) = (PRInt64)(i))
-#define LL_MUL(r, a, b) ((r) = (a) * (b))
-#define LL_ADD(r, a, b) ((r) = (a) + (b))
-#define LL_SUB(r, a, b) ((r) = (a) - (b))
-
-/*
  * The COUNT_LEAPS macro counts the number of leap years passed by
  * till the start of the given year Y.  At the start of the year 4
  * A.D. the number of leap years passed by is 0, while at the start of
diff --git a/base/third_party/nspr/prtime.h b/base/third_party/nspr/prtime.h
index 01a4e540..20bae38 100644
--- a/base/third_party/nspr/prtime.h
+++ b/base/third_party/nspr/prtime.h
@@ -73,6 +73,17 @@
 #define PR_INT16_MAX 32767
 #define NSPR_API(__type) extern __type
 
+/*
+ * Long-long (64-bit signed integer type) support macros used by
+ * PR_ImplodeTime().
+ * See http://lxr.mozilla.org/nspr/source/pr/include/prlong.h
+ */
+
+#define LL_I2L(l, i) ((l) = (PRInt64)(i))
+#define LL_MUL(r, a, b) ((r) = (a) * (b))
+#define LL_ADD(r, a, b) ((r) = (a) + (b))
+#define LL_SUB(r, a, b) ((r) = (a) - (b))
+
 /**********************************************************************/
 /************************* TYPES AND CONSTANTS ************************/
 /**********************************************************************/
diff --git a/chrome/VERSION b/chrome/VERSION
index 19449368..f70fa4e 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=50
 MINOR=0
-BUILD=2656
+BUILD=2657
 PATCH=0
diff --git a/chrome/browser/chrome_service_worker_browsertest.cc b/chrome/browser/chrome_service_worker_browsertest.cc
index e6c32fd..fca0447 100644
--- a/chrome/browser/chrome_service_worker_browsertest.cc
+++ b/chrome/browser/chrome_service_worker_browsertest.cc
@@ -6,21 +6,28 @@
 // embedder.
 
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#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/browser_context.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/service_worker_context.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "ppapi/shared_impl/ppapi_switches.h"
 
 namespace {
 
@@ -29,6 +36,7 @@
   ChromeServiceWorkerTest() {
     EXPECT_TRUE(service_worker_dir_.CreateUniqueTempDir());
   }
+  ~ChromeServiceWorkerTest() override {}
 
   void WriteFile(const base::FilePath::StringType& filename,
                  base::StringPiece contents) {
@@ -39,6 +47,9 @@
   }
 
   base::ScopedTempDir service_worker_dir_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ChromeServiceWorkerTest);
 };
 
 static void ExpectResultAndRun(bool expected,
@@ -109,4 +120,382 @@
   // Test passes if we don't crash.
 }
 
+class ChromeServiceWorkerFetchTest : public ChromeServiceWorkerTest {
+ protected:
+  ChromeServiceWorkerFetchTest() {}
+  ~ChromeServiceWorkerFetchTest() override {}
+
+  void SetUpOnMainThread() override {
+    WriteServiceWorkerFetchTestFiles();
+    embedded_test_server()->ServeFilesFromDirectory(service_worker_dir_.path());
+    ASSERT_TRUE(embedded_test_server()->Start());
+    InitializeServiceWorkerFetchTestPage();
+  }
+
+  std::string ExecuteScriptAndExtractString(const std::string& js) {
+    std::string result;
+    EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+        browser()->tab_strip_model()->GetActiveWebContents(), js, &result));
+    return result;
+  }
+
+  std::string RequestString(const std::string& url,
+                            const std::string& mode,
+                            const std::string& credentials) const {
+    return base::StringPrintf("url:%s, mode:%s, credentials:%s\n", url.c_str(),
+                              mode.c_str(), credentials.c_str());
+  }
+
+  std::string GetURL(const std::string& relative_url) const {
+    return embedded_test_server()->GetURL(relative_url).spec();
+  }
+
+ private:
+  void WriteServiceWorkerFetchTestFiles() {
+    WriteFile(FILE_PATH_LITERAL("sw.js"),
+              "this.onactivate = function(event) {"
+              "  event.waitUntil(self.clients.claim());"
+              "};"
+              "this.onfetch = function(event) {"
+              "  event.respondWith("
+              "      self.clients.matchAll().then(function(clients) {"
+              "          clients.forEach(function(client) {"
+              "              client.postMessage("
+              "                'url:' + event.request.url + ', ' +"
+              "                'mode:' + event.request.mode + ', ' +"
+              "                'credentials:' + event.request.credentials"
+              "              );"
+              "            });"
+              "          return fetch(event.request);"
+              "        }));"
+              "};");
+    WriteFile(FILE_PATH_LITERAL("test.html"),
+              "<script>"
+              "navigator.serviceWorker.register('./sw.js', {scope: './'})"
+              "  .then(function(reg) {"
+              "      reg.addEventListener('updatefound', function() {"
+              "          var worker = reg.installing;"
+              "          worker.addEventListener('statechange', function() {"
+              "              if (worker.state == 'activated')"
+              "                document.title = 'READY';"
+              "            });"
+              "        });"
+              "    });"
+              "var reportOnFetch = true;"
+              "var issuedRequests = [];"
+              "function reportRequests() {"
+              "  var str = '';"
+              "  issuedRequests.forEach(function(data) {"
+              "      str += data + '\\n';"
+              "    });"
+              "  window.domAutomationController.setAutomationId(0);"
+              "  window.domAutomationController.send(str);"
+              "}"
+              "navigator.serviceWorker.addEventListener("
+              "    'message',"
+              "    function(event) {"
+              "      issuedRequests.push(event.data);"
+              "      if (reportOnFetch) {"
+              "        reportRequests();"
+              "      }"
+              "    }, false);"
+              "</script>");
+  }
+
+  void InitializeServiceWorkerFetchTestPage() {
+    // The message "READY" will be sent when the service worker is activated.
+    const base::string16 expected_title = base::ASCIIToUTF16("READY");
+    content::TitleWatcher title_watcher(
+        browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
+    ui_test_utils::NavigateToURL(browser(),
+                                 embedded_test_server()->GetURL("/test.html"));
+    EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeServiceWorkerFetchTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchTest, EmbedPdfSameOrigin) {
+  // <embed src="test.pdf">
+  const std::string result(ExecuteScriptAndExtractString(
+      "var embed = document.createElement('embed');"
+      "embed.src = 'test.pdf';"
+      "document.body.appendChild(embed);"));
+  EXPECT_EQ(RequestString(GetURL("/test.pdf"), "no-cors", "include"), result);
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchTest, EmbedPdfOtherOrigin) {
+  // <embed src="https://www.example.com/test.pdf">
+  const std::string result(ExecuteScriptAndExtractString(
+      "var embed = document.createElement('embed');"
+      "embed.src = 'https://www.example.com/test.pdf';"
+      "document.body.appendChild(embed);"));
+  EXPECT_EQ(
+      RequestString("https://www.example.com/test.pdf", "no-cors", "include"),
+      result);
+}
+
+class ChromeServiceWorkerManifestFetchTest
+    : public ChromeServiceWorkerFetchTest {
+ protected:
+  ChromeServiceWorkerManifestFetchTest() {}
+  ~ChromeServiceWorkerManifestFetchTest() override {}
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    ChromeServiceWorkerFetchTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitch(switches::kEnableAddToShelf);
+  }
+
+  std::string ExecuteManifestFetchTest(const std::string& url,
+                                       const std::string& cross_origin) {
+    std::string js(
+        base::StringPrintf("reportOnFetch = false;"
+                           "var link = document.createElement('link');"
+                           "link.rel = 'manifest';"
+                           "link.href = '%s';",
+                           url.c_str()));
+    if (!cross_origin.empty()) {
+      js +=
+          base::StringPrintf("link.crossOrigin = '%s';", cross_origin.c_str());
+    }
+    js += "document.head.appendChild(link);";
+    ExecuteJavaScriptForTests(js);
+    return RequestAppBannerAndGetIssuedRequests();
+  }
+
+ private:
+  void ExecuteJavaScriptForTests(const std::string& js) {
+    browser()
+        ->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetMainFrame()
+        ->ExecuteJavaScriptForTests(base::ASCIIToUTF16(js));
+  }
+
+  std::string RequestAppBannerAndGetIssuedRequests() {
+    EXPECT_TRUE(browser()->RequestAppBanner(
+        browser()->tab_strip_model()->GetActiveWebContents()));
+    return ExecuteScriptAndExtractString(
+        "if (issuedRequests.length != 0) reportRequests();"
+        "else reportOnFetch = true;");
+  }
+  DISALLOW_COPY_AND_ASSIGN(ChromeServiceWorkerManifestFetchTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerManifestFetchTest, SameOrigin) {
+  // <link rel="manifest" href="manifest.json">
+  EXPECT_EQ(RequestString(GetURL("/manifest.json"), "cors", "same-origin"),
+            ExecuteManifestFetchTest("manifest.json", ""));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerManifestFetchTest,
+                       SameOriginUseCredentials) {
+  // <link rel="manifest" href="manifest.json" crossorigin="use-credentials">
+  EXPECT_EQ(RequestString(GetURL("/manifest.json"), "cors", "include"),
+            ExecuteManifestFetchTest("manifest.json", "use-credentials"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerManifestFetchTest, OtherOrigin) {
+  // <link rel="manifest" href="https://www.example.com/manifest.json">
+  EXPECT_EQ(
+      RequestString("https://www.example.com/manifest.json", "cors",
+                    "same-origin"),
+      ExecuteManifestFetchTest("https://www.example.com/manifest.json", ""));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerManifestFetchTest,
+                       OtherOriginUseCredentials) {
+  // <link rel="manifest" href="https://www.example.com/manifest.json"
+  //  crossorigin="use-credentials">
+  EXPECT_EQ(
+      RequestString("https://www.example.com/manifest.json", "cors", "include"),
+      ExecuteManifestFetchTest("https://www.example.com/manifest.json",
+                               "use-credentials"));
+}
+
+class ChromeServiceWorkerFetchPPAPITest : public ChromeServiceWorkerFetchTest {
+ protected:
+  ChromeServiceWorkerFetchPPAPITest() {}
+  ~ChromeServiceWorkerFetchPPAPITest() override {}
+
+  void SetUpOnMainThread() override {
+    base::FilePath document_root;
+    ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&document_root));
+    embedded_test_server()->AddDefaultHandlers(
+        document_root.Append(FILE_PATH_LITERAL("nacl_test_data"))
+            .Append(FILE_PATH_LITERAL("pnacl")));
+    ChromeServiceWorkerFetchTest::SetUpOnMainThread();
+    test_page_url_ = GetURL("/pnacl_url_loader.html");
+  }
+
+  std::string GetRequestStringForPNACL() const {
+    return RequestString(test_page_url_, "navigate", "include") +
+           RequestString(GetURL("/pnacl_url_loader.nmf"), "same-origin",
+                         "include") +
+           RequestString(GetURL("/pnacl_url_loader_newlib_pnacl.pexe"),
+                         "same-origin", "include");
+  }
+
+  std::string ExecutePNACLUrlLoaderTest(const std::string& mode) {
+    std::string result(ExecuteScriptAndExtractString(
+        base::StringPrintf("reportOnFetch = false;"
+                           "var iframe = document.createElement('iframe');"
+                           "iframe.src='%s#%s';"
+                           "document.body.appendChild(iframe);",
+                           test_page_url_.c_str(), mode.c_str())));
+    EXPECT_EQ(base::StringPrintf("OnOpen%s", mode.c_str()), result);
+    return ExecuteScriptAndExtractString("reportRequests();");
+  }
+
+ private:
+  std::string test_page_url_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeServiceWorkerFetchPPAPITest);
+};
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPITest, SameOrigin) {
+  // In pnacl_url_loader.cc:
+  //   request.SetMethod("GET");
+  //   request.SetURL("/echo");
+  EXPECT_EQ(GetRequestStringForPNACL() +
+                RequestString(GetURL("/echo"), "same-origin", "include"),
+            ExecutePNACLUrlLoaderTest("Same"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPITest, SameOriginCORS) {
+  // In pnacl_url_loader.cc:
+  //   request.SetMethod("GET");
+  //   request.SetURL("/echo");
+  //   request.SetAllowCrossOriginRequests(true);
+  EXPECT_EQ(GetRequestStringForPNACL() +
+                RequestString(GetURL("/echo"), "cors", "same-origin"),
+            ExecutePNACLUrlLoaderTest("SameCORS"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPITest,
+                       SameOriginCredentials) {
+  // In pnacl_url_loader.cc:
+  //   request.SetMethod("GET");
+  //   request.SetURL("/echo");
+  //   request.SetAllowCredentials(true);
+  EXPECT_EQ(GetRequestStringForPNACL() +
+                RequestString(GetURL("/echo"), "same-origin", "include"),
+            ExecutePNACLUrlLoaderTest("SameCredentials"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPITest,
+                       SameOriginCORSCredentials) {
+  // In pnacl_url_loader.cc:
+  //   request.SetMethod("GET");
+  //   request.SetURL("/echo");
+  //   request.SetAllowCrossOriginRequests(true);
+  //   request.SetAllowCredentials(true);
+  EXPECT_EQ(GetRequestStringForPNACL() +
+                RequestString(GetURL("/echo"), "cors", "include"),
+            ExecutePNACLUrlLoaderTest("SameCORSCredentials"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPITest, OtherOrigin) {
+  // In pnacl_url_loader.cc:
+  //   request.SetMethod("GET");
+  //   request.SetURL("https://www.example.com/echo");
+  // This request fails because AllowCrossOriginRequests is not set.
+  EXPECT_EQ(GetRequestStringForPNACL(), ExecutePNACLUrlLoaderTest("Other"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPITest, OtherOriginCORS) {
+  // In pnacl_url_loader.cc:
+  //   request.SetMethod("GET");
+  //   request.SetURL("https://www.example.com/echo");
+  //   request.SetAllowCrossOriginRequests(true);
+  EXPECT_EQ(
+      GetRequestStringForPNACL() +
+          RequestString("https://www.example.com/echo", "cors", "same-origin"),
+      ExecutePNACLUrlLoaderTest("OtherCORS"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPITest,
+                       OtherOriginCredentials) {
+  // In pnacl_url_loader.cc:
+  //   request.SetMethod("GET");
+  //   request.SetURL("https://www.example.com/echo");
+  //   request.SetAllowCredentials(true);
+  // This request fails because AllowCrossOriginRequests is not set.
+  EXPECT_EQ(GetRequestStringForPNACL(),
+            ExecutePNACLUrlLoaderTest("OtherCredentials"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPITest,
+                       OtherOriginCORSCredentials) {
+  // In pnacl_url_loader.cc:
+  //   request.SetMethod("GET");
+  //   request.SetURL("https://www.example.com/echo");
+  //   request.SetAllowCrossOriginRequests(true);
+  //   request.SetAllowCredentials(true);
+  EXPECT_EQ(
+      GetRequestStringForPNACL() +
+          RequestString("https://www.example.com/echo", "cors", "include"),
+      ExecutePNACLUrlLoaderTest("OtherCORSCredentials"));
+}
+
+class ChromeServiceWorkerFetchPPAPIPrivateTest
+    : public ChromeServiceWorkerFetchPPAPITest {
+ protected:
+  ChromeServiceWorkerFetchPPAPIPrivateTest() {}
+  ~ChromeServiceWorkerFetchPPAPIPrivateTest() override {}
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    ChromeServiceWorkerFetchPPAPITest::SetUpCommandLine(command_line);
+    // Sets this flag to test that the fetch request from the plugins with
+    // private permission (PERMISSION_PRIVATE) should not go to the service
+    // worker.
+    command_line->AppendSwitch(switches::kEnablePepperTesting);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ChromeServiceWorkerFetchPPAPIPrivateTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest, SameOrigin) {
+  EXPECT_EQ(GetRequestStringForPNACL(), ExecutePNACLUrlLoaderTest("Same"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest,
+                       SameOriginCORS) {
+  EXPECT_EQ(GetRequestStringForPNACL(), ExecutePNACLUrlLoaderTest("SameCORS"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest,
+                       SameOriginCredentials) {
+  EXPECT_EQ(GetRequestStringForPNACL(),
+            ExecutePNACLUrlLoaderTest("SameCredentials"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest,
+                       SameOriginCORSCredentials) {
+  EXPECT_EQ(GetRequestStringForPNACL(),
+            ExecutePNACLUrlLoaderTest("SameCORSCredentials"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest, OtherOrigin) {
+  EXPECT_EQ(GetRequestStringForPNACL(), ExecutePNACLUrlLoaderTest("Other"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest,
+                       OtherOriginCORS) {
+  EXPECT_EQ(GetRequestStringForPNACL(), ExecutePNACLUrlLoaderTest("OtherCORS"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest,
+                       OtherOriginCredentials) {
+  EXPECT_EQ(GetRequestStringForPNACL(),
+            ExecutePNACLUrlLoaderTest("OtherCredentials"));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest,
+                       OtherOriginCORSCredentials) {
+  EXPECT_EQ(GetRequestStringForPNACL(),
+            ExecutePNACLUrlLoaderTest("OtherCORSCredentials"));
+}
+
 }  // namespace
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc b/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc
index 0048914..bd7a266 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc
@@ -23,13 +23,12 @@
 
 namespace chromeos {
 
-UserImageLoader::ImageInfo::ImageInfo(const std::string& file_path,
+UserImageLoader::ImageInfo::ImageInfo(const base::FilePath& file_path,
                                       int pixels_per_side,
                                       const LoadedCallback& loaded_cb)
     : file_path(file_path),
       pixels_per_side(pixels_per_side),
-      loaded_cb(loaded_cb) {
-}
+      loaded_cb(loaded_cb) {}
 
 UserImageLoader::ImageInfo::~ImageInfo() {
 }
@@ -58,33 +57,29 @@
 UserImageLoader::~UserImageLoader() {
 }
 
-void UserImageLoader::Start(const std::string& filepath,
-                            int pixels_per_side,
-                            const LoadedCallback& loaded_cb) {
+void UserImageLoader::StartWithFilePath(const base::FilePath& file_path,
+                                        int pixels_per_side,
+                                        const LoadedCallback& loaded_cb) {
   background_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&UserImageLoader::ReadAndDecodeImage,
-                 this,
-                 ImageInfo(filepath, pixels_per_side, loaded_cb)));
+      FROM_HERE, base::Bind(&UserImageLoader::ReadAndDecodeImage, this,
+                            ImageInfo(file_path, pixels_per_side, loaded_cb)));
 }
 
-void UserImageLoader::Start(scoped_ptr<std::string> data,
-                            int pixels_per_side,
-                            const LoadedCallback& loaded_cb) {
+void UserImageLoader::StartWithData(scoped_ptr<std::string> data,
+                                    int pixels_per_side,
+                                    const LoadedCallback& loaded_cb) {
   background_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&UserImageLoader::DecodeImage,
-                 this,
-                 base::Passed(&data),
-                 ImageInfo(std::string(), pixels_per_side, loaded_cb)));
+      base::Bind(&UserImageLoader::DecodeImage, this, base::Passed(&data),
+                 ImageInfo(base::FilePath(), pixels_per_side, loaded_cb)));
 }
 
 void UserImageLoader::ReadAndDecodeImage(const ImageInfo& image_info) {
   DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
 
   scoped_ptr<std::string> data(new std::string);
-  if (!base::ReadFileToString(base::FilePath(image_info.file_path), data.get()))
-    LOG(ERROR) << "Failed to read image " << image_info.file_path;
+  if (!base::ReadFileToString(image_info.file_path, data.get()))
+    LOG(ERROR) << "Failed to read image " << image_info.file_path.value();
 
   // In case ReadFileToString() fails, |data| is empty and DecodeImage() calls
   // back to OnDecodeImageFailed().
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_loader.h b/chrome/browser/chromeos/login/users/avatar/user_image_loader.h
index b8bc3741..3f96a9d4 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_loader.h
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_loader.h
@@ -9,6 +9,7 @@
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "chrome/browser/image_decoder.h"
@@ -42,26 +43,26 @@
   // UserImage (which may be empty in case of error). If |pixels_per_side| is
   // positive, the image is cropped to a square and shrunk so that it does not
   // exceed |pixels_per_side|x|pixels_per_side|. The first variant of this
-  // method reads the image from |filepath| on disk, the second processes |data|
-  // read into memory already.
-  void Start(const std::string& filepath,
-             int pixels_per_side,
-             const LoadedCallback& loaded_cb);
-  void Start(scoped_ptr<std::string> data,
-             int pixels_per_side,
-             const LoadedCallback& loaded_cb);
+  // method reads the image from |file_path| on disk, the second processes
+  // |data| read into memory already.
+  void StartWithFilePath(const base::FilePath& file_path,
+                         int pixels_per_side,
+                         const LoadedCallback& loaded_cb);
+  void StartWithData(scoped_ptr<std::string> data,
+                     int pixels_per_side,
+                     const LoadedCallback& loaded_cb);
 
  private:
   friend class base::RefCountedThreadSafe<UserImageLoader>;
 
   // Contains attributes we need to know about each image we decode.
   struct ImageInfo {
-    ImageInfo(const std::string& file_path,
+    ImageInfo(const base::FilePath& file_path,
               int pixels_per_side,
               const LoadedCallback& loaded_cb);
     ~ImageInfo();
 
-    const std::string file_path;
+    const base::FilePath file_path;
     const int pixels_per_side;
     const LoadedCallback loaded_cb;
   };
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
index b9c01461..c8192a1d 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
@@ -319,11 +319,9 @@
     // LoadImage() is called only for users whose user image has previously
     // been set by one of the Set*() methods, which transcode to JPEG format.
     DCHECK(!image_path_.empty());
-    parent_->image_loader_->Start(image_path_.value(),
-                                  0,
-                                  base::Bind(&Job::OnLoadImageDone,
-                                             weak_factory_.GetWeakPtr(),
-                                             false));
+    parent_->image_loader_->StartWithFilePath(
+        image_path_, 0,  // Do not crop.
+        base::Bind(&Job::OnLoadImageDone, weak_factory_.GetWeakPtr(), false));
   } else {
     NOTREACHED();
     NotifyJobDone();
@@ -378,7 +376,7 @@
   // * This is safe because the image_loader_ employs a hardened JPEG decoder
   //   that protects against malicious invalid image data being used to attack
   //   the login screen or another user session currently in progress.
-  parent_->image_loader_->Start(
+  parent_->image_loader_->StartWithData(
       std::move(data), login::kMaxUserImageSize,
       base::Bind(&Job::OnLoadImageDone, weak_factory_.GetWeakPtr(), true));
 }
@@ -394,11 +392,9 @@
   image_url_ = image_url;
 
   DCHECK(!path.empty());
-  parent_->unsafe_image_loader_->Start(path.value(),
-                                       resize ? login::kMaxUserImageSize : 0,
-                                       base::Bind(&Job::OnLoadImageDone,
-                                                  weak_factory_.GetWeakPtr(),
-                                                  true));
+  parent_->unsafe_image_loader_->StartWithFilePath(
+      path, resize ? login::kMaxUserImageSize : 0,
+      base::Bind(&Job::OnLoadImageDone, weak_factory_.GetWeakPtr(), true));
 }
 
 void UserImageManagerImpl::Job::OnLoadImageDone(
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
index 3f146e6..17dcda8 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -448,7 +448,7 @@
   if (!data)
     return;
 
-  wallpaper_loader_->Start(
+  wallpaper_loader_->StartWithData(
       std::move(data),
       0,  // Do not crop.
       base::Bind(&WallpaperManager::SetPolicyControlledWallpaper,
@@ -577,7 +577,7 @@
                 : wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED;
   DCHECK(file);
   if (!default_wallpaper_image_.get() ||
-      default_wallpaper_image_->file_path() != file->value()) {
+      default_wallpaper_image_->file_path() != *file) {
     default_wallpaper_image_.reset();
     if (!file->empty()) {
       loaded_wallpapers_for_test_++;
@@ -954,8 +954,8 @@
     wallpaper_cache_[account_id] =
         CustomWallpaperElement(wallpaper_path, gfx::ImageSkia());
   }
-  wallpaper_loader_->Start(
-      wallpaper_path.value(),
+  wallpaper_loader_->StartWithFilePath(
+      wallpaper_path,
       0,  // Do not crop.
       base::Bind(&WallpaperManager::OnWallpaperDecoded,
                  weak_factory_.GetWeakPtr(), account_id, info.layout,
@@ -975,8 +975,8 @@
 
     // Either resized images do not exist or cached version is incorrect.
     // Need to start resize again.
-    wallpaper_loader_->Start(
-        downloaded_file.value(),
+    wallpaper_loader_->StartWithFilePath(
+        downloaded_file,
         0,  // Do not crop.
         base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperDecoded,
                    weak_factory_.GetWeakPtr(), wallpaper_url,
@@ -1051,8 +1051,8 @@
     const wallpaper::WallpaperLayout layout,
     MovableOnDestroyCallbackHolder on_finish,
     scoped_ptr<user_manager::UserImage>* result_out) {
-  wallpaper_loader_->Start(
-      path.value(),
+  wallpaper_loader_->StartWithFilePath(
+      path,
       0,  // Do not crop.
       base::Bind(&WallpaperManager::OnDefaultWallpaperDecoded,
                  weak_factory_.GetWeakPtr(), path, layout,
@@ -1087,15 +1087,13 @@
     if (small_wallpaper_image) {
       default_wallpaper_image_.reset(
           new user_manager::UserImage(*small_wallpaper_image));
-      default_wallpaper_image_->set_file_path(
-          default_small_wallpaper_file.value());
+      default_wallpaper_image_->set_file_path(default_small_wallpaper_file);
     }
   } else {
     if (large_wallpaper_image) {
       default_wallpaper_image_.reset(
           new user_manager::UserImage(*large_wallpaper_image));
-      default_wallpaper_image_->set_file_path(
-          default_large_wallpaper_file.value());
+      default_wallpaper_image_->set_file_path(default_large_wallpaper_file);
     }
   }
 
diff --git a/chrome/browser/engagement/site_engagement_metrics.cc b/chrome/browser/engagement/site_engagement_metrics.cc
index 06a301e..1159253 100644
--- a/chrome/browser/engagement/site_engagement_metrics.cc
+++ b/chrome/browser/engagement/site_engagement_metrics.cc
@@ -51,6 +51,12 @@
 const char SiteEngagementMetrics::kDaysSinceLastShortcutLaunchHistogram[] =
     "SiteEngagementService.DaysSinceLastShortcutLaunch";
 
+const char SiteEngagementMetrics::kScoreDecayedFromHistogram[] =
+    "SiteEngagementService.ScoreDecayedFrom";
+
+const char SiteEngagementMetrics::kScoreDecayedToHistogram[] =
+    "SiteEngagementService.ScoreDecayedTo";
+
 void SiteEngagementMetrics::RecordTotalSiteEngagement(double total_engagement) {
   UMA_HISTOGRAM_COUNTS_10000(kTotalEngagementHistogram, total_engagement);
 }
@@ -116,6 +122,14 @@
   UMA_HISTOGRAM_COUNTS_100(kDaysSinceLastShortcutLaunchHistogram, days);
 }
 
+void SiteEngagementMetrics::RecordScoreDecayedFrom(double score) {
+  UMA_HISTOGRAM_COUNTS_100(kScoreDecayedFromHistogram, score);
+}
+
+void SiteEngagementMetrics::RecordScoreDecayedTo(double score) {
+  UMA_HISTOGRAM_COUNTS_100(kScoreDecayedToHistogram, score);
+}
+
 // static
 std::vector<std::string>
 SiteEngagementMetrics::GetEngagementBucketHistogramNames() {
diff --git a/chrome/browser/engagement/site_engagement_metrics.h b/chrome/browser/engagement/site_engagement_metrics.h
index 1c362304..c424824 100644
--- a/chrome/browser/engagement/site_engagement_metrics.h
+++ b/chrome/browser/engagement/site_engagement_metrics.h
@@ -40,10 +40,13 @@
   static void RecordPercentOriginsWithMaxEngagement(double percentage);
   static void RecordEngagement(EngagementType type);
   static void RecordDaysSinceLastShortcutLaunch(int days);
+  static void RecordScoreDecayedFrom(double score);
+  static void RecordScoreDecayedTo(double score);
 
  private:
   FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, CheckHistograms);
   FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, LastShortcutLaunch);
+  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, ScoreDecayHistograms);
   FRIEND_TEST_ALL_PREFIXES(SiteEngagementHelperTest,
                            MixedInputEngagementAccumulation);
   static const char kTotalEngagementHistogram[];
@@ -57,6 +60,8 @@
   static const char kEngagementTypeHistogram[];
   static const char kEngagementBucketHistogramBase[];
   static const char kDaysSinceLastShortcutLaunchHistogram[];
+  static const char kScoreDecayedFromHistogram[];
+  static const char kScoreDecayedToHistogram[];
 
   static std::vector<std::string> GetEngagementBucketHistogramNames();
 };
diff --git a/chrome/browser/engagement/site_engagement_service.cc b/chrome/browser/engagement/site_engagement_service.cc
index 6b4c0728..03a7ff0 100644
--- a/chrome/browser/engagement/site_engagement_service.cc
+++ b/chrome/browser/engagement/site_engagement_service.cc
@@ -220,9 +220,17 @@
 
 void SiteEngagementScore::AddPoints(double points) {
   DCHECK_NE(0, points);
+  double decayed_score = DecayedScore();
+
+  // Record the original and decayed scores after a decay event.
+  if (decayed_score < raw_score_) {
+    SiteEngagementMetrics::RecordScoreDecayedFrom(raw_score_);
+    SiteEngagementMetrics::RecordScoreDecayedTo(decayed_score);
+  }
+
   // As the score is about to be updated, commit any decay that has happened
   // since the last update.
-  raw_score_ = DecayedScore();
+  raw_score_ = decayed_score;
 
   base::Time now = clock_->Now();
   if (!last_engagement_time_.is_null() &&
@@ -317,8 +325,7 @@
     return raw_score_;
 
   int periods = days_since_engagement / GetDecayPeriodInDays();
-  double decayed_score = raw_score_ - periods * GetDecayPoints();
-  return std::max(0.0, decayed_score);
+  return std::max(0.0, raw_score_ - periods * GetDecayPoints());
 }
 
 double SiteEngagementScore::BonusScore() const {
diff --git a/chrome/browser/engagement/site_engagement_service.h b/chrome/browser/engagement/site_engagement_service.h
index 48bb0e5..2c4afa4 100644
--- a/chrome/browser/engagement/site_engagement_service.h
+++ b/chrome/browser/engagement/site_engagement_service.h
@@ -251,6 +251,7 @@
   FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest,
                            CleanupOriginsOnHistoryDeletion);
   FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, IsBootstrapped);
+  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, ScoreDecayHistograms);
   FRIEND_TEST_ALL_PREFIXES(AppBannerSettingsHelperTest, SiteEngagementTrigger);
 
   // Only used in tests.
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc
index 741fcc23..14f0e93 100644
--- a/chrome/browser/engagement/site_engagement_service_unittest.cc
+++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
@@ -1156,3 +1156,93 @@
     EXPECT_EQ(5.0, engagement->GetTotalEngagementPoints());
   }
 }
+
+TEST_F(SiteEngagementServiceTest, ScoreDecayHistograms) {
+  base::SimpleTestClock* clock = new base::SimpleTestClock();
+  scoped_ptr<SiteEngagementService> service(
+      new SiteEngagementService(profile(), make_scoped_ptr(clock)));
+
+  base::Time current_day = GetReferenceTime();
+  clock->SetNow(current_day);
+  base::HistogramTester histograms;
+  GURL origin1("http://www.google.com/");
+  GURL origin2("http://drive.google.com/");
+
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
+                              0);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
+                              0);
+
+  service->AddPoints(origin2, SiteEngagementScore::GetNavigationPoints());
+
+  // Max the score for origin1.
+  for (int i = 0; i < kMoreDaysThanNeededToMaxTotalEngagement; ++i) {
+    current_day += base::TimeDelta::FromDays(1);
+    clock->SetNow(current_day);
+
+    for (int j = 0; j < kMoreAccumulationsThanNeededToMaxDailyEngagement; ++j)
+      service->AddPoints(origin1, SiteEngagementScore::GetNavigationPoints());
+  }
+
+  EXPECT_EQ(SiteEngagementScore::kMaxPoints, service->GetScore(origin1));
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
+                              0);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
+                              0);
+
+  // Check histograms after one decay period.
+  clock->SetNow(current_day + base::TimeDelta::FromDays(
+                                  SiteEngagementScore::GetDecayPeriodInDays()));
+
+  // Trigger decay and histogram hit.
+  service->AddPoints(origin1, 0.01);
+  histograms.ExpectUniqueSample(
+      SiteEngagementMetrics::kScoreDecayedFromHistogram,
+      SiteEngagementScore::kMaxPoints, 1);
+  histograms.ExpectUniqueSample(
+      SiteEngagementMetrics::kScoreDecayedToHistogram,
+      SiteEngagementScore::kMaxPoints - SiteEngagementScore::GetDecayPoints(),
+      1);
+
+  // Check histograms after a few decay periods.
+  clock->SetNow(current_day + base::TimeDelta::FromDays(
+                                  kLessPeriodsThanNeededToDecayMaxScore *
+                                  SiteEngagementScore::GetDecayPeriodInDays()));
+  // Trigger decay and histogram hit.
+  service->AddPoints(origin1, 0.01);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
+                              2);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
+                              2);
+
+  // Check decay to zero.
+  clock->SetNow(current_day + base::TimeDelta::FromDays(
+                                  kMorePeriodsThanNeededToDecayMaxScore *
+                                  SiteEngagementScore::GetDecayPeriodInDays()));
+  // Trigger decay and histogram hit.
+  service->AddPoints(origin1, 0.01);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
+                              3);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
+                              3);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
+                               0, 1);
+  // Trigger decay and histogram hit for origin2, checking an independent decay.
+  service->AddPoints(origin2, 0.01);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
+                              4);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
+                              4);
+  histograms.ExpectBucketCount(
+      SiteEngagementMetrics::kScoreDecayedFromHistogram, 0, 1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
+                               0, 2);
+
+  // Add more points and ensure no more samples are present.
+  service->AddPoints(origin1, 0.01);
+  service->AddPoints(origin2, 0.01);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
+                              4);
+  histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
+                              4);
+}
diff --git a/chrome/browser/ui/webui/chromeos/image_source.cc b/chrome/browser/ui/webui/chromeos/image_source.cc
index 5e51f37..1a4fb9c 100644
--- a/chrome/browser/ui/webui/chromeos/image_source.cc
+++ b/chrome/browser/ui/webui/chromeos/image_source.cc
@@ -15,6 +15,7 @@
 #include "base/memory/ref_counted_memory.h"
 #include "base/sequenced_task_runner.h"
 #include "base/single_thread_task_runner.h"
+#include "base/task_runner_util.h"
 #include "base/thread_task_runner_handle.h"
 #include "chrome/browser/chromeos/login/users/avatar/user_image_loader.h"
 #include "chrome/common/url_constants.h"
@@ -43,25 +44,6 @@
     got_data_callback.Run(NULL);
 }
 
-// Looks for the image at |path| under the shared assets directory.
-void StartOnBlockingPool(
-    const std::string& path,
-    scoped_refptr<UserImageLoader> image_loader,
-    const content::URLDataSource::GotDataCallback& got_data_callback,
-    scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner) {
-  DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-
-  const base::FilePath asset_dir(FILE_PATH_LITERAL(chrome::kChromeOSAssetPath));
-  const base::FilePath image_path = asset_dir.AppendASCII(path);
-  if (base::PathExists(image_path)) {
-    image_loader->Start(image_path.value(), 0,
-                        base::Bind(&ImageLoaded, got_data_callback));
-  } else {
-    thread_task_runner->PostTask(FROM_HERE,
-                                 base::Bind(got_data_callback, nullptr));
-  }
-}
-
 }  // namespace
 
 ImageSource::ImageSource() : weak_factory_(this) {
@@ -94,13 +76,28 @@
                                         task_runner_);
   }
 
-  content::BrowserThread::GetBlockingPool()->PostTask(
+  const base::FilePath asset_dir(FILE_PATH_LITERAL(chrome::kChromeOSAssetPath));
+  const base::FilePath image_path = asset_dir.AppendASCII(path);
+  base::PostTaskAndReplyWithResult(
+      content::BrowserThread::GetBlockingPool(),
       FROM_HERE,
-      base::Bind(&StartOnBlockingPool,
-                 path,
-                 image_loader_,
-                 got_data_callback,
-                 base::ThreadTaskRunnerHandle::Get()));
+      base::Bind(&base::PathExists, image_path),
+      base::Bind(&ImageSource::StartDataRequestAfterPathExists,
+                 weak_factory_.GetWeakPtr(), image_path, got_data_callback));
+}
+
+void ImageSource::StartDataRequestAfterPathExists(
+    const base::FilePath& image_path,
+    const content::URLDataSource::GotDataCallback& got_data_callback,
+    bool path_exists) {
+  if (path_exists) {
+    image_loader_->StartWithFilePath(
+        image_path,
+        0,  // Do not crop.
+        base::Bind(&ImageLoaded, got_data_callback));
+  } else {
+    got_data_callback.Run(nullptr);
+  }
 }
 
 std::string ImageSource::GetMimeType(const std::string& path) const {
diff --git a/chrome/browser/ui/webui/chromeos/image_source.h b/chrome/browser/ui/webui/chromeos/image_source.h
index 3d330b0..a5ab9e1f 100644
--- a/chrome/browser/ui/webui/chromeos/image_source.h
+++ b/chrome/browser/ui/webui/chromeos/image_source.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
@@ -44,6 +45,12 @@
   std::string GetMimeType(const std::string& path) const override;
 
  private:
+  // Continuation from StartDataRequest().
+  void StartDataRequestAfterPathExists(
+      const base::FilePath& image_path,
+      const content::URLDataSource::GotDataCallback& got_data_callback,
+      bool path_exists);
+
   // Checks whether we have allowed the image to be loaded.
   bool IsWhitelisted(const std::string& path) const;
 
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index d09e44b4b..ea7dddff 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2284,6 +2284,9 @@
             'browser/extensions/extension_nacl_browsertest.cc',
             'browser/nacl_host/test/gdb_debug_stub_browsertest.cc',
           ],
+          'dependencies': [
+            'test/data/nacl/nacl_test_data.gyp:pnacl_url_loader_test',
+          ],
           'conditions': [
             ['disable_nacl_untrusted==0', {
               'sources': [
diff --git a/chrome/test/data/nacl/BUILD.gn b/chrome/test/data/nacl/BUILD.gn
index 29cd5cb..11946e4 100644
--- a/chrome/test/data/nacl/BUILD.gn
+++ b/chrome/test/data/nacl/BUILD.gn
@@ -27,6 +27,7 @@
     ":pnacl_mime_type_test($newlib)",
     ":pnacl_mime_type_test($pnacl)",
     ":pnacl_options_test($pnacl)",
+    ":pnacl_url_loader_test($pnacl)",
     ":ppapi_bad_get_ppp_instance_crash($newlib)",
     ":ppapi_bad_no_ppp_instance($newlib)",
     ":ppapi_bad_ppp_initialize($newlib)",
@@ -434,6 +435,19 @@
     ]
   }
 
+  nacl_test_data("pnacl_url_loader_test") {
+    output_name = "pnacl_url_loader"
+    sources = [
+      "pnacl_url_loader/pnacl_url_loader.cc",
+    ]
+    deps = [
+      "//ppapi:ppapi_cpp_lib",
+    ]
+    generate_nmf = true
+    destination_dir = "nacl_test_data"
+    test_files = [ "pnacl_url_loader/pnacl_url_loader.html" ]
+  }
+
   nacl_test_data("pnacl_dyncode_syscall_disabled_test") {
     output_name = "pnacl_dyncode_syscall_disabled"
     sources = [
diff --git a/chrome/test/data/nacl/nacl_test_data.gyp b/chrome/test/data/nacl/nacl_test_data.gyp
index b68e381..47da251 100644
--- a/chrome/test/data/nacl/nacl_test_data.gyp
+++ b/chrome/test/data/nacl/nacl_test_data.gyp
@@ -701,6 +701,25 @@
       },
     },
     {
+      'target_name': 'pnacl_url_loader_test',
+      'type': 'none',
+      'variables': {
+        'nexe_target': 'pnacl_url_loader',
+        'build_pnacl_newlib': 1,
+        'nexe_destination_dir': 'nacl_test_data',
+        'generate_nmf': 1,
+        'link_flags': [
+          '-lppapi',
+        ],
+        'sources': [
+          'pnacl_url_loader/pnacl_url_loader.cc',
+        ],
+        'test_files': [
+          'pnacl_url_loader/pnacl_url_loader.html',
+        ],
+      },
+    },
+    {
       'target_name': 'pnacl_dyncode_syscall_disabled_test',
       'type': 'none',
       'variables': {
diff --git a/chrome/test/data/nacl/pnacl_url_loader/pnacl_url_loader.cc b/chrome/test/data/nacl/pnacl_url_loader/pnacl_url_loader.cc
new file mode 100644
index 0000000..9ef656b
--- /dev/null
+++ b/chrome/test/data/nacl/pnacl_url_loader/pnacl_url_loader.cc
@@ -0,0 +1,60 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/url_loader.h"
+#include "ppapi/cpp/url_request_info.h"
+#include "ppapi/cpp/url_response_info.h"
+#include "ppapi/cpp/var.h"
+#include "ppapi/utility/completion_callback_factory.h"
+
+class PnaclUrlLoaderInstance : public pp::Instance {
+ public:
+  explicit PnaclUrlLoaderInstance(PP_Instance instance)
+      : pp::Instance(instance), loader_(this), factory_(this) {}
+
+  void HandleMessage(const pp::Var& var_message) override {
+    if (var_message.is_string()) {
+      command_ = var_message.AsString();
+      pp::URLRequestInfo request(this);
+      request.SetMethod("GET");
+      if (command_.find("Other") != std::string::npos)
+        request.SetURL("https://www.example.com/echo");
+      else
+        request.SetURL("/echo");
+      if (command_.find("CORS") != std::string::npos)
+        request.SetAllowCrossOriginRequests(true);
+      if (command_.find("Credentials") != std::string::npos)
+        request.SetAllowCredentials(true);
+      loader_.Open(request,
+                   factory_.NewCallback(&PnaclUrlLoaderInstance::OnOpen));
+      return;
+    }
+  }
+
+ private:
+  void OnOpen(int32_t result) { PostMessage(pp::Var("OnOpen" + command_)); }
+
+  pp::URLLoader loader_;
+  pp::CompletionCallbackFactory<PnaclUrlLoaderInstance> factory_;
+  std::string command_;
+};
+
+class PnaclUrlLoaderModule : public pp::Module {
+ public:
+  virtual pp::Instance* CreateInstance(PP_Instance instance) {
+    return new PnaclUrlLoaderInstance(instance);
+  }
+};
+
+namespace pp {
+
+__attribute__((visibility("default"))) Module* CreateModule() {
+  return new PnaclUrlLoaderModule();
+}
+
+}  // namespace pp
diff --git a/chrome/test/data/nacl/pnacl_url_loader/pnacl_url_loader.html b/chrome/test/data/nacl/pnacl_url_loader/pnacl_url_loader.html
new file mode 100644
index 0000000..6f186ec
--- /dev/null
+++ b/chrome/test/data/nacl/pnacl_url_loader/pnacl_url_loader.html
@@ -0,0 +1,19 @@
+<script>
+window.addEventListener('load', function() {
+    init();
+  }, false);
+
+function init() {
+  var embed = document.createElement('embed');
+  embed.addEventListener('message', function(message) {
+      window.domAutomationController.setAutomationId(0);
+      window.domAutomationController.send(message.data);
+    }, false);
+  embed.addEventListener('load', function() {
+      embed.postMessage(location.hash.substr(1));
+    }, false);
+  embed.src = 'pnacl_url_loader.nmf';
+  embed.type = 'application/x-pnacl';
+  document.body.appendChild(embed);
+}
+</script>
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 8e84d0be..e6f3068 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-7946.0.0
\ No newline at end of file
+7948.0.0
\ No newline at end of file
diff --git a/components/user_manager/user_image/user_image.h b/components/user_manager/user_image/user_image.h
index 03da41b63..1a05aeb 100644
--- a/components/user_manager/user_image/user_image.h
+++ b/components/user_manager/user_image/user_image.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "base/files/file_path.h"
 #include "components/user_manager/user_manager_export.h"
 #include "ui/gfx/image/image_skia.h"
 #include "url/gurl.h"
@@ -55,8 +56,10 @@
   bool is_safe_format() const { return is_safe_format_; }
   void MarkAsSafe();
 
-  const std::string& file_path() const { return file_path_; }
-  void set_file_path(const std::string& file_path) { file_path_ = file_path; }
+  const base::FilePath& file_path() const { return file_path_; }
+  void set_file_path(const base::FilePath& file_path) {
+    file_path_ = file_path;
+  }
 
  private:
   gfx::ImageSkia image_;
@@ -65,7 +68,7 @@
   GURL url_;
 
   // If image was loaded from the local file, file path is stored here.
-  std::string file_path_;
+  base::FilePath file_path_;
   bool is_safe_format_;
 };
 
diff --git a/content/child/simple_webmimeregistry_impl.cc b/content/child/simple_webmimeregistry_impl.cc
index d65a0cc..9b83704 100644
--- a/content/child/simple_webmimeregistry_impl.cc
+++ b/content/child/simple_webmimeregistry_impl.cc
@@ -10,6 +10,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "components/mime_util/mime_util.h"
 #include "net/base/mime_util.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 
 using blink::WebString;
@@ -87,7 +88,7 @@
     const WebString& file_extension) {
   std::string mime_type;
   net::GetMimeTypeFromExtension(
-      base::FilePath::FromUTF16Unsafe(file_extension).value(), &mime_type);
+      blink::WebStringToFilePath(file_extension).value(), &mime_type);
   return WebString::fromUTF8(mime_type);
 }
 
@@ -95,7 +96,7 @@
     const WebString& file_extension) {
   std::string mime_type;
   net::GetWellKnownMimeTypeFromExtension(
-      base::FilePath::FromUTF16Unsafe(file_extension).value(), &mime_type);
+      blink::WebStringToFilePath(file_extension).value(), &mime_type);
   return WebString::fromUTF8(mime_type);
 }
 
diff --git a/content/child/web_url_request_util.cc b/content/child/web_url_request_util.cc
index f98343a..c08a6377 100644
--- a/content/child/web_url_request_util.cc
+++ b/content/child/web_url_request_util.cc
@@ -13,6 +13,7 @@
 #include "base/strings/string_util.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
@@ -256,11 +257,11 @@
       case WebHTTPBody::Element::TypeFile:
         if (element.fileLength == -1) {
           request_body->AppendFileRange(
-              base::FilePath::FromUTF16Unsafe(element.filePath), 0,
+              blink::WebStringToFilePath(element.filePath), 0,
               std::numeric_limits<uint64_t>::max(), base::Time());
         } else {
           request_body->AppendFileRange(
-              base::FilePath::FromUTF16Unsafe(element.filePath),
+              blink::WebStringToFilePath(element.filePath),
               static_cast<uint64_t>(element.fileStart),
               static_cast<uint64_t>(element.fileLength),
               base::Time::FromDoubleT(element.modificationTime));
diff --git a/content/child/webblobregistry_impl.cc b/content/child/webblobregistry_impl.cc
index 3b534ea..b4f0c4f 100644
--- a/content/child/webblobregistry_impl.cc
+++ b/content/child/webblobregistry_impl.cc
@@ -15,6 +15,7 @@
 #include "content/child/child_thread_impl.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/common/fileapi/webblob_messages.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/WebBlobData.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebThreadSafeData.h"
@@ -210,7 +211,7 @@
     uint64_t length,
     double expected_modification_time) {
   consolidation_.AddFileItem(
-      base::FilePath::FromUTF16Unsafe(base::string16(path)), offset, length,
+      blink::WebStringToFilePath(path), offset, length,
       expected_modification_time);
 }
 
diff --git a/content/child/webfileutilities_impl.cc b/content/child/webfileutilities_impl.cc
index 72ddc73d..268ed09 100644
--- a/content/child/webfileutilities_impl.cc
+++ b/content/child/webfileutilities_impl.cc
@@ -10,6 +10,7 @@
 #include "content/child/file_info_util.h"
 #include "net/base/file_stream.h"
 #include "net/base/filename_util.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/WebFileInfo.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
@@ -32,7 +33,7 @@
     return false;
   }
   base::File::Info file_info;
-  if (!base::GetFileInfo(base::FilePath::FromUTF16Unsafe(path),
+  if (!base::GetFileInfo(blink::WebStringToFilePath(path),
                          reinterpret_cast<base::File::Info*>(&file_info)))
     return false;
 
@@ -42,15 +43,15 @@
 }
 
 WebString WebFileUtilitiesImpl::directoryName(const WebString& path) {
-  return base::FilePath::FromUTF16Unsafe(path).DirName().AsUTF16Unsafe();
+  return blink::WebStringToFilePath(path).DirName().AsUTF16Unsafe();
 }
 
 WebString WebFileUtilitiesImpl::baseName(const WebString& path) {
-  return base::FilePath::FromUTF16Unsafe(path).BaseName().AsUTF16Unsafe();
+  return blink::WebStringToFilePath(path).BaseName().AsUTF16Unsafe();
 }
 
 blink::WebURL WebFileUtilitiesImpl::filePathToURL(const WebString& path) {
-  return net::FilePathToFileURL(base::FilePath::FromUTF16Unsafe(path));
+  return net::FilePathToFileURL(blink::WebStringToFilePath(path));
 }
 
 }  // namespace content
diff --git a/content/renderer/drop_data_builder.cc b/content/renderer/drop_data_builder.cc
index 232428b..1016bcff 100644
--- a/content/renderer/drop_data_builder.cc
+++ b/content/renderer/drop_data_builder.cc
@@ -8,6 +8,7 @@
 
 #include "base/strings/string_util.h"
 #include "content/public/common/drop_data.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/URLConversion.h"
 #include "third_party/WebKit/public/platform/WebDragData.h"
 #include "third_party/WebKit/public/platform/WebString.h"
@@ -60,8 +61,8 @@
       case WebDragData::Item::StorageTypeFilename:
         // TODO(varunjain): This only works on chromeos. Support win/mac/gtk.
         result.filenames.push_back(ui::FileInfo(
-            base::FilePath::FromUTF16Unsafe(item.filenameData),
-            base::FilePath::FromUTF16Unsafe(item.displayNameData)));
+            blink::WebStringToFilePath(item.filenameData),
+            blink::WebStringToFilePath(item.displayNameData)));
         break;
       case WebDragData::Item::StorageTypeFileSystemFile: {
         DropData::FileSystemFileInfo info;
diff --git a/content/renderer/pepper/url_response_info_util.cc b/content/renderer/pepper/url_response_info_util.cc
index d657800..723e657 100644
--- a/content/renderer/pepper/url_response_info_util.cc
+++ b/content/renderer/pepper/url_response_info_util.cc
@@ -17,6 +17,7 @@
 #include "ipc/ipc_message.h"
 #include "ppapi/proxy/ppapi_messages.h"
 #include "ppapi/shared_impl/url_response_info_data.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/WebCString.h"
 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
 #include "third_party/WebKit/public/platform/WebString.h"
@@ -91,7 +92,7 @@
 
   WebString file_path = response.downloadFilePath();
   if (!file_path.isEmpty()) {
-    base::FilePath external_path = base::FilePath::FromUTF16Unsafe(file_path);
+    base::FilePath external_path = blink::WebStringToFilePath(file_path);
     // TODO(teravest): Write a utility function to create resource hosts in the
     // renderer and browser.
     PepperFileRefRendererHost* renderer_host =
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index a906c38..ae0e5589 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2488,7 +2488,7 @@
       render_thread->compositor_task_runner(), context_3d_cb,
       base::Bind(&v8::Isolate::AdjustAmountOfExternalAllocatedMemory,
                  base::Unretained(blink::mainThreadIsolate())),
-      GetMediaPermission(), initial_cdm, media_surface_manager_);
+      GetMediaPermission(), initial_cdm, media_surface_manager_, media_session);
 
 #if defined(OS_ANDROID)
   if (!UseWebMediaPlayerImpl(load_type, url))
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 90c24f7..ee8b8394 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -112,6 +112,7 @@
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "net/http/http_util.h"
 #include "skia/ext/platform_canvas.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/URLConversion.h"
 #include "third_party/WebKit/public/platform/WebCString.h"
 #include "third_party/WebKit/public/platform/WebConnectionType.h"
@@ -1739,7 +1740,7 @@
   int id = enumeration_completion_id_++;
   enumeration_completions_[id] = chooser_completion;
   return Send(new ViewHostMsg_EnumerateDirectory(
-      routing_id(), id, base::FilePath::FromUTF16Unsafe(path)));
+      routing_id(), id, blink::WebStringToFilePath(path)));
 }
 
 void RenderViewImpl::FrameDidStartLoading(WebFrame* frame) {
@@ -1819,7 +1820,7 @@
     ipc_params.mode = FileChooserParams::Open;
   ipc_params.title = params.title;
   ipc_params.default_file_name =
-      base::FilePath::FromUTF16Unsafe(params.initialValue).BaseName();
+      blink::WebStringToFilePath(params.initialValue).BaseName();
   ipc_params.accept_types.reserve(params.acceptTypes.size());
   for (size_t i = 0; i < params.acceptTypes.size(); ++i)
     ipc_params.accept_types.push_back(params.acceptTypes[i]);
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 27965a7..8c2fb0c 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -84,6 +84,7 @@
 #include "media/filters/stream_parser_factory.h"
 #include "storage/common/database/database_identifier.h"
 #include "storage/common/quota/quota_types.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/URLConversion.h"
 #include "third_party/WebKit/public/platform/WebBatteryStatusListener.h"
 #include "third_party/WebKit/public/platform/WebBlobRegistry.h"
@@ -506,7 +507,7 @@
   std::string mime_type;
   RenderThread::Get()->Send(
       new MimeRegistryMsg_GetMimeTypeFromExtension(
-          base::FilePath::FromUTF16Unsafe(file_extension).value(), &mime_type));
+          blink::WebStringToFilePath(file_extension).value(), &mime_type));
   return base::ASCIIToUTF16(mime_type);
 }
 
@@ -518,7 +519,7 @@
   base::File::Info file_info;
   base::File::Error status = base::File::FILE_ERROR_MAX;
   if (!SendSyncMessageFromAnyThread(new FileUtilitiesMsg_GetFileInfo(
-           base::FilePath::FromUTF16Unsafe(path), &file_info, &status)) ||
+           blink::WebStringToFilePath(path), &file_info, &status)) ||
       status != base::File::FILE_OK) {
     return false;
   }
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc
index 0a2beba..cfcfcf21 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.cc
+++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -57,6 +57,7 @@
 #include "net/base/filename_util.h"
 #include "net/base/net_errors.h"
 #include "skia/ext/platform_canvas.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/Platform.h"
 #include "third_party/WebKit/public/platform/WebCString.h"
 #include "third_party/WebKit/public/platform/WebPoint.h"
@@ -327,7 +328,7 @@
     const blink::WebVector<blink::WebString>& absolute_filenames) {
   std::vector<base::FilePath> files;
   for (size_t i = 0; i < absolute_filenames.size(); ++i)
-    files.push_back(base::FilePath::FromUTF16Unsafe(absolute_filenames[i]));
+    files.push_back(blink::WebStringToFilePath(absolute_filenames[i]));
   std::string filesystem_id;
   Send(new LayoutTestHostMsg_RegisterIsolatedFileSystem(
       routing_id(), files, &filesystem_id));
diff --git a/content/test/weburl_loader_mock_factory.cc b/content/test/weburl_loader_mock_factory.cc
index 112c4423..6e0f02b3 100644
--- a/content/test/weburl_loader_mock_factory.cc
+++ b/content/test/weburl_loader_mock_factory.cc
@@ -11,6 +11,7 @@
 #include "base/run_loop.h"
 #include "build/build_config.h"
 #include "content/test/weburl_loader_mock.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURLError.h"
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
@@ -36,15 +37,7 @@
   ResponseInfo response_info;
   response_info.response = response;
   if (!file_path.isNull() && !file_path.isEmpty()) {
-#if defined(OS_POSIX)
-    // TODO(jcivelli): On Linux, UTF8 might not be correct.
-    response_info.file_path =
-        base::FilePath(static_cast<std::string>(file_path.utf8()));
-#elif defined(OS_WIN)
-    base::string16 file_path_16 = file_path;
-    response_info.file_path = base::FilePath(std::wstring(
-        file_path_16.data(), file_path_16.length()));
-#endif
+    response_info.file_path = blink::WebStringToFilePath(file_path);
     DCHECK(base::PathExists(response_info.file_path))
         << response_info.file_path.MaybeAsASCII() << " does not exist.";
   }
diff --git a/media/blink/webmediaplayer_params.cc b/media/blink/webmediaplayer_params.cc
index f36543b..59e9b211 100644
--- a/media/blink/webmediaplayer_params.cc
+++ b/media/blink/webmediaplayer_params.cc
@@ -22,7 +22,8 @@
     const AdjustAllocatedMemoryCB& adjust_allocated_memory_cb,
     MediaPermission* media_permission,
     blink::WebContentDecryptionModule* initial_cdm,
-    SurfaceManager* surface_manager)
+    SurfaceManager* surface_manager,
+    blink::WebMediaSession* media_session)
     : defer_load_cb_(defer_load_cb),
       audio_renderer_sink_(audio_renderer_sink),
       media_log_(media_log),
@@ -33,7 +34,8 @@
       adjust_allocated_memory_cb_(adjust_allocated_memory_cb),
       media_permission_(media_permission),
       initial_cdm_(initial_cdm),
-      surface_manager_(surface_manager) {}
+      surface_manager_(surface_manager),
+      media_session_(media_session) {}
 
 WebMediaPlayerParams::~WebMediaPlayerParams() {}
 
diff --git a/media/blink/webmediaplayer_params.h b/media/blink/webmediaplayer_params.h
index 3efd40b..0c728da 100644
--- a/media/blink/webmediaplayer_params.h
+++ b/media/blink/webmediaplayer_params.h
@@ -21,6 +21,7 @@
 namespace blink {
 class WebContentDecryptionModule;
 class WebMediaPlayerClient;
+class WebMediaSession;
 }
 
 namespace media {
@@ -57,7 +58,8 @@
       const AdjustAllocatedMemoryCB& adjust_allocated_memory_cb,
       MediaPermission* media_permission,
       blink::WebContentDecryptionModule* initial_cdm,
-      SurfaceManager* surface_manager);
+      SurfaceManager* surface_manager,
+      blink::WebMediaSession* media_session);
 
   ~WebMediaPlayerParams();
 
@@ -99,6 +101,8 @@
 
   SurfaceManager* surface_manager() const { return surface_manager_; }
 
+  const blink::WebMediaSession* media_session() const { return media_session_; }
+
  private:
   DeferLoadCB defer_load_cb_;
   scoped_refptr<RestartableAudioRendererSink> audio_renderer_sink_;
@@ -114,6 +118,8 @@
   blink::WebContentDecryptionModule* initial_cdm_;
   SurfaceManager* surface_manager_;
 
+  blink::WebMediaSession* media_session_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(WebMediaPlayerParams);
 };
 
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations
index bbefe01..4e54261 100644
--- a/third_party/WebKit/LayoutTests/LeakExpectations
+++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -99,6 +99,8 @@
 crbug.com/564571 virtual/threaded/animations/svg-length-unittype-crash.html [ Leak ]
 crbug.com/571534 virtual/threaded/animations/svg-element-css-animation-crash.html [ Leak ]
 
+crbug.com/588598 web-animations-api/player-cancel-event.html [ Leak ]
+
 # -----------------------------------------------------------------
 # Untriaged but known leaks of ActiveDOMObject (fast).
 # -----------------------------------------------------------------
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index e69cf60..8abb0e7 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -206,10 +206,6 @@
 # would let us differentiate test_shell and WebKit DumpTreeNode.
 crbug.com/7482 [ Win Mac ] http/tests/misc/timer-vs-loading.html [ WontFix ]
 
-# On Linux bold emoji are already supported.
-crbug.com/551843 [ Linux ] fast/text/fallback-traits-fixup.html [ WontFix ]
-crbug.com/551843 [ Linux Win ] fast/text/emoji-font-weight-mac.html [ WontFix ]
-
 # These tests are too slow with our MESA backend.  We can re-enable when we have
 # bots running tests on real hardware. Don't want to just delete these because they
 # pass in the virtual test suite version.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 21845a5..a419f15f 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1377,8 +1377,6 @@
 
 crbug.com/571773 inspector/console/worker-exception-message-contains-stack.html [ Failure Timeout Crash Pass ]
 
-crbug.com/551843 fast/text/fallback-traits-fixup.html [ NeedsManualRebaseline ]
-
 crbug.com/399951 http/tests/mime/javascript-mimetype-usecounters.html [ Pass Failure ]
 
 crbug.com/572710 [ Debug ] inspector/extensions/extensions-sidebar.html [ Timeout Pass ]
@@ -1408,7 +1406,7 @@
 
 crbug.com/587593 [ Android ] fast/js/pic/cached-single-entry-transition.html [ Pass Failure ]
 
-crbug.com/587779 [ Mac10.10 ] fast/dynamic/window-resize-scrollbars-test.html [ Timeout Failure Pass ]
+crbug.com/587779 [ Mac10.9 Mac10.10 ] fast/dynamic/window-resize-scrollbars-test.html [ Timeout Failure Pass ]
 
 crbug.com/587950 [ Mac Win ] virtual/threaded/animations/background-shorthand-crash.html [ Failure ]
 
diff --git a/third_party/WebKit/LayoutTests/animations/cross-fade-border-image-source-expected.txt b/third_party/WebKit/LayoutTests/animations/cross-fade-border-image-source-expected.txt
index 908994c..b21c14b 100644
--- a/third_party/WebKit/LayoutTests/animations/cross-fade-border-image-source-expected.txt
+++ b/third_party/WebKit/LayoutTests/animations/cross-fade-border-image-source-expected.txt
@@ -1,3 +1,4 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
 PASS - "borderImageSource" property for "box" and "boxStatic" elements at 2.5s are close enough to each other
 PASS - "borderImageSource" property for "boxShorthand" and "boxStatic" elements at 2.5s are close enough to each other
 
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-shorthand-get-set-expected.txt b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-shorthand-get-set-expected.txt
index 5c0dd709..3ad2a930 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-shorthand-get-set-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-shorthand-get-set-expected.txt
@@ -28,12 +28,12 @@
 PASS window.getComputedStyle(gridNoInherit, '').getPropertyValue('grid-auto-flow') is "row"
 PASS window.getComputedStyle(gridNoInherit, '').getPropertyValue('grid-auto-columns') is "auto"
 PASS window.getComputedStyle(gridNoInherit, '').getPropertyValue('grid-auto-rows') is "auto"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumns, '').getPropertyValue('grid-template-columns') is "none"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumns, '').getPropertyValue('grid-template-rows') is "none"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumns, '').getPropertyValue('grid-template-areas') is "none"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumns, '').getPropertyValue('grid-auto-flow') is "column"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumns, '').getPropertyValue('grid-auto-columns') is "10px"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumns, '').getPropertyValue('grid-auto-rows') is "10px"
+PASS window.getComputedStyle(gridWithAutoFlowAndRows, '').getPropertyValue('grid-template-columns') is "none"
+PASS window.getComputedStyle(gridWithAutoFlowAndRows, '').getPropertyValue('grid-template-rows') is "none"
+PASS window.getComputedStyle(gridWithAutoFlowAndRows, '').getPropertyValue('grid-template-areas') is "none"
+PASS window.getComputedStyle(gridWithAutoFlowAndRows, '').getPropertyValue('grid-auto-flow') is "column"
+PASS window.getComputedStyle(gridWithAutoFlowAndRows, '').getPropertyValue('grid-auto-columns') is "10px"
+PASS window.getComputedStyle(gridWithAutoFlowAndRows, '').getPropertyValue('grid-auto-rows') is "10px"
 PASS window.getComputedStyle(gridWithAutoFlowNone, '').getPropertyValue('grid-template-columns') is "none"
 PASS window.getComputedStyle(gridWithAutoFlowNone, '').getPropertyValue('grid-template-rows') is "none"
 PASS window.getComputedStyle(gridWithAutoFlowNone, '').getPropertyValue('grid-template-areas') is "none"
@@ -52,12 +52,12 @@
 PASS window.getComputedStyle(gridWithAutoFlowDenseRow, '').getPropertyValue('grid-auto-flow') is "row dense"
 PASS window.getComputedStyle(gridWithAutoFlowDenseRow, '').getPropertyValue('grid-auto-columns') is "10px"
 PASS window.getComputedStyle(gridWithAutoFlowDenseRow, '').getPropertyValue('grid-auto-rows') is "10px"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumnsAndRows, '').getPropertyValue('grid-template-columns') is "none"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumnsAndRows, '').getPropertyValue('grid-template-rows') is "none"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumnsAndRows, '').getPropertyValue('grid-template-areas') is "none"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumnsAndRows, '').getPropertyValue('grid-auto-flow') is "column"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumnsAndRows, '').getPropertyValue('grid-auto-columns') is "10px"
-PASS window.getComputedStyle(gridWithAutoFlowAndColumnsAndRows, '').getPropertyValue('grid-auto-rows') is "20px"
+PASS window.getComputedStyle(gridWithAutoFlowAndRowsAndColumns, '').getPropertyValue('grid-template-columns') is "none"
+PASS window.getComputedStyle(gridWithAutoFlowAndRowsAndColumns, '').getPropertyValue('grid-template-rows') is "none"
+PASS window.getComputedStyle(gridWithAutoFlowAndRowsAndColumns, '').getPropertyValue('grid-template-areas') is "none"
+PASS window.getComputedStyle(gridWithAutoFlowAndRowsAndColumns, '').getPropertyValue('grid-auto-flow') is "column"
+PASS window.getComputedStyle(gridWithAutoFlowAndRowsAndColumns, '').getPropertyValue('grid-auto-columns') is "20px"
+PASS window.getComputedStyle(gridWithAutoFlowAndRowsAndColumns, '').getPropertyValue('grid-auto-rows') is "10px"
 
 Test getting wrong values for 'grid' shorthand through CSS (they should resolve to the default: 'none')
 PASS window.getComputedStyle(gridWithExplicitAndImplicit, '').getPropertyValue('grid-template-columns') is "none"
@@ -130,10 +130,10 @@
 PASS element.style.gridTemplateAreas is "initial"
 PASS getComputedStyle(element, '').getPropertyValue('grid-auto-flow') is "column"
 PASS element.style.gridAutoFlow is "column"
-PASS getComputedStyle(element, '').getPropertyValue('grid-auto-columns') is "20px"
-PASS element.style.gridAutoColumns is "20px"
-PASS getComputedStyle(element, '').getPropertyValue('grid-auto-rows') is "10px"
-PASS element.style.gridAutoRows is "10px"
+PASS getComputedStyle(element, '').getPropertyValue('grid-auto-columns') is "10px"
+PASS element.style.gridAutoColumns is "10px"
+PASS getComputedStyle(element, '').getPropertyValue('grid-auto-rows') is "20px"
+PASS element.style.gridAutoRows is "20px"
 
 Test the initial value
 PASS window.getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "none"
@@ -158,10 +158,10 @@
 PASS element.style.gridTemplateAreas is "initial"
 PASS getComputedStyle(element, '').getPropertyValue('grid-auto-flow') is "column"
 PASS element.style.gridAutoFlow is "column"
-PASS getComputedStyle(element, '').getPropertyValue('grid-auto-columns') is "10px"
-PASS element.style.gridAutoColumns is "10px"
-PASS getComputedStyle(element, '').getPropertyValue('grid-auto-rows') is "20px"
-PASS element.style.gridAutoRows is "20px"
+PASS getComputedStyle(element, '').getPropertyValue('grid-auto-columns') is "20px"
+PASS element.style.gridAutoColumns is "20px"
+PASS getComputedStyle(element, '').getPropertyValue('grid-auto-rows') is "10px"
+PASS element.style.gridAutoRows is "10px"
 PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "none"
 PASS element.style.gridTemplateColumns is "none"
 PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "none"
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-shorthand-get-set.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-shorthand-get-set.html
index 523aabdd..e90c290 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-shorthand-get-set.html
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-shorthand-get-set.html
@@ -12,7 +12,7 @@
 .gridWithInherit {
     grid: inherit;
 }
-#gridWithAutoFlowAndColumns {
+#gridWithAutoFlowAndRows {
     grid: column 10px;
 }
 #gridWithAutoFlowNone {
@@ -24,7 +24,7 @@
 #gridWithAutoFlowDenseRow {
     grid: dense row 10px;
 }
-#gridWithAutoFlowAndColumnsAndRows {
+#gridWithAutoFlowAndRowsAndColumns {
     grid: column 10px / 20px;
 }
 
@@ -54,11 +54,11 @@
 <div class="grid" class="gridWithTemplate">
     <div><div class="grid gridWithInherit" id="gridNoInherit"></div></div>
 </div-->
-<div class="grid" id="gridWithAutoFlowAndColumns"></div>
+<div class="grid" id="gridWithAutoFlowAndRows"></div>
 <div class="grid" id="gridWithAutoFlowNone"></div>
 <div class="grid" id="gridWithAutoFlowColumnDense"></div>
 <div class="grid" id="gridWithAutoFlowDenseRow"></div>
-<div class="grid" id="gridWithAutoFlowAndColumnsAndRows"></div>
+<div class="grid" id="gridWithAutoFlowAndRowsAndColumns"></div>
 <div class="grid" id="gridWithExplicitAndImplicit"></div>
 <div class="grid" id="gridWithMisplacedNone1"></div>
 <div class="grid" id="gridWithMisplacedNone2"></div>
@@ -72,11 +72,11 @@
     testGridDefinitionsValues(document.getElementById("gridWithTemplate"), "15px", "10px", "none", "row", "auto", "auto");
     testGridDefinitionsValues(document.getElementById("gridInherit"), "15px", "10px", "none", "row", "auto", "auto");
     testGridDefinitionsValues(document.getElementById("gridNoInherit"), "none", "none", "none", "row", "auto", "auto");
-    testGridDefinitionsValues(document.getElementById("gridWithAutoFlowAndColumns"), "none", "none", "none", "column", "10px", "10px");
+    testGridDefinitionsValues(document.getElementById("gridWithAutoFlowAndRows"), "none", "none", "none", "column", "10px", "10px");
     testGridDefinitionsValues(document.getElementById("gridWithAutoFlowNone"), "none", "none", "none", "row", "auto", "auto");
     testGridDefinitionsValues(document.getElementById("gridWithAutoFlowColumnDense"), "none", "none", "none", "column dense", "10px", "10px");
     testGridDefinitionsValues(document.getElementById("gridWithAutoFlowDenseRow"), "none", "none", "none", "row dense", "10px", "10px");
-    testGridDefinitionsValues(document.getElementById("gridWithAutoFlowAndColumnsAndRows"), "none", "none", "none", "column", "10px", "20px");
+    testGridDefinitionsValues(document.getElementById("gridWithAutoFlowAndRowsAndColumns"), "none", "none", "none", "column", "20px", "10px");
 
     debug("");
     debug("Test getting wrong values for 'grid' shorthand through CSS (they should resolve to the default: 'none')");
@@ -90,7 +90,7 @@
     testGridDefinitionsSetJSValues("20px / 10px", "10px", "20px", "none", "row", "auto", "auto", "10px", "20px", "none", "initial", "initial", "initial");
     testGridDefinitionsSetJSValues("[line] 'a' 20px / 10px", "10px", "[line] 20px", "\"a\"", "row", "auto", "auto", "10px", "[line] 20px", "\"a\"", "initial", "initial", "initial");
     testGridDefinitionsSetJSValues("row dense 20px", "none", "none", "none", "row dense", "20px", "20px", "initial", "initial", "initial", "row dense", "20px", "20px");
-    testGridDefinitionsSetJSValues("column 20px / 10px", "none", "none", "none", "column", "20px", "10px", "initial", "initial", "initial", "column", "20px", "10px");
+    testGridDefinitionsSetJSValues("column 20px / 10px", "none", "none", "none", "column", "10px", "20px", "initial", "initial", "initial", "column", "10px", "20px");
 
     debug("");
     debug("Test the initial value");
@@ -106,7 +106,7 @@
 
     debug("");
     debug("Test setting grid-template-columns and grid-template-rows back to 'none' through JS");
-    testGridDefinitionsSetJSValues("column 10px / 20px", "none", "none", "none", "column", "10px", "20px", "initial", "initial", "initial", "column", "10px", "20px");
+    testGridDefinitionsSetJSValues("column 10px / 20px", "none", "none", "none", "column", "20px", "10px", "initial", "initial", "initial", "column", "20px", "10px");
     testGridDefinitionsSetJSValues("none", "none", "none", "none", "row", "auto", "auto", "none", "none", "none", "initial", "initial", "initial");
 
     debug("");
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-template-shorthand-get-set-expected.txt b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-template-shorthand-get-set-expected.txt
index af77a0b9..23fb087 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-template-shorthand-get-set-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-template-shorthand-get-set-expected.txt
@@ -25,15 +25,27 @@
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNames, '').getPropertyValue('grid-template-columns') is "10px"
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNames, '').getPropertyValue('grid-template-rows') is "[head] 15px [tail]"
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNames, '').getPropertyValue('grid-template-areas') is "\"a\""
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesWithoutRowSize, '').getPropertyValue('grid-template-columns') is "10px"
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesWithoutRowSize, '').getPropertyValue('grid-template-rows') is "[head] 0px [tail]"
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesWithoutRowSize, '').getPropertyValue('grid-template-areas') is "\"a\""
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleColumns, '').getPropertyValue('grid-template-columns') is "10px"
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleColumns, '').getPropertyValue('grid-template-rows') is "[head] 15px [tail]"
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleColumns, '').getPropertyValue('grid-template-areas') is "\"a b\""
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleColumnsWithoutRowSize, '').getPropertyValue('grid-template-columns') is "10px"
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleColumnsWithoutRowSize, '').getPropertyValue('grid-template-rows') is "[head] 0px [tail]"
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleColumnsWithoutRowSize, '').getPropertyValue('grid-template-areas') is "\"a b\""
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRows, '').getPropertyValue('grid-template-columns') is "10px"
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRows, '').getPropertyValue('grid-template-rows') is "[head1] 15px [tail1 head2] 20px [tail2]"
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRows, '').getPropertyValue('grid-template-areas') is "\"a\" \"b\""
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsWithoutRowsSizes, '').getPropertyValue('grid-template-columns') is "10px"
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsWithoutRowsSizes, '').getPropertyValue('grid-template-rows') is "[head1] 0px [tail1 head2] 0px [tail2]"
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsWithoutRowsSizes, '').getPropertyValue('grid-template-areas') is "\"a\" \"b\""
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsAndColumns, '').getPropertyValue('grid-template-columns') is "[first] 10px [nav nav2] 15px [nav nav2] 15px"
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsAndColumns, '').getPropertyValue('grid-template-rows') is "100px [nav nav2] 25px [nav nav2] 25px [last]"
 PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsAndColumns, '').getPropertyValue('grid-template-areas') is "\"a b c\" \"d e f\" \"g h i\""
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsAndColumnsWithoutRowsSizes, '').getPropertyValue('grid-template-columns') is "[first] 10px [nav nav2] 15px [nav nav2] 15px"
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsAndColumnsWithoutRowsSizes, '').getPropertyValue('grid-template-rows') is "0px [nav nav2] 0px [nav nav2] 0px [last]"
+PASS window.getComputedStyle(gridTemplateComplexFormWithLineNamesMultipleRowsAndColumnsWithoutRowsSizes, '').getPropertyValue('grid-template-areas') is "\"a b c\" \"d e f\" \"g h i\""
 PASS window.getComputedStyle(gridTemplateComplexFormWithAuto, '').getPropertyValue('grid-template-columns') is "10px"
 PASS window.getComputedStyle(gridTemplateComplexFormWithAuto, '').getPropertyValue('grid-template-rows') is "0px"
 PASS window.getComputedStyle(gridTemplateComplexFormWithAuto, '').getPropertyValue('grid-template-areas') is "\"a\""
@@ -99,6 +111,12 @@
 PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize2, '').getPropertyValue('grid-template-columns') is "none"
 PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize2, '').getPropertyValue('grid-template-rows') is "none"
 PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize2, '').getPropertyValue('grid-template-areas') is "none"
+PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize3, '').getPropertyValue('grid-template-columns') is "none"
+PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize3, '').getPropertyValue('grid-template-rows') is "none"
+PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize3, '').getPropertyValue('grid-template-areas') is "none"
+PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize4, '').getPropertyValue('grid-template-columns') is "none"
+PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize4, '').getPropertyValue('grid-template-rows') is "none"
+PASS window.getComputedStyle(gridTemplateComplexFormMisplacedRowsSize4, '').getPropertyValue('grid-template-areas') is "none"
 PASS window.getComputedStyle(gridTemplateComplexFormColumnsNotParsing1, '').getPropertyValue('grid-template-columns') is "none"
 PASS window.getComputedStyle(gridTemplateComplexFormColumnsNotParsing1, '').getPropertyValue('grid-template-rows') is "none"
 PASS window.getComputedStyle(gridTemplateComplexFormColumnsNotParsing1, '').getPropertyValue('grid-template-areas') is "none"
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-template-shorthand-get-set.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-template-shorthand-get-set.html
index f09780f..f1d58c6 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-template-shorthand-get-set.html
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-template-shorthand-get-set.html
@@ -24,18 +24,33 @@
 #gridTemplateComplexFormWithLineNames {
     grid-template: [head] "a" 15px [tail] / 10px;
 }
+#gridTemplateComplexFormWithLineNamesWithoutRowSize {
+    grid-template: [head] "a" [tail] / 10px;
+}
 #gridTemplateComplexFormWithLineNamesMultipleColumns {
     grid-template: [head] "a b" 15px [tail] / 10px;
 }
+#gridTemplateComplexFormWithLineNamesMultipleColumnsWithoutRowSize {
+    grid-template: [head] "a b" [tail] / 10px;
+}
 #gridTemplateComplexFormWithLineNamesMultipleRows {
     grid-template: [head1] "a" 15px [tail1]
                    [head2] "b" 20px [tail2] / 10px;
 }
+#gridTemplateComplexFormWithLineNamesMultipleRowsWithoutRowsSizes {
+    grid-template: [head1] "a" [tail1]
+                   [head2] "b" [tail2] / 10px;
+}
 #gridTemplateComplexFormWithLineNamesMultipleRowsAndColumns {
-    grid-template: "a b c" 100px [nav]
+    grid-template:        "a b c" 100px [nav]
                    [nav2] "d e f" 25px  [nav]
                    [nav2] "g h i" 25px  [last] / [first] 10px repeat(2, [nav nav2] 15px);
 }
+#gridTemplateComplexFormWithLineNamesMultipleRowsAndColumnsWithoutRowsSizes {
+    grid-template:        "a b c" [nav]
+                   [nav2] "d e f" [nav]
+                   [nav2] "g h i" [last] / [first] 10px repeat(2, [nav nav2] 15px);
+}
 #gridTemplateComplexFormWithAuto {
     grid-template: "a" / 10px;
 }
@@ -103,6 +118,13 @@
 #gridTemplateComplexFormMisplacedRowsSize2 {
     grid-template: "a" [name] 10px / 25px;
 }
+#gridTemplateComplexFormMisplacedRowsSize3 {
+    grid-template: [head] "a" [tail] 10px / 10px;
+}
+#gridTemplateComplexFormMisplacedRowsSize4 {
+    grid-template: [head1] "a" [tail1]
+                   [head2] "a" [tail2] 100px / 10px;
+}
 #gridTemplateComplexFormColumnsNotParsing1 {
     grid-template: "a" [name] 10px / a;
 }
@@ -119,6 +141,7 @@
     grid-template: [first] "a" auto [] [tail];
 }
 
+
 </style>
 <script src="../../resources/js-test.js"></script>
 </head>
@@ -130,9 +153,13 @@
 <div class="grid" id="gridTemplateSimpleFormWithNone"></div>
 <div class="grid" id="gridTemplateComplexForm"></div>
 <div class="grid" id="gridTemplateComplexFormWithLineNames"></div>
+<div class="grid" id="gridTemplateComplexFormWithLineNamesWithoutRowSize"></div>
 <div class="grid" id="gridTemplateComplexFormWithLineNamesMultipleColumns"></div>
+<div class="grid" id="gridTemplateComplexFormWithLineNamesMultipleColumnsWithoutRowSize"></div>
 <div class="grid" id="gridTemplateComplexFormWithLineNamesMultipleRows"></div>
+<div class="grid" id="gridTemplateComplexFormWithLineNamesMultipleRowsWithoutRowsSizes"></div>
 <div class="grid" id="gridTemplateComplexFormWithLineNamesMultipleRowsAndColumns"></div>
+<div class="grid" id="gridTemplateComplexFormWithLineNamesMultipleRowsAndColumnsWithoutRowsSizes"></div>
 <div class="grid" id="gridTemplateComplexFormWithAuto"></div>
 <div class="grid" id="gridTemplateComplexFormOnlyAreas"></div>
 <div class="grid" id="gridTemplateNoColumnsRowWithEmptyTrailingLineNames"></div>
@@ -155,6 +182,8 @@
 <div class="grid" id="gridTemplateComplexFormNoColumnSize"></div>
 <div class="grid" id="gridTemplateComplexFormMisplacedRowsSize1"></div>
 <div class="grid" id="gridTemplateComplexFormMisplacedRowsSize2"></div>
+<div class="grid" id="gridTemplateComplexFormMisplacedRowsSize3"></div>
+<div class="grid" id="gridTemplateComplexFormMisplacedRowsSize4"></div>
 <div class="grid" id="gridTemplateComplexFormColumnsNotParsing1"></div>
 <div class="grid" id="gridTemplateComplexFormColumnsNotParsing2"></div>
 <div class="grid" id="gridTemplateComplexFormWithNoneColumns"></div>
@@ -172,9 +201,13 @@
     testGridDefinitionsValues(document.getElementById("gridTemplateSimpleFormWithNone"), "none", "none", "none");
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexForm"), "10px", "15px", '"a"');
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithLineNames"), "10px", "[head] 15px [tail]", '"a"');
+    testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithLineNamesWithoutRowSize"), "10px", "[head] 0px [tail]", '"a"');
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithLineNamesMultipleColumns"), "10px", "[head] 15px [tail]", '"a b"');
+    testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithLineNamesMultipleColumnsWithoutRowSize"), "10px", "[head] 0px [tail]", '"a b"');
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithLineNamesMultipleRows"), "10px", "[head1] 15px [tail1 head2] 20px [tail2]", '"a" "b"');
+    testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithLineNamesMultipleRowsWithoutRowsSizes"), "10px", "[head1] 0px [tail1 head2] 0px [tail2]", '"a" "b"');
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithLineNamesMultipleRowsAndColumns"), "[first] 10px [nav nav2] 15px [nav nav2] 15px", "100px [nav nav2] 25px [nav nav2] 25px [last]", '"a b c" "d e f" "g h i"');
+    testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithLineNamesMultipleRowsAndColumnsWithoutRowsSizes"), "[first] 10px [nav nav2] 15px [nav nav2] 15px", "0px [nav nav2] 0px [nav nav2] 0px [last]", '"a b c" "d e f" "g h i"');
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithAuto"), "10px", "0px", '"a"');
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormOnlyAreas"), "none", "0px", '"a"');
     testGridDefinitionsValues(document.getElementById("gridTemplateNoColumnsRowWithEmptyTrailingLineNames"), "none", "[first] 0px", '"a"');
@@ -199,6 +232,8 @@
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormNoColumnSize"), "none", "none", "none");
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormMisplacedRowsSize1"), "none", "none", "none");
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormMisplacedRowsSize2"), "none", "none", "none");
+    testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormMisplacedRowsSize3"), "none", "none", "none");
+    testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormMisplacedRowsSize4"), "none", "none", "none");
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormColumnsNotParsing1"), "none", "none", "none");
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormColumnsNotParsing2"), "none", "none", "none");
     testGridDefinitionsValues(document.getElementById("gridTemplateComplexFormWithNoneColumns"), "none", "none", "none");
diff --git a/third_party/WebKit/LayoutTests/fast/css/border-image-style-none-expected.txt b/third_party/WebKit/LayoutTests/fast/css/border-image-style-none-expected.txt
index 26e5dee0..96c6bee 100644
--- a/third_party/WebKit/LayoutTests/fast/css/border-image-style-none-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css/border-image-style-none-expected.txt
@@ -1,3 +1,4 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
 PASS window.internals.isUseCounted(document, BorderImageWithBorderStyleNone) is false
 PASS window.internals.isUseCounted(document, BorderImageWithBorderStyleNone) is false
 PASS window.internals.isUseCounted(document, BorderImageWithBorderStyleNone) is false
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/slotted-expected.txt b/third_party/WebKit/LayoutTests/fast/css/invalidation/slotted-expected.txt
new file mode 100644
index 0000000..e474682
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/slotted-expected.txt
@@ -0,0 +1,14 @@
+Style invalidation of slotted elements.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getComputedStyle(slotted).backgroundColor is "rgba(0, 0, 0, 0)"
+PASS internals.updateStyleAndReturnAffectedElementCount() is 1
+PASS getComputedStyle(slotted).backgroundColor is "rgb(255, 0, 0)"
+PASS internals.updateStyleAndReturnAffectedElementCount() is 1
+PASS getComputedStyle(slotted).backgroundColor is "rgb(0, 128, 0)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/slotted.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/slotted.html
new file mode 100644
index 0000000..8c781aa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/slotted.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<script src="../../../resources/js-test.js"></script>
+<div id="host">
+    <div>
+        <span></span>
+        <span></span>
+    </div>
+    <div id="slotted">
+        <span></span>
+        <span></span>
+    </div>
+    <div>
+        <span></span>
+        <span></span>
+    </div>
+</host>
+<script>
+description("Style invalidation of slotted elements.");
+
+var root = host.attachShadow({"mode":"open"});
+root.innerHTML = '<style>.outer ::slotted(#slotted) { background-color: red } .outer .inner::slotted(#slotted) { background-color: green }</style><div id="outer"><slot id="inner"></slot></div>';
+
+shouldBeEqualToString("getComputedStyle(slotted).backgroundColor", "rgba(0, 0, 0, 0)");
+
+host.offsetTop; // force recalc
+
+root.querySelector("#outer").className = "outer";
+if (window.internals)
+    shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "1");
+shouldBeEqualToString("getComputedStyle(slotted).backgroundColor", "rgb(255, 0, 0)");
+
+host.offsetTop; // force recalc
+
+root.querySelector("#inner").className = "inner";
+if (window.internals)
+    shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "1");
+shouldBeEqualToString("getComputedStyle(slotted).backgroundColor", "rgb(0, 128, 0)");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-in-v0-tree-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-in-v0-tree-crash-expected.txt
new file mode 100644
index 0000000..ea4527b7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-in-v0-tree-crash-expected.txt
@@ -0,0 +1,3 @@
+PASS if no crash.
+
+
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-in-v0-tree-crash.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-in-v0-tree-crash.html
new file mode 100644
index 0000000..a05f8153
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-in-v0-tree-crash.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<script>
+    if (window.testRunner)
+        testRunner.dumpAsText();
+</script>
+<p>PASS if no crash.</p>
+<div id="host">
+    <div id="inner"></div>
+</div>
+<script>
+var root = host.createShadowRoot();
+root.innerHTML = '<style>::slotted(*) { color: green }</style>';
+getComputedStyle(inner).color;
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/images/color-profile-border-image-expected.txt b/third_party/WebKit/LayoutTests/fast/images/color-profile-border-image-expected.txt
index 8b13789..0e590b6 100644
--- a/third_party/WebKit/LayoutTests/fast/images/color-profile-border-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/images/color-profile-border-image-expected.txt
@@ -1 +1,2 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
 
diff --git a/third_party/WebKit/LayoutTests/fast/images/color-profile-border-image-source-expected.txt b/third_party/WebKit/LayoutTests/fast/images/color-profile-border-image-source-expected.txt
index ab45984..2df1778 100644
--- a/third_party/WebKit/LayoutTests/fast/images/color-profile-border-image-source-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/images/color-profile-border-image-source-expected.txt
@@ -1,2 +1,3 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
   
  
diff --git a/third_party/WebKit/LayoutTests/fast/images/color-profile-group-expected.txt b/third_party/WebKit/LayoutTests/fast/images/color-profile-group-expected.txt
index 8d1c8b6..6826899b 100644
--- a/third_party/WebKit/LayoutTests/fast/images/color-profile-group-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/images/color-profile-group-expected.txt
@@ -1 +1,2 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
  
diff --git a/third_party/WebKit/LayoutTests/fast/text/emoji-font-fallback-mac-expected.html b/third_party/WebKit/LayoutTests/fast/text/emoji-font-fallback-mac-expected.html
deleted file mode 100644
index 3001bdcb..0000000
--- a/third_party/WebKit/LayoutTests/fast/text/emoji-font-fallback-mac-expected.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <meta charset="utf-8" />
-        <title>'GRINNING FACE WITH SMILING EYES' (U+1F601)</title>
-    </head>
-    <body>
-        <p style="font-family: Apple Color Emoji;">&#x1f601;😁😜</p>
-        <p>There should be three smiling emojis above.</p>
-    </body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/text/emoji-font-fallback-mac.html b/third_party/WebKit/LayoutTests/fast/text/emoji-font-fallback-mac.html
deleted file mode 100644
index 3e330b4..0000000
--- a/third_party/WebKit/LayoutTests/fast/text/emoji-font-fallback-mac.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <meta charset="utf-8" />
-        <title>'GRINNING FACE WITH SMILING EYES' (U+1F601)</title>
-    </head>
-    <body>
-        <p>&#x1f601;😁😜</p>
-        <p>There should be three smiling emojis above.</p>
-    </body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/text/emoji-font-weight-mac-expected.html b/third_party/WebKit/LayoutTests/fast/text/emoji-font-weight-mac-expected.html
deleted file mode 100644
index 0c895cc..0000000
--- a/third_party/WebKit/LayoutTests/fast/text/emoji-font-weight-mac-expected.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <meta charset="utf-8" />
-        <title>'GRINNING FACE WITH SMILING EYES' (U+1F601)</title>
-    </head>
-    <body>
-      <h1 style="font-weight: normal; font-family: Apple Color Emoji;">&#x1f601;😁😜</h1>
-      <p>There should be three giant smiling emojis above.</p>
-    </body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/text/emoji-font-weight-mac.html b/third_party/WebKit/LayoutTests/fast/text/emoji-font-weight-mac.html
deleted file mode 100644
index 9c590891..0000000
--- a/third_party/WebKit/LayoutTests/fast/text/emoji-font-weight-mac.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <meta charset="utf-8" />
-        <title>'GRINNING FACE WITH SMILING EYES' (U+1F601)</title>
-    </head>
-    <body>
-        <h1 style="font-weight: bold;">&#x1f601;😁😜</h1>
-        <p>There should be three giant smiling emojis above.</p>
-    </body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/styles-2/inject-stylesheet-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/styles-2/inject-stylesheet-expected.txt
index 1323b1f..222a979 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/styles-2/inject-stylesheet-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/elements/styles-2/inject-stylesheet-expected.txt
@@ -1,3 +1,4 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
 CONSOLE MESSAGE: line 10: iframe loaded
 Tests that injected user stylesheets are reflected in the Styles pane.
 
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/decode-resize-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/decode-resize-expected.txt
index 556b484..c0c21f6 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/decode-resize-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/decode-resize-expected.txt
@@ -1,3 +1,4 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
 Tests the instrumentation of a DecodeImage and ResizeImage events
 
 event: Decode Image
diff --git a/third_party/WebKit/LayoutTests/transitions/cross-fade-border-image-expected.txt b/third_party/WebKit/LayoutTests/transitions/cross-fade-border-image-expected.txt
index 5f1a4ed4..efcc1de 100644
--- a/third_party/WebKit/LayoutTests/transitions/cross-fade-border-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/transitions/cross-fade-border-image-expected.txt
@@ -1,3 +1,4 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
 PASS - "border-image-source" property for "box" and "boxStatic" elements at 0.5s are close enough to each other
 PASS - "border-image" property for "boxShorthand" and "boxStatic" elements at 0.5s are close enough to each other
 
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html
index f47492d0..2663002b 100644
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html
+++ b/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html
@@ -119,9 +119,9 @@
 test(function() {
   var animation = idleAnimation();
   animation.finish();
-  assert_unresolved(animation.startTime);
-  assert_unresolved(animation.currentTime);
-  assert_equals(animation.playState, 'idle');
+  assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
+  assert_equals(animation.currentTime, 0);
+  assert_equals(animation.playState, 'finished');
 }, "idle -> finish()");
 
 test(function() {
@@ -345,9 +345,9 @@
 test(function() {
   var animation = pausedAnimation();
   animation.finish();
-  assert_unresolved(animation.startTime);
+  assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
   assert_equals(animation.currentTime, 0);
-  assert_equals(animation.playState, 'paused');
+  assert_equals(animation.playState, 'finished');
 }, "paused -> finish()");
 
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes.html
index 667dd1ba..140b9fb3 100644
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes.html
+++ b/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes.html
@@ -118,9 +118,9 @@
 test(function() {
   var animation = idleAnimation();
   animation.finish();
-  assert_unresolved(animation.startTime);
-  assert_unresolved(animation.currentTime);
-  assert_equals(animation.playState, 'idle');
+  assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime);
+  assert_equals(animation.currentTime, duration);
+  assert_equals(animation.playState, 'finished');
 }, "idle -> finish()");
 
 test(function() {
@@ -344,9 +344,9 @@
 test(function() {
   var animation = pausedAnimation();
   animation.finish();
-  assert_unresolved(animation.startTime);
+  assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime);
   assert_equals(animation.currentTime, duration);
-  assert_equals(animation.playState, 'paused');
+  assert_equals(animation.playState, 'finished');
 }, "paused -> finish()");
 
 test(function() {
diff --git a/third_party/WebKit/Source/core/animation/Animation.cpp b/third_party/WebKit/Source/core/animation/Animation.cpp
index f1a90d5..8dd9f50 100644
--- a/third_party/WebKit/Source/core/animation/Animation.cpp
+++ b/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -577,23 +577,25 @@
 {
     PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
 
-    if (!m_playbackRate || playStateInternal() == Idle) {
+    if (!m_playbackRate) {
+        exceptionState.throwDOMException(InvalidStateError, "Cannot finish Animation with a playbackRate of 0.");
         return;
     }
     if (m_playbackRate > 0 && effectEnd() == std::numeric_limits<double>::infinity()) {
-        exceptionState.throwDOMException(InvalidStateError, "Animation has effect whose end time is infinity.");
+        exceptionState.throwDOMException(InvalidStateError, "Cannot finish Animation with an infinite target effect end.");
         return;
     }
 
+    // Avoid updating start time when already finished.
+    if (calculatePlayState() == Finished)
+        return;
+
     double newCurrentTime = m_playbackRate < 0 ? 0 : effectEnd();
     setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand);
-    if (!paused()) {
-        m_startTime = calculateStartTime(newCurrentTime);
-    }
-
+    m_paused = false;
     m_currentTimePending = false;
-    ASSERT(playStateInternal() != Idle);
-    ASSERT(limited());
+    m_startTime = calculateStartTime(newCurrentTime);
+    m_playState = Finished;
 }
 
 ScriptPromise Animation::finished(ScriptState* scriptState)
diff --git a/third_party/WebKit/Source/core/animation/AnimationTest.cpp b/third_party/WebKit/Source/core/animation/AnimationTest.cpp
index e5cc4df5..95ea90a 100644
--- a/third_party/WebKit/Source/core/animation/AnimationTest.cpp
+++ b/third_party/WebKit/Source/core/animation/AnimationTest.cpp
@@ -253,18 +253,18 @@
     EXPECT_EQ(Animation::Pending, animation->playStateInternal());
     EXPECT_TRUE(std::isnan(animation->startTime()));
     animation->finish(exceptionState);
-    EXPECT_EQ(Animation::Paused, animation->playStateInternal());
-    EXPECT_TRUE(std::isnan(animation->startTime()));
+    EXPECT_EQ(Animation::Finished, animation->playStateInternal());
+    EXPECT_EQ(-30000, animation->startTime());
 }
 
-TEST_F(AnimationAnimationTest, PauseBeatsFinish)
+TEST_F(AnimationAnimationTest, FinishWhenPaused)
 {
     animation->pause();
     EXPECT_EQ(Animation::Pending, animation->playStateInternal());
     simulateFrame(10);
     EXPECT_EQ(Animation::Paused, animation->playStateInternal());
     animation->finish(exceptionState);
-    EXPECT_EQ(Animation::Paused, animation->playStateInternal());
+    EXPECT_EQ(Animation::Finished, animation->playStateInternal());
 }
 
 TEST_F(AnimationAnimationTest, StartTimeFinishPause)
@@ -448,7 +448,7 @@
 {
     animation->setCurrentTime(40 * 1000);
     animation->finish(exceptionState);
-    EXPECT_EQ(30, animation->currentTimeInternal());
+    EXPECT_EQ(40, animation->currentTimeInternal());
 }
 
 TEST_F(AnimationAnimationTest, FinishBeforeStart)
@@ -813,9 +813,9 @@
     EXPECT_TRUE(std::isnan(animation->currentTime()));
     EXPECT_TRUE(std::isnan(animation->startTime()));
     animation->finish(exceptionState);
-    EXPECT_TRUE(std::isnan(animation->currentTime()));
-    EXPECT_TRUE(std::isnan(animation->startTime()));
-    EXPECT_EQ(Animation::Idle, animation->playStateInternal());
+    EXPECT_EQ(30000, animation->currentTime());
+    EXPECT_EQ(-30000, animation->startTime());
+    EXPECT_EQ(Animation::Finished, animation->playStateInternal());
 }
 
 TEST_F(AnimationAnimationTest, PauseAfterCancel)
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.h b/third_party/WebKit/Source/core/css/CSSSelector.h
index 7517f5b..c0544d0d 100644
--- a/third_party/WebKit/Source/core/css/CSSSelector.h
+++ b/third_party/WebKit/Source/core/css/CSSSelector.h
@@ -255,7 +255,7 @@
     bool isShadowSelector() const { return m_relation == ShadowPseudo || m_relation == ShadowDeep; }
     bool isAttributeSelector() const { return m_match >= FirstAttributeSelectorMatch; }
     bool isHostPseudoClass() const { return m_pseudoType == PseudoHost || m_pseudoType == PseudoHostContext; }
-    bool isInsertionPointCrossing() const { return m_pseudoType == PseudoHostContext || m_pseudoType == PseudoContent || m_pseudoType == PseudoSlotted; }
+    bool isInsertionPointCrossing() const { return m_pseudoType == PseudoHostContext || m_pseudoType == PseudoContent; }
 
     Relation relation() const { return static_cast<Relation>(m_relation); }
     void setRelation(Relation relation)
diff --git a/third_party/WebKit/Source/core/css/CSSVariableData.h b/third_party/WebKit/Source/core/css/CSSVariableData.h
index 8e83a8f..5e19511 100644
--- a/third_party/WebKit/Source/core/css/CSSVariableData.h
+++ b/third_party/WebKit/Source/core/css/CSSVariableData.h
@@ -23,9 +23,9 @@
         return adoptRef(new CSSVariableData(range, needsVariableResolution));
     }
 
-    static PassRefPtr<CSSVariableData> createResolved(const Vector<CSSParserToken>& resolvedTokens, PassRefPtr<CSSVariableData> unresolvedData)
+    static PassRefPtr<CSSVariableData> createResolved(const Vector<CSSParserToken>& resolvedTokens, const CSSVariableData& unresolvedData)
     {
-        return adoptRef(new CSSVariableData(resolvedTokens, unresolvedData->m_backingString));
+        return adoptRef(new CSSVariableData(resolvedTokens, unresolvedData.m_backingString));
     }
 
     CSSParserTokenRange tokenRange() { return m_tokens; }
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.cpp b/third_party/WebKit/Source/core/css/RuleFeature.cpp
index 3d76fb5..7eee870 100644
--- a/third_party/WebKit/Source/core/css/RuleFeature.cpp
+++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp
@@ -420,6 +420,10 @@
                 return std::make_pair(&selector, ForceSubtree);
             }
             if (const CSSSelectorList* selectorList = current->selectorList()) {
+                if (current->pseudoType() == CSSSelector::PseudoSlotted) {
+                    ASSERT(position == Subject);
+                    features.invalidatesSlotted = true;
+                }
                 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType()));
                 const CSSSelector* subSelector = selectorList->first();
                 bool allSubSelectorsHaveFeatures = !!subSelector;
@@ -468,6 +472,8 @@
         invalidationSet.setTreeBoundaryCrossing();
     if (features.insertionPointCrossing)
         invalidationSet.setInsertionPointCrossing();
+    if (features.invalidatesSlotted)
+        invalidationSet.setInvalidatesSlotted();
     if (features.forceSubtree)
         invalidationSet.setWholeSubtreeInvalid();
     if (features.contentPseudoCrossing || features.forceSubtree)
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.h b/third_party/WebKit/Source/core/css/RuleFeature.h
index 8f39286..77502aa9 100644
--- a/third_party/WebKit/Source/core/css/RuleFeature.h
+++ b/third_party/WebKit/Source/core/css/RuleFeature.h
@@ -145,6 +145,7 @@
         bool insertionPointCrossing = false;
         bool forceSubtree = false;
         bool contentPseudoCrossing = false;
+        bool invalidatesSlotted = false;
     };
 
     static bool extractInvalidationSetFeature(const CSSSelector&, InvalidationSetFeatures&);
diff --git a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp
index 0c2c95cc..8178f36 100644
--- a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp
+++ b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp
@@ -57,6 +57,7 @@
     , m_customPseudoInvalid(false)
     , m_treeBoundaryCrossing(false)
     , m_insertionPointCrossing(false)
+    , m_invalidatesSlotted(false)
 {
 }
 
@@ -132,6 +133,9 @@
     if (other.insertionPointCrossing())
         setInsertionPointCrossing();
 
+    if (other.invalidatesSlotted())
+        setInvalidatesSlotted();
+
     if (other.m_classes) {
         for (const auto& className : *other.m_classes)
             addClass(className);
@@ -226,6 +230,7 @@
     m_customPseudoInvalid = false;
     m_treeBoundaryCrossing = false;
     m_insertionPointCrossing = false;
+    m_invalidatesSlotted = false;
     m_classes = nullptr;
     m_ids = nullptr;
     m_tagNames = nullptr;
@@ -246,6 +251,8 @@
         value->setBoolean("treeBoundaryCrossing", true);
     if (m_insertionPointCrossing)
         value->setBoolean("insertionPointCrossing", true);
+    if (m_invalidatesSlotted)
+        value->setBoolean("invalidatesSlotted", true);
 
     if (m_ids) {
         value->beginArray("ids");
diff --git a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h
index ff60f30..35f8a42 100644
--- a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h
+++ b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h
@@ -109,7 +109,10 @@
     void setCustomPseudoInvalid() { m_customPseudoInvalid = true; }
     bool customPseudoInvalid() const { return m_customPseudoInvalid; }
 
-    bool isEmpty() const { return !m_classes && !m_ids && !m_tagNames && !m_attributes && !m_customPseudoInvalid && !m_insertionPointCrossing; }
+    void setInvalidatesSlotted() { m_invalidatesSlotted = true; }
+    bool invalidatesSlotted() const { return m_invalidatesSlotted; }
+
+    bool isEmpty() const { return !m_classes && !m_ids && !m_tagNames && !m_attributes && !m_customPseudoInvalid && !m_insertionPointCrossing && !m_invalidatesSlotted; }
 
     void toTracedValue(TracedValue*) const;
 
@@ -164,6 +167,9 @@
 
     // If true, insertion point descendants must be invalidated.
     unsigned m_insertionPointCrossing : 1;
+
+    // If true, distributed nodes of <slot> elements need to be invalidated.
+    unsigned m_invalidatesSlotted : 1;
 };
 
 class CORE_EXPORT DescendantInvalidationSet final : public InvalidationSet {
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
index 67c96eb..211ec34b 100644
--- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
+++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
@@ -10,6 +10,7 @@
 #include "core/dom/ElementTraversal.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLSlotElement.h"
 #include "core/inspector/InspectorTraceEvents.h"
 #include "core/layout/LayoutObject.h"
 
@@ -121,6 +122,8 @@
         m_treeBoundaryCrossing = true;
     if (invalidationSet.insertionPointCrossing())
         m_insertionPointCrossing = true;
+    if (invalidationSet.invalidatesSlotted())
+        m_invalidatesSlotted = true;
     m_invalidationSets.append(&invalidationSet);
     m_invalidateCustomPseudo = invalidationSet.customPseudoInvalid();
 }
@@ -143,6 +146,19 @@
     return false;
 }
 
+bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSetsAsSlotted(Element& element) const
+{
+    ASSERT(m_invalidatesSlotted);
+
+    for (const auto& invalidationSet : m_invalidationSets) {
+        if (!invalidationSet->invalidatesSlotted())
+            continue;
+        if (invalidationSet->invalidatesElement(element))
+            return true;
+    }
+    return false;
+}
+
 void StyleInvalidator::SiblingData::pushInvalidationSet(const SiblingInvalidationSet& invalidationSet)
 {
     unsigned invalidationLimit;
@@ -290,6 +306,8 @@
 
     if (recursionData.insertionPointCrossing() && element.isInsertionPoint())
         element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator));
+    if (recursionData.invalidatesSlotted() && isHTMLSlotElement(element))
+        invalidateSlotDistributedElements(toHTMLSlotElement(element), recursionData);
 
     element.clearChildNeedsStyleInvalidation();
     element.clearNeedsStyleInvalidation();
@@ -297,6 +315,18 @@
     return thisElementNeedsStyleRecalc;
 }
 
+void StyleInvalidator::invalidateSlotDistributedElements(HTMLSlotElement& slot, const RecursionData& recursionData) const
+{
+    for (auto& distributedNode : slot.getDistributedNodes()) {
+        if (distributedNode->needsStyleRecalc())
+            continue;
+        if (!distributedNode->isElementNode())
+            continue;
+        if (recursionData.matchesCurrentInvalidationSetsAsSlotted(toElement(*distributedNode)))
+            distributedNode->setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator));
+    }
+}
+
 DEFINE_TRACE(StyleInvalidator)
 {
 #if ENABLE(OILPAN)
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
index dabe953..e6c1f87 100644
--- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
+++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
@@ -13,6 +13,7 @@
 
 class Document;
 class Element;
+class HTMLSlotElement;
 class InvalidationSet;
 
 
@@ -35,10 +36,13 @@
             , m_wholeSubtreeInvalid(false)
             , m_treeBoundaryCrossing(false)
             , m_insertionPointCrossing(false)
+            , m_invalidatesSlotted(false)
         { }
 
         void pushInvalidationSet(const DescendantInvalidationSet&);
         bool matchesCurrentInvalidationSets(Element&) const;
+        bool matchesCurrentInvalidationSetsAsSlotted(Element&) const;
+
         bool hasInvalidationSets() const { return !wholeSubtreeInvalid() && m_invalidationSets.size(); }
 
         bool wholeSubtreeInvalid() const { return m_wholeSubtreeInvalid; }
@@ -46,6 +50,7 @@
 
         bool treeBoundaryCrossing() const { return m_treeBoundaryCrossing; }
         bool insertionPointCrossing() const { return m_insertionPointCrossing; }
+        bool invalidatesSlotted() const { return m_invalidatesSlotted; }
 
         using DescendantInvalidationSets = Vector<const DescendantInvalidationSet*, 16>;
         DescendantInvalidationSets m_invalidationSets;
@@ -53,6 +58,7 @@
         bool m_wholeSubtreeInvalid;
         bool m_treeBoundaryCrossing;
         bool m_insertionPointCrossing;
+        bool m_invalidatesSlotted;
     };
 
     class SiblingData {
@@ -87,6 +93,7 @@
     bool invalidate(Element&, RecursionData&, SiblingData&);
     bool invalidateShadowRootChildren(Element&, RecursionData&);
     bool invalidateChildren(Element&, RecursionData&);
+    void invalidateSlotDistributedElements(HTMLSlotElement&, const RecursionData&) const;
     bool checkInvalidationSetsAgainstElement(Element&, RecursionData&, SiblingData&);
     void pushInvalidationSetsForElement(Element&, RecursionData&, SiblingData&);
 
@@ -98,6 +105,7 @@
             , m_prevWholeSubtreeInvalid(data->m_wholeSubtreeInvalid)
             , m_treeBoundaryCrossing(data->m_treeBoundaryCrossing)
             , m_insertionPointCrossing(data->m_insertionPointCrossing)
+            , m_invalidatesSlotted(data->m_invalidatesSlotted)
             , m_data(data)
         { }
         ~RecursionCheckpoint()
@@ -107,6 +115,7 @@
             m_data->m_wholeSubtreeInvalid = m_prevWholeSubtreeInvalid;
             m_data->m_treeBoundaryCrossing = m_treeBoundaryCrossing;
             m_data->m_insertionPointCrossing = m_insertionPointCrossing;
+            m_data->m_invalidatesSlotted = m_invalidatesSlotted;
         }
 
     private:
@@ -115,6 +124,7 @@
         bool m_prevWholeSubtreeInvalid;
         bool m_treeBoundaryCrossing;
         bool m_insertionPointCrossing;
+        bool m_invalidatesSlotted;
         RecursionData* m_data;
     };
 
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
index c47bdf3..e299b5e 100644
--- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -1443,7 +1443,7 @@
         ++rowCount;
 
         // Handle template-rows's track-size.
-        if (m_valueList->current() && !isForwardSlashOperator(m_valueList->current()) && m_valueList->current()->m_unit != CSSParserValue::String) {
+        if (m_valueList->current() && m_valueList->current()->m_unit != CSSParserValue::Operator && m_valueList->current()->m_unit != CSSParserValue::String) {
             RefPtrWillBeRawPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
             if (!value)
                 return false;
@@ -1519,7 +1519,7 @@
         return true;
     }
 
-    // 3- [<line-names>? <string> [<track-size> <line-names>]? ]+ syntax.
+    // 3- [<line-names>? <string> <track-size>? <line-names>? ]+ syntax.
     // It requires to rewind parsing due to previous syntax failures.
     m_valueList->setCurrentIndex(0);
     return parseGridTemplateRowsAndAreasAndColumns(important);
@@ -1545,7 +1545,7 @@
     // Need to rewind parsing to explore the alternative syntax of this shorthand.
     m_valueList->setCurrentIndex(0);
 
-    // 2- <grid-auto-flow> [ <grid-auto-columns> [ / <grid-auto-rows> ]? ]
+    // 2- <grid-auto-flow> [ <grid-auto-rows> [ / <grid-auto-columns> ]? ]
     if (!legacyParseAndApplyValue(CSSPropertyGridAutoFlow, important))
         return false;
 
@@ -1553,14 +1553,14 @@
     RefPtrWillBeRawPtr<CSSValue> autoRowsValue = nullptr;
 
     if (m_valueList->current()) {
-        autoColumnsValue = parseGridTrackSize(*m_valueList);
-        if (!autoColumnsValue)
+        autoRowsValue = parseGridTrackSize(*m_valueList);
+        if (!autoRowsValue)
             return false;
         if (m_valueList->current()) {
             if (!isForwardSlashOperator(m_valueList->current()) || !m_valueList->next())
                 return false;
-            autoRowsValue = parseGridTrackSize(*m_valueList);
-            if (!autoRowsValue)
+            autoColumnsValue = parseGridTrackSize(*m_valueList);
+            if (!autoColumnsValue)
                 return false;
         }
         if (m_valueList->current())
@@ -1571,9 +1571,9 @@
         autoRowsValue = cssValuePool().createImplicitInitialValue();
     }
 
-    // if <grid-auto-rows> value is omitted, it is set to the value specified for grid-auto-columns.
-    if (!autoRowsValue)
-        autoRowsValue = autoColumnsValue;
+    // if <grid-auto-columns> value is omitted, it is set to the value specified for grid-auto-rows.
+    if (!autoColumnsValue)
+        autoColumnsValue = autoRowsValue;
 
     addProperty(CSSPropertyGridAutoColumns, autoColumnsValue, important);
     addProperty(CSSPropertyGridAutoRows, autoRowsValue, important);
diff --git a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp
index 47405f9..21ba3a2 100644
--- a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp
@@ -28,73 +28,72 @@
         return false;
     ASSERT(range.peek().type() == CommaToken);
     range.consume();
-    return resolveVariableReferencesFromTokens(range, result);
+    return resolveTokenRange(range, result);
 }
 
-bool CSSVariableResolver::resolveVariableTokensRecursive(CSSParserTokenRange range,
-    Vector<CSSParserToken>& result)
+CSSVariableData* CSSVariableResolver::valueForCustomProperty(AtomicString name)
 {
-    Vector<CSSParserToken> trash;
+    if (m_variablesSeen.contains(name)) {
+        m_cycleStartPoints.add(name);
+        return nullptr;
+    }
+
+    if (!m_styleVariableData)
+        return nullptr;
+    CSSVariableData* variableData = m_styleVariableData->getVariable(name);
+    if (!variableData)
+        return nullptr;
+    if (!variableData->needsVariableResolution())
+        return variableData;
+    RefPtr<CSSVariableData> newVariableData = resolveCustomProperty(name, *variableData);
+    m_styleVariableData->setVariable(name, newVariableData);
+    return newVariableData.get();
+}
+
+PassRefPtr<CSSVariableData> CSSVariableResolver::resolveCustomProperty(AtomicString name, const CSSVariableData& variableData)
+{
+    ASSERT(variableData.needsVariableResolution());
+
+    Vector<CSSParserToken> tokens;
+    m_variablesSeen.add(name);
+    bool success = resolveTokenRange(variableData.tokens(), tokens);
+    m_variablesSeen.remove(name);
+
+    // The old variable data holds onto the backing string the new resolved CSSVariableData
+    // relies on. Ensure it will live beyond us overwriting the RefPtr in StyleVariableData.
+    ASSERT(variableData.refCount() > 1);
+
+    if (!success || !m_cycleStartPoints.isEmpty()) {
+        m_cycleStartPoints.remove(name);
+        return nullptr;
+    }
+    return CSSVariableData::createResolved(tokens, variableData);
+}
+
+bool CSSVariableResolver::resolveVariableReference(CSSParserTokenRange range, Vector<CSSParserToken>& result)
+{
     range.consumeWhitespace();
     ASSERT(range.peek().type() == IdentToken);
     AtomicString variableName = range.consumeIncludingWhitespace().value();
     ASSERT(range.atEnd() || (range.peek().type() == CommaToken));
 
-    // Cycle detection.
-    if (m_variablesSeen.contains(variableName)) {
-        m_cycleStartPoints.add(variableName);
-        resolveFallback(range, trash);
-        return false;
-    }
+    CSSVariableData* variableData = valueForCustomProperty(variableName);
+    if (!variableData)
+        return resolveFallback(range, result);
 
-    CSSVariableData* variableData = m_styleVariableData ? m_styleVariableData->getVariable(variableName) : nullptr;
-    if (variableData) {
-        Vector<CSSParserToken> tokens;
-        if (variableData->needsVariableResolution()) {
-            m_variablesSeen.add(variableName);
-            bool referenceValid = resolveVariableReferencesFromTokens(variableData->tokens(), tokens);
-            m_variablesSeen.remove(variableName);
-
-            // The old variable data holds onto the backing string the new resolved CSSVariableData
-            // relies on. Ensure it will live beyond us overwriting the RefPtr in StyleVariableData.
-            ASSERT(variableData->refCount() > 1);
-
-            if (!referenceValid || !m_cycleStartPoints.isEmpty()) {
-                m_styleVariableData->setVariable(variableName, nullptr);
-                m_cycleStartPoints.remove(variableName);
-                if (!m_cycleStartPoints.isEmpty()) {
-                    resolveFallback(range, trash);
-                    return false;
-                }
-                return resolveFallback(range, result);
-            }
-
-            m_styleVariableData->setVariable(variableName, CSSVariableData::createResolved(tokens, variableData));
-        } else {
-            tokens = variableData->tokens();
-        }
-
-        ASSERT(!tokens.isEmpty());
-        // Check that loops are not induced by the fallback.
-        resolveFallback(range, trash);
-        if (m_cycleStartPoints.isEmpty()) {
-            // It's OK if the fallback fails to resolve - we're not actually taking it.
-            result.appendVector(tokens);
-            return true;
-        }
-        return false;
-    }
-
-    return resolveFallback(range, result);
+    result.appendVector(variableData->tokens());
+    Vector<CSSParserToken> trash;
+    resolveFallback(range, trash);
+    return true;
 }
 
-bool CSSVariableResolver::resolveVariableReferencesFromTokens(CSSParserTokenRange range,
+bool CSSVariableResolver::resolveTokenRange(CSSParserTokenRange range,
     Vector<CSSParserToken>& result)
 {
     bool success = true;
     while (!range.atEnd()) {
         if (range.peek().functionId() == CSSValueVar) {
-            success &= resolveVariableTokensRecursive(range.consumeBlock(), result);
+            success &= resolveVariableReference(range.consumeBlock(), result);
         } else {
             result.append(range.consume());
         }
@@ -108,7 +107,7 @@
 
     CSSVariableResolver resolver(styleVariableData);
     Vector<CSSParserToken> tokens;
-    if (!resolver.resolveVariableReferencesFromTokens(value.variableDataValue()->tokens(), tokens))
+    if (!resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens))
         return cssValuePool().createUnsetValue();
 
     CSSParserContext context(HTMLStandardMode, nullptr);
@@ -122,12 +121,10 @@
 
 void CSSVariableResolver::resolveAndApplyVariableReferences(StyleResolverState& state, CSSPropertyID id, const CSSVariableReferenceValue& value)
 {
-
-    // TODO(leviw): This should be a stack
     CSSVariableResolver resolver(state.style()->variables());
 
     Vector<CSSParserToken> tokens;
-    if (resolver.resolveVariableReferencesFromTokens(value.variableDataValue()->tokens(), tokens)) {
+    if (resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens)) {
         CSSParserContext context(HTMLStandardMode, 0);
 
         WillBeHeapVector<CSSProperty, 256> parsedProperties;
@@ -156,16 +153,10 @@
     if (!variables)
         return;
 
+    CSSVariableResolver resolver(variables);
     for (auto& variable : variables->m_data) {
-        if (!variable.value || !variable.value->needsVariableResolution())
-            continue;
-        Vector<CSSParserToken> resolvedTokens;
-
-        CSSVariableResolver resolver(variables, variable.key);
-        if (resolver.resolveVariableReferencesFromTokens(variable.value->tokens(), resolvedTokens))
-            variable.value = CSSVariableData::createResolved(resolvedTokens, variable.value);
-        else
-            variable.value = nullptr;
+        if (variable.value && variable.value->needsVariableResolution())
+            variable.value = resolver.resolveCustomProperty(variable.key, *variable.value);
     }
 }
 
@@ -174,10 +165,4 @@
 {
 }
 
-CSSVariableResolver::CSSVariableResolver(StyleVariableData* styleVariableData, AtomicString& variable)
-    : m_styleVariableData(styleVariableData)
-{
-    m_variablesSeen.add(variable);
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.h b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.h
index bb740d8..81d69bd 100644
--- a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.h
+++ b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.h
@@ -14,6 +14,7 @@
 namespace blink {
 
 class CSSParserTokenRange;
+class CSSVariableData;
 class CSSVariableReferenceValue;
 class StyleResolverState;
 class StyleVariableData;
@@ -28,12 +29,22 @@
 
 private:
     CSSVariableResolver(StyleVariableData*);
-    CSSVariableResolver(StyleVariableData*, AtomicString& variable);
 
-    // Returns false if we encounter a reference to an invalid variable with no fallback
+    // These return false if we encounter a reference to an invalid variable with no fallback
+
+    // Resolves a range which may contain var() references
+    bool resolveTokenRange(CSSParserTokenRange, Vector<CSSParserToken>& result);
+    // Resolves the fallback (if present) of a var() reference, starting from the comma
     bool resolveFallback(CSSParserTokenRange, Vector<CSSParserToken>& result);
-    bool resolveVariableTokensRecursive(CSSParserTokenRange, Vector<CSSParserToken>& result);
-    bool resolveVariableReferencesFromTokens(CSSParserTokenRange tokens, Vector<CSSParserToken>& result);
+    // Resolves the contents of a var() reference
+    bool resolveVariableReference(CSSParserTokenRange, Vector<CSSParserToken>& result);
+
+    // These return null if the custom property is invalid
+
+    // Returns the CSSVariableData for a custom property, resolving and storing it if necessary
+    CSSVariableData* valueForCustomProperty(AtomicString name);
+    // Resolves the CSSVariableData from a custom property declaration
+    PassRefPtr<CSSVariableData> resolveCustomProperty(AtomicString name, const CSSVariableData&);
 
     StyleVariableData* m_styleVariableData;
     HashSet<AtomicString> m_variablesSeen;
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 7e548db..4601c18 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -2269,8 +2269,10 @@
 HTMLSlotElement* Node::assignedSlot() const
 {
     ASSERT(!needsDistributionRecalc());
-    if (ElementShadow* shadow = parentElementShadow())
-        return shadow->assignedSlotFor(*this);
+    if (ElementShadow* shadow = parentElementShadow()) {
+        if (shadow->isV1())
+            return shadow->assignedSlotFor(*this);
+    }
     return nullptr;
 }
 
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp
index 3d40162..2526de7 100644
--- a/third_party/WebKit/Source/core/frame/Deprecation.cpp
+++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -342,6 +342,9 @@
     case UseCounter::SVGZoomEvent:
         return willBeRemoved("'SVGZoomEvent'", 52, "5760883808534528");
 
+    case UseCounter::BorderImageWithBorderStyleNone:
+        return "Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently does. Setting 'border-style' will be required in M51, around June 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.";
+
     // Features that aren't deprecated don't have a deprecation message.
     default:
         return String();
diff --git a/third_party/WebKit/Source/core/html/HTMLTagNames.in b/third_party/WebKit/Source/core/html/HTMLTagNames.in
index d782dfb..d223b1a 100644
--- a/third_party/WebKit/Source/core/html/HTMLTagNames.in
+++ b/third_party/WebKit/Source/core/html/HTMLTagNames.in
@@ -114,7 +114,7 @@
 script constructorNeedsCreatedByParser
 section interfaceName=HTMLElement
 select constructorNeedsFormElement
-slot interfaceName=HTMLSlotElement
+slot interfaceName=HTMLSlotElement, runtimeEnabled=shadowDOMV1
 small interfaceName=HTMLElement
 source runtimeEnabled=media
 span
diff --git a/third_party/WebKit/Source/core/paint/NinePieceImagePainter.cpp b/third_party/WebKit/Source/core/paint/NinePieceImagePainter.cpp
index e77448e..9eed86d 100644
--- a/third_party/WebKit/Source/core/paint/NinePieceImagePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/NinePieceImagePainter.cpp
@@ -4,7 +4,7 @@
 
 #include "core/paint/NinePieceImagePainter.h"
 
-#include "core/frame/UseCounter.h"
+#include "core/frame/Deprecation.h"
 #include "core/layout/ImageQualityController.h"
 #include "core/layout/LayoutBoxModelObject.h"
 #include "core/paint/BoxPainter.h"
@@ -41,7 +41,7 @@
         || (style.borderRightWidth() && (style.borderRight().style() == BNONE || style.borderRight().style() == BHIDDEN))
         || (style.borderTopWidth() && (style.borderTop().style() == BNONE || style.borderTop().style() == BHIDDEN))
         || (style.borderBottomWidth() && (style.borderBottom().style() == BNONE || style.borderBottom().style() == BHIDDEN)))
-        UseCounter::count(m_layoutObject.document(), UseCounter::BorderImageWithBorderStyleNone);
+        Deprecation::countDeprecation(m_layoutObject.document(), UseCounter::BorderImageWithBorderStyleNone);
 
     // FIXME: border-image is broken with full page zooming when tiling has to happen, since the tiling function
     // doesn't have any understanding of the zoom that is in effect on the tile.
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp
index 3e3803e..88567612d 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp
@@ -32,6 +32,7 @@
 
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/SerializedScriptValue.h"
+#include "core/dom/CrossThreadTask.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "core/workers/DedicatedWorkerThread.h"
@@ -78,39 +79,26 @@
     return static_cast<DedicatedWorkerThread*>(Base::thread());
 }
 
-class UseCounterTask : public ExecutionContextTask {
-public:
-    static PassOwnPtr<UseCounterTask> createCount(UseCounter::Feature feature) { return adoptPtr(new UseCounterTask(feature, false)); }
-    static PassOwnPtr<UseCounterTask> createDeprecation(UseCounter::Feature feature) { return adoptPtr(new UseCounterTask(feature, true)); }
+static void countOnDocument(UseCounter::Feature feature, ExecutionContext* context)
+{
+    ASSERT(context->isDocument());
+    UseCounter::count(context, feature);
+}
 
-private:
-    UseCounterTask(UseCounter::Feature feature, bool isDeprecation)
-        : m_feature(feature)
-        , m_isDeprecation(isDeprecation)
-    {
-    }
-
-    void performTask(ExecutionContext* context) override
-    {
-        ASSERT(context->isDocument());
-        if (m_isDeprecation)
-            Deprecation::countDeprecation(context, m_feature);
-        else
-            UseCounter::count(context, m_feature);
-    }
-
-    UseCounter::Feature m_feature;
-    bool m_isDeprecation;
-};
+static void countDeprecationOnDocument(UseCounter::Feature feature, ExecutionContext* context)
+{
+    ASSERT(context->isDocument());
+    Deprecation::countDeprecation(context, feature);
+}
 
 void DedicatedWorkerGlobalScope::countFeature(UseCounter::Feature feature) const
 {
-    thread()->workerObjectProxy().postTaskToMainExecutionContext(UseCounterTask::createCount(feature));
+    thread()->workerObjectProxy().postTaskToMainExecutionContext(createCrossThreadTask(&countOnDocument, feature));
 }
 
 void DedicatedWorkerGlobalScope::countDeprecation(UseCounter::Feature feature) const
 {
-    thread()->workerObjectProxy().postTaskToMainExecutionContext(UseCounterTask::createDeprecation(feature));
+    thread()->workerObjectProxy().postTaskToMainExecutionContext(createCrossThreadTask(&countDeprecationOnDocument, feature));
 }
 
 DEFINE_TRACE(DedicatedWorkerGlobalScope)
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index 68894fc..238b3ddd 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -104,49 +104,35 @@
     return workerThreads().size();
 }
 
-class WorkerThreadTask : public WebTaskRunner::Task {
-    WTF_MAKE_NONCOPYABLE(WorkerThreadTask); USING_FAST_MALLOC(WorkerThreadTask);
-public:
-    static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
-    {
-        return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented));
+void WorkerThread::performTask(PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
+{
+    ASSERT(isCurrentThread());
+    WorkerGlobalScope* globalScope = workerGlobalScope();
+    // If the thread is terminated before it had a chance initialize (see
+    // WorkerThread::Initialize()), we mustn't run any of the posted tasks.
+    if (!globalScope) {
+        ASSERT(terminated());
+        return;
     }
 
-    ~WorkerThreadTask() override { }
+    if (isInstrumented)
+        InspectorInstrumentation::willPerformExecutionContextTask(globalScope, task.get());
+    task->performTask(globalScope);
+    if (isInstrumented)
+        InspectorInstrumentation::didPerformExecutionContextTask(globalScope);
+}
 
-    void run() override
-    {
-        WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope();
-        // If the thread is terminated before it had a chance initialize (see
-        // WorkerThread::Initialize()), we mustn't run any of the posted tasks.
-        if (!workerGlobalScope) {
-            ASSERT(m_workerThread.terminated());
-            return;
-        }
-
-        if (m_isInstrumented)
-            InspectorInstrumentation::willPerformExecutionContextTask(workerGlobalScope, m_task.get());
-        m_task->performTask(workerGlobalScope);
-        if (m_isInstrumented)
-            InspectorInstrumentation::didPerformExecutionContextTask(workerGlobalScope);
+WebTaskRunner::Task* WorkerThread::createWorkerThreadTask(PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
+{
+    if (isInstrumented)
+        isInstrumented = !task->taskNameForInstrumentation().isEmpty();
+    if (isInstrumented) {
+        // TODO(hiroshige): This doesn't work when called on the main thread.
+        // https://crbug.com/588497
+        InspectorInstrumentation::didPostExecutionContextTask(workerGlobalScope(), task.get());
     }
-
-private:
-    WorkerThreadTask(WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
-        : m_workerThread(workerThread)
-        , m_task(task)
-        , m_isInstrumented(isInstrumented)
-    {
-        if (m_isInstrumented)
-            m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty();
-        if (m_isInstrumented)
-            InspectorInstrumentation::didPostExecutionContextTask(m_workerThread.workerGlobalScope(), m_task.get());
-    }
-
-    WorkerThread& m_workerThread;
-    OwnPtr<ExecutionContextTask> m_task;
-    bool m_isInstrumented;
-};
+    return new Task(threadSafeBind(&WorkerThread::performTask, AllowCrossThreadAccess(this), task, isInstrumented));
+}
 
 class WorkerThread::DebuggerTaskQueue {
     WTF_MAKE_NONCOPYABLE(DebuggerTaskQueue);
@@ -454,12 +440,12 @@
 
 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task)
 {
-    backingThread().postTask(location, WorkerThreadTask::create(*this, task, true).leakPtr());
+    backingThread().postTask(location, createWorkerThreadTask(task, true));
 }
 
 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task, long long delayMs)
 {
-    backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, task, true).leakPtr(), delayMs);
+    backingThread().postDelayedTask(location, createWorkerThreadTask(task, true), delayMs);
 }
 
 void WorkerThread::initializeBackingThread()
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.h b/third_party/WebKit/Source/core/workers/WorkerThread.h
index b39d8bf..f25b045 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.h
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.h
@@ -145,12 +145,15 @@
     class DebuggerTaskQueue;
     friend class WorkerMicrotaskRunner;
 
+    WebTaskRunner::Task* createWorkerThreadTask(PassOwnPtr<ExecutionContextTask>, bool isInstrumented);
+
     // Called on the main thread.
     void terminateInternal();
 
     // Called on the worker thread.
     void initialize(PassOwnPtr<WorkerThreadStartupData>);
     void shutdown();
+    void performTask(PassOwnPtr<ExecutionContextTask>, bool isInstrumented);
     void performShutdownTask();
     void postDelayedTask(const WebTraceLocation&, PassOwnPtr<ExecutionContextTask>, long long delayMs);
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
index b9ebd12..eb93613 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
@@ -10,6 +10,8 @@
 #include "core/workers/WorkerReportingProxy.h"
 #include "core/workers/WorkerThreadStartupData.h"
 #include "platform/NotImplemented.h"
+#include "platform/Task.h"
+#include "platform/ThreadSafeFunctional.h"
 #include "platform/WaitableEvent.h"
 #include "public/platform/WebScheduler.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -142,48 +144,6 @@
     static_cast<WorkerThreadForTest*>(thread)->scriptLoaded();
 }
 
-class WakeupTask : public WebTaskRunner::Task {
-public:
-    WakeupTask() { }
-
-    ~WakeupTask() override { }
-
-    void run() override { }
-};
-
-class PostDelayedWakeupTask : public WebTaskRunner::Task {
-public:
-    PostDelayedWakeupTask(WebScheduler* scheduler, long long delay) : m_scheduler(scheduler), m_delay(delay) { }
-
-    ~PostDelayedWakeupTask() override { }
-
-    void run() override
-    {
-        m_scheduler->timerTaskRunner()->postDelayedTask(BLINK_FROM_HERE, new WakeupTask(), m_delay);
-    }
-
-    WebScheduler* m_scheduler; // Not owned.
-    long long m_delay;
-};
-
-class SignalTask : public WebTaskRunner::Task {
-public:
-    SignalTask(WaitableEvent* completionEvent)
-        : m_completionEvent(completionEvent)
-    {
-    }
-
-    ~SignalTask() override { }
-
-    void run() override
-    {
-        m_completionEvent->signal();
-    }
-
-private:
-    WaitableEvent* m_completionEvent; // Not owned.
-};
-
 } // namespace
 
 class WorkerThreadTest : public testing::Test {
@@ -231,7 +191,7 @@
     void waitForInit()
     {
         OwnPtr<WaitableEvent> completionEvent = adoptPtr(new WaitableEvent());
-        m_workerThread->backingThread().postTask(BLINK_FROM_HERE, new SignalTask(completionEvent.get()));
+        m_workerThread->backingThread().postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&WaitableEvent::signal, AllowCrossThreadAccess(completionEvent.get()))));
         completionEvent->wait();
     }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
index 308efd7..0851dee 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -585,10 +585,11 @@
      * @param {boolean} isLiveEdit
      * @param {string=} sourceMapURL
      * @param {boolean=} hasSourceURL
+     * @param {boolean=} deprecatedCommentWasUsed
      * @param {boolean=} hasSyntaxError
      * @return {!WebInspector.Script}
      */
-    _parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL, hasSyntaxError)
+    _parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, hasSyntaxError)
     {
         var script = new WebInspector.Script(this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL);
         this._registerScript(script);
@@ -596,6 +597,14 @@
             this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script);
         else
             this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, script);
+
+        if (deprecatedCommentWasUsed) {
+            var text = WebInspector.UIString("'//@ sourceURL' and '//@ sourceMappingURL' are deprecated, please use '//# sourceURL=' and '//# sourceMappingURL=' instead.");
+            var msg = new WebInspector.ConsoleMessage(this.target(), WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageLevel.Warning, text, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, scriptId);
+            var consoleModel = this.target().consoleModel;
+            if (consoleModel)
+                consoleModel.addMessage(msg);
+        }
         return script;
     },
 
@@ -950,10 +959,11 @@
      * @param {boolean=} isLiveEdit
      * @param {string=} sourceMapURL
      * @param {boolean=} hasSourceURL
+     * @param {boolean=} deprecatedCommentWasUsed
      */
-    scriptParsed: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL)
+    scriptParsed: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed)
     {
-        this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, !!isContentScript, !!isInternalScript, !!isLiveEdit, sourceMapURL, hasSourceURL, false);
+        this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, !!isContentScript, !!isInternalScript, !!isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, false);
     },
 
     /**
@@ -969,10 +979,11 @@
      * @param {boolean=} isInternalScript
      * @param {string=} sourceMapURL
      * @param {boolean=} hasSourceURL
+     * @param {boolean=} deprecatedCommentWasUsed
      */
-    scriptFailedToParse: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, isContentScript, isInternalScript, sourceMapURL, hasSourceURL)
+    scriptFailedToParse: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, isContentScript, isInternalScript, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed)
     {
-        this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, !!isContentScript, !!isInternalScript, false, sourceMapURL, hasSourceURL, true);
+        this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, !!isContentScript, !!isInternalScript, false, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, true);
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/protocol.json b/third_party/WebKit/Source/devtools/protocol.json
index 1baa4757..367bcab 100644
--- a/third_party/WebKit/Source/devtools/protocol.json
+++ b/third_party/WebKit/Source/devtools/protocol.json
@@ -3912,7 +3912,8 @@
                     { "name": "isInternalScript", "type": "boolean", "optional": true, "description": "Determines whether this script is an internal script.", "hidden": true },
                     { "name": "isLiveEdit", "type": "boolean", "optional": true, "description": "True, if this script is generated as a result of the live edit operation.", "hidden": true },
                     { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with script (if any)." },
-                    { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "hidden": true }
+                    { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "hidden": true },
+                    { "name": "deprecatedCommentWasUsed", "type": "boolean", "optional": true, "hidden": true, "description": "True, if '//@ sourceURL' or '//@ sourceMappingURL' was used."}
                 ],
                 "description": "Fired when virtual machine parses script. This event is also fired for all known and uncollected scripts upon enabling debugger."
             },
@@ -3929,7 +3930,8 @@
                     { "name": "isContentScript", "type": "boolean", "optional": true, "description": "Determines whether this script is a user extension script." },
                     { "name": "isInternalScript", "type": "boolean", "optional": true, "description": "Determines whether this script is an internal script.", "hidden": true },
                     { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with script (if any)." },
-                    { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "hidden": true }
+                    { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "hidden": true },
+                    { "name": "deprecatedCommentWasUsed", "type": "boolean", "optional": true, "hidden": true, "description": "True, if '//@ sourceURL' or '//@ sourceMappingURL' was used."}
                 ],
                 "description": "Fired when virtual machine fails to parse the script."
             },
diff --git a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandle.cpp b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandle.cpp
index 095550d2..dff58e9 100644
--- a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandle.cpp
+++ b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandle.cpp
@@ -186,7 +186,8 @@
         ASSERT(!m_pendingBuffer);
         ASSERT(!m_pendingOffset);
         m_isReading = false;
-        m_pendingBuffer = buffer;
+        if (buffer->length() > 0)
+            m_pendingBuffer = buffer;
         notify();
     }
 
diff --git a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
index 478e0170..9a9daead 100644
--- a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
+++ b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
@@ -185,6 +185,7 @@
     ScriptValue stream(scriptState(), evalWithPrintingError(
         "var controller;"
         "var stream = new ReadableStream({start: c => controller = c});"
+        "controller.enqueue(new Uint8Array());"
         "controller.enqueue(new Uint8Array([0x43, 0x44, 0x45, 0x46]));"
         "controller.enqueue(new Uint8Array([0x47, 0x48, 0x49, 0x4a]));"
         "controller.close();"
@@ -205,6 +206,8 @@
     EXPECT_CALL(checkpoint, Call(4));
     EXPECT_CALL(*client, didGetReadable());
     EXPECT_CALL(checkpoint, Call(5));
+    EXPECT_CALL(*client, didGetReadable());
+    EXPECT_CALL(checkpoint, Call(6));
 
     char buffer[3];
     size_t readBytes;
@@ -216,6 +219,9 @@
     EXPECT_EQ(kShouldWait, reader->read(buffer, 3, kNone, &readBytes));
     testing::runPendingTasks();
     checkpoint.Call(3);
+    EXPECT_EQ(kShouldWait, reader->read(buffer, 3, kNone, &readBytes));
+    testing::runPendingTasks();
+    checkpoint.Call(4);
     EXPECT_EQ(kOk, reader->read(buffer, 3, kNone, &readBytes));
     EXPECT_EQ(3u, readBytes);
     EXPECT_EQ(0x43, buffer[0]);
@@ -226,7 +232,7 @@
     EXPECT_EQ(0x46, buffer[0]);
     EXPECT_EQ(kShouldWait, reader->read(buffer, 3, kNone, &readBytes));
     testing::runPendingTasks();
-    checkpoint.Call(4);
+    checkpoint.Call(5);
     EXPECT_EQ(kOk, reader->read(buffer, 3, kNone, &readBytes));
     EXPECT_EQ(3u, readBytes);
     EXPECT_EQ(0x47, buffer[0]);
@@ -237,7 +243,7 @@
     EXPECT_EQ(0x4a, buffer[0]);
     EXPECT_EQ(kShouldWait, reader->read(buffer, 3, kNone, &readBytes));
     testing::runPendingTasks();
-    checkpoint.Call(5);
+    checkpoint.Call(6);
     EXPECT_EQ(kDone, reader->read(buffer, 3, kNone, &readBytes));
 }
 
@@ -247,6 +253,7 @@
     ScriptValue stream(scriptState(), evalWithPrintingError(
         "var controller;"
         "var stream = new ReadableStream({start: c => controller = c});"
+        "controller.enqueue(new Uint8Array());"
         "controller.enqueue(new Uint8Array([0x43, 0x44, 0x45, 0x46]));"
         "controller.enqueue(new Uint8Array([0x47, 0x48, 0x49, 0x4a]));"
         "controller.close();"
@@ -267,6 +274,8 @@
     EXPECT_CALL(checkpoint, Call(4));
     EXPECT_CALL(*client, didGetReadable());
     EXPECT_CALL(checkpoint, Call(5));
+    EXPECT_CALL(*client, didGetReadable());
+    EXPECT_CALL(checkpoint, Call(6));
 
     const void* buffer;
     size_t available;
@@ -278,6 +287,9 @@
     EXPECT_EQ(kShouldWait, reader->beginRead(&buffer, kNone, &available));
     testing::runPendingTasks();
     checkpoint.Call(3);
+    EXPECT_EQ(kShouldWait, reader->beginRead(&buffer, kNone, &available));
+    testing::runPendingTasks();
+    checkpoint.Call(4);
     EXPECT_EQ(kOk, reader->beginRead(&buffer, kNone, &available));
     EXPECT_EQ(4u, available);
     EXPECT_EQ(0x43, static_cast<const char*>(buffer)[0]);
@@ -300,7 +312,7 @@
     EXPECT_EQ(kOk, reader->endRead(3));
     EXPECT_EQ(kShouldWait, reader->beginRead(&buffer, kNone, &available));
     testing::runPendingTasks();
-    checkpoint.Call(4);
+    checkpoint.Call(5);
     EXPECT_EQ(kOk, reader->beginRead(&buffer, kNone, &available));
     EXPECT_EQ(4u, available);
     EXPECT_EQ(0x47, static_cast<const char*>(buffer)[0]);
@@ -310,7 +322,7 @@
     EXPECT_EQ(kOk, reader->endRead(4));
     EXPECT_EQ(kShouldWait, reader->beginRead(&buffer, kNone, &available));
     testing::runPendingTasks();
-    checkpoint.Call(5);
+    checkpoint.Call(6);
     EXPECT_EQ(kDone, reader->beginRead(&buffer, kNone, &available));
 }
 
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index 95cb9d8..545f40cc 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -26,6 +26,7 @@
   visibility = []  # Allow re-assignment of list.
   visibility = [ "//third_party/WebKit/*" ]
   sources = [
+    "exported/FilePathConversion.cpp",
     "exported/URLConversion.cpp",
     "exported/WebCString.cpp",
     "exported/WebCommon.cpp",
diff --git a/third_party/WebKit/Source/platform/DEPS b/third_party/WebKit/Source/platform/DEPS
index 57e3c62..9566235c 100644
--- a/third_party/WebKit/Source/platform/DEPS
+++ b/third_party/WebKit/Source/platform/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
     # To whitelist base/ stuff Blink is allowed to include, we list up all
     # directories and files instead of writing 'base/'.
+    "+base/files",
     "+base/json",
     "+base/location.h",
     "+base/metrics/histogram.h",
diff --git a/third_party/WebKit/Source/platform/blink_platform.gyp b/third_party/WebKit/Source/platform/blink_platform.gyp
index 4e56cfa..ee2cb4c8 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gyp
+++ b/third_party/WebKit/Source/platform/blink_platform.gyp
@@ -63,6 +63,7 @@
       '<(SHARED_INTERMEDIATE_DIR)/blink',
     ],
     'sources': [
+      'exported/FilePathConversion.cpp',
       'exported/URLConversion.cpp',
       'exported/WebCString.cpp',
       'exported/WebCommon.cpp',
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi
index 4bad7ff..3275e1c 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gypi
+++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -1113,6 +1113,7 @@
       'animation/CompositorFloatAnimationCurveTest.cpp',
       'blob/BlobDataTest.cpp',
       'clipboard/ClipboardUtilitiesTest.cpp',
+      'exported/FilePathConversionTest.cpp',
       'fonts/AcceptLanguagesResolverTest.cpp',
       'fonts/CharacterTest.cpp',
       'fonts/FontCacheTest.cpp',
diff --git a/third_party/WebKit/Source/platform/blink_platform_tests.gyp b/third_party/WebKit/Source/platform/blink_platform_tests.gyp
index 34c4b7e..8525966 100644
--- a/third_party/WebKit/Source/platform/blink_platform_tests.gyp
+++ b/third_party/WebKit/Source/platform/blink_platform_tests.gyp
@@ -80,7 +80,6 @@
         '<(DEPTH)/ui/gfx/gfx.gyp:gfx',
         '<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry',
         '<(DEPTH)/url/url.gyp:url_lib',
-        'blink_platform.gyp:blink_common',
         'blink_platform.gyp:blink_platform',
       ],
       'defines': [
@@ -109,6 +108,7 @@
       'dependencies': [
         '../config.gyp:config',
         '../wtf/wtf.gyp:wtf',
+        'blink_platform.gyp:blink_common',
         'blink_platform.gyp:blink_platform',
         '<(DEPTH)/testing/gmock.gyp:gmock',
       ],
diff --git a/third_party/WebKit/Source/platform/exported/FilePathConversion.cpp b/third_party/WebKit/Source/platform/exported/FilePathConversion.cpp
new file mode 100644
index 0000000..e518e59
--- /dev/null
+++ b/third_party/WebKit/Source/platform/exported/FilePathConversion.cpp
@@ -0,0 +1,35 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "public/platform/FilePathConversion.h"
+
+#include "base/files/file_path.h"
+#include "public/platform/WebString.h"
+#include "wtf/text/StringUTF8Adaptor.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+base::FilePath WebStringToFilePath(const WebString& webString)
+{
+    if (webString.isEmpty())
+        return base::FilePath();
+
+    String str = webString;
+    if (!str.is8Bit()) {
+        return base::FilePath::FromUTF16Unsafe(
+            base::StringPiece16(str.characters16(), str.length()));
+    }
+
+#if OS(POSIX)
+    StringUTF8Adaptor utf8(str);
+    return base::FilePath::FromUTF8Unsafe(utf8.asStringPiece());
+#else
+    const LChar* data8 = str.characters8();
+    return base::FilePath::FromUTF16Unsafe(
+        base::string16(data8, data8 + str.length()));
+#endif
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/platform/exported/FilePathConversionTest.cpp b/third_party/WebKit/Source/platform/exported/FilePathConversionTest.cpp
new file mode 100644
index 0000000..f4f52ec
--- /dev/null
+++ b/third_party/WebKit/Source/platform/exported/FilePathConversionTest.cpp
@@ -0,0 +1,43 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "public/platform/FilePathConversion.h"
+
+#include "base/files/file_path.h"
+#include "public/platform/WebString.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+TEST(FilePathConversionTest, convert)
+{
+    String test8bitString("path");
+    String test8bitLatin1("a\xC4");
+
+    static const UChar test[5] = { 0x0070, 0x0061, 0x0074, 0x0068, 0 }; // path
+    static const UChar testLatin1[3] = { 0x0061, 0x00C4, 0 }; // a\xC4
+    static const UChar testUTF16[3] = { 0x6587, 0x5B57, 0 }; // \u6587 \u5B57
+    String test16bitString(test);
+    String test16bitLatin1(testLatin1);
+    String test16bitUTF16(testUTF16);
+
+    // Latin1 a\xC4 == UTF8 a\xC3\x84
+    base::FilePath pathLatin1 = base::FilePath::FromUTF8Unsafe("a\xC3\x84");
+    // UTF16 \u6587\u5B57 == \xE6\x96\x87\xE5\xAD\x97
+    base::FilePath pathUTF16 = base::FilePath::FromUTF8Unsafe("\xE6\x96\x87\xE5\xAD\x97");
+
+    EXPECT_TRUE(test8bitString.is8Bit());
+    EXPECT_TRUE(test8bitLatin1.is8Bit());
+    EXPECT_FALSE(test16bitString.is8Bit());
+    EXPECT_FALSE(test16bitLatin1.is8Bit());
+
+    EXPECT_EQ(FILE_PATH_LITERAL("path"), WebStringToFilePath(test8bitString).value());
+    EXPECT_EQ(pathLatin1.value(), WebStringToFilePath(test8bitLatin1).value());
+    EXPECT_EQ(FILE_PATH_LITERAL("path"), WebStringToFilePath(test16bitString).value());
+    EXPECT_EQ(pathLatin1.value(), WebStringToFilePath(test16bitLatin1).value());
+    EXPECT_EQ(pathUTF16.value(), WebStringToFilePath(test16bitUTF16).value());
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
index 28dacdb..629b7eb 100644
--- a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
+++ b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
@@ -167,14 +167,8 @@
     substituteFontTraits = [fontManager traitsOfFont:substituteFont];
     substituteFontWeight = [fontManager weightOfFont:substituteFont];
 
-    // TODO(eae): Remove once skia supports bold emoji. See https://bugs.chromium.org/p/skia/issues/detail?id=4904
-    // Bold emoji look the same as normal emoji, so syntheticBold isn't needed.
-    bool syntheticBold = isAppKitFontWeightBold(weight) &&
-        !isAppKitFontWeightBold(substituteFontWeight) &&
-        ![substituteFont.familyName isEqual:@"Apple Color Emoji"];
-
     FontPlatformData alternateFont(substituteFont, platformData.size(),
-        syntheticBold,
+        isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(substituteFontWeight),
         (traits & NSFontItalicTrait) && !(substituteFontTraits & NSFontItalicTrait),
         platformData.orientation());
 
@@ -217,12 +211,7 @@
 
     NSFont *platformFont = useHinting() ? [nsFont screenFont] : [nsFont printerFont];
     NSInteger appKitWeight = toAppKitFontWeight(fontDescription.weight());
-
-    // TODO(eae): Remove once skia supports bold emoji. See https://bugs.chromium.org/p/skia/issues/detail?id=4904
-    // Bold emoji look the same as normal emoji, so syntheticBold isn't needed.
-    bool syntheticBold = [platformFont.familyName isEqual:@"Apple Color Emoji"] ? false :
-        (isAppKitFontWeightBold(appKitWeight) && !isAppKitFontWeightBold(actualWeight)) || fontDescription.isSyntheticBold();
-
+    bool syntheticBold = (isAppKitFontWeightBold(appKitWeight) && !isAppKitFontWeightBold(actualWeight)) || fontDescription.isSyntheticBold();
     bool syntheticItalic = ((traits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait)) || fontDescription.isSyntheticItalic();
 
     // FontPlatformData::typeface() is null in the case of Chromium out-of-process font loading failing.
diff --git a/third_party/WebKit/Source/platform/testing/DEPS b/third_party/WebKit/Source/platform/testing/DEPS
index 1df02fe7..ce8ac9d 100644
--- a/third_party/WebKit/Source/platform/testing/DEPS
+++ b/third_party/WebKit/Source/platform/testing/DEPS
@@ -2,7 +2,6 @@
     # To whitelist base/ stuff Blink is allowed to include, we list up all
     # directories and files instead of writing 'base/'.
     "+base/command_line.h",
-    "+base/files",
     "+base/path_service.h",
     "+base/message_loop",
 ]
diff --git a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
index cb771fa8..9db6c76 100644
--- a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
+++ b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
@@ -30,7 +30,9 @@
 #include "base/message_loop/message_loop.h"
 #include "base/path_service.h"
 #include "platform/SharedBuffer.h"
+#include "public/platform/FilePathConversion.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebString.h"
 #include "public/platform/WebTaskRunner.h"
 #include "public/platform/WebThread.h"
 #include "public/platform/WebTraceLocation.h"
@@ -57,9 +59,7 @@
 
 PassRefPtr<SharedBuffer> readFromFile(const String& path)
 {
-    StringUTF8Adaptor utf8(path);
-    base::FilePath filePath = base::FilePath::FromUTF8Unsafe(
-        std::string(utf8.data(), utf8.length()));
+    base::FilePath filePath = blink::WebStringToFilePath(path);
     std::string buffer;
     base::ReadFileToString(filePath, &buffer);
     return SharedBuffer::create(buffer.data(), buffer.size());
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
index a18dd05..aa38878c 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
@@ -1376,19 +1376,21 @@
     return result.release();
 }
 
-String V8DebuggerAgentImpl::sourceMapURLForScript(const V8DebuggerScript& script, bool success)
-{
-    if (success)
-        return script.sourceMappingURL();
-    return V8ContentSearchUtil::findSourceMapURL(script.source(), false);
-}
-
 void V8DebuggerAgentImpl::didParseSource(const V8DebuggerParsedScript& parsedScript)
 {
     V8DebuggerScript script = parsedScript.script;
 
+    bool isDeprecatedSourceURL = false;
     if (!parsedScript.success)
-        script.setSourceURL(V8ContentSearchUtil::findSourceURL(script.source(), false));
+        script.setSourceURL(V8ContentSearchUtil::findSourceURL(script.source(), false, &isDeprecatedSourceURL));
+    else if (script.hasSourceURL())
+        V8ContentSearchUtil::findSourceURL(script.source(), false, &isDeprecatedSourceURL);
+
+    bool isDeprecatedSourceMappingURL = false;
+    if (!parsedScript.success)
+        script.setSourceMappingURL(V8ContentSearchUtil::findSourceMapURL(script.source(), false, &isDeprecatedSourceMappingURL));
+    else if (!script.sourceMappingURL().isEmpty())
+        V8ContentSearchUtil::findSourceMapURL(script.source(), false, &isDeprecatedSourceMappingURL);
 
     int executionContextId = script.executionContextId();
     bool isContentScript = script.isContentScript();
@@ -1396,17 +1398,19 @@
     bool isLiveEdit = script.isLiveEdit();
     bool hasSourceURL = script.hasSourceURL();
     String scriptURL = script.sourceURL();
-    String sourceMapURL = sourceMapURLForScript(script, parsedScript.success);
+    String sourceMapURL = script.sourceMappingURL();
+    bool deprecatedCommentWasUsed = isDeprecatedSourceURL || isDeprecatedSourceMappingURL;
 
     const String* sourceMapURLParam = sourceMapURL.isNull() ? nullptr : &sourceMapURL;
     const bool* isContentScriptParam = isContentScript ? &isContentScript : nullptr;
     const bool* isInternalScriptParam = isInternalScript ? &isInternalScript : nullptr;
     const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr;
     const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr;
+    const bool* deprecatedCommentWasUsedParam = deprecatedCommentWasUsed ? &deprecatedCommentWasUsed : nullptr;
     if (parsedScript.success)
-        m_frontend->scriptParsed(parsedScript.scriptId, scriptURL, script.startLine(), script.startColumn(), script.endLine(), script.endColumn(), executionContextId, isContentScriptParam, isInternalScriptParam, isLiveEditParam, sourceMapURLParam, hasSourceURLParam);
+        m_frontend->scriptParsed(parsedScript.scriptId, scriptURL, script.startLine(), script.startColumn(), script.endLine(), script.endColumn(), executionContextId, isContentScriptParam, isInternalScriptParam, isLiveEditParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam);
     else
-        m_frontend->scriptFailedToParse(parsedScript.scriptId, scriptURL, script.startLine(), script.startColumn(), script.endLine(), script.endColumn(), executionContextId, isContentScriptParam, isInternalScriptParam, sourceMapURLParam, hasSourceURLParam);
+        m_frontend->scriptFailedToParse(parsedScript.scriptId, scriptURL, script.startLine(), script.startColumn(), script.endLine(), script.endColumn(), executionContextId, isContentScriptParam, isInternalScriptParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam);
 
     m_scripts.set(parsedScript.scriptId, script);
 
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h
index 3ecfab6..9fec35f 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h
@@ -174,8 +174,6 @@
     bool assertPaused(ErrorString*);
     void clearBreakDetails();
 
-    String sourceMapURLForScript(const V8DebuggerScript&, bool success);
-
     bool isCallStackEmptyOrBlackboxed();
     bool isTopCallFrameBlackboxed();
     bool isCallFrameWithUnknownScriptOrBlackboxed(PassRefPtr<JavaScriptCallFrame>);
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 7242f22..a78d8af 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -3234,24 +3234,6 @@
     FrameTestHelpers::reloadFrameIgnoringCache(webViewHelper.webView()->mainFrame());
 }
 
-class ReloadWithOverrideURLTask : public WebTaskRunner::Task {
-public:
-    ReloadWithOverrideURLTask(WebFrame* frame, const KURL& url, bool ignoreCache)
-        : m_frame(frame), m_url(url), m_ignoreCache(ignoreCache)
-    {
-    }
-
-    void run() override
-    {
-        m_frame->reloadWithOverrideURL(m_url, m_ignoreCache);
-    }
-
-private:
-    WebFrame* const m_frame;
-    const KURL m_url;
-    const bool m_ignoreCache;
-};
-
 class ClearScrollStateOnCommitWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
 public:
     void didCommitProvisionalLoad(WebLocalFrame* frame, const WebHistoryItem&, WebHistoryCommitType) override
@@ -3284,24 +3266,21 @@
     float previousScale = webViewHelper.webViewImpl()->pageScaleFactor();
 
     // Reload the page and end up at the same url. State should be propagated.
-    Platform::current()->currentThread()->taskRunner()->postTask(
-        BLINK_FROM_HERE, new ReloadWithOverrideURLTask(webViewHelper.webViewImpl()->mainFrame(), toKURL(m_baseURL + firstURL), false));
+    webViewHelper.webViewImpl()->mainFrame()->reloadWithOverrideURL(toKURL(m_baseURL + firstURL), false);
     FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper.webViewImpl()->mainFrame());
     EXPECT_EQ(previousOffset.width, webViewHelper.webViewImpl()->mainFrame()->scrollOffset().width);
     EXPECT_EQ(previousOffset.height, webViewHelper.webViewImpl()->mainFrame()->scrollOffset().height);
     EXPECT_EQ(previousScale, webViewHelper.webViewImpl()->pageScaleFactor());
 
     // Reload the page using the cache. State should not be propagated.
-    Platform::current()->currentThread()->taskRunner()->postTask(
-        BLINK_FROM_HERE, new ReloadWithOverrideURLTask(webViewHelper.webViewImpl()->mainFrame(), toKURL(m_baseURL + secondURL), false));
+    webViewHelper.webViewImpl()->mainFrame()->reloadWithOverrideURL(toKURL(m_baseURL + secondURL), false);
     FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper.webViewImpl()->mainFrame());
     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrame()->scrollOffset().width);
     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrame()->scrollOffset().height);
     EXPECT_EQ(1.0f, webViewHelper.webViewImpl()->pageScaleFactor());
 
     // Reload the page while ignoring the cache. State should not be propagated.
-    Platform::current()->currentThread()->taskRunner()->postTask(
-        BLINK_FROM_HERE, new ReloadWithOverrideURLTask(webViewHelper.webViewImpl()->mainFrame(), toKURL(m_baseURL + thirdURL), true));
+    webViewHelper.webViewImpl()->mainFrame()->reloadWithOverrideURL(toKURL(m_baseURL + thirdURL), true);
     FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper.webViewImpl()->mainFrame());
     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrame()->scrollOffset().width);
     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrame()->scrollOffset().height);
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
index 7aeae02..831c2d4e 100644
--- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -1345,22 +1345,6 @@
     m_webViewHelper.reset();
 }
 
-class DropTask : public WebTaskRunner::Task {
-public:
-    explicit DropTask(WebView* webView) : m_webView(webView)
-    {
-    }
-
-    void run() override
-    {
-        const WebPoint clientPoint(0, 0);
-        const WebPoint screenPoint(0, 0);
-        m_webView->dragTargetDrop(clientPoint, screenPoint, 0);
-    }
-
-private:
-    WebView* const m_webView;
-};
 static void DragAndDropURL(WebViewImpl* webView, const std::string& url)
 {
     WebDragData dragData;
@@ -1375,7 +1359,7 @@
     const WebPoint clientPoint(0, 0);
     const WebPoint screenPoint(0, 0);
     webView->dragTargetDragEnter(dragData, clientPoint, screenPoint, WebDragOperationCopy, 0);
-    Platform::current()->currentThread()->taskRunner()->postTask(BLINK_FROM_HERE, new DropTask(webView));
+    webView->dragTargetDrop(clientPoint, screenPoint, 0);
     FrameTestHelpers::pumpPendingRequestsDoNotUse(webView->mainFrame());
 }
 
diff --git a/third_party/WebKit/public/blink_headers.gypi b/third_party/WebKit/public/blink_headers.gypi
index 80c4ade..9096d5e 100644
--- a/third_party/WebKit/public/blink_headers.gypi
+++ b/third_party/WebKit/public/blink_headers.gypi
@@ -6,6 +6,7 @@
   'variables': {
     'blink_public_sources': [
       "platform/Platform.h",
+      "platform/FilePathConversion.h",
       "platform/URLConversion.h",
       "platform/WebApiKeyValidator.h",
       "platform/WebApplicationCacheHost.h",
diff --git a/third_party/WebKit/public/platform/FilePathConversion.h b/third_party/WebKit/public/platform/FilePathConversion.h
new file mode 100644
index 0000000..17e934ed
--- /dev/null
+++ b/third_party/WebKit/public/platform/FilePathConversion.h
@@ -0,0 +1,22 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FilePathConversion_h
+#define FilePathConversion_h
+
+#include "WebCommon.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace blink {
+
+class WebString;
+
+BLINK_COMMON_EXPORT base::FilePath WebStringToFilePath(const WebString&);
+
+} // namespace blink
+
+#endif // FilePathConversion_h
diff --git a/tools/android/loading/trace_test/results/3.result b/tools/android/loading/trace_test/results/3.result
index f909cae2..bcebf63 100644
--- a/tools/android/loading/trace_test/results/3.result
+++ b/tools/android/loading/trace_test/results/3.result
@@ -1,6 +1,6 @@
 parser (no stack) 3a.js
 parser (no stack) 3c.js
-script () 3a.jpg
-script () 3b.jpg
-script () 3c.jpg
+script (3a.js:10/3a.js:14/3.html:23) 3a.jpg
 script (3a.js:20) 3b.js
+script (3b.js:9) 3b.jpg
+script (3c.js:7/3.html:24) 3c.jpg
diff --git a/tools/android/loading/trace_test/tests/3.html b/tools/android/loading/trace_test/tests/3.html
index 03bbce6..f6850eb 100644
--- a/tools/android/loading/trace_test/tests/3.html
+++ b/tools/android/loading/trace_test/tests/3.html
@@ -10,9 +10,6 @@
 
   Note that as 3b.js adds a tag to the body, it is executed only after
   the body has been parsed. No, I don't know how that works either.
-
-  At any rate, only 3c.js has a meaningful stack trace in the
-  initiator. The images have script initiators with empty stacks.
 -->
 <html>
 <head>
diff --git a/tools/android/loading/trace_test/webserver_test.py b/tools/android/loading/trace_test/webserver_test.py
index 2b413a8..800b8d6 100755
--- a/tools/android/loading/trace_test/webserver_test.py
+++ b/tools/android/loading/trace_test/webserver_test.py
@@ -148,14 +148,24 @@
       return
     for rq in trace.request_track.GetEvents():
       if rq.initiator['type'] in ('parser', 'script'):
-        stack = 'no stack'
-        if 'stack' in rq.initiator:
-          stack = '/'.join(
+        stack_string = ''
+        stack = rq.initiator.get('stack')
+        # Iteratively walk the stack and its parents.
+        while stack:
+          current_string = '/'.join(
               ['%s:%s' % (self._ShortUrl(frame['url']), frame['lineNumber'])
-               for frame in rq.initiator['stack']['callFrames']])
+               for frame in stack['callFrames']])
+          if len(current_string) and len(stack_string):
+            stack_string += '/'
+          stack_string += current_string
+          stack = stack.get('parent')
+
+        if stack_string == '':
+          stack_string = 'no stack'
+
         self._seq.append('%s (%s) %s' % (
             rq.initiator['type'],
-            stack,
+            stack_string,
             self._ShortUrl(rq.url)))
     self._seq.sort()
 
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
index bad4b7b..79814e6 100644
--- a/tools/gn/setup.cc
+++ b/tools/gn/setup.cc
@@ -226,21 +226,6 @@
 }
 #endif
 
-// Expands all ./, ../, and symbolic links in the given path.
-bool NormalizePath(const base::FilePath& path, base::FilePath* out) {
-#if defined(OS_POSIX)
-  char buf[PATH_MAX];
-  if (!realpath(path.value().c_str(), buf)) {
-    return false;
-  }
-  *out = base::FilePath(buf);
-#else
-  // Do nothing on a non-POSIX system.
-  *out = path;
-#endif
-  return true;
-}
-
 }  // namespace
 
 const char Setup::kBuildArgFileName[] = "args.gn";
@@ -528,16 +513,9 @@
     root_path = dotfile_name_.DirName();
   }
 
-  base::FilePath root_path_normalized;
-  if (!NormalizePath(root_path, &root_path_normalized)) {
-    Err(Location(), "Can't normalize the root path.",
-        "I could not normalize the path \"" + FilePathToUTF8(root_path) + "\".")
-        .PrintToStdout();
-    return false;
-  }
   if (scheduler_.verbose_logging())
-    scheduler_.Log("Using source root", FilePathToUTF8(root_path_normalized));
-  build_settings_.SetRootPath(root_path_normalized);
+    scheduler_.Log("Using source root", FilePathToUTF8(root_path));
+  build_settings_.SetRootPath(root_path);
 
   return true;
 }
@@ -553,21 +531,11 @@
     return false;
   }
 
-  base::FilePath build_dir_path = build_settings_.GetFullPath(resolved);
-  base::FilePath build_dir_path_normalized;
-  if (!NormalizePath(build_dir_path, &build_dir_path_normalized)) {
-    Err(Location(), "Can't normalize the root path.",
-        "I could not normalize the path \"" + FilePathToUTF8(build_dir_path) +
-        "\".").PrintToStdout();
-    return false;
-  }
-  resolved = SourceDirForPath(build_settings_.root_path(),
-                              build_dir_path_normalized);
-
   if (scheduler_.verbose_logging())
     scheduler_.Log("Using build dir", resolved.value());
 
   if (require_exists) {
+    base::FilePath build_dir_path = build_settings_.GetFullPath(resolved);
     if (!base::PathExists(build_dir_path.Append(
             FILE_PATH_LITERAL("build.ninja")))) {
       Err(Location(), "Not a build directory.",
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index cf050a1..31c72c0c 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -47044,6 +47044,42 @@
   </summary>
 </histogram>
 
+<histogram name="SiteEngagementService.ScoreDecayedFrom">
+  <owner>calamity@chromium.org</owner>
+  <owner>dominickn@chromium.org</owner>
+  <summary>
+    The site engagement score of an origin prior to applying decay. Recorded at
+    the first engagement event after decay, independently per decay event.
+  </summary>
+</histogram>
+
+<histogram name="SiteEngagementService.ScoreDecayedTo">
+  <owner>calamity@chromium.org</owner>
+  <owner>dominickn@chromium.org</owner>
+  <summary>
+    The site engagement score of an origin once decay has occured. Recorded at
+    the first engagement event after decay, independently per decay event.
+  </summary>
+</histogram>
+
+<histogram name="SiteEngagementService.ScoreDecayedFrom">
+  <owner>calamity@chromium.org</owner>
+  <owner>dominickn@chromium.org</owner>
+  <summary>
+    The site engagement score of an origin prior to applying decay. Recorded at
+    the first engagement event after decay, independently per decay event.
+  </summary>
+</histogram>
+
+<histogram name="SiteEngagementService.ScoreDecayedTo">
+  <owner>calamity@chromium.org</owner>
+  <owner>dominickn@chromium.org</owner>
+  <summary>
+    The site engagement score of an origin once decay has occured. Recorded at
+    the first engagement event after decay, independently per decay event.
+  </summary>
+</histogram>
+
 <histogram name="SiteEngagementService.TotalEngagement">
   <owner>calamity@chromium.org</owner>
   <owner>dominickn@chromium.org</owner>