merge mozilla-inbound to mozilla-central. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 04 Nov 2017 10:58:24 +0100
changeset 390187 14fd26761bc4d10c5334abe50d7b6f3a5908f08d
parent 390186 52b2b0d65a904292c5646494183ede51ab842349 (current diff)
parent 390021 405cc8ca7f764e985c6ab1e6d4365681b6ff2e10 (diff)
child 390188 39d71149faea86d74a770711992b745892e49801
child 390190 e437203962cc7d97b1646d09ed3061272a1df443
child 390196 6d0ba331fc8e6e146f3ed9933ec564dfd08dcc8e
push id96988
push userarchaeopteryx@coole-files.de
push dateSat, 04 Nov 2017 10:03:29 +0000
treeherdermozilla-inbound@39d71149faea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone58.0a1
first release with
nightly linux32
14fd26761bc4 / 58.0a1 / 20171104100412 / files
nightly linux64
14fd26761bc4 / 58.0a1 / 20171104100412 / files
nightly mac
14fd26761bc4 / 58.0a1 / 20171104100412 / files
nightly win32
14fd26761bc4 / 58.0a1 / 20171104100412 / files
nightly win64
14fd26761bc4 / 58.0a1 / 20171104100412 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central. r=merge a=merge MozReview-Commit-ID: Ai6Y5GGfkfT
browser/config/tooltool-manifests/win32/vs2017.manifest
browser/config/tooltool-manifests/win64/vs2017.manifest
dom/interfaces/xul/nsIDOMXULImageElement.idl
dom/plugins/base/PluginPRLibrary.cpp
dom/plugins/base/PluginPRLibrary.h
js/src/tests/js1_8_5/extensions/is-generator.js
modules/libpref/test/unit/test_extprefs.js
toolkit/xre/nsXREDirProvider.cpp
xpcom/io/nsAppDirectoryServiceDefs.h
new file mode 100644
--- /dev/null
+++ b/accessible/base/XULMap.h
@@ -0,0 +1,5 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+XULMAP(image, New_MaybeImageOrToolbarButtonAccessible)
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -245,16 +245,34 @@ static Accessible*
 New_HTMLTableHeaderCellIfScope(nsIContent* aContent, Accessible* aContext)
 {
   if (aContext->IsTableRow() && aContext->GetContent() == aContent->GetParent() &&
       aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::scope))
     return new HTMLTableHeaderCellAccessibleWrap(aContent, aContext->Document());
   return nullptr;
 }
 
+#ifdef MOZ_XUL
+static Accessible*
+New_MaybeImageOrToolbarButtonAccessible(nsIContent* aContent,
+                                        Accessible* aContext)
+{
+  if (aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::onclick)) {
+    return new XULToolbarButtonAccessible(aContent, aContext->Document());
+  }
+
+  // Don't include nameless images in accessible tree.
+  if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext)) {
+    return nullptr;
+  }
+
+  return new ImageAccessibleWrap(aContent, aContext->Document());
+}
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 // Markup maps array.
 
 #define Attr(name, value) \
   { &nsGkAtoms::name, &nsGkAtoms::value }
 
 #define AttrFromDOM(name, DOMAttrName) \
   { &nsGkAtoms::name, nullptr, &nsGkAtoms::DOMAttrName }
@@ -264,32 +282,47 @@ New_HTMLTableHeaderCellIfScope(nsIConten
 
 #define MARKUPMAP(atom, new_func, r, ... ) \
   { &nsGkAtoms::atom, new_func, static_cast<a11y::role>(r), { __VA_ARGS__ } },
 
 static const MarkupMapInfo sMarkupMapList[] = {
   #include "MarkupMap.h"
 };
 
+#ifdef MOZ_XUL
+#define XULMAP(atom, new_func) \
+  { &nsGkAtoms::atom, new_func },
+
+static const XULMarkupMapInfo sXULMapList[] = {
+  #include "XULMap.h"
+};
+#endif
+
 #undef Attr
 #undef AttrFromDOM
 #undef AttrFromDOMIf
 #undef MARKUPMAP
+#ifdef MOZ_XUL
+#undef XULMAP
+#endif
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService
 ////////////////////////////////////////////////////////////////////////////////
 
 nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nullptr;
 ApplicationAccessible* nsAccessibilityService::gApplicationAccessible = nullptr;
 xpcAccessibleApplication* nsAccessibilityService::gXPCApplicationAccessible = nullptr;
 uint32_t nsAccessibilityService::gConsumers = 0;
 
 nsAccessibilityService::nsAccessibilityService() :
   DocManager(), FocusManager(), mMarkupMaps(ArrayLength(sMarkupMapList))
+#ifdef MOZ_XUL
+  , mXULMarkupMaps(ArrayLength(sXULMapList))
+#endif
 {
 }
 
 nsAccessibilityService::~nsAccessibilityService()
 {
   NS_ASSERTION(IsShutdown(), "Accessibility wasn't shutdown!");
   gAccessibilityService = nullptr;
 }
@@ -1157,19 +1190,30 @@ nsAccessibilityService::CreateAccessible
       if (deckFrame && deckFrame->GetSelectedBox() != frame) {
         if (aIsSubtreeHidden)
           *aIsSubtreeHidden = true;
 
         return nullptr;
       }
     }
 
+#ifdef MOZ_XUL
+    // Prefer to use XUL to decide if and what kind of accessible to create.
+    const XULMarkupMapInfo* xulMap =
+      mXULMarkupMaps.Get(content->NodeInfo()->NameAtom());
+    if (xulMap && xulMap->new_func) {
+      newAcc = xulMap->new_func(content, aContext);
+    }
+#endif
+
     // XBL bindings may use @role attribute to point the accessible type
     // they belong to.
-    newAcc = CreateAccessibleByType(content, document);
+    if (!newAcc) {
+      newAcc = CreateAccessibleByType(content, document);
+    }
 
     // Any XUL box can be used as tabpanel, make sure we create a proper
     // accessible for it.
     if (!newAcc && aContext->IsXULTabpanels() &&
         content->GetParent() == aContext->GetContent()) {
       LayoutFrameType frameType = frame->Type();
       if (frameType == LayoutFrameType::Box ||
           frameType == LayoutFrameType::Scroll) {
@@ -1271,16 +1315,21 @@ nsAccessibilityService::Init()
   if (!eventListenerService)
     return false;
 
   eventListenerService->AddListenerChangeListener(this);
 
   for (uint32_t i = 0; i < ArrayLength(sMarkupMapList); i++)
     mMarkupMaps.Put(*sMarkupMapList[i].tag, &sMarkupMapList[i]);
 
+#ifdef MOZ_XUL
+  for (uint32_t i = 0; i < ArrayLength(sXULMapList); i++)
+    mXULMarkupMaps.Put(*sXULMapList[i].tag, &sXULMapList[i]);
+#endif
+
 #ifdef A11Y_LOG
   logging::CheckEnv();
 #endif
 
   gAccessibilityService = this;
   NS_ADDREF(gAccessibilityService); // will release in Shutdown()
 
   if (XRE_IsParentProcess()) {
@@ -1416,29 +1465,16 @@ nsAccessibilityService::CreateAccessible
       accessible = new XULTabpanelsAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:dropmarker")) {
       accessible = new XULDropmarkerAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:groupbox")) {
       accessible = new XULGroupboxAccessible(aContent, aDoc);
 
-  } else if (role.EqualsLiteral("xul:image")) {
-    if (aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::onclick)) {
-      accessible = new XULToolbarButtonAccessible(aContent, aDoc);
-
-    } else {
-      // Don't include nameless images in accessible tree.
-      if (!aContent->HasAttr(kNameSpaceID_None,
-                             nsGkAtoms::tooltiptext))
-        return nullptr;
-
-      accessible = new ImageAccessibleWrap(aContent, aDoc);
-    }
-
   } else if (role.EqualsLiteral("xul:link")) {
     accessible = new XULLinkAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:listbox")) {
       accessible = new XULListboxAccessibleWrap(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:listcell")) {
     // Only create cells if there's more than one per row.
--- a/accessible/base/nsAccessibilityService.h
+++ b/accessible/base/nsAccessibilityService.h
@@ -62,16 +62,23 @@ struct MarkupAttrInfo {
 
 struct MarkupMapInfo {
   nsStaticAtom** tag;
   New_Accessible* new_func;
   a11y::role role;
   MarkupAttrInfo attrs[4];
 };
 
+#ifdef MOZ_XUL
+struct XULMarkupMapInfo {
+  nsStaticAtom** tag;
+  New_Accessible* new_func;
+};
+#endif
+
 } // namespace a11y
 } // namespace mozilla
 
 class nsAccessibilityService final : public mozilla::a11y::DocManager,
                                      public mozilla::a11y::FocusManager,
                                      public mozilla::a11y::SelectionManager,
                                      public nsIListenerChangeListener,
                                      public nsIObserver
@@ -306,16 +313,19 @@ private:
   static mozilla::a11y::xpcAccessibleApplication* gXPCApplicationAccessible;
 
   /**
    * Contains a set of accessibility service consumers.
    */
   static uint32_t gConsumers;
 
   nsDataHashtable<nsPtrHashKey<const nsAtom>, const mozilla::a11y::MarkupMapInfo*> mMarkupMaps;
+#ifdef MOZ_XUL
+  nsDataHashtable<nsPtrHashKey<const nsAtom>, const mozilla::a11y::XULMarkupMapInfo*> mXULMarkupMaps;
+#endif
 
   friend nsAccessibilityService* GetAccService();
   friend nsAccessibilityService* GetOrCreateAccService(uint32_t);
   friend void MaybeShutdownAccService(uint32_t);
   friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
   friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
   friend mozilla::a11y::ApplicationAccessible* mozilla::a11y::ApplicationAcc();
   friend mozilla::a11y::xpcAccessibleApplication* mozilla::a11y::XPCApplicationAcc();
--- a/accessible/tests/mochitest/role/test_general.xul
+++ b/accessible/tests/mochitest/role/test_general.xul
@@ -13,16 +13,21 @@
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
 
   <script type="application/javascript">
   <![CDATA[
     function doTest()
     {
+      ok(!isAccessible("image"),
+                      "image without tooltiptext shouldn't be accessible.");
+      testRole("image-tooltiptext", ROLE_GRAPHIC);
+      testRole("image-onclick", ROLE_PUSHBUTTON);
+
       ok(!isAccessible("statusbarpanel"),
                       "statusbarpanel shouldn't be accessible.");
       testRole("statusbarpanel-iconic", ROLE_PUSHBUTTON);
       testRole("statusbarpanel-iconic-text", ROLE_PUSHBUTTON);
       testRole("statusbar", ROLE_STATUSBAR);
 
       SimpleTest.finish();
     }
@@ -42,16 +47,20 @@
     </a>
   <p id="display"></p>
     <div id="content" style="display: none">
     </div>
     <pre id="test">
     </pre>
   </body>
 
+  <image id="image" src="../moz.png"/>
+  <image id="image-tooltiptext" src="../moz.png" tooltiptext="hello"/>
+  <image id="image-onclick" src="../moz.png" onclick=""/>
+
   <statusbarpanel id="statusbarpanel"></statusbarpanel>
   <statusbarpanel id="statusbarpanel-iconic" class="statusbarpanel-iconic"></statusbarpanel>
   <statusbarpanel id="statusbarpanel-iconic-text" class="statusbarpanel-iconic-text"></statusbarpanel>
   <statusbar id="statusbar"></statusbar>
 
   </hbox>
 </window>
 
--- a/accessible/tests/mochitest/tree/a11y.ini
+++ b/accessible/tests/mochitest/tree/a11y.ini
@@ -29,16 +29,17 @@ skip-if = true # Bug 561508
 [test_dockids.html]
 [test_filectrl.html]
 [test_formctrl.html]
 skip-if = buildapp == "mulet"
 [test_formctrl.xul]
 [test_gencontent.html]
 [test_groupbox.xul]
 [test_iframe.html]
+[test_image.xul]
 [test_img.html]
 [test_invalid_img.xhtml]
 [test_invalidationlist.html]
 [test_list.html]
 [test_map.html]
 [test_media.html]
 skip-if = buildapp == "mulet"
 [test_select.html]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/tree/test_image.xul
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Accessible XUL textbox and textarea hierarchy tests">
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+  <script type="application/javascript"
+          src="../common.js" />
+  <script type="application/javascript"
+          src="../role.js" />
+  <script type="application/javascript"
+          src="../events.js" />
+
+  <script type="application/javascript">
+  <![CDATA[
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+
+    function doTest()
+    {
+      var accTree = {
+        role: ROLE_GRAPHIC,
+        children: []
+      };
+      testAccessibleTree("image", accTree);
+
+      SimpleTest.finish()
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  ]]>
+  </script>
+
+  <hbox flex="1" style="overflow: auto;">
+    <body xmlns="http://www.w3.org/1999/xhtml">
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=1403231"
+         title="Remove the image XBL binding">
+        Mozilla Bug 1403231
+      </a><br/>
+      <p id="display"></p>
+      <div id="content" style="display: none">
+      </div>
+      <pre id="test">
+      </pre>
+    </body>
+
+    <vbox flex="1">
+      <image id="image" src="../moz.png" tooltiptext="hello"/>
+    </vbox>
+  </hbox>
+
+</window>
--- a/accessible/windows/msaa/Compatibility.cpp
+++ b/accessible/windows/msaa/Compatibility.cpp
@@ -163,17 +163,17 @@ uint32_t Compatibility::sConsumers = Com
 
 void
 Compatibility::Init()
 {
   // Note we collect some AT statistics/telemetry here for convenience.
 
   HMODULE jawsHandle = ::GetModuleHandleW(L"jhook");
   if (jawsHandle)
-    sConsumers |= (IsModuleVersionLessThan(jawsHandle, 20, 0)) ?
+    sConsumers |= (IsModuleVersionLessThan(jawsHandle, 19, 0)) ?
                    OLDJAWS : JAWS;
 
   if (::GetModuleHandleW(L"gwm32inc"))
     sConsumers |= WE;
 
   if (::GetModuleHandleW(L"dolwinhk"))
     sConsumers |= DOLPHIN;
 
--- a/browser/components/shell/test/test_headless_screenshot.html
+++ b/browser/components/shell/test/test_headless_screenshot.html
@@ -27,16 +27,21 @@ https://bugzilla.mozilla.org/show_bug.cg
     const prefsPath = OS.Path.join(profilePath, mochiPrefsName);
     const firefoxArgs = ["-profile", profilePath, "-no-remote"];
 
     await OS.File.makeDir(profilePath);
     await OS.File.copy(mochiPrefsPath, prefsPath);
     let proc = await Subprocess.call({
       command: firefoxExe,
       arguments: firefoxArgs.concat(args),
+      // Disable leak detection to avoid intermittent failure bug 1331152.
+      environmentAppend: true,
+      environment: {
+        ASAN_OPTIONS: "detect_leaks=0:quarantine_size=50331648:malloc_context_size=5",
+      },
     });
     let stdout;
     while ((stdout = await proc.stdout.readString())) {
       dump(">>> " + stdout + "\n");
     }
     let {exitCode} = await proc.wait();
     is(exitCode, 0, "Firefox process should exit with code 0");
     await OS.File.removeDir(profilePath);
--- a/browser/config/mozconfigs/win32/clang
+++ b/browser/config/mozconfigs/win32/clang
@@ -4,12 +4,12 @@ MOZ_AUTOMATION_L10N_CHECK=0
 
 . "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/common"
 
 ac_add_options --enable-optimize
 
 ac_add_options --enable-clang-plugin
 
-. $topsrcdir/build/win32/mozconfig.vs2015-win64
+. $topsrcdir/build/win32/mozconfig.vs-latest
 
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.clang-cl"
--- a/browser/config/mozconfigs/win32/clang-debug
+++ b/browser/config/mozconfigs/win32/clang-debug
@@ -5,12 +5,12 @@ MOZ_AUTOMATION_L10N_CHECK=0
 . "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/common"
 
 ac_add_options --enable-optimize
 ac_add_options --enable-debug
 
 ac_add_options --enable-clang-plugin
 
-. $topsrcdir/build/win32/mozconfig.vs2015-win64
+. $topsrcdir/build/win32/mozconfig.vs-latest
 
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.clang-cl"
--- a/browser/config/mozconfigs/win32/debug-static-analysis
+++ b/browser/config/mozconfigs/win32/debug-static-analysis
@@ -5,12 +5,12 @@ MOZ_AUTOMATION_L10N_CHECK=0
 . "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/common"
 
 ac_add_options --enable-debug
 ac_add_options --enable-dmd
 
 ac_add_options --enable-clang-plugin
 
-. $topsrcdir/build/win32/mozconfig.vs2015-win64
+. $topsrcdir/build/win32/mozconfig.vs-latest
 
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.clang-cl"
--- a/browser/config/mozconfigs/win64/clang
+++ b/browser/config/mozconfigs/win64/clang
@@ -6,12 +6,12 @@ MOZ_AUTOMATION_PACKAGE_TEST=0
 
 ac_add_options --target=x86_64-pc-mingw32
 ac_add_options --host=x86_64-pc-mingw32
 
 ac_add_options --enable-optimize
 
 ac_add_options --enable-clang-plugin
 
-. $topsrcdir/build/win64/mozconfig.vs2015
+. $topsrcdir/build/win64/mozconfig.vs-latest
 
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.clang-cl"
--- a/browser/config/mozconfigs/win64/clang-debug
+++ b/browser/config/mozconfigs/win64/clang-debug
@@ -7,12 +7,12 @@ MOZ_AUTOMATION_PACKAGE_TEST=0
 ac_add_options --target=x86_64-pc-mingw32
 ac_add_options --host=x86_64-pc-mingw32
 
 ac_add_options --enable-optimize
 ac_add_options --enable-debug
 
 ac_add_options --enable-clang-plugin
 
-. $topsrcdir/build/win64/mozconfig.vs2015
+. $topsrcdir/build/win64/mozconfig.vs-latest
 
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.clang-cl"
--- a/browser/config/mozconfigs/win64/debug-asan
+++ b/browser/config/mozconfigs/win64/debug-asan
@@ -1,16 +1,16 @@
 MOZ_AUTOMATION_L10N_CHECK=0
 
 . "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/common"
 
 ac_add_options --enable-debug
 ac_add_options --enable-optimize="-O1"
 
-. "$topsrcdir/build/win64/mozconfig.vs2015"
+. "$topsrcdir/build/win64/mozconfig.vs-latest"
 
 . "$topsrcdir/build/win64/mozconfig.asan"
 
 export MOZ_PACKAGE_JSSHELL=1
 export MOZ_PKG_SPECIAL=asan
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win64/nightly-asan
+++ b/browser/config/mozconfigs/win64/nightly-asan
@@ -1,16 +1,16 @@
 MOZ_AUTOMATION_L10N_CHECK=0
 
 . "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/common"
 
 ac_add_options --disable-debug
 ac_add_options --enable-optimize="-O2 -gline-tables-only"
 
-. "$topsrcdir/build/win64/mozconfig.vs2015"
+. "$topsrcdir/build/win64/mozconfig.vs-latest"
 
 . "$topsrcdir/build/win64/mozconfig.asan"
 
 export MOZ_PACKAGE_JSSHELL=1
 export MOZ_PKG_SPECIAL=asan
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/tooltool-manifests/win32/build-clang-cl.manifest
+++ b/browser/config/tooltool-manifests/win32/build-clang-cl.manifest
@@ -1,15 +1,15 @@
 [
   {
-    "version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",
-    "size": 326656969,
-    "digest": "babc414ffc0457d27f5a1ed24a8e4873afbe2f1c1a4075469a27c005e1babc3b2a788f643f825efedff95b79686664c67ec4340ed535487168a3482e68559bc7",
+    "version": "Visual Studio 2017 15.4.2 / SDK 10.0.15063.0",
+    "digest": "18700889e6b5e81613b9cf57ce4e0d46a6ee45bb4c5c33bae2604a5275326128775b8a032a1eb178c5db973746d565340c4e36d98375789e1d5bd836ab16ba58",
+    "size": 303146863,
     "algorithm": "sha512",
-    "filename": "vs2015u3.zip",
+    "filename": "vs2017_15.4.2.zip",
     "unpack": true
   },
   {
     "version": "SVN 1.9.4, repacked from SlikSvn (https://sliksvn.com/download/)",
     "size": 3934520,
     "digest": "d3b8f74936857ecbf542e403ed6835938a31d65302985729cbfa7191bf2cf94138565cefcc2f31517098013fbfc51868348863a55b588250902f9dec214dbc42",
     "algorithm": "sha512",
     "filename": "svn194.zip",
--- a/browser/config/tooltool-manifests/win32/releng.manifest
+++ b/browser/config/tooltool-manifests/win32/releng.manifest
@@ -1,21 +1,21 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "Visual Studio 2017 15.4.1 / SDK 10.0.16299.0",
-    "digest": "b22783f94d8c1304f9640e0cf0c614175c3f2e21f084bb08a31d5b3dc2f387e38a6917170eeb37e6446f191f2d685ca69c5e935f9d18ef41d16abf3a3b981d63",
-    "size": 322544627,
+    "version": "Visual Studio 2017 15.4.2 / SDK 10.0.15063.0",
+    "digest": "18700889e6b5e81613b9cf57ce4e0d46a6ee45bb4c5c33bae2604a5275326128775b8a032a1eb178c5db973746d565340c4e36d98375789e1d5bd836ab16ba58",
+    "size": 303146863,
     "algorithm": "sha512",
-    "filename": "vs2017_15.4.1.zip",
+    "filename": "vs2017_15.4.2.zip",
     "unpack": true
   },
   {
     "version": "makecab rev d2bc6797648b7a834782714a55d339d2fd4e58c8",
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "makecab.tar.bz2",
     "unpack": true,
deleted file mode 100644
--- a/browser/config/tooltool-manifests/win32/vs2017.manifest
+++ /dev/null
@@ -1,25 +0,0 @@
-[
-  {
-    "size": 266240,
-    "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
-    "algorithm": "sha512",
-    "filename": "mozmake.exe"
-  },
-  {
-    "version": "Visual Studio 2017 15.4.1 / SDK 10.0.16299.0",
-    "digest": "b22783f94d8c1304f9640e0cf0c614175c3f2e21f084bb08a31d5b3dc2f387e38a6917170eeb37e6446f191f2d685ca69c5e935f9d18ef41d16abf3a3b981d63",
-    "size": 322544627,
-    "algorithm": "sha512",
-    "filename": "vs2017_15.4.1.zip",
-    "unpack": true
-  },
-  {
-    "version": "makecab rev d2bc6797648b7a834782714a55d339d2fd4e58c8",
-    "algorithm": "sha512",
-    "visibility": "public",
-    "filename": "makecab.tar.bz2",
-    "unpack": true,
-    "digest": "196ac6a567c85559957dfe511c3d8654d23c94d5603259e19ccafe9d71e0e4ccee63ccc9a778f2699654b786cda54266108b7d4db543d01bb0b42545b4e6ec75",
-    "size": 297118
-  }
-]
--- a/browser/config/tooltool-manifests/win64/releng.manifest
+++ b/browser/config/tooltool-manifests/win64/releng.manifest
@@ -1,21 +1,21 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "Visual Studio 2017 15.4.1 / SDK 10.0.16299.0",
-    "digest": "b22783f94d8c1304f9640e0cf0c614175c3f2e21f084bb08a31d5b3dc2f387e38a6917170eeb37e6446f191f2d685ca69c5e935f9d18ef41d16abf3a3b981d63",
-    "size": 322544627,
+    "version": "Visual Studio 2017 15.4.2 / SDK 10.0.15063.0",
+    "digest": "18700889e6b5e81613b9cf57ce4e0d46a6ee45bb4c5c33bae2604a5275326128775b8a032a1eb178c5db973746d565340c4e36d98375789e1d5bd836ab16ba58",
+    "size": 303146863,
     "algorithm": "sha512",
-    "filename": "vs2017_15.4.1.zip",
+    "filename": "vs2017_15.4.2.zip",
     "unpack": true
   },
   {
     "version": "makecab rev d2bc6797648b7a834782714a55d339d2fd4e58c8",
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "makecab.tar.bz2",
     "unpack": true,
deleted file mode 100644
--- a/browser/config/tooltool-manifests/win64/vs2017.manifest
+++ /dev/null
@@ -1,25 +0,0 @@
-[
-  {
-    "size": 266240,
-    "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
-    "algorithm": "sha512",
-    "filename": "mozmake.exe"
-  },
-  {
-    "version": "Visual Studio 2017 15.4.1 / SDK 10.0.16299.0",
-    "digest": "b22783f94d8c1304f9640e0cf0c614175c3f2e21f084bb08a31d5b3dc2f387e38a6917170eeb37e6446f191f2d685ca69c5e935f9d18ef41d16abf3a3b981d63",
-    "size": 322544627,
-    "algorithm": "sha512",
-    "filename": "vs2017_15.4.1.zip",
-    "unpack": true
-  },
-  {
-    "version": "makecab rev d2bc6797648b7a834782714a55d339d2fd4e58c8",
-    "algorithm": "sha512",
-    "visibility": "public",
-    "filename": "makecab.tar.bz2",
-    "unpack": true,
-    "digest": "196ac6a567c85559957dfe511c3d8654d23c94d5603259e19ccafe9d71e0e4ccee63ccc9a778f2699654b786cda54266108b7d4db543d01bb0b42545b4e6ec75",
-    "size": 297118
-  }
-]
--- a/build/build-clang/build-clang.py
+++ b/build/build-clang/build-clang.py
@@ -510,17 +510,17 @@ if __name__ == "__main__":
             os.environ['LD_LIBRARY_PATH'] = '%s/lib64/' % gcc_dir
     elif is_windows():
         extra_cflags = []
         extra_cxxflags = []
         # clang-cl would like to figure out what it's supposed to be emulating
         # by looking at an MSVC install, but we don't really have that here.
         # Force things on.
         extra_cflags2 = []
-        extra_cxxflags2 = ['-fms-compatibility-version=19.00.24213', '-Xclang', '-std=c++14']
+        extra_cxxflags2 = ['-fms-compatibility-version=19.11.25547', '-Xclang', '-std=c++14']
         extra_asmflags = []
         extra_ldflags = []
 
     if osx_cross_compile:
         # undo the damage done in the is_linux() block above, and also simulate
         # the is_darwin() block above.
         extra_cflags = []
         extra_cxxflags = ["-stdlib=libc++"]
--- a/build/build-clang/clang-win32.json
+++ b/build/build-clang/clang-win32.json
@@ -5,10 +5,14 @@
     "build_type": "Release",
     "assertions": false,
     "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
     "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
     "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
     "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
-    "cxx": "cl.exe"
+    "cxx": "cl.exe",
+    "patches": [
+      "build/src/build/build-clang/msvc-host-x64.patch",
+      "build/src/build/build-clang/loosen-msvc-detection.patch"
+    ]
 }
--- a/build/build-clang/clang-win64.json
+++ b/build/build-clang/clang-win64.json
@@ -6,10 +6,13 @@
     "assertions": false,
     "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
     "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
     "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
     "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
-    "ml": "ml64.exe"
+    "ml": "ml64.exe",
+    "patches": [
+      "build/src/build/build-clang/loosen-msvc-detection.patch"
+    ]
 }
new file mode 100644
--- /dev/null
+++ b/build/build-clang/loosen-msvc-detection.patch
@@ -0,0 +1,22 @@
+In a proper VS install, the path to cl.exe looks like:
+...\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64\cl.exe
+
+In our automation, the path is just:
+...\VC\bin\HostX64\x64\cl.exe
+
+Clang tries to do some sanity-checking to make sure that the cl.exe it finds is the Microsoft compiler and not some other program. But the checks are a little too strict for us, so just look for "bin\Host*\*\cl.exe".
+
+diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
+index 7978a6941cb..0159e89fa27 100644
+--- a/clang/lib/Driver/ToolChains/MSVC.cpp
++++ b/clang/lib/Driver/ToolChains/MSVC.cpp
+@@ -152,8 +152,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
+         // path components with these prefixes when walking backwards through
+         // the path.
+         // Note: empty strings match anything.
+-        llvm::StringRef ExpectedPrefixes[] = {"",     "Host",  "bin", "",
+-                                              "MSVC", "Tools", "VC"};
++        llvm::StringRef ExpectedPrefixes[] = {"", "Host",  "bin"};
+ 
+         auto It = llvm::sys::path::rbegin(PathEntry);
+         auto End = llvm::sys::path::rend(PathEntry);
new file mode 100644
--- /dev/null
+++ b/build/build-clang/msvc-host-x64.patch
@@ -0,0 +1,17 @@
+When looking for a linker, 32-bit clang-cl.exe wants to use the 32-bit-native link.exe located in Hostx86/x86, but this executable does not exist in our releng package, because we only use 64-bit-host toolchains.
+
+This patch makes clang-cl use the Hostx64/x86 linker instead. Ideally we wouldn't be using 32-bit clang-cl.exe in the first place. Bug 1414287 is on file to do so and remove this hack.
+
+diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
+--- a/clang/lib/Driver/ToolChains/MSVC.cpp
++++ b/clang/lib/Driver/ToolChains/MSVC.cpp
+@@ -817,8 +816,7 @@
+   switch (Type) {
+   case SubDirectoryType::Bin:
+     if (VSLayout == ToolsetLayout::VS2017OrNewer) {
+-      const bool HostIsX64 =
+-          llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
++      const bool HostIsX64 = true;
+       const char *const HostName = HostIsX64 ? "HostX64" : "HostX86";
+       llvm::sys::path::append(Path, "bin", HostName, SubdirName);
+     } else { // OlderVS or DevDivInternal
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -506,21 +506,21 @@ def check_compiler(compiler, language, t
                 append_flag('-std=c++14')
             # GCC 4.9 indicates that it implements draft C++14 features
             # instead of the full language.
             elif info.type == 'gcc' and not \
                 (info.language_version == draft_cxx14_version or
                  info.language_version == cxx14_version):
                 append_flag('-std=gnu++14')
 
-    # We force clang-cl to emulate Visual C++ 2015 Update 3.
-    if info.type == 'clang-cl' and info.version != '19.00.24213':
+    # We force clang-cl to emulate Visual C++ 2017 version 15.4
+    if info.type == 'clang-cl' and info.version != '19.11.25547':
         # This flag is a direct clang-cl flag that doesn't need -Xclang,
         # add it directly.
-        flags.append('-fms-compatibility-version=19.00.24213')
+        flags.append('-fms-compatibility-version=19.11.25547')
 
     # Check compiler target
     # --------------------------------------------------------------------
     if not info.cpu or info.cpu != target.cpu:
         if info.type == 'clang':
             append_flag('--target=%s' % target.toolchain)
         elif info.type == 'gcc':
             same_arch_different_bits = (
--- a/build/win32/mozconfig.vs2017
+++ b/build/win32/mozconfig.vs2017
@@ -1,25 +1,25 @@
 if [ -z "${VSPATH}" ]; then
     TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
-    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.4.1"
+    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.4.2"
 fi
 
 if [ -d "${VSPATH}" ]; then
     VSWINPATH="$(cd ${VSPATH} && pwd -W)"
 
     export WINDOWSSDKDIR="${VSWINPATH}/SDK"
     export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x86/Microsoft.VC141.CRT"
     export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x86"
 
-    export PATH="${VSPATH}/VC/bin/Hostx86/x86:${VSPATH}/VC/bin/Hostx64/x86:${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/10.0.16299.0/x64:${VSPATH}/DIA SDK/bin:${PATH}"
+    export PATH="${VSPATH}/VC/bin/Hostx86/x86:${VSPATH}/VC/bin/Hostx64/x86:${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/10.0.15063.0/x64:${VSPATH}/DIA SDK/bin:${PATH}"
     export PATH="${VSPATH}/VC/redist/x86/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x86:${PATH}"
 
-    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.16299.0/ucrt:${VSPATH}/SDK/Include/10.0.16299.0/shared:${VSPATH}/SDK/Include/10.0.16299.0/um:${VSPATH}/SDK/Include/10.0.16299.0/winrt:${VSPATH}/DIA SDK/include"
-    export LIB="${VSPATH}/VC/lib/x86:${VSPATH}/VC/atlmfc/lib/x86:${VSPATH}/SDK/Lib/10.0.16299.0/ucrt/x86:${VSPATH}/SDK/Lib/10.0.16299.0/um/x86:${VSPATH}/DIA SDK/lib"
+    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.15063.0/ucrt:${VSPATH}/SDK/Include/10.0.15063.0/shared:${VSPATH}/SDK/Include/10.0.15063.0/um:${VSPATH}/SDK/Include/10.0.15063.0/winrt:${VSPATH}/DIA SDK/include"
+    export LIB="${VSPATH}/VC/lib/x86:${VSPATH}/VC/atlmfc/lib/x86:${VSPATH}/SDK/Lib/10.0.15063.0/ucrt/x86:${VSPATH}/SDK/Lib/10.0.15063.0/um/x86:${VSPATH}/DIA SDK/lib"
 fi
 
 . $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style WINDOWSSDKDIR
 mk_export_correct_style WIN32_REDIST_DIR
 mk_export_correct_style WIN_UCRT_REDIST_DIR
 mk_export_correct_style PATH
--- a/build/win64/mozconfig.vs2017
+++ b/build/win64/mozconfig.vs2017
@@ -1,24 +1,24 @@
 if [ -z "${VSPATH}" ]; then
     TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
-    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.4.1"
+    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.4.2"
 fi
 
 if [ -d "${VSPATH}" ]; then
     VSWINPATH="$(cd ${VSPATH} && pwd -W)"
 
     export WINDOWSSDKDIR="${VSWINPATH}/SDK"
     export WIN32_REDIST_DIR=${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT
     export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64"
 
-    export PATH="${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/10.0.16299.0/x64:${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${VSPATH}/DIA SDK/bin/amd64:${PATH}"
+    export PATH="${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/10.0.15063.0/x64:${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${VSPATH}/DIA SDK/bin/amd64:${PATH}"
 
-    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.16299.0/ucrt:${VSPATH}/SDK/Include/10.0.16299.0/shared:${VSPATH}/SDK/Include/10.0.16299.0/um:${VSPATH}/SDK/Include/10.0.16299.0/winrt:${VSPATH}/DIA SDK/include"
-    export LIB="${VSPATH}/VC/lib/x64:${VSPATH}/VC/atlmfc/lib/x64:${VSPATH}/SDK/Lib/10.0.16299.0/ucrt/x64:${VSPATH}/SDK/Lib/10.0.16299.0/um/x64:${VSPATH}/DIA SDK/lib/amd64"
+    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.15063.0/ucrt:${VSPATH}/SDK/Include/10.0.15063.0/shared:${VSPATH}/SDK/Include/10.0.15063.0/um:${VSPATH}/SDK/Include/10.0.15063.0/winrt:${VSPATH}/DIA SDK/include"
+    export LIB="${VSPATH}/VC/lib/x64:${VSPATH}/VC/atlmfc/lib/x64:${VSPATH}/SDK/Lib/10.0.15063.0/ucrt/x64:${VSPATH}/SDK/Lib/10.0.15063.0/um/x64:${VSPATH}/DIA SDK/lib/amd64"
 fi
 
 . $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style WINDOWSSDKDIR
 mk_export_correct_style WIN32_REDIST_DIR
 mk_export_correct_style WIN_UCRT_REDIST_DIR
 mk_export_correct_style PATH
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -8,16 +8,17 @@
 
 #include "nsDocShell.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIStandardURL.h"
 
 #include "ContentPrincipal.h"
+#include "ExpandedPrincipal.h"
 #include "nsNetUtil.h"
 #include "nsIURIWithPrincipal.h"
 #include "NullPrincipal.h"
 #include "nsScriptSecurityManager.h"
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/CSPDictionariesBinding.h"
@@ -352,16 +353,27 @@ bool
 BasePrincipal::AddonHasPermission(const nsAtom* aPerm)
 {
   if (auto policy = AddonPolicy()) {
     return policy->HasPermission(aPerm);
   }
   return false;
 }
 
+nsIPrincipal*
+BasePrincipal::PrincipalToInherit(nsIURI* aRequestedURI,
+                                  bool aAllowIfInheritsPrincipal)
+{
+  if (Is<ExpandedPrincipal>()) {
+    return As<ExpandedPrincipal>()->PrincipalToInherit(aRequestedURI,
+                                                       aAllowIfInheritsPrincipal);
+  }
+  return this;
+}
+
 already_AddRefed<BasePrincipal>
 BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI,
                                        const OriginAttributes& aAttrs)
 {
   MOZ_ASSERT(aURI);
 
   nsAutoCString originNoSuffix;
   nsresult rv =
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -120,16 +120,28 @@ public:
 
   // Call these to avoid the cost of virtual dispatch.
   inline bool FastEquals(nsIPrincipal* aOther);
   inline bool FastEqualsConsideringDomain(nsIPrincipal* aOther);
   inline bool FastSubsumes(nsIPrincipal* aOther);
   inline bool FastSubsumesConsideringDomain(nsIPrincipal* aOther);
   inline bool FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther);
 
+  // Returns the principal to inherit when a caller with this principal loads
+  // the given URI.
+  //
+  // For most principal types, this returns the principal itself. For expanded
+  // principals, it returns the first sub-principal which subsumes the given URI
+  // (or, if no URI is given, the last whitelist principal).
+  //
+  // The aAllowIfInheritsPrincipal argument is passed through to CheckMayLoad()
+  // to determine which consistituent principals may load the requested URI.
+  nsIPrincipal* PrincipalToInherit(nsIURI* aRequestedURI = nullptr,
+                                   bool aAllowIfInheritsPrincipal = true);
+
   /**
    * Returns true if this principal's CSP should override a document's CSP for
    * loads that it triggers. Currently true only for expanded principals which
    * subsume the document principal.
    */
   bool OverridesCSP(nsIPrincipal* aDocumentPrincipal)
   {
     return mKind == eExpandedPrincipal && FastSubsumes(aDocumentPrincipal);
--- a/caps/ExpandedPrincipal.cpp
+++ b/caps/ExpandedPrincipal.cpp
@@ -175,16 +175,31 @@ ExpandedPrincipal::AddonHasPermission(co
   for (size_t i = 0; i < mPrincipals.Length(); ++i) {
     if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) {
       return true;
     }
   }
   return false;
 }
 
+nsIPrincipal*
+ExpandedPrincipal::PrincipalToInherit(nsIURI* aRequestedURI,
+                                      bool aAllowIfInheritsPrincipal)
+{
+  if (aRequestedURI) {
+    for (const auto& principal : mPrincipals) {
+      if (NS_SUCCEEDED(principal->CheckMayLoad(aRequestedURI, false,
+                                               aAllowIfInheritsPrincipal))) {
+        return principal;
+      }
+    }
+  }
+  return mPrincipals.LastElement();
+}
+
 nsresult
 ExpandedPrincipal::GetScriptLocation(nsACString& aStr)
 {
   aStr.AssignLiteral("[Expanded Principal [");
   for (size_t i = 0; i < mPrincipals.Length(); ++i) {
     if (i != 0) {
       aStr.AppendLiteral(", ");
     }
--- a/caps/ExpandedPrincipal.h
+++ b/caps/ExpandedPrincipal.h
@@ -32,16 +32,21 @@ public:
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
   NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   virtual bool AddonHasPermission(const nsAtom* aPerm) override;
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
 
+  // Returns the principal to inherit when this principal requests the given
+  // URL. See BasePrincipal::PrincipalToInherit.
+  nsIPrincipal* PrincipalToInherit(nsIURI* aRequestedURI = nullptr,
+                                   bool aAllowIfInheritsPrincipal = true);
+
 protected:
   explicit ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList);
 
   virtual ~ExpandedPrincipal();
 
   bool SubsumesInternal(nsIPrincipal* aOther,
                         DocumentDomainConsideration aConsideration) override;
 
--- a/caps/nsIPrincipal.idl
+++ b/caps/nsIPrincipal.idl
@@ -332,14 +332,20 @@ interface nsIPrincipal : nsISerializable
  * content and a well defined set of other domains, without the risk of
  * leaking out a system principal to the content. See: Bug 734891
  */
 [uuid(f3e177Df-6a5e-489f-80a7-2dd1481471d8)]
 interface nsIExpandedPrincipal : nsISupports
 {
   /**
    * An array of principals that the expanded principal subsumes.
+   *
+   * When an expanded principal is used as a triggering principal for a
+   * request that inherits a security context, one of its constitutent
+   * principals is inherited rather than the expanded principal itself. The
+   * last principal in the whitelist is the default principal to inherit.
+   *
    * Note: this list is not reference counted, it is shared, so
    * should not be changed and should only be used ephemerally.
    */
   [noscript, notxpcom, nostdcall]
   PrincipalArray WhiteList();
 };
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -225,20 +225,19 @@ InheritAndSetCSPOnPrincipalIfNeeded(nsIC
 
   bool isSrcDoc = URISpec.EqualsLiteral("about:srcdoc");
   bool isData = (NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData);
 
   if (!isSrcDoc && !isData) {
     return;
   }
 
-  nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
-  if (!principalToInherit) {
-    principalToInherit = loadInfo->TriggeringPrincipal();
-  }
+  nsCOMPtr<nsIPrincipal> principalToInherit =
+    loadInfo->FindPrincipalToInherit(aChannel);
+
   nsCOMPtr<nsIContentSecurityPolicy> originalCSP;
   principalToInherit->GetCsp(getter_AddRefs(originalCSP));
   if (!originalCSP) {
     return;
   }
 
   // if the principalToInherit had a CSP, add it to the before
   // created NullPrincipal (unless it already has one)
@@ -259,20 +258,18 @@ nsresult
 nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel,
                                                    nsIPrincipal** aPrincipal,
                                                    bool aIgnoreSandboxing)
 {
   NS_PRECONDITION(aChannel, "Must have channel!");
   // Check whether we have an nsILoadInfo that says what we should do.
   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
   if (loadInfo && loadInfo->GetForceInheritPrincipalOverruleOwner()) {
-    nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
-    if (!principalToInherit) {
-      principalToInherit = loadInfo->TriggeringPrincipal();
-    }
+    nsCOMPtr<nsIPrincipal> principalToInherit =
+      loadInfo->FindPrincipalToInherit(aChannel);
     principalToInherit.forget(aPrincipal);
     return NS_OK;
   }
 
   nsCOMPtr<nsISupports> owner;
   aChannel->GetOwner(getter_AddRefs(owner));
   if (owner) {
     CallQueryInterface(owner, aPrincipal);
@@ -294,39 +291,36 @@ nsScriptSecurityManager::GetChannelResul
       // Check if SEC_FORCE_INHERIT_PRINCIPAL was dropped because of
       // sandboxing:
       if (loadInfo->GetLoadingSandboxed() &&
         loadInfo->GetForceInheritPrincipalDropped()) {
         forceInherit = true;
       }
     }
     if (forceInherit) {
-      nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
-      if (!principalToInherit) {
-        principalToInherit = loadInfo->TriggeringPrincipal();
-      }
+      nsCOMPtr<nsIPrincipal> principalToInherit =
+        loadInfo->FindPrincipalToInherit(aChannel);
       principalToInherit.forget(aPrincipal);
       return NS_OK;
     }
 
     auto securityMode = loadInfo->GetSecurityMode();
     // The data: inheritance flags should only apply to the initial load,
     // not to loads that it might have redirected to.
     if (loadInfo->RedirectChain().IsEmpty() &&
         (securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS ||
          securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS ||
          securityMode == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) {
 
       nsCOMPtr<nsIURI> uri;
       nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
       NS_ENSURE_SUCCESS(rv, rv);
-      nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
-      if (!principalToInherit) {
-        principalToInherit = loadInfo->TriggeringPrincipal();
-      }
+
+      nsCOMPtr<nsIPrincipal> principalToInherit =
+        loadInfo->FindPrincipalToInherit(aChannel);
       bool inheritForAboutBlank = loadInfo->GetAboutBlankInherits();
 
       if (nsContentUtils::ChannelShouldInheritPrincipal(principalToInherit,
                                                         uri,
                                                         inheritForAboutBlank,
                                                         false)) {
         principalToInherit.forget(aPrincipal);
         return NS_OK;
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -193,20 +193,24 @@ MarkupView.prototype = {
    */
   _onToolboxPickerCanceled: function () {
     if (this._selectedContainer) {
       scrollIntoViewIfNeeded(this._selectedContainer.editor.elt);
     }
   },
 
   isDragging: false,
+  _draggedContainer: null,
 
   _onMouseMove: function (event) {
     let target = event.target;
 
+    if (this._draggedContainer) {
+      this._draggedContainer.onMouseMove(event);
+    }
     // Auto-scroll if we're dragging.
     if (this.isDragging) {
       event.preventDefault();
       this._autoScroll(event);
       return;
     }
 
     // Show the current container as hovered and highlight it.
@@ -324,17 +328,21 @@ MarkupView.prototype = {
     if (container instanceof MarkupElementContainer) {
       // With the newly found container, delegate the tooltip content creation
       // and decision to show or not the tooltip
       container._buildEventTooltipContent(event.target,
         this.eventDetailsTooltip);
     }
   },
 
-  _onMouseUp: function () {
+  _onMouseUp: function (event) {
+    if (this._draggedContainer) {
+      this._draggedContainer.onMouseUp(event);
+    }
+
     this.indicateDropTarget(null);
     this.indicateDragTarget(null);
     if (this._autoScrollAnimationFrame) {
       this.win.cancelAnimationFrame(this._autoScrollAnimationFrame);
     }
   },
 
   _onCollapseAttributesPrefChange: function () {
--- a/devtools/client/inspector/markup/test/head.js
+++ b/devtools/client/inspector/markup/test/head.js
@@ -518,17 +518,17 @@ function* simulateNodeDrag(inspector, se
 
   // _onMouseDown selects the node, so make sure to wait for the
   // inspector-updated event if the current selection was different.
   if (inspector.selection.nodeFront !== container.node) {
     yield inspector.once("inspector-updated");
   }
 
   info("Simulate mouseMove on element " + selector);
-  container._onMouseMove({
+  container.onMouseMove({
     pageX: scrollX + rect.x + xOffset,
     pageY: scrollY + rect.y + yOffset
   });
 }
 
 /**
  * Simulate dropping a MarkupContainer by calling its mouseup handler. This is
  * meant to be called after simulateNodeDrag has been called.
@@ -536,17 +536,17 @@ function* simulateNodeDrag(inspector, se
  * @param {String|MarkupContainer} selector The selector to identify the node or
  * the MarkupContainer for this node.
  */
 function* simulateNodeDrop(inspector, selector) {
   info("Simulate mouseUp on element " + selector);
   let container = typeof selector === "string"
                   ? yield getContainerForSelector(selector, inspector)
                   : selector;
-  container._onMouseUp();
+  container.onMouseUp();
   inspector.markup._onMouseUp();
 }
 
 /**
  * Simulate drag'n'dropping a MarkupContainer by calling its mousedown,
  * mousemove and mouseup handlers.
  * @param {InspectorPanel} inspector The current inspector-panel instance.
  * @param {String|MarkupContainer} selector The selector to identify the node or
--- a/devtools/client/inspector/markup/views/markup-container.js
+++ b/devtools/client/inspector/markup/views/markup-container.js
@@ -52,24 +52,20 @@ MarkupContainer.prototype = {
     this.htmlElt = this.win.document.documentElement;
 
     this.buildMarkup(type);
 
     this.elt.container = this;
 
     this._onMouseDown = this._onMouseDown.bind(this);
     this._onToggle = this._onToggle.bind(this);
-    this._onMouseUp = this._onMouseUp.bind(this);
-    this._onMouseMove = this._onMouseMove.bind(this);
     this._onKeyDown = this._onKeyDown.bind(this);
 
     // Binding event listeners
     this.elt.addEventListener("mousedown", this._onMouseDown);
-    this.win.addEventListener("mouseup", this._onMouseUp, true);
-    this.win.addEventListener("mousemove", this._onMouseMove, true);
     this.elt.addEventListener("dblclick", this._onToggle);
     if (this.expander) {
       this.expander.addEventListener("click", this._onToggle);
     }
 
     // Marking the node as shown or hidden
     this.updateIsDisplayed();
   },
@@ -519,24 +515,27 @@ MarkupContainer.prototype = {
       this.markup.inspector.followAttributeLink(type, link);
       return;
     }
 
     // Start node drag & drop (if the mouse moved, see _onMouseMove).
     if (isLeftClick && this.isDraggable()) {
       this._isPreDragging = true;
       this._dragStartY = event.pageY;
+      this.markup._draggedContainer = this;
     }
   },
 
   /**
    * On mouse up, stop dragging.
+   * This handler is called from the markup view, to reduce number of listeners.
    */
-  _onMouseUp: Task.async(function* () {
+  onMouseUp: Task.async(function* () {
     this._isPreDragging = false;
+    this.markup._draggedContainer = null;
 
     if (this.isDragging) {
       this.cancelDragging();
 
       let dropTargetNodes = this.markup.dropTargetNodes;
 
       if (!dropTargetNodes) {
         return;
@@ -545,18 +544,19 @@ MarkupContainer.prototype = {
       yield this.markup.walker.insertBefore(this.node, dropTargetNodes.parent,
                                             dropTargetNodes.nextSibling);
       this.markup.emit("drop-completed");
     }
   }),
 
   /**
    * On mouse move, move the dragged element and indicate the drop target.
+   * This handler is called from the markup view, to reduce number of listeners.
    */
-  _onMouseMove: function (event) {
+  onMouseMove: function (event) {
     // If this is the first move after mousedown, only start dragging after the
     // mouse has travelled a few pixels and then indicate the start position.
     let initialDiff = Math.abs(event.pageY - this._dragStartY);
     if (this._isPreDragging && initialDiff >= DRAG_DROP_MIN_INITIAL_DISTANCE) {
       this._isPreDragging = false;
       this.isDragging = true;
 
       // If this is the last child, use the closing <div.tag-line> of parent as
@@ -717,19 +717,19 @@ MarkupContainer.prototype = {
    * Get rid of event listeners and references, when the container is no longer
    * needed
    */
   destroy: function () {
     // Remove event listeners
     this.elt.removeEventListener("mousedown", this._onMouseDown);
     this.elt.removeEventListener("dblclick", this._onToggle);
     this.tagLine.removeEventListener("keydown", this._onKeyDown, true);
-    if (this.win) {
-      this.win.removeEventListener("mouseup", this._onMouseUp, true);
-      this.win.removeEventListener("mousemove", this._onMouseMove, true);
+
+    if (this.markup._draggedContainer === this) {
+      this.markup._draggedContainer = null;
     }
 
     this.win = null;
     this.htmlElt = null;
 
     if (this.expander) {
       this.expander.removeEventListener("click", this._onToggle);
     }
--- a/docshell/base/nsDSURIContentListener.cpp
+++ b/docshell/base/nsDSURIContentListener.cpp
@@ -9,21 +9,84 @@
 #include "nsIChannel.h"
 #include "nsServiceManagerUtils.h"
 #include "nsDocShellCID.h"
 #include "nsIWebNavigationInfo.h"
 #include "nsIDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsIHttpChannel.h"
 #include "nsError.h"
+#include "nsContentSecurityManager.h"
 #include "nsDocShellLoadTypes.h"
+#include "nsIInterfaceRequestor.h"
 #include "nsIMultiPartChannel.h"
 
 using namespace mozilla;
 
+NS_IMPL_ADDREF(MaybeCloseWindowHelper)
+NS_IMPL_RELEASE(MaybeCloseWindowHelper)
+
+NS_INTERFACE_MAP_BEGIN(MaybeCloseWindowHelper)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+MaybeCloseWindowHelper::MaybeCloseWindowHelper(nsIInterfaceRequestor* aContentContext)
+  : mContentContext(aContentContext)
+  , mWindowToClose(nullptr)
+  , mTimer(nullptr)
+  , mShouldCloseWindow(false)
+{
+}
+
+MaybeCloseWindowHelper::~MaybeCloseWindowHelper()
+{
+}
+
+void
+MaybeCloseWindowHelper::SetShouldCloseWindow(bool aShouldCloseWindow)
+{
+  mShouldCloseWindow = aShouldCloseWindow;
+}
+
+nsIInterfaceRequestor*
+MaybeCloseWindowHelper::MaybeCloseWindow()
+{
+  nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(mContentContext);
+  NS_ENSURE_TRUE(window, mContentContext);
+
+  if (mShouldCloseWindow) {
+    // Reset the window context to the opener window so that the dependent
+    // dialogs have a parent
+    nsCOMPtr<nsPIDOMWindowOuter> opener = window->GetOpener();
+
+    if (opener && !opener->Closed()) {
+      mContentContext = do_GetInterface(opener);
+
+      // Now close the old window.  Do it on a timer so that we don't run
+      // into issues trying to close the window before it has fully opened.
+      NS_ASSERTION(!mTimer, "mTimer was already initialized once!");
+      NS_NewTimerWithCallback(getter_AddRefs(mTimer), this, 0, nsITimer::TYPE_ONE_SHOT);
+      mWindowToClose = window;
+    }
+  }
+  return mContentContext;
+}
+
+NS_IMETHODIMP
+MaybeCloseWindowHelper::Notify(nsITimer* timer)
+{
+  NS_ASSERTION(mWindowToClose, "No window to close after timer fired");
+
+  mWindowToClose->Close();
+  mWindowToClose = nullptr;
+  mTimer = nullptr;
+
+  return NS_OK;
+}
+
 nsDSURIContentListener::nsDSURIContentListener(nsDocShell* aDocShell)
   : mDocShell(aDocShell)
   , mExistingJPEGRequest(nullptr)
   , mParentContentListener(nullptr)
 {
 }
 
 nsDSURIContentListener::~nsDSURIContentListener()
@@ -81,16 +144,35 @@ nsDSURIContentListener::DoContent(const 
   *aAbortProcess = false;
 
   // determine if the channel has just been retargeted to us...
   nsLoadFlags loadFlags = 0;
   nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(aRequest);
 
   if (aOpenedChannel) {
     aOpenedChannel->GetLoadFlags(&loadFlags);
+
+    // block top-level data URI navigations if triggered by the web
+    if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI(aOpenedChannel)) {
+      // logging to console happens within AllowTopLevelNavigationToDataURI
+      aRequest->Cancel(NS_ERROR_DOM_BAD_URI);
+      *aAbortProcess = true;
+      // close the window since the navigation to a data URI was blocked
+      if (mDocShell) {
+        nsCOMPtr<nsIInterfaceRequestor> contentContext =
+          do_QueryInterface(mDocShell->GetWindow());
+        if (contentContext) {
+          RefPtr<MaybeCloseWindowHelper> maybeCloseWindowHelper =
+            new MaybeCloseWindowHelper(contentContext);
+          maybeCloseWindowHelper->SetShouldCloseWindow(true);
+          maybeCloseWindowHelper->MaybeCloseWindow();
+        }
+      }
+      return NS_OK; 
+    }
   }
 
   if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) {
     // XXX: Why does this not stop the content too?
     mDocShell->Stop(nsIWebNavigation::STOP_NETWORK);
 
     mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL);
   }
--- a/docshell/base/nsDSURIContentListener.h
+++ b/docshell/base/nsDSURIContentListener.h
@@ -5,19 +5,64 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDSURIContentListener_h__
 #define nsDSURIContentListener_h__
 
 #include "nsCOMPtr.h"
 #include "nsIURIContentListener.h"
 #include "nsWeakReference.h"
+#include "nsITimer.h"
 
 class nsDocShell;
+class nsIInterfaceRequestor;
 class nsIWebNavigationInfo;
+class nsPIDOMWindowOuter;
+
+// Helper Class to eventually close an already openend window
+class MaybeCloseWindowHelper final
+  : public nsITimerCallback
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSITIMERCALLBACK
+
+  explicit MaybeCloseWindowHelper(nsIInterfaceRequestor* aContentContext);
+
+  /**
+   * Closes the provided window async (if mShouldCloseWindow is true)
+   * and returns its opener if the window was just openend.
+   */
+  nsIInterfaceRequestor* MaybeCloseWindow();
+
+  void SetShouldCloseWindow(bool aShouldCloseWindow);
+
+protected:
+  ~MaybeCloseWindowHelper();
+
+private:
+  /**
+   * The dom window associated to handle content.
+   */
+  nsCOMPtr<nsIInterfaceRequestor> mContentContext;
+
+  /**
+   * Used to close the window on a timer, to avoid any exceptions that are
+   * thrown if we try to close the window before it's fully loaded.
+   */
+  nsCOMPtr<nsPIDOMWindowOuter> mWindowToClose;
+  nsCOMPtr<nsITimer> mTimer;
+
+  /**
+   * This is set based on whether the channel indicates that a new window
+   * was opened, e.g. for a download, or was blocked. If so, then we
+   * close it.
+   */
+  bool mShouldCloseWindow;
+};
 
 class nsDSURIContentListener final
   : public nsIURIContentListener
   , public nsSupportsWeakReference
 {
   friend class nsDocShell;
 
 public:
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9962,29 +9962,16 @@ nsDocShell::InternalLoad(nsIURI* aURI,
       // an iframe since that's more common.
       contentType = nsIContentPolicy::TYPE_INTERNAL_IFRAME;
     }
   } else {
     contentType = nsIContentPolicy::TYPE_DOCUMENT;
     isTargetTopLevelDocShell = true;
   }
 
-  nsIDocument* doc = mContentViewer ? mContentViewer->GetDocument()
-                                    : nullptr;
-  if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
-        aURI,
-        contentType,
-        aTriggeringPrincipal,
-        doc,
-        (aLoadType == LOAD_NORMAL_EXTERNAL),
-        !aFileName.IsVoid())) {
-    // logging to console happens within AllowTopLevelNavigationToDataURI
-    return NS_OK;
-  }
-
   // If there's no targetDocShell, that means we are about to create a new
   // window (or aWindowTarget is empty). Perform a content policy check before
   // creating the window. Please note for all other docshell loads
   // content policy checks are performed within the contentSecurityManager
   // when the channel is about to be openend.
   if (!targetDocShell && !aWindowTarget.IsEmpty()) {
     MOZ_ASSERT(contentType == nsIContentPolicy::TYPE_DOCUMENT,
                "opening a new window requires type to be TYPE_DOCUMENT");
@@ -10103,16 +10090,19 @@ nsDocShell::InternalLoad(nsIURI* aURI,
 
         nsCOMPtr<nsIDocShellTreeItem> parent;
         treeItem->GetSameTypeParent(getter_AddRefs(parent));
         parent.swap(treeItem);
       } while (treeItem);
     }
   }
 
+  nsIDocument* doc = mContentViewer ? mContentViewer->GetDocument()
+                                    : nullptr;
+
   const bool isDocumentAuxSandboxed = doc &&
     (doc->GetSandboxFlags() & SANDBOXED_AUXILIARY_NAVIGATION);
 
   if (aURI && mLoadURIDelegate &&
       (!targetDocShell || targetDocShell == static_cast<nsIDocShell*>(this))) {
     // Dispatch only load requests for the current or a new window to the
     // delegate, e.g., to allow for GeckoView apps to handle the load event
     // outside of Gecko.
@@ -11187,16 +11177,17 @@ nsDocShell::DoURILoad(nsIURI* aURI,
       new LoadInfo(loadingWindow, aTriggeringPrincipal, topLevelLoadingContext,
                    securityFlags) :
       new LoadInfo(loadingPrincipal, aTriggeringPrincipal, loadingNode,
                    securityFlags, aContentPolicyType);
 
   if (aPrincipalToInherit) {
     loadInfo->SetPrincipalToInherit(aPrincipalToInherit);
   }
+  loadInfo->SetLoadTriggeredFromExternal(aLoadFromExternal);
 
   // We have to do this in case our OriginAttributes are different from the
   // OriginAttributes of the parent document. Or in case there isn't a
   // parent document.
   bool isTopLevelDoc = mItemType == typeContent &&
                        (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
                         GetIsMozBrowser());
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -2500,20 +2500,20 @@ nsDocument::MaybeDowngradePrincipal(nsIP
     return nullptr;
   }
 
   // We can't load a document with an expanded principal. If we're given one,
   // automatically downgrade it to the last principal it subsumes (which is the
   // extension principal, in the case of extension content scripts).
   auto* basePrin = BasePrincipal::Cast(aPrincipal);
   if (basePrin->Is<ExpandedPrincipal>()) {
+    MOZ_DIAGNOSTIC_ASSERT(false, "Should never try to create a document with "
+                                 "an expanded principal");
+
     auto* expanded = basePrin->As<ExpandedPrincipal>();
-
-    MOZ_ASSERT(expanded->WhiteList().Length() > 0);
-
     return do_AddRef(expanded->WhiteList().LastElement());
   }
 
   if (!sChromeInContentPrefCached) {
     sChromeInContentPrefCached = true;
     Preferences::AddBoolVarCache(&sChromeInContentAllowed,
                                  kChromeInContentPref, false);
   }
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -11393,17 +11393,17 @@ class CGProxySpecialOperation(CGPerSigna
 
         # We pass len(arguments) as the final argument so that the
         # CGPerSignatureCall won't do any argument conversion of its own.
         CGPerSignatureCall.__init__(self, returnType, arguments, nativeName,
                                     False, descriptor, operation,
                                     len(arguments), resultVar=resultVar,
                                     objectName="proxy")
 
-        if operation.isSetter() or operation.isCreator():
+        if operation.isSetter():
             # arguments[0] is the index or name of the item that we're setting.
             argument = arguments[1]
             info = getJSToNativeConversionInfo(
                 argument.type, descriptor,
                 treatNullAs=argument.treatNullAs,
                 sourceDescription=("value being assigned to %s setter" %
                                    descriptor.interface.identifier.name))
             if argumentHandleValue is None:
@@ -11820,18 +11820,16 @@ class CGDOMJSProxyHandler_defineProperty
         ClassMethod.__init__(self, "defineProperty", "bool", args, virtual=True, override=True, const=True)
         self.descriptor = descriptor
 
     def getBody(self):
         set = ""
 
         indexedSetter = self.descriptor.operations['IndexedSetter']
         if indexedSetter:
-            if self.descriptor.operations['IndexedCreator'] is not indexedSetter:
-                raise TypeError("Can't handle creator that's different from the setter")
             set += fill(
                 """
                 uint32_t index = GetArrayIndexFromId(cx, id);
                 if (IsArrayIndex(index)) {
                   *defined = true;
                   $*{callSetter}
                   return opresult.succeed();
                 }
@@ -11852,18 +11850,16 @@ class CGDOMJSProxyHandler_defineProperty
                 """)
 
         namedSetter = self.descriptor.operations['NamedSetter']
         if namedSetter:
             if self.descriptor.hasUnforgeableMembers:
                 raise TypeError("Can't handle a named setter on an interface "
                                 "that has unforgeables.  Figure out how that "
                                 "should work!")
-            if self.descriptor.operations['NamedCreator'] is not namedSetter:
-                raise TypeError("Can't handle creator that's different from the setter")
             # If we support indexed properties, we won't get down here for
             # indices, so we can just do our setter unconditionally here.
             set += fill(
                 """
                 *defined = true;
                 $*{callSetter}
 
                 return opresult.succeed();
@@ -12332,37 +12328,30 @@ class CGDOMJSProxyHandler_setCustom(Clas
         # always call the NamedSetter and never do anything else.
         namedSetter = self.descriptor.operations['NamedSetter']
         if (namedSetter is not None and
             self.descriptor.interface.getExtendedAttribute('OverrideBuiltins')):
             # Check assumptions.
             if self.descriptor.supportsIndexedProperties():
                 raise ValueError("In interface " + self.descriptor.name + ": " +
                                  "Can't cope with [OverrideBuiltins] and an indexed getter")
-            if self.descriptor.operations['NamedCreator'] is not namedSetter:
-                raise ValueError("In interface " + self.descriptor.name + ": " +
-                                 "Can't cope with named setter that is not also a named creator")
             if self.descriptor.hasUnforgeableMembers:
                 raise ValueError("In interface " + self.descriptor.name + ": " +
                                  "Can't cope with [OverrideBuiltins] and unforgeable members")
 
             callSetter = CGProxyNamedSetter(self.descriptor, argumentHandleValue="v")
             return (assertion +
                     callSetter.define() +
                     "*done = true;\n"
                     "return true;\n")
 
         # As an optimization, if we are going to call an IndexedSetter, go
         # ahead and call it and have done.
         indexedSetter = self.descriptor.operations['IndexedSetter']
         if indexedSetter is not None:
-            if self.descriptor.operations['IndexedCreator'] is not indexedSetter:
-                raise ValueError("In interface " + self.descriptor.name + ": " +
-                                 "Can't cope with indexed setter that is not " +
-                                 "also an indexed creator")
             setIndexed = fill(
                 """
                 uint32_t index = GetArrayIndexFromId(cx, id);
                 if (IsArrayIndex(index)) {
                   $*{callSetter}
                   *done = true;
                   return true;
                 }
@@ -15011,19 +15000,16 @@ class CGBindingImplClass(CGClass):
                 self.methodDecls.append(cgGetter(descriptor, m))
                 if not m.readonly:
                     self.methodDecls.append(cgSetter(descriptor, m))
 
         # Now do the special operations
         def appendSpecialOperation(name, op):
             if op is None:
                 return
-            if name == "IndexedCreator" or name == "NamedCreator":
-                # These are identical to the setters
-                return
             assert len(op.signatures()) == 1
             returnType, args = op.signatures()[0]
             # Make a copy of the args, since we plan to modify them.
             args = list(args)
             if op.isGetter() or op.isDeleter():
                 # This is a total hack.  The '&' belongs with the
                 # type, not the name!  But it works, and is simpler
                 # than trying to somehow make this pretty.
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -388,21 +388,19 @@ class Descriptor(DescriptorProvider):
                          not self.interface.isNamespace() and
                          desc.get('concrete', True))
         self.hasUnforgeableMembers = (self.concrete and
                                       any(MemberIsUnforgeable(m, self) for m in
                                           self.interface.members))
         self.operations = {
             'IndexedGetter': None,
             'IndexedSetter': None,
-            'IndexedCreator': None,
             'IndexedDeleter': None,
             'NamedGetter': None,
             'NamedSetter': None,
-            'NamedCreator': None,
             'NamedDeleter': None,
             'Stringifier': None,
             'LegacyCaller': None,
             'Jsonifier': None
             }
 
         # Stringifiers and jsonifiers need to be set up whether an interface is
         # concrete or not, because they're actually prototype methods and hence
@@ -449,18 +447,16 @@ class Descriptor(DescriptorProvider):
                             assert m.isNamed()
                             operation = 'Named' + operation
                         addOperation(operation, m)
 
                     if m.isGetter():
                         addIndexedOrNamedOperation('Getter', m)
                     if m.isSetter():
                         addIndexedOrNamedOperation('Setter', m)
-                    if m.isCreator():
-                        addIndexedOrNamedOperation('Creator', m)
                     if m.isDeleter():
                         addIndexedOrNamedOperation('Deleter', m)
                     if m.isLegacycaller() and iface != self.interface:
                         raise TypeError("We don't support legacycaller on "
                                         "non-leaf interface %s.\n%s" %
                                         (iface, iface.location))
 
                 iface.setUserData('hasConcreteDescendant', True)
@@ -469,25 +465,23 @@ class Descriptor(DescriptorProvider):
             self.proxy = (self.supportsIndexedProperties() or
                           (self.supportsNamedProperties() and
                            not self.hasNamedPropertiesObject) or
                           self.hasNonOrdinaryGetPrototypeOf())
 
             if self.proxy:
                 if (not self.operations['IndexedGetter'] and
                     (self.operations['IndexedSetter'] or
-                     self.operations['IndexedDeleter'] or
-                     self.operations['IndexedCreator'])):
+                     self.operations['IndexedDeleter'])):
                     raise SyntaxError("%s supports indexed properties but does "
                                       "not have an indexed getter.\n%s" %
                                       (self.interface, self.interface.location))
                 if (not self.operations['NamedGetter'] and
                     (self.operations['NamedSetter'] or
-                     self.operations['NamedDeleter'] or
-                     self.operations['NamedCreator'])):
+                     self.operations['NamedDeleter'])):
                     raise SyntaxError("%s supports named properties but does "
                                       "not have a named getter.\n%s" %
                                       (self.interface, self.interface.location))
                 iface = self.interface
                 while iface:
                     iface.setUserData('hasProxyDescendant', True)
                     iface = iface.parent
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1090,34 +1090,32 @@ class IDLInterfaceOrNamespace(IDLObjectW
             isAncestor = False
             while testInterface:
                 self.maplikeOrSetlikeOrIterable.checkCollisions(testInterface.members,
                                                                 isAncestor)
                 isAncestor = True
                 testInterface = testInterface.parent
 
         # Ensure that there's at most one of each {named,indexed}
-        # {getter,setter,creator,deleter}, at most one stringifier,
+        # {getter,setter,deleter}, at most one stringifier,
         # and at most one legacycaller.  Note that this last is not
         # quite per spec, but in practice no one overloads
         # legacycallers.  Also note that in practice we disallow
         # indexed deleters, but it simplifies some other code to
-        # treat deleter analogously to getter/setter/creator by
+        # treat deleter analogously to getter/setter by
         # prefixing it with "named".
         specialMembersSeen = {}
         for member in self.members:
             if not member.isMethod():
                 continue
 
             if member.isGetter():
                 memberType = "getters"
             elif member.isSetter():
                 memberType = "setters"
-            elif member.isCreator():
-                memberType = "creators"
             elif member.isDeleter():
                 memberType = "deleters"
             elif member.isStringifier():
                 memberType = "stringifiers"
             elif member.isJsonifier():
                 memberType = "jsonifiers"
             elif member.isLegacycaller():
                 memberType = "legacycallers"
@@ -1153,18 +1151,18 @@ class IDLInterfaceOrNamespace(IDLObjectW
                     raise WebIDLError(
                         "Interface with [LegacyUnenumerableNamedProperties] "
                         "inherits from another interface with "
                         "[LegacyUnenumerableNamedProperties]",
                         [self.location, ancestor.location])
                 ancestor = ancestor.parent
 
         if self._isOnGlobalProtoChain:
-            # Make sure we have no named setters, creators, or deleters
-            for memberType in ["setter", "creator", "deleter"]:
+            # Make sure we have no named setters or deleters
+            for memberType in ["setter", "deleter"]:
                 memberId = "named " + memberType + "s"
                 if memberId in specialMembersSeen:
                     raise WebIDLError("Interface with [Global] has a named %s" %
                                       memberType,
                                       [self.location,
                                        specialMembersSeen[memberId].location])
             # Make sure we're not [OverrideBuiltins]
             if self.getExtendedAttribute("OverrideBuiltins"):
@@ -4615,30 +4613,29 @@ class IDLMethodOverload:
         return deps
 
 
 class IDLMethod(IDLInterfaceMember, IDLScope):
 
     Special = enum(
         'Getter',
         'Setter',
-        'Creator',
         'Deleter',
         'LegacyCaller',
         base=IDLInterfaceMember.Special
     )
 
     NamedOrIndexed = enum(
         'Neither',
         'Named',
         'Indexed'
     )
 
     def __init__(self, location, identifier, returnType, arguments,
-                 static=False, getter=False, setter=False, creator=False,
+                 static=False, getter=False, setter=False,
                  deleter=False, specialType=NamedOrIndexed.Neither,
                  legacycaller=False, stringifier=False, jsonifier=False,
                  maplikeOrSetlikeOrIterable=None, htmlConstructor=False):
         # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
         IDLInterfaceMember.__init__(self, location, identifier,
                                     IDLInterfaceMember.Tags.Method)
 
         self._hasOverloads = False
@@ -4649,18 +4646,16 @@ class IDLMethod(IDLInterfaceMember, IDLS
         self._overloads = [IDLMethodOverload(returnType, arguments, location)]
 
         assert isinstance(static, bool)
         self._static = static
         assert isinstance(getter, bool)
         self._getter = getter
         assert isinstance(setter, bool)
         self._setter = setter
-        assert isinstance(creator, bool)
-        self._creator = creator
         assert isinstance(deleter, bool)
         self._deleter = deleter
         assert isinstance(legacycaller, bool)
         self._legacycaller = legacycaller
         assert isinstance(stringifier, bool)
         self._stringifier = stringifier
         assert isinstance(jsonifier, bool)
         self._jsonifier = jsonifier
@@ -4691,17 +4686,17 @@ class IDLMethod(IDLInterfaceMember, IDLS
             overload = self._overloads[0]
             arguments = overload.arguments
             assert len(arguments) == 1
             assert (arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or
                     arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long])
             assert not arguments[0].optional and not arguments[0].variadic
             assert not self._getter or not overload.returnType.isVoid()
 
-        if self._setter or self._creator:
+        if self._setter:
             assert len(self._overloads) == 1
             arguments = self._overloads[0].arguments
             assert len(arguments) == 2
             assert (arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or
                     arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long])
             assert not arguments[0].optional and not arguments[0].variadic
             assert not arguments[1].optional and not arguments[1].variadic
 
@@ -4724,19 +4719,16 @@ class IDLMethod(IDLInterfaceMember, IDLS
         self._static = True
 
     def isGetter(self):
         return self._getter
 
     def isSetter(self):
         return self._setter
 
-    def isCreator(self):
-        return self._creator
-
     def isDeleter(self):
         return self._deleter
 
     def isNamed(self):
         assert (self._specialType == IDLMethod.NamedOrIndexed.Named or
                 self._specialType == IDLMethod.NamedOrIndexed.Indexed)
         return self._specialType == IDLMethod.NamedOrIndexed.Named
 
@@ -4759,17 +4751,16 @@ class IDLMethod(IDLInterfaceMember, IDLS
         True if this method was generated as part of a
         maplike/setlike/etc interface (e.g. has/get methods)
         """
         return self.maplikeOrSetlikeOrIterable is not None
 
     def isSpecial(self):
         return (self.isGetter() or
                 self.isSetter() or
-                self.isCreator() or
                 self.isDeleter() or
                 self.isLegacycaller() or
                 self.isStringifier() or
                 self.isJsonifier())
 
     def isHTMLConstructor(self):
         return self._htmlConstructor
 
@@ -4815,18 +4806,16 @@ class IDLMethod(IDLInterfaceMember, IDLS
             raise WebIDLError("Overloaded identifier %s appears with different values of the 'legacycaller' attribute" % method.identifier,
                               [method.location])
 
         # Can't overload special things!
         assert not self.isGetter()
         assert not method.isGetter()
         assert not self.isSetter()
         assert not method.isSetter()
-        assert not self.isCreator()
-        assert not method.isCreator()
         assert not self.isDeleter()
         assert not method.isDeleter()
         assert not self.isStringifier()
         assert not method.isStringifier()
         assert not self.isJsonifier()
         assert not method.isJsonifier()
         assert not self.isHTMLConstructor()
         assert not method.isHTMLConstructor()
@@ -5272,17 +5261,16 @@ class Tokenizer(object):
         "jsonifier": "JSONIFIER",
         "unrestricted": "UNRESTRICTED",
         "attribute": "ATTRIBUTE",
         "readonly": "READONLY",
         "inherit": "INHERIT",
         "static": "STATIC",
         "getter": "GETTER",
         "setter": "SETTER",
-        "creator": "CREATOR",
         "deleter": "DELETER",
         "legacycaller": "LEGACYCALLER",
         "optional": "OPTIONAL",
         "...": "ELLIPSIS",
         "::": "SCOPE",
         "Date": "DATE",
         "DOMString": "DOMSTRING",
         "ByteString": "BYTESTRING",
@@ -5987,23 +5975,22 @@ class Parser(Tokenizer):
 
         stringifier = IDLInterfaceMember.Special.Stringifier in p[1]
         # If stringifier is there that's all that's allowed.  This is disallowed
         # by the parser, so we can assert here.
         assert not stringifier or len(qualifiers) == 1
 
         getter = True if IDLMethod.Special.Getter in p[1] else False
         setter = True if IDLMethod.Special.Setter in p[1] else False
-        creator = True if IDLMethod.Special.Creator in p[1] else False
         deleter = True if IDLMethod.Special.Deleter in p[1] else False
         legacycaller = True if IDLMethod.Special.LegacyCaller in p[1] else False
 
         if getter or deleter:
-            if setter or creator:
-                raise WebIDLError("getter and deleter are incompatible with setter and creator",
+            if setter:
+                raise WebIDLError("getter and deleter are incompatible with setter",
                                   [self.getLocation(p, 1)])
 
         (returnType, identifier, arguments) = p[2]
 
         assert isinstance(returnType, IDLType)
 
         specialType = IDLMethod.NamedOrIndexed.Neither
 
@@ -6028,72 +6015,67 @@ class Parser(Tokenizer):
                 raise WebIDLError("%s cannot have %s argument" %
                                   ("getter" if getter else "deleter",
                                    "optional" if arguments[0].optional else "variadic"),
                                   [arguments[0].location])
         if getter:
             if returnType.isVoid():
                 raise WebIDLError("getter cannot have void return type",
                                   [self.getLocation(p, 2)])
-        if setter or creator:
+        if setter:
             if len(arguments) != 2:
-                raise WebIDLError("%s has wrong number of arguments" %
-                                  ("setter" if setter else "creator"),
+                raise WebIDLError("setter has wrong number of arguments",
                                   [self.getLocation(p, 2)])
             argType = arguments[0].type
             if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]:
                 specialType = IDLMethod.NamedOrIndexed.Named
             elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]:
                 specialType = IDLMethod.NamedOrIndexed.Indexed
             else:
-                raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" %
-                                  ("setter" if setter else "creator"),
+                raise WebIDLError("settter has wrong argument type (must be DOMString or UnsignedLong)",
                                   [arguments[0].location])
             if arguments[0].optional or arguments[0].variadic:
-                raise WebIDLError("%s cannot have %s argument" %
-                                  ("setter" if setter else "creator",
-                                   "optional" if arguments[0].optional else "variadic"),
+                raise WebIDLError("setter cannot have %s argument" %
+                                   ("optional" if arguments[0].optional else "variadic"),
                                   [arguments[0].location])
             if arguments[1].optional or arguments[1].variadic:
-                raise WebIDLError("%s cannot have %s argument" %
-                                  ("setter" if setter else "creator",
-                                   "optional" if arguments[1].optional else "variadic"),
+                raise WebIDLError("setter cannot have %s argument" %
+                                   ("optional" if arguments[1].optional else "variadic"),
                                   [arguments[1].location])
 
         if stringifier:
             if len(arguments) != 0:
                 raise WebIDLError("stringifier has wrong number of arguments",
                                   [self.getLocation(p, 2)])
             if not returnType.isDOMString():
                 raise WebIDLError("stringifier must have DOMString return type",
                                   [self.getLocation(p, 2)])
 
         # identifier might be None.  This is only permitted for special methods.
         if not identifier:
-            if (not getter and not setter and not creator and
+            if (not getter and not setter and
                 not deleter and not legacycaller and not stringifier):
                 raise WebIDLError("Identifier required for non-special methods",
                                   [self.getLocation(p, 2)])
 
             location = BuiltinLocation("<auto-generated-identifier>")
             identifier = IDLUnresolvedIdentifier(
                 location,
-                "__%s%s%s%s%s%s%s" %
+                "__%s%s%s%s%s%s" %
                 ("named" if specialType == IDLMethod.NamedOrIndexed.Named else
                  "indexed" if specialType == IDLMethod.NamedOrIndexed.Indexed else "",
                  "getter" if getter else "",
                  "setter" if setter else "",
                  "deleter" if deleter else "",
-                 "creator" if creator else "",
                  "legacycaller" if legacycaller else "",
                  "stringifier" if stringifier else ""),
                 allowDoubleUnderscore=True)
 
         method = IDLMethod(self.getLocation(p, 2), identifier, returnType, arguments,
-                           static=static, getter=getter, setter=setter, creator=creator,
+                           static=static, getter=getter, setter=setter,
                            deleter=deleter, specialType=specialType,
                            legacycaller=legacycaller, stringifier=stringifier)
         p[0] = method
 
     def p_Stringifier(self, p):
         """
             Operation : STRINGIFIER SEMICOLON
         """
@@ -6159,22 +6141,16 @@ class Parser(Tokenizer):
         p[0] = IDLMethod.Special.Getter
 
     def p_SpecialSetter(self, p):
         """
             Special : SETTER
         """
         p[0] = IDLMethod.Special.Setter
 
-    def p_SpecialCreator(self, p):
-        """
-            Special : CREATOR
-        """
-        p[0] = IDLMethod.Special.Creator
-
     def p_SpecialDeleter(self, p):
         """
             Special : DELETER
         """
         p[0] = IDLMethod.Special.Deleter
 
     def p_SpecialLegacyCaller(self, p):
         """
@@ -6256,17 +6232,16 @@ class Parser(Tokenizer):
         p[0].addExtendedAttributes(p[1])
 
     def p_ArgumentName(self, p):
         """
             ArgumentName : IDENTIFIER
                          | ATTRIBUTE
                          | CALLBACK
                          | CONST
-                         | CREATOR
                          | DELETER
                          | DICTIONARY
                          | ENUM
                          | EXCEPTION
                          | GETTER
                          | IMPLEMENTS
                          | INHERIT
                          | INTERFACE
@@ -6406,17 +6381,16 @@ class Parser(Tokenizer):
                   | BYTESTRING
                   | USVSTRING
                   | ANY
                   | ATTRIBUTE
                   | BOOLEAN
                   | BYTE
                   | LEGACYCALLER
                   | CONST
-                  | CREATOR
                   | DELETER
                   | DOUBLE
                   | EXCEPTION
                   | FALSE
                   | FLOAT
                   | GETTER
                   | IMPLEMENTS
                   | INHERIT
--- a/dom/bindings/parser/tests/test_cereactions.py
+++ b/dom/bindings/parser/tests/test_cereactions.py
@@ -101,31 +101,16 @@ def WebIDLTest(parser, harness):
     harness.ok(threw,
                "Should have thrown for [CEReactions] used on a named getter")
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
           interface Foo {
-            [CEReactions] creator boolean (DOMString name, boolean value);
-          };
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw,
-               "Should have thrown for [CEReactions] used on a named creator")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-          interface Foo {
             [CEReactions] legacycaller double compute(double x);
           };
         """)
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw,
--- a/dom/bindings/parser/tests/test_constructor.py
+++ b/dom/bindings/parser/tests/test_constructor.py
@@ -6,30 +6,29 @@ def WebIDLTest(parser, harness):
                    "Should be an IDLArgument")
         harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
         harness.check(argument.identifier.name, name, "Argument has the right name")
         harness.check(str(argument.type), type, "Argument has the right return type")
         harness.check(argument.optional, optional, "Argument has the right optional value")
         harness.check(argument.variadic, variadic, "Argument has the right variadic value")
 
     def checkMethod(method, QName, name, signatures,
-                    static=True, getter=False, setter=False, creator=False,
+                    static=True, getter=False, setter=False,
                     deleter=False, legacycaller=False, stringifier=False,
                     chromeOnly=False, htmlConstructor=False):
         harness.ok(isinstance(method, WebIDL.IDLMethod),
                    "Should be an IDLMethod")
         harness.ok(method.isMethod(), "Method is a method")
         harness.ok(not method.isAttr(), "Method is not an attr")
         harness.ok(not method.isConst(), "Method is not a const")
         harness.check(method.identifier.QName(), QName, "Method has the right QName")
         harness.check(method.identifier.name, name, "Method has the right name")
         harness.check(method.isStatic(), static, "Method has the correct static value")
         harness.check(method.isGetter(), getter, "Method has the correct getter value")
         harness.check(method.isSetter(), setter, "Method has the correct setter value")
-        harness.check(method.isCreator(), creator, "Method has the correct creator value")
         harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
         harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
         harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
         harness.check(method.getExtendedAttribute("ChromeOnly") is not None, chromeOnly, "Method has the correct value for ChromeOnly")
         harness.check(method.isHTMLConstructor(), htmlConstructor, "Method has the correct htmlConstructor value")
         harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
 
         sigpairs = zip(method.signatures(), signatures)
--- a/dom/bindings/parser/tests/test_duplicate_qualifiers.py
+++ b/dom/bindings/parser/tests/test_duplicate_qualifiers.py
@@ -25,30 +25,16 @@ def WebIDLTest(parser, harness):
     except:
         threw = True
 
     harness.ok(threw, "Should have thrown.")
 
     threw = False
     try:
         parser.parse("""
-            interface DuplicateQualifiers3 {
-              creator creator byte foo(unsigned long index, byte value);
-            };
-        """)
-
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown.")
-
-    threw = False
-    try:
-        parser.parse("""
             interface DuplicateQualifiers4 {
               deleter deleter byte foo(unsigned long index);
             };
         """)
 
         results = parser.finish()
     except:
         threw = True
@@ -63,22 +49,8 @@ def WebIDLTest(parser, harness):
             };
         """)
 
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw, "Should have thrown.")
-
-    threw = False
-    try:
-        results = parser.parse("""
-            interface DuplicateQualifiers6 {
-              creator setter creator byte foo(unsigned long index, byte value);
-            };
-        """)
-
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown.")
--- a/dom/bindings/parser/tests/test_global_extended_attr.py
+++ b/dom/bindings/parser/tests/test_global_extended_attr.py
@@ -34,34 +34,16 @@ def WebIDLTest(parser, harness):
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
           [Global]
           interface Foo {
             getter any(DOMString name);
-            creator void(DOMString name, any arg);
-          };
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw,
-               "Should have thrown for [Global] used on an interface with a "
-               "named creator")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-          [Global]
-          interface Foo {
-            getter any(DOMString name);
             deleter void(DOMString name);
           };
         """)
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw,
--- a/dom/bindings/parser/tests/test_method.py
+++ b/dom/bindings/parser/tests/test_method.py
@@ -36,29 +36,28 @@ def WebIDLTest(parser, harness):
                    "Should be an IDLArgument")
         harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
         harness.check(argument.identifier.name, name, "Argument has the right name")
         harness.check(str(argument.type), type, "Argument has the right return type")
         harness.check(argument.optional, optional, "Argument has the right optional value")
         harness.check(argument.variadic, variadic, "Argument has the right variadic value")
 
     def checkMethod(method, QName, name, signatures,
-                    static=False, getter=False, setter=False, creator=False,
+                    static=False, getter=False, setter=False,
                     deleter=False, legacycaller=False, stringifier=False):
         harness.ok(isinstance(method, WebIDL.IDLMethod),
                    "Should be an IDLMethod")
         harness.ok(method.isMethod(), "Method is a method")
         harness.ok(not method.isAttr(), "Method is not an attr")
         harness.ok(not method.isConst(), "Method is not a const")
         harness.check(method.identifier.QName(), QName, "Method has the right QName")
         harness.check(method.identifier.name, name, "Method has the right name")
         harness.check(method.isStatic(), static, "Method has the correct static value")
         harness.check(method.isGetter(), getter, "Method has the correct getter value")
         harness.check(method.isSetter(), setter, "Method has the correct setter value")
-        harness.check(method.isCreator(), creator, "Method has the correct creator value")
         harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
         harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
         harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
         harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
 
         sigpairs = zip(method.signatures(), signatures)
         for (gotSignature, expectedSignature) in sigpairs:
             (gotRetType, gotArgs) = gotSignature
--- a/dom/bindings/parser/tests/test_special_method_signature_mismatch.py
+++ b/dom/bindings/parser/tests/test_special_method_signature_mismatch.py
@@ -217,78 +217,8 @@ def WebIDLTest(parser, harness):
             };
         """)
 
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw, "Should have thrown.")
-
-    threw = False
-    try:
-        parser.parse("""
-            interface SpecialMethodSignatureMismatch20 {
-              creator long long foo(long index, long long value);
-            };
-        """)
-
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown.")
-
-    threw = False
-    try:
-        parser.parse("""
-            interface SpecialMethodSignatureMismatch22 {
-              creator boolean foo(unsigned long index, boolean value, long long extraArg);
-            };
-        """)
-
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown.")
-
-    threw = False
-    try:
-        parser.parse("""
-            interface SpecialMethodSignatureMismatch23 {
-              creator boolean foo(unsigned long index, boolean... value);
-            };
-        """)
-
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown.")
-
-    threw = False
-    try:
-        parser.parse("""
-            interface SpecialMethodSignatureMismatch24 {
-              creator boolean foo(unsigned long index, optional boolean value);
-            };
-        """)
-
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown.")
-
-    threw = False
-    try:
-        parser.parse("""
-            interface SpecialMethodSignatureMismatch25 {
-              creator boolean foo();
-            };
-        """)
-
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown.")
--- a/dom/bindings/parser/tests/test_special_methods.py
+++ b/dom/bindings/parser/tests/test_special_methods.py
@@ -1,76 +1,63 @@
 import WebIDL
 
 def WebIDLTest(parser, harness):
     parser.parse("""
         interface SpecialMethods {
           getter long long (unsigned long index);
           setter long long (unsigned long index, long long value);
-          creator long long (unsigned long index, long long value);
           getter boolean (DOMString name);
           setter boolean (DOMString name, boolean value);
-          creator boolean (DOMString name, boolean value);
           deleter boolean (DOMString name);
           readonly attribute unsigned long length;
         };
 
         interface SpecialMethodsCombination {
-          setter creator long long (unsigned long index, long long value);
           getter deleter boolean (DOMString name);
-          setter creator boolean (DOMString name, boolean value);
         };
     """)
 
     results = parser.finish()
 
     def checkMethod(method, QName, name,
-                    static=False, getter=False, setter=False, creator=False,
+                    static=False, getter=False, setter=False,
                     deleter=False, legacycaller=False, stringifier=False):
         harness.ok(isinstance(method, WebIDL.IDLMethod),
                    "Should be an IDLMethod")
         harness.check(method.identifier.QName(), QName, "Method has the right QName")
         harness.check(method.identifier.name, name, "Method has the right name")
         harness.check(method.isStatic(), static, "Method has the correct static value")
         harness.check(method.isGetter(), getter, "Method has the correct getter value")
         harness.check(method.isSetter(), setter, "Method has the correct setter value")
-        harness.check(method.isCreator(), creator, "Method has the correct creator value")
         harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
         harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
         harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
 
     harness.check(len(results), 2, "Expect 2 interfaces")
 
     iface = results[0]
-    harness.check(len(iface.members), 8, "Expect 8 members")
+    harness.check(len(iface.members), 6, "Expect 6 members")
 
     checkMethod(iface.members[0], "::SpecialMethods::__indexedgetter", "__indexedgetter",
                 getter=True)
     checkMethod(iface.members[1], "::SpecialMethods::__indexedsetter", "__indexedsetter",
                 setter=True)
-    checkMethod(iface.members[2], "::SpecialMethods::__indexedcreator", "__indexedcreator",
-                creator=True)
-    checkMethod(iface.members[3], "::SpecialMethods::__namedgetter", "__namedgetter",
+    checkMethod(iface.members[2], "::SpecialMethods::__namedgetter", "__namedgetter",
                 getter=True)
-    checkMethod(iface.members[4], "::SpecialMethods::__namedsetter", "__namedsetter",
+    checkMethod(iface.members[3], "::SpecialMethods::__namedsetter", "__namedsetter",
                 setter=True)
-    checkMethod(iface.members[5], "::SpecialMethods::__namedcreator", "__namedcreator",
-                creator=True)
-    checkMethod(iface.members[6], "::SpecialMethods::__nameddeleter", "__nameddeleter",
+    checkMethod(iface.members[4], "::SpecialMethods::__nameddeleter", "__nameddeleter",
                 deleter=True)
 
     iface = results[1]
-    harness.check(len(iface.members), 3, "Expect 3 members")
+    harness.check(len(iface.members), 1, "Expect 1 member")
 
-    checkMethod(iface.members[0], "::SpecialMethodsCombination::__indexedsettercreator",
-                "__indexedsettercreator", setter=True, creator=True)
-    checkMethod(iface.members[1], "::SpecialMethodsCombination::__namedgetterdeleter",
+    checkMethod(iface.members[0], "::SpecialMethodsCombination::__namedgetterdeleter",
                 "__namedgetterdeleter", getter=True, deleter=True)
-    checkMethod(iface.members[2], "::SpecialMethodsCombination::__namedsettercreator",
-                "__namedsettercreator", setter=True, creator=True)
 
     parser = parser.reset();
 
     threw = False
     try:
         parser.parse(
             """
             interface IndexedDeleter {
--- a/dom/bindings/parser/tests/test_special_methods_uniqueness.py
+++ b/dom/bindings/parser/tests/test_special_methods_uniqueness.py
@@ -30,33 +30,18 @@ def WebIDLTest(parser, harness):
         threw = True
 
     harness.ok(threw, "Should have thrown.")
 
     threw = False
     try:
         parser.parse("""
             interface SpecialMethodUniqueness1 {
-              setter creator boolean (DOMString name);
-              creator boolean (DOMString name);
+              setter boolean (DOMString name);
+              setter boolean (DOMString name);
             };
         """)
 
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw, "Should have thrown.")
-
-    threw = False
-    try:
-        parser.parse("""
-            interface SpecialMethodUniqueness1 {
-              setter boolean (DOMString name);
-              creator setter boolean (DOMString name);
-            };
-        """)
-
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown.")
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -1206,50 +1206,50 @@ interface TestIndexedGetterInterface {
 
 interface TestNamedGetterInterface {
   getter DOMString (DOMString name);
 };
 
 interface TestIndexedGetterAndSetterAndNamedGetterInterface {
   getter DOMString (DOMString myName);
   getter long (unsigned long index);
-  setter creator void (unsigned long index, long arg);
+  setter void (unsigned long index, long arg);
   readonly attribute unsigned long length;
 };
 
 interface TestIndexedAndNamedGetterInterface {
   getter long (unsigned long index);
   getter DOMString namedItem(DOMString name);
   readonly attribute unsigned long length;
 };
 
 interface TestIndexedSetterInterface {
-  setter creator void setItem(unsigned long idx, DOMString item);
+  setter void setItem(unsigned long idx, DOMString item);
   getter DOMString (unsigned long idx);
   readonly attribute unsigned long length;
 };
 
 interface TestNamedSetterInterface {
-  setter creator void (DOMString myName, TestIndexedSetterInterface item);
+  setter void (DOMString myName, TestIndexedSetterInterface item);
   getter TestIndexedSetterInterface (DOMString name);
 };
 
 interface TestIndexedAndNamedSetterInterface {
-  setter creator void (unsigned long index, TestIndexedSetterInterface item);
+  setter void (unsigned long index, TestIndexedSetterInterface item);
   getter TestIndexedSetterInterface (unsigned long index);
   readonly attribute unsigned long length;
-  setter creator void setNamedItem(DOMString name, TestIndexedSetterInterface item);
+  setter void setNamedItem(DOMString name, TestIndexedSetterInterface item);
   getter TestIndexedSetterInterface (DOMString name);
 };
 
 interface TestIndexedAndNamedGetterAndSetterInterface : TestIndexedSetterInterface {
   getter long item(unsigned long index);
   getter DOMString namedItem(DOMString name);
-  setter creator void (unsigned long index, long item);
-  setter creator void (DOMString name, DOMString item);
+  setter void (unsigned long index, long item);
+  setter void (DOMString name, DOMString item);
   stringifier DOMString ();
   readonly attribute unsigned long length;
 };
 
 interface TestNamedDeleterInterface {
   deleter void (DOMString name);
   getter long (DOMString name);
 };
@@ -1305,15 +1305,15 @@ interface TestWorkerExposedInterface {
   [NeedsCallerType] attribute boolean needsCallerTypeAttr;
 };
 
 [HTMLConstructor]
 interface TestHTMLConstructorInterface {
 };
 
 interface TestCEReactionsInterface {
-  [CEReactions] setter creator void (unsigned long index, long item);
-  [CEReactions] setter creator void (DOMString name, DOMString item);
+  [CEReactions] setter void (unsigned long index, long item);
+  [CEReactions] setter void (DOMString name, DOMString item);
   [CEReactions] deleter void (DOMString name);
   getter long item(unsigned long index);
   getter DOMString (DOMString name);
   readonly attribute unsigned long length;
 };
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -814,22 +814,22 @@ interface TestExampleInterface {
   [NeedsWindowsUndef]
   const unsigned long NO_ERROR = 0xffffffff;
 
   // If you add things here, add them to TestCodeGen and TestJSImplGen as well
 };
 
 interface TestExampleProxyInterface {
   getter long longIndexedGetter(unsigned long ix);
-  setter creator void longIndexedSetter(unsigned long y, long z);
+  setter void longIndexedSetter(unsigned long y, long z);
   readonly attribute unsigned long length;
   stringifier DOMString myStringifier();
   getter short shortNameGetter(DOMString nom);
   deleter void (DOMString nomnom);
-  setter creator void shortNamedSetter(DOMString me, short value);
+  setter void shortNamedSetter(DOMString me, short value);
 };
 
 [Exposed=(Window,Worker)]
 interface TestExampleWorkerInterface {
   [NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
   [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
   [NeedsCallerType] void needsCallerTypeMethod();
   [NeedsCallerType] attribute boolean needsCallerTypeAttr;
--- a/dom/interfaces/xul/moz.build
+++ b/dom/interfaces/xul/moz.build
@@ -12,17 +12,16 @@ XPIDL_SOURCES += [
     'nsIDOMXULCheckboxElement.idl',
     'nsIDOMXULCommandDispatcher.idl',
     'nsIDOMXULCommandEvent.idl',
     'nsIDOMXULContainerElement.idl',
     'nsIDOMXULControlElement.idl',
     'nsIDOMXULDescriptionElement.idl',
     'nsIDOMXULDocument.idl',
     'nsIDOMXULElement.idl',
-    'nsIDOMXULImageElement.idl',
     'nsIDOMXULLabeledControlEl.idl',
     'nsIDOMXULLabelElement.idl',
     'nsIDOMXULMenuListElement.idl',
     'nsIDOMXULMultSelectCntrlEl.idl',
     'nsIDOMXULPopupElement.idl',
     'nsIDOMXULRelatedElement.idl',
     'nsIDOMXULSelectCntrlEl.idl',
     'nsIDOMXULSelectCntrlItemEl.idl',
deleted file mode 100644
--- a/dom/interfaces/xul/nsIDOMXULImageElement.idl
+++ /dev/null
@@ -1,12 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsIDOMElement.idl"
-#include "nsIDOMXULElement.idl"
-
-[scriptable, uuid(0a391077-c509-49d2-af73-72e2114edd65)]
-interface nsIDOMXULImageElement : nsISupports {
-  attribute DOMString src;
-};
-
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -460,16 +460,24 @@ TabChild::TabChild(nsIContentChild* aMan
   }
   mCoalesceMouseMoveEvents =
     Preferences::GetBool("dom.event.coalesce_mouse_move");
   if (mCoalesceMouseMoveEvents) {
     mCoalescedMouseEventFlusher = new CoalescedMouseMoveFlusher(this);
   }
 }
 
+const CompositorOptions&
+TabChild::GetCompositorOptions() const
+{
+  // If you're calling this before mCompositorOptions is set, well.. don't.
+  MOZ_ASSERT(mCompositorOptions);
+  return mCompositorOptions.ref();
+}
+
 bool
 TabChild::AsyncPanZoomEnabled() const
 {
   // This might get called by the TouchEvent::PrefEnabled code before we have
   // mCompositorOptions populated (bug 1370089). In that case we just assume
   // APZ is enabled because we're in a content process (because TabChild) and
   // APZ is probably going to be enabled here since e10s is enabled.
   return mCompositorOptions ? mCompositorOptions->UseAPZ() : true;
@@ -2945,17 +2953,17 @@ TabChild::InitRenderingState(const Textu
 }
 
 bool
 TabChild::CreateRemoteLayerManager(mozilla::layers::PCompositorBridgeChild* aCompositorChild)
 {
   MOZ_ASSERT(aCompositorChild);
 
   bool success = false;
-  if (gfxVars::UseWebRender()) {
+  if (mCompositorOptions->UseWebRender()) {
     success = mPuppetWidget->CreateRemoteLayerManager([&] (LayerManager* aLayerManager) -> bool {
       MOZ_ASSERT(aLayerManager->AsWebRenderLayerManager());
       return aLayerManager->AsWebRenderLayerManager()->Initialize(aCompositorChild,
                                                                   wr::AsPipelineId(mLayersId),
                                                                   &mTextureFactoryIdentifier);
     });
   } else {
     nsTArray<LayersBackend> ignored;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -680,16 +680,17 @@ public:
 
   bool IPCOpen() const { return mIPCOpen; }
 
   bool ParentIsActive() const
   {
     return mParentIsActive;
   }
 
+  const mozilla::layers::CompositorOptions& GetCompositorOptions() const;
   bool AsyncPanZoomEnabled() const;
 
   virtual ScreenIntSize GetInnerSize() override;
 
   // Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
   void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                   const uint64_t& aLayersId,
                   const mozilla::layers::CompositorOptions& aCompositorOptions,
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -153,20 +153,17 @@ nsresult nsJSThunk::EvaluateScript(nsICh
     // Get principal of code for execution
     nsCOMPtr<nsISupports> owner;
     aChannel->GetOwner(getter_AddRefs(owner));
     nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(owner);
     if (!principal) {
         nsCOMPtr<nsILoadInfo> loadInfo;
         aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
         if (loadInfo && loadInfo->GetForceInheritPrincipal()) {
-            principal = loadInfo->PrincipalToInherit();
-            if (!principal) {
-                principal = loadInfo->TriggeringPrincipal();
-            }
+            principal = loadInfo->FindPrincipalToInherit(aChannel);
         } else {
             // No execution without a principal!
             NS_ASSERTION(!owner, "Non-principal owner?");
             NS_WARNING("No principal to execute JS with");
             return NS_ERROR_DOM_RETVAL_UNDEFINED;
         }
     }
 
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -123,17 +123,16 @@ public:
   explicit WebMContainerParser(const MediaContainerType& aType)
     : ContainerParser(aType)
     , mParser(0)
     , mOffset(0)
   {
   }
 
   static const unsigned NS_PER_USEC = 1000;
-  static const unsigned USEC_PER_SEC = 1000000;
 
   MediaResult IsInitSegmentPresent(MediaByteBuffer* aData) override
   {
     ContainerParser::IsInitSegmentPresent(aData);
     if (aData->Length() < 4) {
       return NS_ERROR_NOT_AVAILABLE;
     }
 
deleted file mode 100644
--- a/dom/plugins/base/PluginPRLibrary.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/Assertions.h"
-#include "mozilla/PluginPRLibrary.h"
-#include "nsNPAPIPluginInstance.h"
-
-// Some plugins on Windows, notably Quake Live, implement NP_Initialize using
-// cdecl instead of the documented stdcall. In order to work around this,
-// we force the caller to use a frame pointer.
-#if defined(XP_WIN) && defined(_M_IX86)
-#include <malloc.h>
-
-// gNotOptimized exists so that the compiler will not optimize the alloca
-// below.
-static int gNotOptimized;
-#define CALLING_CONVENTION_HACK void* foo MOZ_UNUSED_ATTRIBUTE = _alloca(gNotOptimized);
-#else
-#define CALLING_CONVENTION_HACK
-#endif
-
-using namespace mozilla::layers;
-
-namespace mozilla {
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-nsresult
-PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
-                               NPPluginFuncs* pFuncs, NPError* error)
-{
-  if (mNP_Initialize) {
-    *error = mNP_Initialize(bFuncs, pFuncs);
-  } else {
-    NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc)
-      PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
-    if (!pfNP_Initialize)
-      return NS_ERROR_FAILURE;
-    *error = pfNP_Initialize(bFuncs, pFuncs);
-  }
-
-
-  // Save pointers to functions that get called through PluginLibrary itself.
-  mNPP_New = pFuncs->newp;
-  mNPP_ClearSiteData = pFuncs->clearsitedata;
-  mNPP_GetSitesWithData = pFuncs->getsiteswithdata;
-  return NS_OK;
-}
-#else
-nsresult
-PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
-{
-  CALLING_CONVENTION_HACK
-
-  if (mNP_Initialize) {
-    *error = mNP_Initialize(bFuncs);
-  } else {
-    NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc)
-      PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
-    if (!pfNP_Initialize)
-      return NS_ERROR_FAILURE;
-    *error = pfNP_Initialize(bFuncs);
-  }
-
-  return NS_OK;
-}
-#endif
-
-nsresult
-PluginPRLibrary::NP_Shutdown(NPError* error)
-{
-  CALLING_CONVENTION_HACK
-
-  if (mNP_Shutdown) {
-    *error = mNP_Shutdown();
-  } else {
-    NP_ShutdownFunc pfNP_Shutdown = (NP_ShutdownFunc)
-      PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
-    if (!pfNP_Shutdown)
-      return NS_ERROR_FAILURE;
-    *error = pfNP_Shutdown();
-  }
-
-  return NS_OK;
-}
-
-nsresult
-PluginPRLibrary::NP_GetMIMEDescription(const char** mimeDesc)
-{
-  CALLING_CONVENTION_HACK
-
-  if (mNP_GetMIMEDescription) {
-    *mimeDesc = mNP_GetMIMEDescription();
-  }
-  else {
-    NP_GetMIMEDescriptionFunc pfNP_GetMIMEDescription =
-      (NP_GetMIMEDescriptionFunc)
-      PR_FindFunctionSymbol(mLibrary, "NP_GetMIMEDescription");
-    if (!pfNP_GetMIMEDescription) {
-      *mimeDesc = "";
-      return NS_ERROR_FAILURE;
-    }
-    *mimeDesc = pfNP_GetMIMEDescription();
-  }
-
-  return NS_OK;
-}
-
-nsresult
-PluginPRLibrary::NP_GetValue(void *future, NPPVariable aVariable,
-			     void *aValue, NPError* error)
-{
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-  if (mNP_GetValue) {
-    *error = mNP_GetValue(future, aVariable, aValue);
-  } else {
-    NP_GetValueFunc pfNP_GetValue = (NP_GetValueFunc)PR_FindFunctionSymbol(mLibrary, "NP_GetValue");
-    if (!pfNP_GetValue)
-      return NS_ERROR_FAILURE;
-    *error = pfNP_GetValue(future, aVariable, aValue);
-  }
-  return NS_OK;
-#else
-  return NS_ERROR_NOT_IMPLEMENTED;
-#endif
-}
-
-#if defined(XP_WIN) || defined(XP_MACOSX)
-nsresult
-PluginPRLibrary::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error)
-{
-  CALLING_CONVENTION_HACK
-
-  if (mNP_GetEntryPoints) {
-    *error = mNP_GetEntryPoints(pFuncs);
-  } else {
-    NP_GetEntryPointsFunc pfNP_GetEntryPoints = (NP_GetEntryPointsFunc)
-      PR_FindFunctionSymbol(mLibrary, "NP_GetEntryPoints");
-    if (!pfNP_GetEntryPoints)
-      return NS_ERROR_FAILURE;
-    *error = pfNP_GetEntryPoints(pFuncs);
-  }
-
-  // Save pointers to functions that get called through PluginLibrary itself.
-  mNPP_New = pFuncs->newp;
-  mNPP_ClearSiteData = pFuncs->clearsitedata;
-  mNPP_GetSitesWithData = pFuncs->getsiteswithdata;
-  return NS_OK;
-}
-#endif
-
-nsresult
-PluginPRLibrary::NPP_New(NPMIMEType pluginType, NPP instance,
-			 int16_t argc, char* argn[],
-			 char* argv[], NPSavedData* saved,
-			 NPError* error)
-{
-  if (!mNPP_New)
-    return NS_ERROR_FAILURE;
-
-  *error = mNPP_New(pluginType, instance, NP_EMBED, argc, argn, argv, saved);
-  return NS_OK;
-}
-
-nsresult
-PluginPRLibrary::NPP_ClearSiteData(const char* site, uint64_t flags,
-                                   uint64_t maxAge, nsCOMPtr<nsIClearSiteDataCallback> callback)
-{
-  if (!mNPP_ClearSiteData) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  NPError result = mNPP_ClearSiteData(site, flags, maxAge);
-
-  nsresult rv;
-  switch (result) {
-  case NPERR_NO_ERROR:
-    rv = NS_OK;
-    break;
-  case NPERR_TIME_RANGE_NOT_SUPPORTED:
-    rv = NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED;
-    break;
-  case NPERR_MALFORMED_SITE:
-    rv = NS_ERROR_INVALID_ARG;
-    break;
-  default:
-    rv = NS_ERROR_FAILURE;
-  }
-  callback->Callback(rv);
-  return NS_OK;
-}
-
-nsresult
-PluginPRLibrary::NPP_GetSitesWithData(nsCOMPtr<nsIGetSitesWithDataCallback> callback)
-{
-  if (!mNPP_GetSitesWithData) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  char** sites = mNPP_GetSitesWithData();
-  if (!sites) {
-    return NS_OK;
-  }
-  InfallibleTArray<nsCString> result;
-  char** iterator = sites;
-  while (*iterator) {
-    result.AppendElement(*iterator);
-    free(*iterator);
-    ++iterator;
-  }
-  callback->SitesWithData(result);
-  free(sites);
-
-  return NS_OK;
-}
-
-nsresult
-PluginPRLibrary::AsyncSetWindow(NPP instance, NPWindow* window)
-{
-  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
-  NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
-PluginPRLibrary::GetImageContainer(NPP instance, ImageContainer** aContainer)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-#if defined(XP_MACOSX)
-nsresult
-PluginPRLibrary::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing)
-{
-  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
-  NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
-  *aDrawing = false;
-  return NS_OK;
-}
-#endif
-#if defined(XP_MACOSX) || defined(XP_WIN)
-nsresult
-PluginPRLibrary::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor)
-{
-  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
-  NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
-  return NS_OK;
-}
-#endif
-
-nsresult
-PluginPRLibrary::GetImageSize(NPP instance, nsIntSize* aSize)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
-PluginPRLibrary::SetBackgroundUnknown(NPP instance)
-{
-  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
-  NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
-  NS_ERROR("Unexpected use of async APIs for in-process plugin.");
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
-PluginPRLibrary::BeginUpdateBackground(NPP instance, const nsIntRect&,
-                                       DrawTarget** aDrawTarget)
-{
-  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
-  NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
-  NS_ERROR("Unexpected use of async APIs for in-process plugin.");
-  *aDrawTarget = nullptr;
-  return NS_OK;
-}
-
-nsresult
-PluginPRLibrary::EndUpdateBackground(NPP instance, const nsIntRect&)
-{
-  MOZ_CRASH("This should never be called");
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-#if defined(XP_WIN)
-nsresult
-PluginPRLibrary::GetScrollCaptureContainer(NPP aInstance, ImageContainer** aContainer)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-#endif
-
-nsresult
-PluginPRLibrary::HandledWindowedPluginKeyEvent(
-                   NPP aInstance,
-                   const NativeEventData& aNativeKeyData,
-                   bool aIsConsumed)
-{
-  nsNPAPIPluginInstance* instance = (nsNPAPIPluginInstance*)aInstance->ndata;
-  if (NS_WARN_IF(!instance)) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  return NS_OK;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/plugins/base/PluginPRLibrary.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef PluginPRLibrary_h
-#define PluginPRLibrary_h 1
-
-#include "mozilla/PluginLibrary.h"
-#include "nsNPAPIPlugin.h"
-#include "npfunctions.h"
-
-namespace mozilla {
-
-class PluginPRLibrary : public PluginLibrary
-{
-public:
-    PluginPRLibrary(const char* aFilePath, PRLibrary* aLibrary) :
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-        mNP_Initialize(nullptr),
-#else
-        mNP_Initialize(nullptr),
-#endif
-        mNP_Shutdown(nullptr),
-        mNP_GetMIMEDescription(nullptr),
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-        mNP_GetValue(nullptr),
-#endif
-#if defined(XP_WIN) || defined(XP_MACOSX)
-        mNP_GetEntryPoints(nullptr),
-#endif
-        mNPP_New(nullptr),
-        mNPP_ClearSiteData(nullptr),
-        mNPP_GetSitesWithData(nullptr),
-        mLibrary(aLibrary),
-        mFilePath(aFilePath)
-    {
-        NS_ASSERTION(mLibrary, "need non-null lib");
-        // addref here??
-    }
-
-    virtual ~PluginPRLibrary()
-    {
-        // unref here??
-    }
-
-    virtual void SetPlugin(nsNPAPIPlugin*) override { }
-
-    virtual bool HasRequiredFunctions() override {
-        mNP_Initialize = (NP_InitializeFunc)
-            PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
-        if (!mNP_Initialize)
-            return false;
-
-        mNP_Shutdown = (NP_ShutdownFunc)
-            PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
-        if (!mNP_Shutdown)
-            return false;
-
-        mNP_GetMIMEDescription = (NP_GetMIMEDescriptionFunc)
-            PR_FindFunctionSymbol(mLibrary, "NP_GetMIMEDescription");
-#ifndef XP_MACOSX
-        if (!mNP_GetMIMEDescription)
-            return false;
-#endif
-
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-        mNP_GetValue = (NP_GetValueFunc)
-            PR_FindFunctionSymbol(mLibrary, "NP_GetValue");
-        if (!mNP_GetValue)
-            return false;
-#endif
-
-#if defined(XP_WIN) || defined(XP_MACOSX)
-        mNP_GetEntryPoints = (NP_GetEntryPointsFunc)
-            PR_FindFunctionSymbol(mLibrary, "NP_GetEntryPoints");
-        if (!mNP_GetEntryPoints)
-            return false;
-#endif
-        return true;
-    }
-
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-    virtual nsresult NP_Initialize(NPNetscapeFuncs* aNetscapeFuncs,
-                                   NPPluginFuncs* aFuncs, NPError* aError) override;
-#else
-    virtual nsresult NP_Initialize(NPNetscapeFuncs* aNetscapeFuncs,
-                                   NPError* aError) override;
-#endif
-
-    virtual nsresult NP_Shutdown(NPError* aError) override;
-    virtual nsresult NP_GetMIMEDescription(const char** aMimeDesc) override;
-
-    virtual nsresult NP_GetValue(void* aFuture, NPPVariable aVariable,
-                                 void* aValue, NPError* aError) override;
-
-#if defined(XP_WIN) || defined(XP_MACOSX)
-    virtual nsresult NP_GetEntryPoints(NPPluginFuncs* aFuncs, NPError* aError) override;
-#endif
-
-    virtual nsresult NPP_New(NPMIMEType aPluginType, NPP aInstance,
-                             int16_t aArgc, char* aArgn[],
-                             char* aArgv[], NPSavedData* aSaved,
-                             NPError* aError) override;
-
-    virtual nsresult NPP_ClearSiteData(const char* aSite, uint64_t aFlags,
-                                       uint64_t aMaxAge, nsCOMPtr<nsIClearSiteDataCallback> callback) override;
-    virtual nsresult NPP_GetSitesWithData(nsCOMPtr<nsIGetSitesWithDataCallback> callback) override;
-
-    virtual nsresult AsyncSetWindow(NPP aInstance, NPWindow* aWindow) override;
-    virtual nsresult GetImageContainer(NPP aInstance, mozilla::layers::ImageContainer** aContainer) override;
-    virtual nsresult GetImageSize(NPP aInstance, nsIntSize* aSize) override;
-    virtual bool IsOOP() override { return false; }
-#if defined(XP_MACOSX)
-    virtual nsresult IsRemoteDrawingCoreAnimation(NPP aInstance, bool* aDrawing) override;
-#endif
-#if defined(XP_MACOSX) || defined(XP_WIN)
-    virtual nsresult ContentsScaleFactorChanged(NPP aInstance, double aContentsScaleFactor) override;
-#endif
-    virtual nsresult SetBackgroundUnknown(NPP instance) override;
-    virtual nsresult BeginUpdateBackground(NPP instance, const nsIntRect&,
-                                           DrawTarget** aDrawTarget) override;
-    virtual nsresult EndUpdateBackground(NPP instance,
-                                         const nsIntRect&) override;
-    virtual void DidComposite(NPP aInstance) override { }
-    virtual void GetLibraryPath(nsACString& aPath) { aPath.Assign(mFilePath); }
-    virtual nsresult GetRunID(uint32_t* aRunID) override { return NS_ERROR_NOT_IMPLEMENTED; }
-    virtual void SetHasLocalInstance() override { }
-#if defined(XP_WIN)
-    virtual nsresult GetScrollCaptureContainer(NPP aInstance, mozilla::layers::ImageContainer** aContainer) override;
-#endif
-    virtual nsresult HandledWindowedPluginKeyEvent(
-                       NPP aInstance,
-                       const mozilla::NativeEventData& aNativeKeyData,
-                       bool aIsCOnsumed) override;
-
-private:
-    NP_InitializeFunc mNP_Initialize;
-    NP_ShutdownFunc mNP_Shutdown;
-    NP_GetMIMEDescriptionFunc mNP_GetMIMEDescription;
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-    NP_GetValueFunc mNP_GetValue;
-#endif
-#if defined(XP_WIN) || defined(XP_MACOSX)
-    NP_GetEntryPointsFunc mNP_GetEntryPoints;
-#endif
-    NPP_NewProcPtr mNPP_New;
-    NPP_ClearSiteDataPtr mNPP_ClearSiteData;
-    NPP_GetSitesWithDataPtr mNPP_GetSitesWithData;
-    PRLibrary* mLibrary;
-    nsCString mFilePath;
-};
-
-
-} // namespace mozilla
-
-#endif  // ifndef PluginPRLibrary_h
--- a/dom/plugins/base/moz.build
+++ b/dom/plugins/base/moz.build
@@ -28,29 +28,24 @@ EXPORTS += [
     'nsPluginInstanceOwner.h',
     'nsPluginLogging.h',
     'nsPluginNativeWindow.h',
     'nsPluginsCID.h',
     'nsPluginsDir.h',
     'nsPluginTags.h',
 ]
 
-EXPORTS.mozilla += [
-    'PluginPRLibrary.h',
-]
-
 UNIFIED_SOURCES += [
     'nsJSNPRuntime.cpp',
     'nsNPAPIPluginInstance.cpp',
     'nsNPAPIPluginStreamListener.cpp',
     'nsPluginInstanceOwner.cpp',
     'nsPluginModule.cpp',
     'nsPluginStreamListenerPeer.cpp',
     'nsPluginTags.cpp',
-    'PluginPRLibrary.cpp',
 ]
 
 SOURCES += [
     'nsNPAPIPlugin.cpp', # Conflict with X11 headers
     'nsPluginHost.cpp',  # Conflict with NS_NPAPIPLUGIN_CALLBACK
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -71,19 +71,16 @@
 
 #include "nsNetUtil.h"
 #include "nsNetCID.h"
 
 #include "mozilla/Mutex.h"
 #include "mozilla/PluginLibrary.h"
 using mozilla::PluginLibrary;
 
-#include "mozilla/PluginPRLibrary.h"
-using mozilla::PluginPRLibrary;
-
 #include "mozilla/plugins/PluginModuleParent.h"
 using mozilla::plugins::PluginModuleChromeParent;
 using mozilla::plugins::PluginModuleContentParent;
 
 #ifdef MOZ_X11
 #include "mozilla/X11Util.h"
 #endif
 
@@ -199,39 +196,30 @@ nsNPAPIPlugin::~nsNPAPIPlugin()
 void
 nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID,
                              const nsAString& browserDumpID)
 {
   RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
   host->PluginCrashed(this, pluginDumpID, browserDumpID);
 }
 
-bool
-nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
-{
-  return true;
-}
-
 inline PluginLibrary*
 GetNewPluginLibrary(nsPluginTag *aPluginTag)
 {
   AUTO_PROFILER_LABEL("GetNewPluginLibrary", OTHER);
 
   if (!aPluginTag) {
     return nullptr;
   }
 
   if (XRE_IsContentProcess()) {
     return PluginModuleContentParent::LoadModule(aPluginTag->mId, aPluginTag);
   }
 
-  if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
-    return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(), aPluginTag->mId, aPluginTag);
-  }
-  return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
+  return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(), aPluginTag->mId, aPluginTag);
 }
 
 // Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
 nsresult
 nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
 {
   AUTO_PROFILER_LABEL("nsNPAPIPlugin::CreatePlugin", OTHER);
   *aResult = nullptr;
--- a/dom/plugins/base/nsNPAPIPlugin.h
+++ b/dom/plugins/base/nsNPAPIPlugin.h
@@ -51,18 +51,16 @@ public:
 
   // The IPC mechanism notifies the nsNPAPIPlugin if the plugin
   // crashes and is no longer usable. pluginDumpID/browserDumpID are
   // the IDs of respective minidumps that were written, or empty if no
   // minidump was written.
   void PluginCrashed(const nsAString& pluginDumpID,
                      const nsAString& browserDumpID);
 
-  static bool RunPluginOOP(const nsPluginTag *aPluginTag);
-
   nsresult Shutdown();
 
   static nsresult RetainStream(NPStream *pstream, nsISupports **aRetainedPeer);
 
 private:
   ~nsNPAPIPlugin();
 
   NPPluginFuncs mPluginFuncs;
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -1205,31 +1205,16 @@ nsPluginHost::FindNativePluginForExtensi
   // Re-fetch the matching type because of how FindPreferredPlugin works...
   preferredPlugin->HasExtension(aExtension, aMimeType);
   return preferredPlugin;
 }
 
 static nsresult CreateNPAPIPlugin(nsPluginTag *aPluginTag,
                                   nsNPAPIPlugin **aOutNPAPIPlugin)
 {
-  // If this is an in-process plugin we'll need to load it here if we haven't already.
-  if (!nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
-    if (aPluginTag->mFullPath.IsEmpty())
-      return NS_ERROR_FAILURE;
-    nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
-    file->InitWithPath(NS_ConvertUTF8toUTF16(aPluginTag->mFullPath));
-    nsPluginFile pluginFile(file);
-    PRLibrary* pluginLibrary = nullptr;
-
-    if (NS_FAILED(pluginFile.LoadPlugin(&pluginLibrary)) || !pluginLibrary)
-      return NS_ERROR_FAILURE;
-
-    aPluginTag->mLibrary = pluginLibrary;
-  }
-
   nsresult rv;
   rv = nsNPAPIPlugin::CreatePlugin(aPluginTag, aOutNPAPIPlugin);
 
   return rv;
 }
 
 nsresult nsPluginHost::EnsurePluginLoaded(nsPluginTag* aPluginTag)
 {
@@ -2133,24 +2118,16 @@ nsresult nsPluginHost::ScanPluginsDirect
     }
 
     // do it if we still want it
     if (!seenBefore) {
       // We have a valid new plugin so report that plugins have changed.
       *aPluginsChanged = true;
     }
 
-    // Avoid adding different versions of the same plugin if they are running
-    // in-process, otherwise we risk undefined behaviour.
-    if (!nsNPAPIPlugin::RunPluginOOP(pluginTag)) {
-      if (HaveSamePlugin(pluginTag)) {
-        continue;
-      }
-    }
-
     // Don't add the same plugin again if it hasn't changed
     if (nsPluginTag* duplicate = FirstPluginWithPath(pluginTag->mFullPath)) {
       if (pluginTag->mLastModifiedTime == duplicate->mLastModifiedTime) {
         continue;
       }
     }
 
     // If we're not creating a plugin list, simply looking for changes,
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -296,18 +296,16 @@ PluginModuleChild::InitForChrome(const s
     CommonInit();
 
     if (!Open(aChannel, aParentPid, aIOLoop)) {
         return false;
     }
 
     GetIPCChannel()->SetAbortOnError(true);
 
-    // TODO: use PluginPRLibrary here
-
 #if defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS)
     mShutdownFunc =
         (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
 
     // create the new plugin handler
 
     mInitializeFunc =
         (NP_PLUGINUNIXINIT) PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -14,78 +14,88 @@
 #include "nsContentUtils.h"
 #include "nsCORSListenerProxy.h"
 #include "nsIStreamListener.h"
 #include "nsIDocument.h"
 #include "nsMixedContentBlocker.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsIURIFixup.h"
 #include "nsIImageLoadingContent.h"
-#include "NullPrincipal.h"
 
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/TabChild.h"
 
 NS_IMPL_ISUPPORTS(nsContentSecurityManager,
                   nsIContentSecurityManager,
                   nsIChannelEventSink)
 
 /* static */ bool
-nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
-  nsIURI* aURI,
-  nsContentPolicyType aContentPolicyType,
-  nsIPrincipal* aTriggeringPrincipal,
-  nsIDocument* aDoc,
-  bool aLoadFromExternal,
-  bool aIsDownLoad)
+nsContentSecurityManager::AllowTopLevelNavigationToDataURI(nsIChannel* aChannel)
 {
   // Let's block all toplevel document navigations to a data: URI.
   // In all cases where the toplevel document is navigated to a
   // data: URI the triggeringPrincipal is a codeBasePrincipal, or
   // a NullPrincipal. In other cases, e.g. typing a data: URL into
   // the URL-Bar, the triggeringPrincipal is a SystemPrincipal;
   // we don't want to block those loads. Only exception, loads coming
   // from an external applicaton (e.g. Thunderbird) don't load
   // using a codeBasePrincipal, but we want to block those loads.
   if (!mozilla::net::nsIOService::BlockToplevelDataUriNavigations()) {
     return true;
   }
-  if (aContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT || aIsDownLoad) {
+  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
+  if (!loadInfo) {
     return true;
   }
+  if (loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_DOCUMENT) {
+    return true;
+  }
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
+  NS_ENSURE_SUCCESS(rv, true);
   bool isDataURI =
-    (NS_SUCCEEDED(aURI->SchemeIs("data", &isDataURI)) && isDataURI);
+    (NS_SUCCEEDED(uri->SchemeIs("data", &isDataURI)) && isDataURI);
   if (!isDataURI) {
     return true;
   }
   // Whitelist data: images as long as they are not SVGs
   nsAutoCString filePath;
-  aURI->GetFilePath(filePath);
+  uri->GetFilePath(filePath);
   if (StringBeginsWith(filePath, NS_LITERAL_CSTRING("image/")) &&
       !StringBeginsWith(filePath, NS_LITERAL_CSTRING("image/svg+xml"))) {
     return true;
   }
-  // Whitelist data: PDFs
-  if (StringBeginsWith(filePath, NS_LITERAL_CSTRING("application/pdf"))) {
+  // Whitelist data: PDFs and JSON
+  if (StringBeginsWith(filePath, NS_LITERAL_CSTRING("application/pdf")) ||
+      StringBeginsWith(filePath, NS_LITERAL_CSTRING("application/json"))) {
     return true;
   }
-  if (!aLoadFromExternal &&
-      nsContentUtils::IsSystemPrincipal(aTriggeringPrincipal)) {
+  // Redirecting to a toplevel data: URI is not allowed, hence we make
+  // sure the RedirectChain is empty.
+  if (!loadInfo->GetLoadTriggeredFromExternal() &&
+      nsContentUtils::IsSystemPrincipal(loadInfo->TriggeringPrincipal()) &&
+      loadInfo->RedirectChain().IsEmpty()) {
     return true;
   }
   nsAutoCString dataSpec;
-  aURI->GetSpec(dataSpec);
+  uri->GetSpec(dataSpec);
   if (dataSpec.Length() > 50) {
     dataSpec.Truncate(50);
     dataSpec.AppendLiteral("...");
   }
+  nsCOMPtr<nsITabChild> tabChild = do_QueryInterface(loadInfo->ContextForTopLevelLoad());
+  nsCOMPtr<nsIDocument> doc;
+  if (tabChild) {
+    doc = static_cast<mozilla::dom::TabChild*>(tabChild.get())->GetDocument();
+  }
   NS_ConvertUTF8toUTF16 specUTF16(NS_UnescapeURL(dataSpec));
   const char16_t* params[] = { specUTF16.get() };
   nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                   NS_LITERAL_CSTRING("DATA_URI_BLOCKED"),
-                                  aDoc,
+                                  doc,
                                   nsContentUtils::eSECURITY_PROPERTIES,
                                   "BlockTopLevelDataURINavigation",
                                   params, ArrayLength(params));
   return false;
 }
 
 static nsresult
 ValidateSecurityFlags(nsILoadInfo* aLoadInfo)
@@ -571,39 +581,16 @@ nsContentSecurityManager::AsyncOnChannel
   if (loadInfo && loadInfo->GetEnforceSecurity()) {
     nsresult rv = CheckChannel(aNewChannel);
     if (NS_FAILED(rv)) {
       aOldChannel->Cancel(rv);
       return rv;
     }
   }
 
-  // Redirecting to a toplevel data: URI is not allowed, hence we pass
-  // a NullPrincipal as the TriggeringPrincipal to
-  // AllowTopLevelNavigationToDataURI() which definitely blocks any
-  // data: URI load.
-  nsCOMPtr<nsILoadInfo> newLoadInfo = aNewChannel->GetLoadInfo();
-  if (newLoadInfo) {
-    nsCOMPtr<nsIURI> uri;
-    nsresult rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(uri));
-    NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIPrincipal> nullTriggeringPrincipal = NullPrincipal::Create();
-    if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
-          uri,
-          newLoadInfo->GetExternalContentPolicyType(),
-          nullTriggeringPrincipal,
-          nullptr, // no doc available, log to browser console
-          false,
-          false)) {
-        // logging to console happens within AllowTopLevelNavigationToDataURI
-      aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
-      return NS_ERROR_DOM_BAD_URI;
-    }
-  }
-
   // Also verify that the redirecting server is allowed to redirect to the
   // given URI
   nsCOMPtr<nsIPrincipal> oldPrincipal;
   nsContentUtils::GetSecurityManager()->
     GetChannelResultPrincipal(aOldChannel, getter_AddRefs(oldPrincipal));
 
   nsCOMPtr<nsIURI> newURI;
   Unused << NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
--- a/dom/security/nsContentSecurityManager.h
+++ b/dom/security/nsContentSecurityManager.h
@@ -28,22 +28,17 @@ public:
   NS_DECL_NSICONTENTSECURITYMANAGER
   NS_DECL_NSICHANNELEVENTSINK
 
   nsContentSecurityManager() {}
 
   static nsresult doContentSecurityCheck(nsIChannel* aChannel,
                                          nsCOMPtr<nsIStreamListener>& aInAndOutListener);
 
-  static bool AllowTopLevelNavigationToDataURI(nsIURI* aURI,
-                                               nsContentPolicyType aContentPolicyType,
-                                               nsIPrincipal* aTriggeringPrincipal,
-                                               nsIDocument* aDoc,
-                                               bool aLoadFromExternal,
-                                               bool aIsDownload);
+  static bool AllowTopLevelNavigationToDataURI(nsIChannel* aChannel);
 
 private:
   static nsresult CheckChannel(nsIChannel* aChannel);
 
   virtual ~nsContentSecurityManager() {}
 
 };
 
--- a/dom/security/test/general/browser.ini
+++ b/dom/security/test/general/browser.ini
@@ -1,8 +1,11 @@
 [DEFAULT]
 [browser_test_toplevel_data_navigations.js]
 support-files =
   file_toplevel_data_navigations.sjs
   file_toplevel_data_meta_redirect.html
 [browser_test_data_download.js]
 support-files =
   file_data_download.html
+[browser_test_data_text_csv.js]
+support-files =
+  file_data_text_csv.html
new file mode 100644
--- /dev/null
+++ b/dom/security/test/general/browser_test_data_text_csv.js
@@ -0,0 +1,37 @@
+"use strict";
+
+const kTestPath = getRootDirectory(gTestPath)
+                  .replace("chrome://mochitests/content", "http://example.com")
+const kTestURI = kTestPath + "file_data_text_csv.html";
+
+function addWindowListener(aURL, aCallback) {
+  Services.wm.addListener({
+    onOpenWindow(aXULWindow) {
+      info("window opened, waiting for focus");
+      Services.wm.removeListener(this);
+      var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                                .getInterface(Ci.nsIDOMWindow);
+      waitForFocus(function() {
+        is(domwindow.document.location.href, aURL, "should have seen the right window open");
+        aCallback(domwindow);
+      }, domwindow);
+    },
+    onCloseWindow(aXULWindow) { },
+    onWindowTitleChange(aXULWindow, aNewTitle) { }
+  });
+}
+
+function test() {
+  waitForExplicitFinish();
+  Services.prefs.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true);
+  registerCleanupFunction(function() {
+    Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
+  });
+  addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function(win) {
+    is(win.document.getElementById("location").value, "text/csv;foo,bar,foobar",
+       "file name of download should match");
+     win.close();
+     finish();
+  });
+  gBrowser.loadURI(kTestURI);
+}
new file mode 100644
--- /dev/null
+++ b/dom/security/test/general/file_data_text_csv.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test open data:text/csv</title>
+</head>
+<body>
+  <a href="data:text/csv;foo,bar,foobar" id="testlink">test text/csv</a>
+  <script>
+    // click the link to have the downoad panel appear
+    let testlink = document.getElementById("testlink");
+    testlink.click();
+  </script>
+  </body>
+</html>
--- a/dom/security/test/general/mochitest.ini
+++ b/dom/security/test/general/mochitest.ini
@@ -12,8 +12,10 @@ support-files =
 [test_nosniff.html]
 [test_block_script_wrong_mime.html]
 [test_block_toplevel_data_navigation.html]
 skip-if = toolkit == 'android' # intermittent failure
 [test_block_toplevel_data_img_navigation.html]
 skip-if = toolkit == 'android' # intermittent failure
 [test_allow_opening_data_pdf.html]
 skip-if = toolkit == 'android'
+[test_allow_opening_data_json.html]
+skip-if = toolkit == 'android'
new file mode 100644
--- /dev/null
+++ b/dom/security/test/general/test_allow_opening_data_json.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Bug 1403814: Allow toplevel data URI navigation data:application/json</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function test_toplevel_data_json() {
+  const DATA_JSON = "data:application/json,{'my_json_key':'my_json_value'}";
+
+  let win = window.open(DATA_JSON);
+  let wrappedWin = SpecialPowers.wrap(win);
+
+  // Unfortunately we can't detect whether the JSON has loaded or not using some
+  // event, hence we are constantly polling location.href till we see that
+  // the data: URI appears. Test times out on failure.
+  var jsonLoaded = setInterval(function() {
+    if (wrappedWin.document.location.href.startsWith("data:application/json")) {
+      clearInterval(jsonLoaded);
+      ok(true, "navigating to data:application/json allowed");
+      wrappedWin.close();
+      SimpleTest.finish();
+    }
+  }, 200);
+}
+
+SpecialPowers.pushPrefEnv({
+  set: [["security.data_uri.block_toplevel_data_uri_navigations", true]]
+}, test_toplevel_data_json);
+
+</script>
+</body>
+</html>
--- a/dom/security/test/general/test_block_toplevel_data_img_navigation.html
+++ b/dom/security/test/general/test_block_toplevel_data_img_navigation.html
@@ -29,23 +29,25 @@ function test_toplevel_data_image() {
     test_toplevel_data_image_svg();
   }, 1000);
 }
 
 function test_toplevel_data_image_svg() {
   const DATA_SVG =
     "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNOCwxMkwzLDcsNCw2bDQsNCw0LTQsMSwxWiIgZmlsbD0iIzZBNkE2QSIgLz4KPC9zdmc+Cg==";
   let win2 = window.open(DATA_SVG);
-  let wrappedWin2 = SpecialPowers.wrap(win2);
-  setTimeout(function () {
-    isnot(wrappedWin2.document.documentElement.localName, "svg",
-          "Loading data:image/svg+xml should be blocked");
-    wrappedWin2.close();
-    SimpleTest.finish();
-  }, 1000);
+  // Unfortunately we can't detect whether the window was closed using some event,
+  // hence we are constantly polling till we see that win == null.
+  // Test times out on failure.
+  var win2Closed = setInterval(function() {
+    if (win2 == null || win2.closed) {
+      clearInterval(win2Closed);
+      ok(true, "Loading data:image/svg+xml should be blocked");
+      SimpleTest.finish();
+    }
+  }, 200);
 }
-
 // fire up the tests
 test_toplevel_data_image();
 
 </script>
 </body>
 </html>
--- a/dom/security/test/general/test_block_toplevel_data_navigation.html
+++ b/dom/security/test/general/test_block_toplevel_data_navigation.html
@@ -16,26 +16,22 @@ SimpleTest.registerCleanupFunction(() =>
 
 SimpleTest.waitForExplicitFinish();
 SimpleTest.requestFlakyTimeout("have to test that top level data: URI navgiation is blocked");
 
 function test1() {
   // simple data: URI click navigation should be prevented
   let TEST_FILE = "file_block_toplevel_data_navigation.html";
   let win1 = window.open(TEST_FILE);
-  var readyStateCheckInterval = setInterval(function() {
-    let state = win1.document.readyState;
-    if (state === "interactive" || state === "complete") {
-      clearInterval(readyStateCheckInterval);
-      ok(win1.document.body.innerHTML.indexOf("test1:") !== -1,
-         "toplevel data: URI navigation through click() should be blocked");
-      win1.close();
-      test2();
-    }
-  }, 200);
+  setTimeout(function () {
+    ok(SpecialPowers.wrap(win1).document.body.innerHTML.indexOf("test1:") !== -1,
+      "toplevel data: URI navigation through click() should be blocked");
+    win1.close();
+    test2();
+  }, 1000);
 }
 
 function test2() {
   // data: URI in iframe which opens data: URI in _blank should be blocked 
   let win2 = window.open("file_block_toplevel_data_navigation2.html");
   window.addEventListener("message", receiveMessage);
   function receiveMessage(event) {
     window.removeEventListener("message", receiveMessage);
--- a/dom/webidl/DOMStringMap.webidl
+++ b/dom/webidl/DOMStringMap.webidl
@@ -10,12 +10,12 @@
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 [OverrideBuiltins]
 interface DOMStringMap {
   getter DOMString (DOMString name);
   [CEReactions, Throws]
-  setter creator void (DOMString name, DOMString value);
+  setter void (DOMString name, DOMString value);
   [CEReactions]
   deleter void (DOMString name);
 };
--- a/dom/webidl/HTMLOptionsCollection.webidl
+++ b/dom/webidl/HTMLOptionsCollection.webidl
@@ -9,16 +9,16 @@
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface HTMLOptionsCollection : HTMLCollection {
   [CEReactions]
            attribute unsigned long length;
   [CEReactions, Throws]
-  setter creator void (unsigned long index, HTMLOptionElement? option);
+  setter void (unsigned long index, HTMLOptionElement? option);
   [CEReactions, Throws]
   void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
   [CEReactions, Throws]
   void remove(long index);
   [Throws]
            attribute long selectedIndex;
 };
--- a/dom/webidl/HTMLSelectElement.webidl
+++ b/dom/webidl/HTMLSelectElement.webidl
@@ -35,17 +35,17 @@ interface HTMLSelectElement : HTMLElemen
            attribute unsigned long length;
   getter Element? item(unsigned long index);
   HTMLOptionElement? namedItem(DOMString name);
   [CEReactions, Throws]
   void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
   [CEReactions]
   void remove(long index);
   [CEReactions, Throws]
-  setter creator void (unsigned long index, HTMLOptionElement? option);
+  setter void (unsigned long index, HTMLOptionElement? option);
 
   readonly attribute HTMLCollection selectedOptions;
   [SetterThrows, Pure]
            attribute long selectedIndex;
   [Pure]
            attribute DOMString value;
 
   readonly attribute boolean willValidate;
--- a/dom/webidl/MozStorageAsyncStatementParams.webidl
+++ b/dom/webidl/MozStorageAsyncStatementParams.webidl
@@ -10,13 +10,13 @@ interface MozStorageAsyncStatementParams
 
   [Throws]
   getter any(unsigned long index);
 
   [Throws]
   getter any(DOMString name);
 
   [Throws]
-  setter creator void(unsigned long index, any arg);
+  setter void(unsigned long index, any arg);
 
   [Throws]
-  setter creator void(DOMString name, any arg);
+  setter void(DOMString name, any arg);
 };
--- a/dom/webidl/MozStorageStatementParams.webidl
+++ b/dom/webidl/MozStorageStatementParams.webidl
@@ -10,13 +10,13 @@ interface MozStorageStatementParams
 
   [Throws]
   getter any(unsigned long index);
 
   [Throws]
   getter any(DOMString name);
 
   [Throws]
-  setter creator void(unsigned long index, any arg);
+  setter void(unsigned long index, any arg);
 
   [Throws]
-  setter creator void(DOMString name, any arg);
+  setter void(DOMString name, any arg);
 };
--- a/dom/webidl/Storage.webidl
+++ b/dom/webidl/Storage.webidl
@@ -17,17 +17,17 @@ interface Storage {
 
   [Throws, NeedsSubjectPrincipal]
   DOMString? key(unsigned long index);
 
   [Throws, NeedsSubjectPrincipal]
   getter DOMString? getItem(DOMString key);
 
   [Throws, NeedsSubjectPrincipal]
-  setter creator void setItem(DOMString key, DOMString value);
+  setter void setItem(DOMString key, DOMString value);
 
   [Throws, NeedsSubjectPrincipal]
   deleter void removeItem(DOMString key);
 
   [Throws, NeedsSubjectPrincipal]
   void clear();
 
   [ChromeOnly]
--- a/dom/webidl/XULElement.webidl
+++ b/dom/webidl/XULElement.webidl
@@ -75,16 +75,20 @@ interface XULElement : Element {
   attribute DOMString ref;
 
   // Tooltip and status info
   [SetterThrows]
   attribute DOMString tooltipText;
   [SetterThrows]
   attribute DOMString statusText;
 
+  // Properties for images
+  [SetterThrows]
+  attribute DOMString src;
+
   attribute boolean allowEvents;
 
   readonly attribute MozRDFCompositeDataSource? database;
   readonly attribute XULTemplateBuilder?        builder;
   [Throws]
   readonly attribute MozRDFResource?            resource;
   [Throws, ChromeOnly]
   readonly attribute XULControllers             controllers;
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -2495,42 +2495,16 @@ XMLHttpRequestMainThread::CreateChannel(
 
     // Set the initiator type
     nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChannel));
     if (timedChannel) {
       timedChannel->SetInitiatorType(NS_LITERAL_STRING("xmlhttprequest"));
     }
   }
 
-  // Using the provided principal as the triggeringPrincipal is fine, since we
-  // want to be able to access any of the origins that the principal has access
-  // to during the security checks, but we don't want a document to inherit an
-  // expanded principal, so in that case we need to select the principal in the
-  // expanded principal's whitelist that can load our URL as principalToInherit.
-  nsCOMPtr<nsIPrincipal> resultingDocumentPrincipal(mPrincipal);
-  nsCOMPtr<nsIExpandedPrincipal> ep = do_QueryInterface(mPrincipal);
-  if (ep) {
-    MOZ_ASSERT(!(secFlags & nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS));
-    bool dataInherits = (secFlags &
-      (nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
-       nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) != 0;
-    for (const auto& principal : ep->WhiteList()) {
-      if (NS_SUCCEEDED(principal->CheckMayLoad(mRequestURL, false, dataInherits))) {
-        resultingDocumentPrincipal = principal;
-        break;
-      }
-    }
-  }
-
-  nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
-  if (loadInfo) {
-    rv = loadInfo->SetPrincipalToInherit(resultingDocumentPrincipal);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
   return NS_OK;
 }
 
 void
 XMLHttpRequestMainThread::MaybeLowerChannelPriority()
 {
   nsCOMPtr<nsIDocument> doc = GetDocumentIfCurrent();
   if (!doc) {
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -659,16 +659,24 @@ public:
     void GetStatusText(DOMString& aValue) const
     {
         GetXULAttr(nsGkAtoms::statustext, aValue);
     }
     void SetStatusText(const nsAString& aValue, mozilla::ErrorResult& rv)
     {
         SetXULAttr(nsGkAtoms::statustext, aValue, rv);
     }
+    void GetSrc(DOMString& aValue) const
+    {
+        GetXULAttr(nsGkAtoms::src, aValue);
+    }
+    void SetSrc(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::src, aValue, rv);
+    }
     bool AllowEvents() const
     {
         return BoolAttrIsTrue(nsGkAtoms::allowevents);
     }
     void SetAllowEvents(bool aAllowEvents)
     {
         SetXULBoolAttr(nsGkAtoms::allowevents, aAllowEvents);
     }
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -326,16 +326,27 @@ GPUParent::RecvGetDeviceStatus(GPUDevice
 #else
   aOut->gpuDevice() = null_t();
 #endif
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
+GPUParent::RecvSimulateDeviceReset(GPUDeviceData* aOut)
+{
+#if defined(XP_WIN)
+  DeviceManagerDx::Get()->ForceDeviceReset(ForcedDeviceResetReason::COMPOSITOR_UPDATED);
+  DeviceManagerDx::Get()->MaybeResetAndReacquireDevices();
+#endif
+  RecvGetDeviceStatus(aOut);
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
 GPUParent::RecvNewContentCompositorManager(Endpoint<PCompositorManagerParent>&& aEndpoint)
 {
   CompositorManagerParent::Create(Move(aEndpoint));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 GPUParent::RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint)
--- a/gfx/ipc/GPUParent.h
+++ b/gfx/ipc/GPUParent.h
@@ -43,16 +43,17 @@ public:
   mozilla::ipc::IPCResult RecvInitProfiler(Endpoint<PProfilerChild>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvUpdatePref(const GfxPrefSetting& pref) override;
   mozilla::ipc::IPCResult RecvUpdateVar(const GfxVarUpdate& pref) override;
   mozilla::ipc::IPCResult RecvNewContentCompositorManager(Endpoint<PCompositorManagerParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvNewContentVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvNewContentVideoDecoderManager(Endpoint<PVideoDecoderManagerParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvGetDeviceStatus(GPUDeviceData* aOutStatus) override;
+  mozilla::ipc::IPCResult RecvSimulateDeviceReset(GPUDeviceData* aOutStatus) override;
   mozilla::ipc::IPCResult RecvAddLayerTreeIdMapping(const LayerTreeIdMapping& aMapping) override;
   mozilla::ipc::IPCResult RecvRemoveLayerTreeIdMapping(const LayerTreeIdMapping& aMapping) override;
   mozilla::ipc::IPCResult RecvNotifyGpuObservers(const nsCString& aTopic) override;
   mozilla::ipc::IPCResult RecvRequestMemoryReport(
     const uint32_t& generation,
     const bool& anonymize,
     const bool& minimizeMemoryUsage,
     const MaybeFileDesc& DMDFile) override;
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -416,16 +416,20 @@ GPUProcessManager::ResetCompositors()
 
 void
 GPUProcessManager::SimulateDeviceReset()
 {
   // Make sure we rebuild environment and configuration for accelerated features.
   gfxPlatform::GetPlatform()->CompositorUpdated();
 
   if (mProcess) {
+    GPUDeviceData data;
+    if (mGPUChild->SendSimulateDeviceReset(&data)) {
+      gfxPlatform::GetPlatform()->ImportGPUDeviceData(data);
+    }
     OnRemoteProcessDeviceReset(mProcess);
   } else {
     OnInProcessDeviceReset();
   }
 }
 
 void
 GPUProcessManager::DisableWebRender(wr::WebRenderError aError)
--- a/gfx/ipc/PGPU.ipdl
+++ b/gfx/ipc/PGPU.ipdl
@@ -75,16 +75,20 @@ parent:
   // Called to notify the GPU process of who owns a layersId.
   sync AddLayerTreeIdMapping(LayerTreeIdMapping mapping);
   async RemoveLayerTreeIdMapping(LayerTreeIdMapping mapping);
 
   // Request the current DeviceStatus from the GPU process. This blocks until
   // one is available (i.e., Init has completed).
   sync GetDeviceStatus() returns (GPUDeviceData status);
 
+  // Request to simulate device reset and to get the updated DeviceStatus from
+  // the GPU process. This blocks until one is available (i.e., Init has completed).
+  sync SimulateDeviceReset() returns (GPUDeviceData status);
+
   // Have a message be broadcasted to the GPU process by the GPU process
   // observer service.
   async NotifyGpuObservers(nsCString aTopic);
 
   async RequestMemoryReport(uint32_t generation,
                             bool anonymize,
                             bool minimizeMemoryUsage,
                             MaybeFileDesc DMDFile);
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -618,16 +618,28 @@ Compositor::IsValid() const
   return !!mParent;
 }
 
 void
 Compositor::SetDispAcquireFence(Layer* aLayer)
 {
 }
 
+void
+Compositor::UnlockAfterComposition(TextureHost* aTexture)
+{
+  TextureSourceProvider::UnlockAfterComposition(aTexture);
+
+  // If this is being called after we shutdown the compositor, we must finish
+  // read unlocking now to prevent a cycle.
+  if (IsDestroyed()) {
+    ReadUnlockTextures();
+  }
+}
+
 bool
 Compositor::NotifyNotUsedAfterComposition(TextureHost* aTextureHost)
 {
   if (IsDestroyed() || AsBasicCompositor()) {
     return false;
   }
   return TextureSourceProvider::NotifyNotUsedAfterComposition(aTextureHost);
 }
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -462,16 +462,17 @@ public:
   virtual Compositor* AsCompositor() override {
     return this;
   }
 
   TimeStamp GetLastCompositionEndTime() const override {
     return mLastCompositionEndTime;
   }
 
+  void UnlockAfterComposition(TextureHost* aTexture) override;
   bool NotifyNotUsedAfterComposition(TextureHost* aTextureHost) override;
 
   /**
    * Notify the compositor that composition is being paused. This allows the
    * compositor to temporarily release any resources.
    * Between calling Pause and Resume, compositing may fail.
    */
   virtual void Pause() {}
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1472,16 +1472,17 @@ CompositorBridgeParent::NewCompositor(co
         compositor = new BasicCompositor(this, mWidget);
       }
 #ifdef XP_WIN
     } else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11) {
       compositor = new CompositorD3D11(this, mWidget);
 #endif
     }
     nsCString failureReason;
+    MOZ_ASSERT(!gfxVars::UseWebRender() || aBackendHints[i] == LayersBackend::LAYERS_BASIC);
     if (compositor && compositor->Initialize(&failureReason)) {
       if (failureReason.IsEmpty()){
         failureReason = "SUCCESS";
       }
 
       // should only report success here
       if (aBackendHints[i] == LayersBackend::LAYERS_OPENGL){
         Telemetry::Accumulate(Telemetry::OPENGL_COMPOSITING_FAILURE_ID, failureReason);
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -64,37 +64,37 @@ ImageBridgeParent::Setup()
 ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
                                      ProcessId aChildProcessId)
   : mMessageLoop(aLoop)
   , mSetChildThreadPriority(false)
   , mClosed(false)
   , mCompositorThreadHolder(CompositorThreadHolder::GetSingleton())
 {
   MOZ_ASSERT(NS_IsMainThread());
-
-  // creates the map only if it has not been created already, so it is safe
-  // with several bridges
-  {
-    MonitorAutoLock lock(*sImageBridgesLock);
-    sImageBridges[aChildProcessId] = this;
-  }
   SetOtherProcessId(aChildProcessId);
 }
 
 ImageBridgeParent::~ImageBridgeParent()
 {
 }
 
 /* static */ ImageBridgeParent*
 ImageBridgeParent::CreateSameProcess()
 {
+  base::ProcessId pid = base::GetCurrentProcId();
   RefPtr<ImageBridgeParent> parent =
-    new ImageBridgeParent(CompositorThreadHolder::Loop(), base::GetCurrentProcId());
+    new ImageBridgeParent(CompositorThreadHolder::Loop(), pid);
   parent->mSelfRef = parent;
 
+  {
+    MonitorAutoLock lock(*sImageBridgesLock);
+    MOZ_RELEASE_ASSERT(sImageBridges.count(pid) == 0);
+    sImageBridges[pid] = parent;
+  }
+
   sImageBridgeParentSingleton = parent;
   return parent;
 }
 
 /* static */ bool
 ImageBridgeParent::CreateForGPUProcess(Endpoint<PImageBridgeParent>&& aEndpoint)
 {
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
@@ -252,16 +252,38 @@ ImageBridgeParent::CreateForContent(Endp
 }
 
 void
 ImageBridgeParent::Bind(Endpoint<PImageBridgeParent>&& aEndpoint)
 {
   if (!aEndpoint.Bind(this))
     return;
   mSelfRef = this;
+
+  // If the child process ID was reused by the OS before the ImageBridgeParent
+  // object was destroyed, we need to clean it up first.
+  RefPtr<ImageBridgeParent> oldActor;
+  {
+    MonitorAutoLock lock(*sImageBridgesLock);
+    ImageBridgeMap::const_iterator i = sImageBridges.find(OtherPid());
+    if (i != sImageBridges.end()) {
+      oldActor = i->second;
+    }
+  }
+
+  // We can't hold the lock during Close because it erases itself from the map.
+  if (oldActor) {
+    MOZ_RELEASE_ASSERT(!oldActor->mClosed);
+    oldActor->Close();
+  }
+
+  {
+    MonitorAutoLock lock(*sImageBridgesLock);
+    sImageBridges[OtherPid()] = this;
+  }
 }
 
 mozilla::ipc::IPCResult ImageBridgeParent::RecvWillClose()
 {
   // If there is any texture still alive we have to force it to deallocate the
   // device data (GL textures, etc.) now because shortly after SenStop() returns
   // on the child side the widget will be destroyed along with it's associated
   // GL context.
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -872,16 +872,20 @@ LayerTransactionParent::Attach(Layer* aL
   HostLayer* layer = aLayer->AsHostLayer();
   if (!layer) {
     return false;
   }
 
   TextureSourceProvider* provider =
     static_cast<HostLayerManager*>(aLayer->Manager())->GetTextureSourceProvider();
 
+  MOZ_ASSERT(!aCompositable->AsWebRenderImageHost());
+  if (aCompositable->AsWebRenderImageHost()) {
+    gfxCriticalNote << "Use WebRenderImageHost at LayerTransactionParent.";
+  }
   if (!layer->SetCompositableHost(aCompositable)) {
     // not all layer types accept a compositable, see bug 967824
     return false;
   }
   aCompositable->Attach(aLayer,
                         provider,
                         aIsAsync
                           ? CompositableHost::ALLOW_REATTACH
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -795,18 +795,23 @@ WebRenderBridgeParent::RecvAddPipelineId
     }
     host = imageBridge->FindCompositable(aHandle);
   } else {
     host = FindCompositable(aHandle);
   }
   if (!host) {
     return IPC_FAIL_NO_REASON(this);
   }
-  MOZ_ASSERT(host->AsWebRenderImageHost());
+
   WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
+  MOZ_ASSERT(wrHost);
+  if (!wrHost) {
+    gfxCriticalNote << "Incompatible CompositableHost at WebRenderBridgeParent.";
+  }
+
   if (!wrHost) {
     return IPC_OK();
   }
 
   wrHost->SetWrBridge(this);
   wrHost->EnableUseAsyncImagePipeline();
   mAsyncCompositables.Put(wr::AsUint64(aPipelineId), wrHost);
   mAsyncImageManager->AddAsyncImagePipeline(aPipelineId, wrHost);
@@ -838,16 +843,22 @@ WebRenderBridgeParent::RecvAddExternalIm
 {
   if (mDestroyed) {
     return IPC_OK();
   }
   MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
 
   RefPtr<CompositableHost> host = FindCompositable(aHandle);
   WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
+
+  MOZ_ASSERT(wrHost);
+  if (!wrHost) {
+    gfxCriticalNote << "Incompatible CompositableHost for external image at WebRenderBridgeParent.";
+  }
+
   if (!wrHost) {
     return IPC_OK();
   }
 
   wrHost->SetWrBridge(this);
   mExternalImageIds.Put(wr::AsUint64(aImageId), wrHost);
 
   return IPC_OK();
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -399,16 +399,17 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
       aLoadInfo->GetOriginAttributes(),
       redirectChainIncludingInternalRedirects,
       redirectChain,
       ancestorPrincipals,
       aLoadInfo->AncestorOuterWindowIDs(),
       aLoadInfo->CorsUnsafeHeaders(),
       aLoadInfo->GetForcePreflight(),
       aLoadInfo->GetIsPreflight(),
+      aLoadInfo->GetLoadTriggeredFromExternal(),
       aLoadInfo->GetForceHSTSPriming(),
       aLoadInfo->GetMixedContentWouldBlock(),
       aLoadInfo->GetIsHSTSPriming(),
       aLoadInfo->GetIsHSTSPrimingUpgrade()
       );
 
   return NS_OK;
 }
@@ -506,16 +507,17 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
                           loadInfoArgs.originAttributes(),
                           redirectChainIncludingInternalRedirects,
                           redirectChain,
                           Move(ancestorPrincipals),
                           loadInfoArgs.ancestorOuterWindowIDs(),
                           loadInfoArgs.corsUnsafeHeaders(),
                           loadInfoArgs.forcePreflight(),
                           loadInfoArgs.isPreflight(),
+                          loadInfoArgs.loadTriggeredFromExternal(),
                           loadInfoArgs.forceHSTSPriming(),
                           loadInfoArgs.mixedContentWouldBlock(),
                           loadInfoArgs.isHSTSPriming(),
                           loadInfoArgs.isHSTSPrimingUpgrade()
                           );
 
    loadInfo.forget(outLoadInfo);
    return NS_OK;
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -925,16 +925,18 @@ description =
 [PRemoteSpellcheckEngine::CheckAndSuggest]
 description =
 [PRemoteSpellcheckEngine::SetDictionary]
 description =
 [PGPU::AddLayerTreeIdMapping]
 description =
 [PGPU::GetDeviceStatus]
 description =
+[PGPU::SimulateDeviceReset]
+description =
 [PAPZCTreeManager::ReceiveMultiTouchInputEvent]
 description =
 [PAPZCTreeManager::ReceiveMouseInputEvent]
 description =
 [PAPZCTreeManager::ReceivePanGestureInputEvent]
 description =
 [PAPZCTreeManager::ReceivePinchGestureInputEvent]
 description =
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -1530,39 +1530,32 @@ ProtoGetter(JSContext* cx, unsigned argc
     RootedObject proto(cx);
     if (!GetPrototype(cx, obj, &proto))
         return false;
 
     args.rval().setObjectOrNull(proto);
     return true;
 }
 
-namespace js {
-size_t sSetProtoCalled = 0;
-} // namespace js
-
 static bool
 ProtoSetter(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     HandleValue thisv = args.thisv();
     if (thisv.isNullOrUndefined()) {
         ReportIncompatible(cx, args);
         return false;
     }
     if (thisv.isPrimitive()) {
         // Mutating a boxed primitive's [[Prototype]] has no side effects.
         args.rval().setUndefined();
         return true;
     }
 
-    if (!cx->runningWithTrustedPrincipals())
-        ++sSetProtoCalled;
-
     Rooted<JSObject*> obj(cx, &args.thisv().toObject());
 
     /* Do nothing if __proto__ isn't being set to an object or null. */
     if (args.length() == 0 || !args[0].isObjectOrNull()) {
         args.rval().setUndefined();
         return true;
     }
 
--- a/js/src/devtools/automation/winbuildenv.sh
+++ b/js/src/devtools/automation/winbuildenv.sh
@@ -5,17 +5,17 @@ mk_add_options() {
   echo "$@"
 }
 
 topsrcdir="$SOURCE"
 
 # Tooltool installs in parent of topsrcdir for spidermonkey builds.
 # Resolve that path since the mozconfigs assume tooltool installs in
 # topsrcdir.
-export VSPATH="$(cd ${topsrcdir}/.. && pwd)/vs2017_15.4.1"
+export VSPATH="$(cd ${topsrcdir}/.. && pwd)/vs2017_15.4.2"
 
 # When running on a developer machine, several variables will already
 # have the right settings and we will need to keep them since the
 # Windows mozconfigs overwrite them.
 echo "export ORIGINAL_INCLUDE=$INCLUDE"
 echo "export ORIGINAL_LIB=$LIB"
 echo "export ORIGINAL_LIBPATH=$LIBPATH"
 
--- a/js/src/gc/GCEnum.h
+++ b/js/src/gc/GCEnum.h
@@ -67,21 +67,22 @@ enum class AbortReason {
     D(IncrementalMarkAllThenFinish, 9) \
     D(IncrementalMultipleSlices, 10)   \
     D(IncrementalMarkingValidator, 11) \
     D(ElementsBarrier, 12)             \
     D(CheckHashTablesOnMinorGC, 13)    \
     D(Compact, 14)                     \
     D(CheckHeapAfterGC, 15)            \
     D(CheckNursery, 16)                \
-    D(IncrementalSweepThenFinish, 17)
+    D(IncrementalSweepThenFinish, 17)  \
+    D(CheckGrayMarking, 18)
 
 enum class ZealMode {
 #define ZEAL_MODE(name, value) name = value,
     JS_FOR_EACH_ZEAL_MODE(ZEAL_MODE)
 #undef ZEAL_MODE
-    Limit = 17
+    Limit = 18
 };
 
 } /* namespace gc */
 } /* namespace js */
 
 #endif /* gc_GCEnum_h */
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -556,24 +556,38 @@ HeapCheckTracerBase::traceHeap(AutoLockF
             stack.back().processed = true;
             TraceChildren(this, item.thing);
         }
     }
 
     return !oom;
 }
 
+static const char*
+GetCellColorName(Cell* cell)
+{
+    if (cell->isMarkedBlack())
+        return "black";
+    if (cell->isMarkedGray())
+        return "gray";
+    return "white";
+}
+
 void
 HeapCheckTracerBase::dumpCellInfo(Cell* cell)
 {
     auto kind = cell->getTraceKind();
-    fprintf(stderr, "%s", GCTraceKindToAscii(kind));
-    if (kind == JS::TraceKind::Object)
-        fprintf(stderr, " %s", static_cast<JSObject*>(cell)->getClass()->name);
+    JSObject* obj = kind == JS::TraceKind::Object ? static_cast<JSObject*>(cell) : nullptr;
+
+    fprintf(stderr, "%s %s", GetCellColorName(cell), GCTraceKindToAscii(kind));
+    if (obj)
+        fprintf(stderr, " %s", obj->getClass()->name);
     fprintf(stderr, " %p", cell);
+    if (obj)
+        fprintf(stderr, " (compartment %p)", obj->compartment());
 }
 
 void
 HeapCheckTracerBase::dumpCellPath()
 {
     const char* name = contextName();
     for (int index = parentIndex; index != -1; index = stack[index].parentIndex) {
         const WorkItem& parent = stack[index];
@@ -637,17 +651,17 @@ js::gc::CheckHeapAfterGC(JSRuntime* rt)
     AutoTraceSession session(rt, JS::HeapState::Tracing);
     CheckHeapTracer tracer(rt);
     if (tracer.init())
         tracer.check(session.lock);
 }
 
 #endif /* JSGC_HASH_TABLE_CHECKS */
 
-#ifdef DEBUG
+#if defined(JS_GC_ZEAL) || defined(DEBUG)
 
 class CheckGrayMarkingTracer final : public HeapCheckTracerBase
 {
   public:
     explicit CheckGrayMarkingTracer(JSRuntime* rt);
     bool check(AutoLockForExclusiveAccess& lock);
 
   private:
@@ -665,20 +679,26 @@ void
 CheckGrayMarkingTracer::checkCell(Cell* cell)
 {
     Cell* parent = parentCell();
     if (!parent)
         return;
 
     if (parent->isMarkedBlack() && cell->isMarkedGray()) {
         failures++;
+
         fprintf(stderr, "Found black to gray edge to ");
         dumpCellInfo(cell);
         fprintf(stderr, "\n");
         dumpCellPath();
+
+        if (cell->getTraceKind() == JS::TraceKind::Object) {
+            fprintf(stderr, "\n");
+            DumpObject(static_cast<JSObject*>(cell), stderr);
+        }
     }
 }
 
 bool
 CheckGrayMarkingTracer::check(AutoLockForExclusiveAccess& lock)
 {
     if (!traceHeap(lock))
         return true; // Ignore failure.
@@ -698,9 +718,9 @@ js::CheckGrayMarkingState(JSRuntime* rt)
     AutoTraceSession session(rt, JS::HeapState::Tracing);
     CheckGrayMarkingTracer tracer(rt);
     if (!tracer.init())
         return true; // Ignore failure
 
     return tracer.check(session.lock);
 }
 
-#endif // DEBUG
+#endif // defined(JS_GC_ZEAL) || defined(DEBUG)
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1413914.js
@@ -0,0 +1,4 @@
+let a = grayRoot();
+a[0] = {};
+gczeal(18);
+gc();
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -1697,17 +1697,17 @@ DoSetPropFallback(JSContext* cx, Baselin
             }
         }
     }
 
     if (op == JSOP_INITPROP ||
         op == JSOP_INITLOCKEDPROP ||
         op == JSOP_INITHIDDENPROP)
     {
-        if (!InitPropertyOperation(cx, op, obj, id, rhs))
+        if (!InitPropertyOperation(cx, op, obj, name, rhs))
             return false;
     } else if (op == JSOP_SETNAME ||
                op == JSOP_STRICTSETNAME ||
                op == JSOP_SETGNAME ||
                op == JSOP_STRICTSETGNAME)
     {
         if (!SetNameOperation(cx, script, pc, obj, rhs))
             return false;
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -464,17 +464,17 @@ CharCodeAt(JSContext* cx, HandleString s
 JSFlatString*
 StringFromCharCode(JSContext* cx, int32_t code)
 {
     char16_t c = char16_t(code);
 
     if (StaticStrings::hasUnit(c))
         return cx->staticStrings().getUnit(c);
 
-    return NewStringCopyN<CanGC>(cx, &c, 1);
+    return NewStringCopyNDontDeflate<CanGC>(cx, &c, 1);
 }
 
 JSString*
 StringFromCodePoint(JSContext* cx, int32_t codePoint)
 {
     RootedValue rval(cx, Int32Value(codePoint));
     if (!str_fromCodePoint_one_arg(cx, rval, &rval))
         return nullptr;
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -424,41 +424,57 @@ EquivalentYearForDST(int year)
     /*
      * Years and leap years on which Jan 1 is a Sunday, Monday, etc.
      *
      * yearStartingWith[0][i] is an example non-leap year where
      * Jan 1 appears on Sunday (i == 0), Monday (i == 1), etc.
      *
      * yearStartingWith[1][i] is an example leap year where
      * Jan 1 appears on Sunday (i == 0), Monday (i == 1), etc.
+     *
+     * Keep two different mappings, one for past years (< 1970), and a
+     * different one for future years (> 2037).
      */
-    static const int yearStartingWith[2][7] = {
+    static const int pastYearStartingWith[2][7] = {
         {1978, 1973, 1974, 1975, 1981, 1971, 1977},
         {1984, 1996, 1980, 1992, 1976, 1988, 1972}
     };
+    static const int futureYearStartingWith[2][7] = {
+        {2034, 2035, 2030, 2031, 2037, 2027, 2033},
+        {2012, 2024, 2036, 2020, 2032, 2016, 2028}
+    };
 
     int day = int(DayFromYear(year) + 4) % 7;
     if (day < 0)
         day += 7;
 
+    const auto& yearStartingWith = year < 1970 ? pastYearStartingWith : futureYearStartingWith;
     return yearStartingWith[IsLeapYear(year)][day];
 }
 
+// Return true if |t| is representable as a 32-bit time_t variable, that means
+// the year is in [1970, 2038).
+static bool
+IsRepresentableAsTime32(double t)
+{
+    return 0.0 <= t && t < 2145916800000.0;
+}
+
 /* ES5 15.9.1.8. */
 static double
 DaylightSavingTA(double t)
 {
     if (!IsFinite(t))
         return GenericNaN();
 
     /*
      * If earlier than 1970 or after 2038, potentially beyond the ken of
      * many OSes, map it to an equivalent year before asking.
      */
-    if (t < 0.0 || t > 2145916800000.0) {
+    if (!IsRepresentableAsTime32(t)) {
         int year = EquivalentYearForDST(int(YearFromTime(t)));
         double day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
         t = MakeDate(day, TimeWithinDay(t));
     }
 
     int64_t utcMilliseconds = static_cast<int64_t>(t);
     int64_t offsetMilliseconds = DateTimeInfo::getDSTOffsetMilliseconds(utcMilliseconds);
     return static_cast<double>(offsetMilliseconds);
@@ -2616,16 +2632,28 @@ ToPRMJTime(double localTime, double utcT
     prtm.tm_wday = int8_t(WeekDay(localTime));
     prtm.tm_year = year;
     prtm.tm_yday = int16_t(DayWithinYear(localTime, year));
     prtm.tm_isdst = (DaylightSavingTA(utcTime) != 0);
 
     return prtm;
 }
 
+static size_t
+FormatTime(char* buf, int buflen, const char* fmt, double utcTime, double localTime)
+{
+    PRMJTime prtm = ToPRMJTime(localTime, utcTime);
+    int eqivalentYear = IsRepresentableAsTime32(utcTime)
+                        ? prtm.tm_year
+                        : EquivalentYearForDST(prtm.tm_year);
+    int offsetInSeconds = (int) floor((localTime - utcTime) / msPerSecond);
+
+    return PRMJ_FormatTime(buf, buflen, fmt, &prtm, eqivalentYear, offsetInSeconds);
+}
+
 enum class FormatSpec {
     DateTime,
     Date,
     Time
 };
 
 static bool
 FormatDate(JSContext* cx, double utcTime, FormatSpec format, MutableHandleValue rval)
@@ -2658,18 +2686,17 @@ FormatDate(JSContext* cx, double utcTime
              * operating-system dependence on strftime (which PRMJ_FormatTime
              * calls, for %Z only.)  win32 prints PST as
              * 'Pacific Standard Time.'  This way we always know what we're
              * getting, and can parse it if we produce it.  The OS time zone
              * string is included as a comment.
              */
 
             /* get a time zone string from the OS to include as a comment. */
-            PRMJTime prtm = ToPRMJTime(localTime, utcTime);
-            size_t tzlen = PRMJ_FormatTime(tzbuf, sizeof tzbuf, "(%Z)", &prtm);
+            size_t tzlen = FormatTime(tzbuf, sizeof tzbuf, "(%Z)", utcTime, localTime);
             if (tzlen != 0) {
                 /*
                  * Decide whether to use the resulting time zone string.
                  *
                  * Reject it if it contains any non-ASCII or non-printable
                  * characters.  It's then likely in some other character
                  * encoding, and we probably won't display it correctly.
                  */
@@ -2739,20 +2766,19 @@ ToLocaleFormatHelper(JSContext* cx, Hand
 {
     double utcTime = obj->as<DateObject>().UTCTime().toNumber();
 
     char buf[100];
     if (!IsFinite(utcTime)) {
         strcpy(buf, js_NaN_date_str);
     } else {
         double localTime = LocalTime(utcTime);
-        PRMJTime prtm = ToPRMJTime(localTime, utcTime);
 
         /* Let PRMJTime format it. */
-        size_t result_len = PRMJ_FormatTime(buf, sizeof buf, format, &prtm);
+        size_t result_len = FormatTime(buf, sizeof buf, format, utcTime, localTime);
 
         /* If it failed, default to toString. */
         if (result_len == 0)
             return FormatDate(cx, utcTime, FormatSpec::DateTime, rval);
 
         /* Hacked check against undesired 2-digit year 00/00/00 form. */
         if (strcmp(format, "%x") == 0 && result_len >= 6 &&
             /* Format %x means use OS settings, which may have 2-digit yr, so
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -523,32 +523,16 @@ js::SetReservedSlotWithBarrier(JSObject*
 }
 
 void
 js::SetPreserveWrapperCallback(JSContext* cx, PreserveWrapperCallback callback)
 {
     cx->runtime()->preserveWrapperCallback = callback;
 }
 
-/*
- * The below code is for temporary telemetry use. It can be removed when
- * sufficient data has been harvested.
- */
-
-namespace js {
-// Defined in vm/GlobalObject.cpp.
-extern size_t sSetProtoCalled;
-} // namespace js
-
-JS_FRIEND_API(size_t)
-JS_SetProtoCalled(JSContext*)
-{
-    return sSetProtoCalled;
-}
-
 JS_FRIEND_API(unsigned)
 JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp)
 {
     return PCToLineNumber(script, pc, columnp);
 }
 
 JS_FRIEND_API(bool)
 JS_IsDeadWrapper(JSObject* obj)
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -66,19 +66,16 @@ JS_NewObjectWithUniqueType(JSContext* cx
  * attached to them.
  */
 extern JS_FRIEND_API(JSObject*)
 JS_NewObjectWithoutMetadata(JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
 
 extern JS_FRIEND_API(uint32_t)
 JS_ObjectCountDynamicSlots(JS::HandleObject obj);
 
-extern JS_FRIEND_API(size_t)
-JS_SetProtoCalled(JSContext* cx);
-
 extern JS_FRIEND_API(bool)
 JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
 
 extern JS_FRIEND_API(bool)
 JS_NondeterministicGetWeakSetKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
 
 // Raw JSScript* because this needs to be callable from a signal handler.
 extern JS_FRIEND_API(unsigned)
@@ -527,17 +524,17 @@ IterateGrayObjects(JS::Zone* zone, GCThi
 
 /**
  * Invoke cellCallback on every gray JSObject in the given zone while cycle
  * collection is in progress.
  */
 extern JS_FRIEND_API(void)
 IterateGrayObjectsUnderCC(JS::Zone* zone, GCThingCallback cellCallback, void* data);
 
-#ifdef DEBUG
+#if defined(JS_GC_ZEAL) || defined(DEBUG)
 // Trace the heap and check there are no black to gray edges. These are
 // not allowed since the cycle collector could throw away the gray thing and
 // leave a dangling pointer.
 //
 // This doesn't trace weak maps as these are handled separately.
 extern JS_FRIEND_API(bool)
 CheckGrayMarkingState(JSRuntime* rt);
 #endif
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1735,38 +1735,23 @@ JSFunction::maybeRelazify(JSRuntime* rt)
         MOZ_ASSERT(isSelfHostedBuiltin());
         MOZ_ASSERT(isExtended());
         MOZ_ASSERT(getExtendedSlot(LAZY_FUNCTION_NAME_SLOT).toString()->isAtom());
     }
 
     comp->scheduleDelazificationForDebugger();
 }
 
-static bool
-fun_isGenerator(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    JSFunction* fun;
-    if (!IsFunctionObject(args.thisv(), &fun)) {
-        args.rval().setBoolean(false);
-        return true;
-    }
-
-    args.rval().setBoolean(fun->isGenerator());
-    return true;
-}
-
 const JSFunctionSpec js::function_methods[] = {
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str,   fun_toSource,   0,0),
 #endif
     JS_FN(js_toString_str,   fun_toString,   0,0),
     JS_FN(js_apply_str,      fun_apply,      2,0),
     JS_FN(js_call_str,       fun_call,       1,0),
-    JS_FN("isGenerator",     fun_isGenerator,0,0),
     JS_SELF_HOSTED_FN("bind", "FunctionBind", 2, 0),
     JS_SYM_FN(hasInstance, fun_symbolHasInstance, 1, JSPROP_READONLY | JSPROP_PERMANENT),
     JS_FS_END
 };
 
 // ES2018 draft rev 2aea8f3e617b49df06414eb062ab44fad87661d3
 // 19.2.1.1.1 CreateDynamicFunction( constructor, newTarget, kind, args )
 static bool
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -998,17 +998,18 @@ const char* gc::ZealModeHelpText =
     "    9: (IncrementalMarkAllThenFinish) Incremental GC in two slices: 1) mark all 2) new marking and finish\n"
     "   10: (IncrementalMultipleSlices) Incremental GC in multiple slices\n"
     "   11: (IncrementalMarkingValidator) Verify incremental marking\n"
     "   12: (ElementsBarrier) Always use the individual element post-write barrier, regardless of elements size\n"
     "   13: (CheckHashTablesOnMinorGC) Check internal hashtables on minor GC\n"
     "   14: (Compact) Perform a shrinking collection every N allocations\n"
     "   15: (CheckHeapAfterGC) Walk the heap to check its integrity after every GC\n"
     "   16: (CheckNursery) Check nursery integrity on minor GC\n"
-    "   17: (IncrementalSweepThenFinish) Incremental GC in two slices: 1) start sweeping 2) finish collection\n";
+    "   17: (IncrementalSweepThenFinish) Incremental GC in two slices: 1) start sweeping 2) finish collection\n"
+    "   18: (CheckGrayMarking) Check gray marking invariants after every GC\n";
 
 // The set of zeal modes that control incremental slices. These modes are
 // mutually exclusive.
 static const mozilla::EnumSet<ZealMode> IncrementalSliceZealModes = {
     ZealMode::IncrementalRootsThenFinish,
     ZealMode::IncrementalMarkAllThenFinish,
     ZealMode::IncrementalMultipleSlices,
     ZealMode::IncrementalSweepThenFinish
@@ -7505,16 +7506,19 @@ GCRuntime::collect(bool nonincrementalBy
     if (reason == JS::gcreason::COMPARTMENT_REVIVED)
         maybeDoCycleCollection();
 
 #ifdef JS_GC_ZEAL
     if (rt->hasZealMode(ZealMode::CheckHeapAfterGC)) {
         gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::TRACE_HEAP);
         CheckHeapAfterGC(rt);
     }
+    if (rt->hasZealMode(ZealMode::CheckGrayMarking)) {
+        MOZ_RELEASE_ASSERT(CheckGrayMarkingState(rt));
+    }
 #endif
 }
 
 js::AutoEnqueuePendingParseTasksAfterGC::~AutoEnqueuePendingParseTasksAfterGC()
 {
     if (!OffThreadParsingMustWaitForGC(gc_.rt))
         EnqueuePendingParseTasksAfterGC(gc_.rt);
 }
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3406,17 +3406,17 @@ dumpValue(const Value& v, js::GenericPri
         out.put("null");
     else if (v.isUndefined())
         out.put("undefined");
     else if (v.isInt32())
         out.printf("%d", v.toInt32());
     else if (v.isDouble())
         out.printf("%g", v.toDouble());
     else if (v.isString())
-        v.toString()->dump(out);
+        v.toString()->dumpNoNewline(out);
     else if (v.isSymbol())
         v.toSymbol()->dump(out);
     else if (v.isObject() && v.toObject().is<JSFunction>()) {
         JSFunction* fun = &v.toObject().as<JSFunction>();
         if (fun->displayAtom()) {
             out.put("<function ");
             EscapedStringPrinter(out, fun->displayAtom(), 0);
         } else {
@@ -3487,47 +3487,51 @@ js::DumpId(jsid id, js::GenericPrinter& 
     dumpValue(IdToValue(id), out);
     out.putChar('\n');
 }
 
 static void
 DumpProperty(const NativeObject* obj, Shape& shape, js::GenericPrinter& out)
 {
     jsid id = shape.propid();
+    if (JSID_IS_ATOM(id))
+        JSID_TO_ATOM(id)->dumpCharsNoNewline(out);
+    else if (JSID_IS_INT(id))
+       out.printf("%d", JSID_TO_INT(id));
+    else if (JSID_IS_SYMBOL(id))
+        JSID_TO_SYMBOL(id)->dump(out);
+    else
+        out.printf("id %p", reinterpret_cast<void*>(JSID_BITS(id)));
+
+    if (shape.isDataProperty()) {
+        out.printf(": ");
+        dumpValue(obj->getSlot(shape.maybeSlot()), out);
+    }
+
+    out.printf(" (shape %p", (void*) &shape);
+
     uint8_t attrs = shape.attributes();
-
-    out.printf("    ((js::Shape*) %p) ", (void*) &shape);
-    if (attrs & JSPROP_ENUMERATE) out.put("enumerate ");
-    if (attrs & JSPROP_READONLY) out.put("readonly ");
-    if (attrs & JSPROP_PERMANENT) out.put("permanent ");
+    if (attrs & JSPROP_ENUMERATE) out.put(" enumerate");
+    if (attrs & JSPROP_READONLY) out.put(" readonly");
+    if (attrs & JSPROP_PERMANENT) out.put(" permanent");
 
     if (shape.hasGetterValue())
-        out.printf("getterValue=%p ", (void*) shape.getterObject());
+        out.printf(" getterValue %p", shape.getterObject());
     else if (!shape.hasDefaultGetter())
-        out.printf("getterOp=%p ", JS_FUNC_TO_DATA_PTR(void*, shape.getterOp()));
+        out.printf(" getterOp %p", JS_FUNC_TO_DATA_PTR(void*, shape.getterOp()));
 
     if (shape.hasSetterValue())
-        out.printf("setterValue=%p ", (void*) shape.setterObject());
+        out.printf(" setterValue %p", shape.setterObject());
     else if (!shape.hasDefaultSetter())
-        out.printf("setterOp=%p ", JS_FUNC_TO_DATA_PTR(void*, shape.setterOp()));
-
-    if (JSID_IS_ATOM(id) || JSID_IS_INT(id) || JSID_IS_SYMBOL(id))
-        dumpValue(js::IdToValue(id), out);
-    else
-        out.printf("unknown jsid %p", (void*) JSID_BITS(id));
-
-    uint32_t slot = shape.isDataProperty() ? shape.maybeSlot() : SHAPE_INVALID_SLOT;
-    out.printf(": slot %d", slot);
-    if (shape.isDataProperty()) {
-        out.put(" = ");
-        dumpValue(obj->getSlot(slot), out);
-    } else if (slot != SHAPE_INVALID_SLOT) {
-        out.printf(" (INVALID!)");
-    }
-    out.putChar('\n');
+        out.printf(" setterOp %p", JS_FUNC_TO_DATA_PTR(void*, shape.setterOp()));
+
+    if (shape.isDataProperty())
+        out.printf(" slot %d", shape.maybeSlot());
+
+    out.printf(")\n");
 }
 
 bool
 JSObject::uninlinedIsProxy() const
 {
     return is<ProxyObject>();
 }
 
@@ -3537,111 +3541,105 @@ JSObject::uninlinedNonProxyIsExtensible(
     return nonProxyIsExtensible();
 }
 
 void
 JSObject::dump(js::GenericPrinter& out) const
 {
     const JSObject* obj = this;
     JSObject* globalObj = &global();
-    out.printf("object %p from global %p [%s]\n", (void*) obj,
-            (void*) globalObj, globalObj->getClass()->name);
+    out.printf("object %p\n", obj);
+    out.printf("  global %p [%s]\n", globalObj, globalObj->getClass()->name);
+
     const Class* clasp = obj->getClass();
-    out.printf("class %p %s\n", (const void*)clasp, clasp->name);
+    out.printf("  class %p %s\n", clasp, clasp->name);
 
     if (obj->hasLazyGroup()) {
-        out.put("lazy group\n");
+        out.put("  lazy group\n");
     } else {
         const ObjectGroup* group = obj->group();
-        out.printf("group %p\n", (const void*)group);
+        out.printf("  group %p\n", group);
     }
 
-    out.put("flags:");
+    out.put("  flags:");
     if (obj->isDelegate()) out.put(" delegate");
     if (!obj->is<ProxyObject>() && !obj->nonProxyIsExtensible()) out.put(" not_extensible");
     if (obj->maybeHasInterestingSymbolProperty()) out.put(" maybe_has_interesting_symbol");
     if (obj->isBoundFunction()) out.put(" bound_function");
     if (obj->isQualifiedVarObj()) out.put(" varobj");
     if (obj->isUnqualifiedVarObj()) out.put(" unqualified_varobj");
     if (obj->isIteratedSingleton()) out.put(" iterated_singleton");
     if (obj->isNewGroupUnknown()) out.put(" new_type_unknown");
     if (obj->hasUncacheableProto()) out.put(" has_uncacheable_proto");
     if (obj->hasStaticPrototype() && obj->staticPrototypeIsImmutable())
         out.put(" immutable_prototype");
 
-    if (obj->isNative()) {
-        const NativeObject* nobj = &obj->as<NativeObject>();
+    const NativeObject* nobj = obj->isNative() ? &obj->as<NativeObject>() : nullptr;
+    if (nobj) {
         if (nobj->inDictionaryMode())
             out.put(" inDictionaryMode");
         if (nobj->hasShapeTable())
             out.put(" hasShapeTable");
         if (nobj->hadElementsAccess())
             out.put(" had_elements_access");
         if (nobj->isIndexed())
             out.put(" indexed");
         if (nobj->wasNewScriptCleared())
             out.put(" new_script_cleared");
+    } else {
+        out.put(" not_native\n");
     }
     out.putChar('\n');
 
-    if (obj->isNative()) {
-        const NativeObject* nobj = &obj->as<NativeObject>();
-        uint32_t slots = nobj->getDenseInitializedLength();
-        if (slots) {
-            out.put("elements\n");
-            for (uint32_t i = 0; i < slots; i++) {
-                out.printf(" %3d: ", i);
-                dumpValue(nobj->getDenseElement(i), out);
-                out.putChar('\n');
-                out.flush();
-            }
-        }
-    }
-
-    out.put("proto ");
+    out.put("  proto ");
     TaggedProto proto = obj->taggedProto();
     if (proto.isDynamic())
         out.put("<dynamic>");
     else
         dumpValue(ObjectOrNullValue(proto.toObjectOrNull()), out);
     out.putChar('\n');
 
-    if (clasp->flags & JSCLASS_HAS_PRIVATE)
-        out.printf("private %p\n", obj->as<NativeObject>().getPrivate());
-
-    if (!obj->isNative())
-        out.put("not native\n");
-
-    uint32_t reservedEnd = JSCLASS_RESERVED_SLOTS(clasp);
-    uint32_t slots = obj->isNative() ? obj->as<NativeObject>().slotSpan() : 0;
-    uint32_t stop = obj->isNative() ? reservedEnd : slots;
-    if (stop > 0)
-        out.printf(obj->isNative() ? "reserved slots:\n" : "slots:\n");
-    for (uint32_t i = 0; i < stop; i++) {
-        out.printf(" %3d ", i);
-        if (i < reservedEnd)
-            out.printf("(reserved) ");
-        out.put("= ");
-        dumpValue(obj->as<NativeObject>().getSlot(i), out);
-        out.putChar('\n');
-    }
-
-    if (obj->isNative()) {
-        out.put("properties:\n");
+    if (nobj) {
+        if (clasp->flags & JSCLASS_HAS_PRIVATE)
+            out.printf("  private %p\n", nobj->getPrivate());
+
+        uint32_t reserved = JSCLASS_RESERVED_SLOTS(clasp);
+        if (reserved) {
+            out.printf("  reserved slots:\n");
+            for (uint32_t i = 0; i < reserved; i++) {
+                out.printf("    %3d ", i);
+                out.put(": ");
+                dumpValue(nobj->getSlot(i), out);
+                out.putChar('\n');
+            }
+        }
+
+        out.put("  properties:\n");
         Vector<Shape*, 8, SystemAllocPolicy> props;
-        for (Shape::Range<NoGC> r(obj->as<NativeObject>().lastProperty()); !r.empty(); r.popFront()) {
+        for (Shape::Range<NoGC> r(nobj->lastProperty()); !r.empty(); r.popFront()) {
             if (!props.append(&r.front())) {
                 out.printf("(OOM while appending properties)\n");
                 break;
             }
         }
-        for (size_t i = props.length(); i-- != 0;)
-            DumpProperty(&obj->as<NativeObject>(), *props[i], out);
+        for (size_t i = props.length(); i-- != 0;) {
+            out.printf("    ");
+            DumpProperty(nobj, *props[i], out);
+        }
+
+        uint32_t slots = nobj->getDenseInitializedLength();
+        if (slots) {
+            out.put("  elements:\n");
+            for (uint32_t i = 0; i < slots; i++) {
+                out.printf("    %3d: ", i);
+                dumpValue(nobj->getDenseElement(i), out);
+                out.putChar('\n');
+            }
+        }
     }
-    out.putChar('\n');
 }
 
 // For debuggers.
 void
 JSObject::dump() const
 {
     Fprinter out(stderr);
     dump(out);
--- a/js/src/tests/ecma/extensions/15-1.js
+++ b/js/src/tests/ecma/extensions/15-1.js
@@ -28,28 +28,26 @@ writeHeaderToLog( SECTION + " "+ TITLE);
 /*
   new TestCase( "Function.prototype.__proto__", Object.prototype,   Function.prototype.__proto__ );
   new TestCase( "Array.prototype.__proto__",    Object.prototype,   Array.prototype.__proto__ );
   new TestCase( "String.prototype.__proto__",   Object.prototype,   String.prototype.__proto__ );
   new TestCase( "Boolean.prototype.__proto__",  Object.prototype,   Boolean.prototype.__proto__ );
   new TestCase( "Number.prototype.__proto__",   Object.prototype,   Number.prototype.__proto__ );
 //    new TestCase( "Math.prototype.__proto__",     Object.prototype,   Math.prototype.__proto__ );
 new TestCase( "Date.prototype.__proto__",     Object.prototype,   Date.prototype.__proto__ );
-new TestCase( "TestCase.prototype.__proto__", Object.prototype,   TestCase.prototype.__proto__ );
 
 new TestCase( "MyObject.prototype.__proto__", Object.prototype,   MyObject.prototype.__proto__ );
 */
 new TestCase( "Function.prototype.__proto__ == Object.prototype", true,   Function.prototype.__proto__ == Object.prototype );
 new TestCase( "Array.prototype.__proto__ == Object.prototype",    true,   Array.prototype.__proto__ == Object.prototype );
 new TestCase( "String.prototype.__proto__ == Object.prototype",   true,   String.prototype.__proto__ == Object.prototype );
 new TestCase( "Boolean.prototype.__proto__ == Object.prototype",  true,   Boolean.prototype.__proto__ == Object.prototype );
 new TestCase( "Number.prototype.__proto__ == Object.prototype",   true,   Number.prototype.__proto__ == Object.prototype );
 //    new TestCase( "Math.prototype.__proto__ == Object.prototype",     true,   Math.prototype.__proto__ == Object.prototype );
 new TestCase( "Date.prototype.__proto__ == Object.prototype",     true,   Date.prototype.__proto__ == Object.prototype );
-new TestCase( "TestCase.prototype.__proto__ == Object.prototype", true,   TestCase.prototype.__proto__ == Object.prototype );
 
 new TestCase( "MyObject.prototype.__proto__ == Object.prototype", true,   MyObject.prototype.__proto__ == Object.prototype );
 
 
 test();
 
 
 function MyObject( value ) {
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Date/time-zone-2038-pst.js
@@ -0,0 +1,59 @@
+// |reftest| skip-if(!xulRuntime.shell)
+
+// Note: The default time zone is set to PST8PDT for all jstests (when run in the shell).
+
+assertEq(/^(PST|PDT)$/.test(getTimeZone()), true);
+
+const Month = {
+    January: 0,
+    February: 1,
+    March: 2,
+    April: 3,
+    May: 4,
+    June: 5,
+    July: 6,
+    August: 7,
+    September: 8,
+    October: 9,
+    November: 10,
+    December: 11,
+};
+
+// U.S. daylight saving rules changed in 2007, excerpt from tzdata's
+// northamerica file:
+// NAME  FROM  TO    IN   ON       AT    SAVE  LETTER/S   
+// US    1967  2006  Oct  lastSun  2:00  0     S
+// US    1967  1973  Apr  lastSun  2:00  1:00  D
+// US    1974  only  Jan  6        2:00  1:00  D
+// US    1975  only  Feb  23       2:00  1:00  D
+// US    1976  1986  Apr  lastSun  2:00  1:00  D
+// US    1987  2006  Apr  Sun>=1   2:00  1:00  D
+// US    2007  max   Mar  Sun>=8   2:00  1:00  D
+// US    2007  max   Nov  Sun>=1   2:00  0     S
+
+
+// When 2040 is mapped to 1984, the old U.S. rules are applied, i.e. DST isn't
+// yet observed on March 31. If mapped to 2012, the new U.S. rules are applied
+// and DST is already observed, which is the expected behaviour.
+// A similar effect is visible in November.
+// NOTE: This test expects that 2012 and 2040 use the same DST rules. If this
+//       ever changes, the test needs to be updated accordingly.
+{
+    let dt1 = new Date(2040, Month.March, 31);
+    assertEq(dt1.toString(), "Sat Mar 31 2040 00:00:00 GMT-0700 (PDT)");
+
+    let dt2 = new Date(2040, Month.November, 1);
+    assertEq(dt2.toString(), "Thu Nov 01 2040 00:00:00 GMT-0700 (PDT)");
+}
+
+// 2038 is mapped to 2027 instead of 1971.
+{
+    let dt1 = new Date(2038, Month.March, 31);
+    assertEq(dt1.toString(), "Wed Mar 31 2038 00:00:00 GMT-0700 (PDT)");
+
+    let dt2 = new Date(2038, Month.November, 1);
+    assertEq(dt2.toString(), "Mon Nov 01 2038 00:00:00 GMT-0700 (PDT)");
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
deleted file mode 100644
--- a/js/src/tests/js1_8_5/extensions/is-generator.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-/*
- * Bug 648355: Function.prototype.isGenerator
- */
-
-reportCompare(true, "isGenerator" in Function.prototype, "Function.prototype.isGenerator present");
-
-reportCompare(false, (function(){}).isGenerator(), "lambda is not a generator fn");
-reportCompare(false, Function.prototype.toString.isGenerator(), "native is not a generator fn");
-reportCompare(false, (function(){with(obj){}}).isGenerator(), "heavyweight is not a generator fn");
-reportCompare(false, (function(){obj}).isGenerator(), "upvar function is not a generator fn");
-
-reportCompare(true, (function*(){yield}).isGenerator(), "simple generator fn");
-reportCompare(true, (function*(){with(obj){yield}}).isGenerator(), "heavyweight generator fn");
-reportCompare(true, (function*(){yield; obj}).isGenerator(), "upvar generator fn");
-
-reportCompare(false, Function.prototype.isGenerator.call(42), "number is not a generator fn");
-reportCompare(false, Function.prototype.isGenerator.call({}), "vanilla object is not a generator fn");
-reportCompare(false, Function.prototype.isGenerator.call(new Date()), "date object is not a generator fn");
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -470,19 +470,16 @@ skip script test262/language/expressions
 skip script test262/language/expressions/class/async-gen-method-yield-star-sync-next.js
 skip script test262/language/expressions/class/async-gen-method-static-yield-star-sync-next.js
 
 
 ###########################################################
 # Tests disabled due to issues in test262 importer script #
 ###########################################################
 
-# https://bugzilla.mozilla.org/show_bug.cgi?id=1346080
-skip script test262/intl402/PluralRules/prototype/select/tainting.js
-
 # test262 importer merges all includes in a per directory shell.js file, breaking this harness test case.
 skip script test262/harness/detachArrayBuffer.js
 
 
 ####################################################
 # Tests disabled due to invalid test expectations  #
 ####################################################
 
--- a/js/src/tests/shell.js
+++ b/js/src/tests/shell.js
@@ -317,39 +317,30 @@
    * Same as `new TestCase(description, expect, actual)`, except it doesn't
    * return the newly created test case object.
    */
   function AddTestCase(description, expect, actual) {
     new TestCase(description, expect, actual);
   }
   global.AddTestCase = AddTestCase;
 
-  var testCasesCounter = 0;
   var testCasesArray = [];
 
   function TestCase(d, e, a, r) {
     this.description = d;
     this.expect = e;
     this.actual = a;
     this.passed = getTestCaseResult(e, a);
     this.reason = typeof r !== 'undefined' ? String(r) : '';
-    ObjectDefineProperty(
-      testCasesArray,
-      testCasesCounter++,
-      {
-        __proto__: null,
-        value: this,
-        enumerable: true,
-        configurable: true,
-        writable: true
-      }
-    );
+
+    ArrayPush(testCasesArray, this);
   }
   global.TestCase = TestCase;
 
+  TestCase.prototype = ObjectCreate(null);
   TestCase.prototype.testPassed = (function TestCase_testPassed() { return this.passed; });
   TestCase.prototype.testFailed = (function TestCase_testFailed() { return !this.passed; });
   TestCase.prototype.testDescription = (function TestCase_testDescription() { return this.description + ' ' + this.reason; });
 
   function getTestCaseResult(expected, actual) {
     if (typeof expected !== typeof actual)
       return false;
     if (typeof expected !== 'number')
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -394,24 +394,26 @@ InitGlobalLexicalOperation(JSContext* cx
     MOZ_ASSERT(*pc == JSOP_INITGLEXICAL);
     Rooted<LexicalEnvironmentObject*> lexicalEnv(cx, lexicalEnvArg);
     RootedShape shape(cx, lexicalEnv->lookup(cx, script->getName(pc)));
     MOZ_ASSERT(shape);
     lexicalEnv->setSlotWithType(cx, shape, value);
 }
 
 inline bool
-InitPropertyOperation(JSContext* cx, JSOp op, HandleObject obj, HandleId id, HandleValue rhs)
+InitPropertyOperation(JSContext* cx, JSOp op, HandleObject obj, HandlePropertyName name,
+                      HandleValue rhs)
 {
     if (obj->is<PlainObject>() || obj->is<JSFunction>()) {
         unsigned propAttrs = GetInitDataPropAttrs(op);
-        return NativeDefineDataProperty(cx, obj.as<NativeObject>(), id, rhs, propAttrs);
+        return NativeDefineDataProperty(cx, obj.as<NativeObject>(), name, rhs, propAttrs);
     }
 
-    MOZ_ASSERT(obj->as<UnboxedPlainObject>().layout().lookup(id));
+    MOZ_ASSERT(obj->as<UnboxedPlainObject>().layout().lookup(name));
+    RootedId id(cx, NameToId(name));
     return PutProperty(cx, obj, id, rhs, false);
 }
 
 inline bool
 DefVarOperation(JSContext* cx, HandleObject varobj, HandlePropertyName dn, unsigned attrs)
 {
     MOZ_ASSERT(varobj->isQualifiedVarObj());
 
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -3773,22 +3773,19 @@ CASE(JSOP_INITHIDDENPROP)
                   "initprop and inithiddenprop must be the same size");
     /* Load the property's initial value into rval. */
     MOZ_ASSERT(REGS.stackDepth() >= 2);
     ReservedRooted<Value> rval(&rootValue0, REGS.sp[-1]);
 
     /* Load the object being initialized into lval/obj. */
     ReservedRooted<JSObject*> obj(&rootObject0, &REGS.sp[-2].toObject());
 
-    PropertyName* name = script->getName(REGS.pc);
-
-    RootedId& id = rootId0;
-    id = NameToId(name);
-
-    if (!InitPropertyOperation(cx, JSOp(*REGS.pc), obj, id, rval))
+    ReservedRooted<PropertyName*> name(&rootName0, script->getName(REGS.pc));
+
+    if (!InitPropertyOperation(cx, JSOp(*REGS.pc), obj, name, rval))
         goto error;
 
     REGS.sp--;
 }
 END_CASE(JSOP_INITPROP)
 
 CASE(JSOP_INITELEM)
 CASE(JSOP_INITHIDDENELEM)
--- a/js/src/vm/String.cpp
+++ b/js/src/vm/String.cpp
@@ -155,33 +155,39 @@ JSString::dump()
 {
     js::Fprinter out(stderr);
     dump(out);
 }
 
 void
 JSString::dump(js::GenericPrinter& out)
 {
+    dumpNoNewline(out);
+    out.putChar('\n');
+}
+
+void
+JSString::dumpNoNewline(js::GenericPrinter& out)
+{
     if (JSLinearString* linear = ensureLinear(nullptr)) {
         AutoCheckCannotGC nogc;
         if (hasLatin1Chars()) {
             const Latin1Char* chars = linear->latin1Chars(nogc);
             out.printf("JSString* (%p) = Latin1Char * (%p) = ", (void*) this,
                     (void*) chars);
             dumpChars(chars, length(), out);
         } else {
             const char16_t* chars = linear->twoByteChars(nogc);
             out.printf("JSString* (%p) = char16_t * (%p) = ", (void*) this,
                     (void*) chars);
             dumpChars(chars, length(), out);
         }
     } else {
         out.put("(oom in JSString::dump)");
     }
-    out.putChar('\n');
 }
 
 
 void
 JSString::dumpRepresentation(js::GenericPrinter& out, int indent) const
 {
     if      (isRope())          asRope()        .dumpRepresentation(out, indent);
     else if (isDependent())     asDependent()   .dumpRepresentation(out, indent);
--- a/js/src/vm/String.h
+++ b/js/src/vm/String.h
@@ -524,16 +524,17 @@ class JSString : public js::gc::TenuredC
         return offsetof(JSString, d.s.u2.nonInlineCharsTwoByte);
     }
 
     static const JS::TraceKind TraceKind = JS::TraceKind::String;
 
 #ifdef DEBUG
     void dump(); // Debugger-friendly stderr dump.
     void dump(js::GenericPrinter& out);
+    void dumpNoNewline(js::GenericPrinter& out);
     void dumpCharsNoNewline(js::GenericPrinter& out);
     void dumpRepresentation(js::GenericPrinter& out, int indent) const;
     void dumpRepresentationHeader(js::GenericPrinter& out, int indent, const char* subclass) const;
 
     template <typename CharT>
     static void dumpChars(const CharT* s, size_t len, js::GenericPrinter& out);
 
     bool equals(const char* s);
--- a/js/src/vm/Time.cpp
+++ b/js/src/vm/Time.cpp
@@ -256,22 +256,22 @@ PRMJ_InvalidParameterHandler(const wchar
                              uintptr_t      pReserved)
 {
     /* empty */
 }
 #endif
 
 /* Format a time value into a buffer. Same semantics as strftime() */
 size_t
-PRMJ_FormatTime(char* buf, int buflen, const char* fmt, PRMJTime* prtm)
+PRMJ_FormatTime(char* buf, int buflen, const char* fmt, const PRMJTime* prtm,
+                int equivalentYear, int offsetInSeconds)
 {
     size_t result = 0;
 #if defined(XP_UNIX) || defined(XP_WIN)
     struct tm a;
-    int fake_tm_year = 0;
 #ifdef XP_WIN
     _invalid_parameter_handler oldHandler;
 #ifndef __MINGW32__
     int oldReportMode;
 #endif // __MINGW32__
 #endif //XP_WIN
 
     memset(&a, 0, sizeof(struct tm));
@@ -284,16 +284,17 @@ PRMJ_FormatTime(char* buf, int buflen, c
     a.tm_wday = prtm->tm_wday;
 
     /*
      * On systems where |struct tm| has members tm_gmtoff and tm_zone, we
      * must fill in those values, or else strftime will return wrong results
      * (e.g., bug 511726, bug 554338).
      */
 #if defined(HAVE_LOCALTIME_R) && defined(HAVE_TM_ZONE_TM_GMTOFF)
+    char emptyTimeZoneId[] = "";
     {
         /*
          * Fill out |td| to the time represented by |prtm|, leaving the
          * timezone fields zeroed out. localtime_r will then fill in the
          * timezone fields for that local time according to the system's
          * timezone parameters.
          */
         struct tm td;
@@ -302,33 +303,49 @@ PRMJ_FormatTime(char* buf, int buflen, c
         td.tm_min = prtm->tm_min;
         td.tm_hour = prtm->tm_hour;
         td.tm_mday = prtm->tm_mday;
         td.tm_mon = prtm->tm_mon;
         td.tm_wday = prtm->tm_wday;
         td.tm_year = prtm->tm_year - 1900;
         td.tm_yday = prtm->tm_yday;
         td.tm_isdst = prtm->tm_isdst;
+
         time_t t = mktime(&td);
-        localtime_r(&t, &td);
+
+        // If |prtm| cannot be represented in |time_t| the year is probably
+        // out of range, try again with the DST equivalent year.
+        if (t == static_cast<time_t>(-1)) {
+            td.tm_year = equivalentYear - 1900;
+            t = mktime(&td);
+        }
 
-        a.tm_gmtoff = td.tm_gmtoff;
-        a.tm_zone = td.tm_zone;
+        // If either mktime or localtime_r failed, fill in the fallback time
+        // zone offset |offsetInSeconds| and set the time zone identifier to
+        // the empty string.
+        if (t != static_cast<time_t>(-1) && localtime_r(&t, &td)) {
+            a.tm_gmtoff = td.tm_gmtoff;
+            a.tm_zone = td.tm_zone;
+        } else {
+            a.tm_gmtoff = offsetInSeconds;
+            a.tm_zone = emptyTimeZoneId;
+        }
     }
 #endif
 
     /*
      * Years before 1900 and after 9999 cause strftime() to abort on Windows.
      * To avoid that we replace it with FAKE_YEAR_BASE + year % 100 and then
      * replace matching substrings in the strftime() result with the real year.
      * Note that FAKE_YEAR_BASE should be a multiple of 100 to make 2-digit
      * year formats (%y) work correctly (since we won't find the fake year
      * in that case).
      */
-#define FAKE_YEAR_BASE 9900
+    constexpr int FAKE_YEAR_BASE = 9900;
+    int fake_tm_year = 0;
     if (prtm->tm_year < 1900 || prtm->tm_year > 9999) {
         fake_tm_year = FAKE_YEAR_BASE + prtm->tm_year % 100;
         a.tm_year = fake_tm_year - 1900;
     }
     else {
         a.tm_year = prtm->tm_year - 1900;
     }
     a.tm_yday = prtm->tm_yday;
--- a/js/src/vm/Time.h
+++ b/js/src/vm/Time.h
@@ -49,17 +49,18 @@ extern void
 PRMJ_NowShutdown();
 #else
 inline void
 PRMJ_NowShutdown() {}
 #endif
 
 /* Format a time value into a buffer. Same semantics as strftime() */
 extern size_t
-PRMJ_FormatTime(char* buf, int buflen, const char* fmt, PRMJTime* tm);
+PRMJ_FormatTime(char* buf, int buflen, const char* fmt, const PRMJTime* tm,
+                int equivalentYear, int offsetInSeconds);
 
 
 /**
  * Requesting the number of cycles from the CPU.
  *
  * `rdtsc`, or Read TimeStamp Cycle, is an instruction provided by
  * x86-compatible CPUs that lets processes request the number of
  * cycles spent by the CPU executing instructions since the CPU was
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3052,22 +3052,17 @@ nsXPCComponents_Utils::GetWatchdogTimest
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::GetJSEngineTelemetryValue(JSContext* cx, MutableHandleValue rval)
 {
     RootedObject obj(cx, JS_NewPlainObject(cx));
     if (!obj)
         return NS_ERROR_OUT_OF_MEMORY;
 
-    unsigned attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
-
-    size_t i = JS_SetProtoCalled(cx);
-    RootedValue v(cx, DoubleValue(i));
-    if (!JS_DefineProperty(cx, obj, "setProto", v, attrs))
-        return NS_ERROR_OUT_OF_MEMORY;
+    // No JS engine telemetry in use at the moment.
 
     rval.setObject(*obj);
     return NS_OK;
 }
 
 bool
 xpc::CloneInto(JSContext* aCx, HandleValue aValue, HandleValue aScope,
                HandleValue aOptions, MutableHandleValue aCloned)
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -230,17 +230,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       gConstructorProperties[c] = constructorProps([]);
   }
   // toString and toSource only live on the parent proto (Error.prototype).
   gPrototypeProperties['Error'].push('toString');
   gPrototypeProperties['Error'].push('toSource');
 
   gPrototypeProperties['Function'] =
     ["constructor", "toSource", "toString", "apply", "call", "bind",
-     "isGenerator", "length", "name", "arguments", "caller", Symbol.hasInstance];
+     "length", "name", "arguments", "caller", Symbol.hasInstance];
   gConstructorProperties['Function'] = constructorProps([])
 
   gPrototypeProperties['RegExp'] =
     ["constructor", "toSource", "toString", "compile", "exec", "test",
      Symbol.match, Symbol.replace, Symbol.search, Symbol.split,
      "flags", "global", "ignoreCase", "multiline", "source", "sticky", "unicode"];
   gConstructorProperties['RegExp'] =
     constructorProps(["input", "lastMatch", "lastParen",
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -711,16 +711,18 @@ JSXrayTraits::resolveOwnProperty(JSConte
 
     return true;
 }
 
 bool
 JSXrayTraits::delete_(JSContext* cx, HandleObject wrapper, HandleId id, ObjectOpResult& result)
 {
     RootedObject holder(cx, ensureHolder(cx, wrapper));
+    if (!holder)
+        return false;
 
     // If we're using Object Xrays, we allow callers to attempt to delete any
     // property from the underlying object that they are able to resolve. Note
     // that this deleting may fail if the property is non-configurable.
     JSProtoKey key = getProtoKey(holder);
     bool isObjectOrArrayInstance = (key == JSProto_Object || key == JSProto_Array) &&
                                    !isPrototype(holder);
     if (isObjectOrArrayInstance) {
@@ -949,16 +951,19 @@ JSXrayTraits::enumerateNames(JSContext* 
 }
 
 bool
 JSXrayTraits::construct(JSContext* cx, HandleObject wrapper,
                         const JS::CallArgs& args, const js::Wrapper& baseInstance)
 {
     JSXrayTraits& self = JSXrayTraits::singleton;
     JS::RootedObject holder(cx, self.ensureHolder(cx, wrapper));
+    if (!holder)
+        return false;
+
     if (self.getProtoKey(holder) == JSProto_Function) {
         JSProtoKey standardConstructor = constructorFor(holder);
         if (standardConstructor == JSProto_Null)
             return baseInstance.construct(cx, wrapper, args);
 
         const js::Class* clasp = js::ProtoKeyToClass(standardConstructor);
         MOZ_ASSERT(clasp);
         if (!(clasp->flags & JSCLASS_HAS_XRAYED_CONSTRUCTOR))
--- a/layout/tools/reftest/reftestcommandline.py
+++ b/layout/tools/reftest/reftestcommandline.py
@@ -66,17 +66,17 @@ class ReftestArgumentsParser(argparse.Ar
                           dest="extraProfileFiles",
                           default=[],
                           help="copy specified files/dirs to testing profile")
 
         self.add_argument("--timeout",
                           action="store",
                           dest="timeout",
                           type=int,
-                          default=5 * 60,  # 5 minutes per bug 479518
+                          default=300,  # 5 minutes per bug 479518
                           help="reftest will timeout in specified number of seconds. "
                                "[default %(default)s].")
 
         self.add_argument("--leak-threshold",
                           action="store",
                           type=int,
                           dest="defaultLeakThreshold",
                           default=0,
--- a/layout/tools/reftest/runreftest.py
+++ b/layout/tools/reftest/runreftest.py
@@ -790,20 +790,28 @@ class RefTest(object):
 
                 # browser environment
                 browserEnv = self.buildBrowserEnv(options, profileDir)
 
                 self.log.info("Running with e10s: {}".format(options.e10s))
                 status, startAfter = self.runApp(profile,
                                                  binary=options.app,
                                                  cmdargs=cmdargs,
-                                                 # give the JS harness 30 seconds to deal with
-                                                 # its own timeouts
                                                  env=browserEnv,
-                                                 timeout=options.timeout + 30.0,
+                                                 # We generally want the JS harness or marionette
+                                                 # to handle timeouts if they can.
+                                                 # The default JS harness timeout is currently
+                                                 # 300 seconds (default options.timeout).
+                                                 # The default Marionette socket timeout is
+                                                 # currently 360 seconds.
+                                                 # Give the JS harness extra time to deal with
+                                                 # its own timeouts and try to usually exceed
+                                                 # the 360 second marionette socket timeout.
+                                                 # See bug 479518 and bug 1414063.
+                                                 timeout=options.timeout + 70.0,
                                                  symbolsPath=options.symbolsPath,
                                                  options=options,
                                                  debuggerInfo=debuggerInfo)
                 self.log.info("Process mode: {}".format('e10s' if options.e10s else 'non-e10s'))
                 mozleak.process_leak_log(self.leakLogFile,
                                          leak_thresholds=options.leakThresholds,
                                          stack_fixer=get_stack_fixer_function(options.utilityPath,
                                                                               options.symbolsPath))
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -2533,30 +2533,17 @@ nsPrefBranch::GetComplexValue(const char
 
   if (aType.Equals(NS_GET_IID(nsISupportsString))) {
     nsCOMPtr<nsISupportsString> theString(
       do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv));
 
     if (NS_SUCCEEDED(rv)) {
       // Debugging to see why we end up with very long strings here with
       // some addons, see bug 836263.
-      nsAutoString wdata;
-      if (!AppendUTF8toUTF16(utf8String, wdata, mozilla::fallible)) {
-#ifdef MOZ_CRASHREPORTER
-        nsCOMPtr<nsICrashReporter> cr =
-          do_GetService("@mozilla.org/toolkit/crash-reporter;1");
-        if (cr) {
-          cr->AnnotateCrashReport(NS_LITERAL_CSTRING("bug836263-size"),
-                                  nsPrintfCString("%x", utf8String.Length()));
-          cr->RegisterAppMemory(uint64_t(utf8String.BeginReading()),
-                                std::min(0x1000U, utf8String.Length()));
-        }
-#endif
-        MOZ_CRASH("bug836263");
-      }
+      NS_ConvertUTF8toUTF16 wdata(utf8String);
       theString->SetData(wdata);
       theString.forget(reinterpret_cast<nsISupportsString**>(aRetVal));
     }
     return rv;
   }
 
   NS_WARNING("nsPrefBranch::GetComplexValue - Unsupported interface type");
   return NS_NOINTERFACE;
@@ -3850,17 +3837,16 @@ Preferences::Init()
     mozilla::services::GetObserverService();
   if (!observerService) {
     return Err("GetObserverService() failed (1)");
   }
 
   observerService->AddObserver(this, "profile-before-change-telemetry", true);
   rv = observerService->AddObserver(this, "profile-before-change", true);
 
-  observerService->AddObserver(this, "load-extension-defaults", true);
   observerService->AddObserver(this, "suspend_process_notification", true);
 
   if (NS_FAILED(rv)) {
     return Err("AddObserver(\"profile-before-change\") failed");
   }
 
   return Ok();
 }
@@ -3914,19 +3900,16 @@ Preferences::Observe(nsISupports* aSubje
   } else if (!nsCRT::strcmp(aTopic, "profile-before-change-telemetry")) {
     // It's possible that a profile-before-change observer after ours
     // set a pref. A blocking save here re-saves if necessary and also waits
     // for any pending saves to complete.
     SavePrefFileBlocking();
     MOZ_ASSERT(!mDirty, "Preferences should not be dirty");
     mProfileShutdown = true;
 
-  } else if (!strcmp(aTopic, "load-extension-defaults")) {
-    pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST);
-
   } else if (!nsCRT::strcmp(aTopic, "reload-default-prefs")) {
     // Reload the default prefs from file.
     Unused << pref_InitInitialObjects();
 
   } else if (!nsCRT::strcmp(aTopic, "suspend_process_notification")) {
     // Our process is being suspended. The OS may wake our process later,
     // or it may kill the process. In case our process is going to be killed
     // from the suspended state, we save preferences before suspending.
@@ -4022,64 +4005,16 @@ Preferences::SavePrefFileAsynchronous()
 
 NS_IMETHODIMP
 Preferences::SavePrefFile(nsIFile* aFile)
 {
   // This is the method accessible from service API. Make it off main thread.
   return SavePrefFileInternal(aFile, SaveMethod::Asynchronous);
 }
 
-static nsresult
-ReadExtensionPrefs(nsIFile* aFile)
-{
-  nsresult rv;
-  nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = reader->Open(aFile);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIUTF8StringEnumerator> files;
-  rv = reader->FindEntries(
-    nsDependentCString("defaults/preferences/*.(J|j)(S|s)$"),
-    getter_AddRefs(files));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  char buffer[4096];
-
-  bool more;
-  while (NS_SUCCEEDED(rv = files->HasMore(&more)) && more) {
-    nsAutoCString entry;
-    rv = files->GetNext(entry);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIInputStream> stream;
-    rv = reader->GetInputStream(entry, getter_AddRefs(stream));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    uint64_t avail;
-    uint32_t read;
-
-    PrefParseState ps;
-    PREF_InitParseState(&ps, PREF_ReaderCallback, ReportToConsole, nullptr);
-    while (NS_SUCCEEDED(rv = stream->Available(&avail)) && avail) {
-      rv = stream->Read(buffer, 4096, &read);
-      if (NS_FAILED(rv)) {
-        NS_WARNING("Pref stream read failed");
-        break;
-      }
-
-      PREF_ParseBuf(&ps, buffer, read);
-    }
-    PREF_FinalizeParseState(&ps);
-  }
-
-  return rv;
-}
-
 void
 Preferences::SetPreference(const PrefSetting& aPref)
 {
   const char* prefName = aPref.name().get();
   const dom::MaybePrefValue& defaultValue = aPref.defaultValue();
   const dom::MaybePrefValue& userValue = aPref.userValue();
 
   if (defaultValue.type() == dom::MaybePrefValue::TPrefValue) {
@@ -4544,25 +4479,18 @@ pref_LoadPrefsInDirList(const char* aLis
       continue;
     }
 
     nsCOMPtr<nsIFile> path = do_QueryInterface(elem);
     if (!path) {
       continue;
     }
 
-    nsAutoCString leaf;
-    path->GetNativeLeafName(leaf);
-
     // Do we care if a file provided by this process fails to load?
-    if (Substring(leaf, leaf.Length() - 4).EqualsLiteral(".xpi")) {
-      ReadExtensionPrefs(path);
-    } else {
-      pref_LoadPrefsInDir(path, nullptr, 0);
-    }
+    pref_LoadPrefsInDir(path, nullptr, 0);
   }
 
   return NS_OK;
 }
 
 static nsresult
 pref_ReadPrefFromJar(nsZipArchive* aJarReader, const char* aName)
 {
@@ -4768,20 +4696,16 @@ pref_InitInitialObjects()
 
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   NS_ENSURE_SUCCESS(rv, Err("GetObserverService() failed (2)"));
 
   observerService->NotifyObservers(
     nullptr, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID, nullptr);
 
-  rv = pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST);
-  NS_ENSURE_SUCCESS(
-    rv, Err("pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST) failed"));
-
   return Ok();
 }
 
 //----------------------------------------------------------------------------
 // Static utilities
 //----------------------------------------------------------------------------
 
 /* static */ nsresult
@@ -5380,18 +5304,16 @@ static mozilla::Module::CIDEntry kPrefCI
   { &kRelativeFilePrefCID, false, nullptr, nsRelativeFilePrefConstructor },
   { nullptr }
 };
 
 static mozilla::Module::ContractIDEntry kPrefContracts[] = {
   { NS_PREFSERVICE_CONTRACTID, &kPrefServiceCID },
   { NS_PREFLOCALIZEDSTRING_CONTRACTID, &kPrefLocalizedStringCID },
   { NS_RELATIVEFILEPREF_CONTRACTID, &kRelativeFilePrefCID },
-  // compatibility for extension that uses old service
-  { "@mozilla.org/preferences;1", &kPrefServiceCID },
   { nullptr }
 };
 
 static void
 UnloadPrefsModule()
 {
   Preferences::Shutdown();
 }
--- a/modules/libpref/nsIPrefService.idl
+++ b/modules/libpref/nsIPrefService.idl
@@ -142,14 +142,13 @@ interface nsIPrefService : nsISupports
 /**
  * Notification sent when resetPrefs has been called, but before the actual
  * reset process occurs.
  */
 #define NS_PREFSERVICE_RESET_TOPIC_ID "prefservice:before-reset"
 
 /**
  * Notification sent when after reading app-provided default
- * preferences, but before user profile override defaults or extension
- * defaults are loaded.
+ * preferences, but before user profile override defaults are loaded.
  */
 #define NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID "prefservice:after-app-defaults"
 
 %}
deleted file mode 100644
--- a/modules/libpref/test/unit/test_extprefs.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/  */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-// The profile directory is already set up in the head_ files.
-
-function arrayenumerator(a)
-{
-  return {
-    i_: 0,
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
-    hasMoreElements: function ae_hasMoreElements() {
-      return this.i_ < a.length;
-    },
-    getNext: function ae_getNext() {
-      return a[this.i_++];
-    }
-  };
-}
-
-function run_test() {
-  var ps = Cc["@mozilla.org/preferences-service;1"].
-    getService(Ci.nsIPrefService).QueryInterface(Ci.nsIPrefBranch);
-
-  var extprefs = [do_get_file("extdata")];
-  
-  var extProvider = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider,
-                                           Ci.nsIDirectoryServiceProvider2]),
-    getFile: function ep_getFile() {
-      throw Cr.NS_ERROR_FAILURE;
-    },
-    
-    getFiles: function ep_getFiles(key) {
-      if (key != "ExtPrefDL")
-        throw Cr.NS_ERROR_FAILURE;
-
-      return arrayenumerator(extprefs);
-    }
-  };
-  
-  let prefFile = do_get_file("data/testPref.js");
-
-  do_check_throws(function() {
-    ps.getBoolPref("testExtPref.bool");
-  }, Cr.NS_ERROR_UNEXPECTED);
-  do_check_throws(function() {
-    ps.getBoolPref("testPref.bool1");
-  }, Cr.NS_ERROR_UNEXPECTED);
-  
-  ps.readUserPrefsFromFile(prefFile);
-
-  do_check_true(ps.getBoolPref("testPref.bool1"));
-  ps.setBoolPref("testPref.bool1", false);
-  do_check_false(ps.getBoolPref("testPref.bool1"));
-  
-  dirSvc.registerProvider(extProvider);
-  Services.obs.notifyObservers(null, "load-extension-defaults");
-
-  // The extension default should be available.
-  do_check_true(ps.getBoolPref("testExtPref.bool"));
-
-  // The extension default should not override existing user prefs
-  do_check_false(ps.getBoolPref("testPref.bool2"));
-
-  // The extension default should not modify existing set values
-  do_check_false(ps.getBoolPref("testPref.bool1"));
-}
--- a/modules/libpref/test/unit/xpcshell.ini
+++ b/modules/libpref/test/unit/xpcshell.ini
@@ -9,11 +9,10 @@ support-files =
 [test_bug506224.js]
 [test_bug577950.js]
 [test_bug790374.js]
 [test_stickyprefs.js]
 support-files = data/testPrefSticky.js data/testPrefStickyUser.js
 [test_changeType.js]
 [test_defaultValues.js]
 [test_dirtyPrefs.js]
-[test_extprefs.js]
 [test_libPrefs.js]
 [test_bug1354613.js]
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/LoadInfo.h"
 
 #include "mozilla/Assertions.h"
+#include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozIThirdPartyUtil.h"
 #include "nsFrameLoader.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIFrameLoader.h"
@@ -63,16 +64,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   , mParentOuterWindowID(0)
   , mTopOuterWindowID(0)
   , mFrameOuterWindowID(0)
   , mEnforceSecurity(false)
   , mInitialSecurityCheckDone(false)
   , mIsThirdPartyContext(false)
   , mForcePreflight(false)
   , mIsPreflight(false)
+  , mLoadTriggeredFromExternal(false)
   , mForceHSTSPriming(false)
   , mMixedContentWouldBlock(false)
   , mIsHSTSPriming(false)
   , mIsHSTSPrimingUpgrade(false)
 {
   MOZ_ASSERT(mLoadingPrincipal);
   MOZ_ASSERT(mTriggeringPrincipal);
 
@@ -245,16 +247,17 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
   , mParentOuterWindowID(0)
   , mTopOuterWindowID(0)
   , mFrameOuterWindowID(0)
   , mEnforceSecurity(false)
   , mInitialSecurityCheckDone(false)
   , mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party.
   , mForcePreflight(false)
   , mIsPreflight(false)
+  , mLoadTriggeredFromExternal(false)
   , mForceHSTSPriming(false)
   , mMixedContentWouldBlock(false)
   , mIsHSTSPriming(false)
   , mIsHSTSPrimingUpgrade(false)
 {
   // Top-level loads are never third-party
   // Grab the information we can out of the window.
   MOZ_ASSERT(aOuterWindow);
@@ -319,16 +322,17 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
   , mRedirectChainIncludingInternalRedirects(
       rhs.mRedirectChainIncludingInternalRedirects)
   , mRedirectChain(rhs.mRedirectChain)
   , mAncestorPrincipals(rhs.mAncestorPrincipals)
   , mAncestorOuterWindowIDs(rhs.mAncestorOuterWindowIDs)
   , mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders)
   , mForcePreflight(rhs.mForcePreflight)
   , mIsPreflight(rhs.mIsPreflight)
+  , mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal)
   , mForceHSTSPriming(rhs.mForceHSTSPriming)
   , mMixedContentWouldBlock(rhs.mMixedContentWouldBlock)
   , mIsHSTSPriming(rhs.mIsHSTSPriming)
   , mIsHSTSPrimingUpgrade(rhs.mIsHSTSPrimingUpgrade)
 {
 }
 
 LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
@@ -354,16 +358,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
                    const OriginAttributes& aOriginAttributes,
                    RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
                    RedirectHistoryArray& aRedirectChain,
                    nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals,
                    const nsTArray<uint64_t>& aAncestorOuterWindowIDs,
                    const nsTArray<nsCString>& aCorsUnsafeHeaders,
                    bool aForcePreflight,
                    bool aIsPreflight,
+                   bool aLoadTriggeredFromExternal,
                    bool aForceHSTSPriming,
                    bool aMixedContentWouldBlock,
                    bool aIsHSTSPriming,
                    bool aIsHSTSPrimingUpgrade)
   : mLoadingPrincipal(aLoadingPrincipal)
   , mTriggeringPrincipal(aTriggeringPrincipal)
   , mPrincipalToInherit(aPrincipalToInherit)
   , mResultPrincipalURI(aResultPrincipalURI)
@@ -383,16 +388,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   , mInitialSecurityCheckDone(aInitialSecurityCheckDone)
   , mIsThirdPartyContext(aIsThirdPartyContext)
   , mOriginAttributes(aOriginAttributes)
   , mAncestorPrincipals(Move(aAncestorPrincipals))
   , mAncestorOuterWindowIDs(aAncestorOuterWindowIDs)
   , mCorsUnsafeHeaders(aCorsUnsafeHeaders)
   , mForcePreflight(aForcePreflight)
   , mIsPreflight(aIsPreflight)
+  , mLoadTriggeredFromExternal(aLoadTriggeredFromExternal)
   , mForceHSTSPriming (aForceHSTSPriming)
   , mMixedContentWouldBlock(aMixedContentWouldBlock)
   , mIsHSTSPriming(aIsHSTSPriming)
   , mIsHSTSPrimingUpgrade(aIsHSTSPrimingUpgrade)
 {
   // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
   MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
   MOZ_ASSERT(mTriggeringPrincipal);
@@ -497,16 +503,36 @@ LoadInfo::SetPrincipalToInherit(nsIPrinc
 }
 
 nsIPrincipal*
 LoadInfo::PrincipalToInherit()
 {
   return mPrincipalToInherit;
 }
 
+nsIPrincipal*
+LoadInfo::FindPrincipalToInherit(nsIChannel* aChannel)
+{
+  if (mPrincipalToInherit) {
+    return mPrincipalToInherit;
+  }
+
+  nsCOMPtr<nsIURI> uri = mResultPrincipalURI;
+  if (!uri) {
+    Unused << aChannel->GetOriginalURI(getter_AddRefs(uri));
+  }
+
+  bool dataInherits = mSecurityFlags & (SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS |
+                                        SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
+                                        SEC_REQUIRE_CORS_DATA_INHERITS);
+
+  auto prin = BasePrincipal::Cast(mTriggeringPrincipal);
+  return prin->PrincipalToInherit(uri, dataInherits);
+}
+
 NS_IMETHODIMP
 LoadInfo::GetSandboxedLoadingPrincipal(nsIPrincipal** aPrincipal)
 {
   if (!(mSecurityFlags & nsILoadInfo::SEC_SANDBOXED)) {
     *aPrincipal = nullptr;
     return NS_OK;
   }
 
@@ -978,16 +1004,33 @@ LoadInfo::SetUpgradeInsecureRequests()
 NS_IMETHODIMP
 LoadInfo::GetIsPreflight(bool* aIsPreflight)
 {
   *aIsPreflight = mIsPreflight;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+LoadInfo::SetLoadTriggeredFromExternal(bool aLoadTriggeredFromExternal)
+{
+  MOZ_ASSERT(!aLoadTriggeredFromExternal ||
+             mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
+             "can only set load triggered from external for TYPE_DOCUMENT");
+  mLoadTriggeredFromExternal = aLoadTriggeredFromExternal;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+LoadInfo::GetLoadTriggeredFromExternal(bool* aLoadTriggeredFromExternal)
+{
+  *aLoadTriggeredFromExternal = mLoadTriggeredFromExternal;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 LoadInfo::GetForceHSTSPriming(bool* aForceHSTSPriming)
 {
   *aForceHSTSPriming = mForceHSTSPriming;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LoadInfo::GetMixedContentWouldBlock(bool *aMixedContentWouldBlock)
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
@@ -115,16 +115,17 @@ private:
            const OriginAttributes& aOriginAttributes,
            RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
            RedirectHistoryArray& aRedirectChain,
            nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals,
            const nsTArray<uint64_t>& aAncestorOuterWindowIDs,
            const nsTArray<nsCString>& aUnsafeHeaders,
            bool aForcePreflight,
            bool aIsPreflight,
+           bool aLoadTriggeredFromExternal,
            bool aForceHSTSPriming,
            bool aMixedContentWouldBlock,
            bool aIsHSTSPriming,
            bool aIsHSTSPrimingUpgrade);
   LoadInfo(const LoadInfo& rhs);
 
   NS_IMETHOD GetRedirects(JSContext* aCx, JS::MutableHandle<JS::Value> aRedirects,
                           const RedirectHistoryArray& aArra);
@@ -170,16 +171,17 @@ private:
   OriginAttributes                 mOriginAttributes;
   RedirectHistoryArray             mRedirectChainIncludingInternalRedirects;
   RedirectHistoryArray             mRedirectChain;
   nsTArray<nsCOMPtr<nsIPrincipal>> mAncestorPrincipals;
   nsTArray<uint64_t>               mAncestorOuterWindowIDs;
   nsTArray<nsCString>              mCorsUnsafeHeaders;
   bool                             mForcePreflight;
   bool                             mIsPreflight;
+  bool                             mLoadTriggeredFromExternal;
 
   bool                             mForceHSTSPriming : 1;
   bool                             mMixedContentWouldBlock : 1;
   bool                             mIsHSTSPriming: 1;
   bool                             mIsHSTSPrimingUpgrade: 1;
 };
 
 } // namespace net
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -2,16 +2,17 @@
  * vim: ft=cpp tw=78 sw=2 et ts=2 sts=2 cin
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 #include "nsIContentPolicy.idl"
 
+interface nsIChannel;
 interface nsIDOMDocument;
 interface nsINode;
 interface nsIPrincipal;
 interface nsIRedirectHistoryEntry;
 interface nsIURI;
 %{C++
 #include "nsTArray.h"
 #include "mozilla/BasePrincipal.h"
@@ -295,16 +296,23 @@ interface nsILoadInfo : nsISupports
 
   /**
    * A C++-friendly version of principalToInherit.
    */
   [noscript, notxpcom, nostdcall, binaryname(PrincipalToInherit)]
   nsIPrincipal binaryPrincipalToInherit();
 
   /**
+   * Finds the correct principal to inherit for the given channel, based on
+   * the values of PrincipalToInherit and TriggeringPrincipal.
+   */
+  [noscript, notxpcom, nostdcall]
+  nsIPrincipal FindPrincipalToInherit(in nsIChannel aChannel);
+
+  /**
    * This is the ownerDocument of the LoadingNode. Unless the LoadingNode
    * is a Document, in which case the LoadingDocument is the same as the
    * LoadingNode.
    *
    * For top-level loads, and for loads originating from workers, the
    * LoadingDocument is null. When the LoadingDocument is not null, the
    * LoadingPrincipal is set to the principal of the LoadingDocument.
    */
@@ -594,16 +602,23 @@ interface nsILoadInfo : nsISupports
    * Please note, once the flag is set to true it must remain true
    * throughout the lifetime of the channel. Trying to set it
    * to anything else than true will be discarded.
    *
    */
   [infallible] attribute boolean initialSecurityCheckDone;
 
   /**
+   * Returns true if the load was triggered from an external application
+   * (e.g. Thunderbird). Please note that this flag will only ever be true
+   * if the load is of TYPE_DOCUMENT. 
+   */
+  [infallible] attribute boolean loadTriggeredFromExternal;
+
+  /**
    * Whenever a channel gets redirected, append the redirect history entry of
    * the channel which contains principal referrer and remote address [before
    * the channels got redirected] to the loadinfo, so that at every point this
    * array provides us information about all the redirects this channel went
    * through.
    * @param entry, the nsIRedirectHistoryEntry before the channel
    *         got redirected.
    * @param aIsInternalRedirect should be true if the channel is going
--- a/netwerk/cache2/CacheFileMetadata.cpp
+++ b/netwerk/cache2/CacheFileMetadata.cpp
@@ -258,18 +258,20 @@ CacheFileMetadata::WriteMetadata(uint32_
 
   mWriteBuf = static_cast<char *>(malloc(CalcMetadataSize(mElementsSize,
                                                           mHashCount)));
   if (!mWriteBuf) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   char *p = mWriteBuf + sizeof(uint32_t);
-  memcpy(p, mHashArray, mHashCount * sizeof(CacheHash::Hash16_t));
-  p += mHashCount * sizeof(CacheHash::Hash16_t);
+  if (mHashCount) {
+    memcpy(p, mHashArray, mHashCount * sizeof(CacheHash::Hash16_t));
+    p += mHashCount * sizeof(CacheHash::Hash16_t);
+  }
   mMetaHdr.WriteToBuf(p);
   p += sizeof(CacheFileMetadataHeader);
   memcpy(p, mKey.get(), mKey.Length());
   p += mKey.Length();
   *p = 0;
   p++;
   memcpy(p, mBuf, mElementsSize);
   p += mElementsSize;
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -65,16 +65,17 @@ struct LoadInfoArgs
    * See nsILoadInfo.idl for details.
    */
   PrincipalInfo[]             ancestorPrincipals;
   uint64_t[]                  ancestorOuterWindowIDs;
 
   nsCString[]                 corsUnsafeHeaders;
   bool                        forcePreflight;
   bool                        isPreflight;
+  bool                        loadTriggeredFromExternal;
   bool                        forceHSTSPriming;
   bool                        mixedContentWouldBlock;
   bool                        isHSTSPriming;
   bool                        isHSTSPrimingUpgrade;
 };
 
 /**
  * Not every channel necessarily has a loadInfo attached.
--- a/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
@@ -247,17 +247,17 @@ VS_PLATFORM_X86_64 = {
 # Note: In reality, the -std=gnu* options are only supported when preceded by
 # -Xclang.
 CLANG_CL_3_9 = (CLANG_BASE('3.9.0') + VS('18.00.00000') + DEFAULT_C11 +
                 SUPPORTS_GNU99 + SUPPORTS_GNUXX11 + SUPPORTS_CXX14) + {
     '*.cpp': {
         '__STDC_VERSION__': False,
         '__cplusplus': '201103L',
     },
-    '-fms-compatibility-version=19.00.24213': VS('19.00.24213')[None],
+    '-fms-compatibility-version=19.11.25547': VS('19.11.25547')[None],
 }
 
 CLANG_CL_PLATFORM_X86 = FakeCompiler(VS_PLATFORM_X86, GCC_PLATFORM_X86[None])
 CLANG_CL_PLATFORM_X86_64 = FakeCompiler(VS_PLATFORM_X86_64, GCC_PLATFORM_X86_64[None])
 
 LIBRARY_NAME_INFOS = {
     'linux-gnu': {
         'DLL_PREFIX': 'lib',
@@ -890,26 +890,26 @@ class WindowsToolchainTest(BaseToolchain
         flags=[],
         version='19.00.24213',
         type='msvc',
         compiler='/usr/bin/cl',
         language='C++',
     )
     CLANG_CL_3_9_RESULT = CompilerResult(
         flags=['-Xclang', '-std=gnu99',
-               '-fms-compatibility-version=19.00.24213'],
-        version='19.00.24213',
+               '-fms-compatibility-version=19.11.25547'],
+        version='19.11.25547',
         type='clang-cl',
         compiler='/usr/bin/clang-cl',
         language='C',
     )
     CLANGXX_CL_3_9_RESULT = CompilerResult(
         flags=['-Xclang', '-std=c++14',
-               '-fms-compatibility-version=19.00.24213'],
-        version='19.00.24213',
+               '-fms-compatibility-version=19.11.25547'],
+        version='19.11.25547',
         type='clang-cl',
         compiler='/usr/bin/clang-cl',
         language='C++',
     )
     CLANG_3_3_RESULT = LinuxToolchainTest.CLANG_3_3_RESULT
     CLANGXX_3_3_RESULT = LinuxToolchainTest.CLANGXX_3_3_RESULT
     CLANG_3_6_RESULT = LinuxToolchainTest.CLANG_3_6_RESULT
     CLANGXX_3_6_RESULT = LinuxToolchainTest.CLANGXX_3_6_RESULT
--- a/services/sync/tests/unit/head_helpers.js
+++ b/services/sync/tests/unit/head_helpers.js
@@ -57,30 +57,16 @@ XPCOMUtils.defineLazyGetter(this, "SyncP
 
 XPCOMUtils.defineLazyGetter(this, "SyncPingValidator", function() {
   let ns = {};
   Cu.import("resource://testing-common/ajv-4.1.1.js", ns);
   let ajv = new ns.Ajv({ async: "co*" });
   return ajv.compile(SyncPingSchema);
 });
 
-var provider = {
-  getFile(prop, persistent) {
-    persistent.value = true;
-    switch (prop) {
-      case "ExtPrefDL":
-        return [Services.dirsvc.get("CurProcD", Ci.nsIFile)];
-      default:
-        throw Cr.NS_ERROR_FAILURE;
-    }
-  },
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider])
-};
-Services.dirsvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
-
 // This is needed for loadAddonTestFunctions().
 var gGlobalScope = this;
 
 function ExtensionsTestPath(path) {
   if (path[0] != "/") {
     throw Error("Path must begin with '/': " + path);
   }
 
--- a/taskcluster/ci/build/windows.yml
+++ b/taskcluster/ci/build/windows.yml
@@ -416,17 +416,17 @@ win64-asan/debug:
     treeherder:
         platform: windows2012-64/asan
         symbol: tc(Bd)
         tier: 3
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
         max-run-time: 7200
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2015.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_win64_asan_debug.py
     run-on-projects: []
     toolchains:
         - win64-clang-cl
@@ -441,17 +441,17 @@ win64-asan/opt:
     treeherder:
         platform: windows2012-64/asan
         symbol: tc(Bo)
         tier: 3
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
         max-run-time: 7200
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2015.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_win64_asan_opt.py
     run-on-projects: []
     toolchains:
         - win64-clang-cl
--- a/taskcluster/ci/static-analysis/kind.yml
+++ b/taskcluster/ci/static-analysis/kind.yml
@@ -82,17 +82,17 @@ jobs:
         treeherder:
             platform: windows2012-32/debug
             symbol: tc(S)
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
             max-run-time: 7200
             env:
-                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/vs2015.manifest"
+                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/releng.manifest"
         run:
             using: mozharness
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/taskcluster_firefox_win32_clang_debug.py
         toolchains:
             - win32-clang-cl
             - win32-rust
@@ -106,17 +106,17 @@ jobs:
         treeherder:
             platform: windows2012-32/opt
             symbol: tc(S)
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
             max-run-time: 7200
             env:
-                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/vs2015.manifest"
+                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/releng.manifest"
         run:
             using: mozharness
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/taskcluster_firefox_win32_clang.py
         toolchains:
             - win32-clang-cl
             - win32-rust
@@ -130,17 +130,17 @@ jobs:
         treeherder:
             platform: windows2012-64/debug
             symbol: tc(S)
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
             max-run-time: 7200
             env:
-                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2015.manifest"
+                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
         run:
             using: mozharness
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/taskcluster_firefox_win64_clang_debug.py
         toolchains:
             - win64-clang-cl
             - win64-rust
@@ -154,17 +154,17 @@ jobs:
         treeherder:
             platform: windows2012-64/opt
             symbol: tc(S)
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
             max-run-time: 7200
             env:
-                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2015.manifest"
+                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
         run:
             using: mozharness
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/taskcluster_firefox_win64_clang.py
         toolchains:
             - win64-clang-cl
             - win64-rust
--- a/taskcluster/scripts/misc/build-clang-windows-helper32.sh
+++ b/taskcluster/scripts/misc/build-clang-windows-helper32.sh
@@ -11,30 +11,30 @@ TOOLTOOL_AUTH_FILE=/c/builds/relengapi.t
 if [ ! -e ${TOOLTOOL_AUTH_FILE} ]; then
     echo cannot find ${TOOLTOOL_AUTH_FILE}
     exit 1
 fi
 
 ./build/src/mach artifact toolchain -v --authentication-file="${TOOLTOOL_AUTH_FILE}" --tooltool-manifest "build/src/${TOOLTOOL_MANIFEST}"${TOOLTOOL_CACHE:+ --cache-dir ${TOOLTOOL_CACHE}}${MOZ_TOOLCHAINS:+ ${MOZ_TOOLCHAINS}}
 
 # Set up all the Visual Studio paths.
-MSVC_DIR=vs2015u3
+MSVC_DIR=vs2017_15.4.2
 VSWINPATH="$(cd ${MSVC_DIR} && pwd)"
 
 echo vswinpath ${VSWINPATH}
 
 export WINDOWSSDKDIR="${VSWINPATH}/SDK"
-export WIN32_REDIST_DIR="${VSWINPATH}/VC/redist/x86/Microsoft.VC140.CRT"
+export WIN32_REDIST_DIR="${VSWINPATH}/VC/redist/x86/Microsoft.VC141.CRT"
 export WIN_UCRT_REDIST_DIR="${VSWINPATH}/SDK/Redist/ucrt/DLLs/x86"
 
-export PATH="${VSWINPATH}/VC/bin/amd64_x86:${VSWINPATH}/VC/bin/amd64:${VSWINPATH}/VC/bin:${VSWINPATH}/SDK/bin/x86:${VSWINPATH}/SDK/bin/x64:${VSWINPATH}/DIA SDK/bin:${PATH}"
-export PATH="${VSWINPATH}/VC/redist/x86/Microsoft.VC140.CRT:${VSWINPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSWINPATH}/SDK/Redist/ucrt/DLLs/x86:${VSWINPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}"
+export PATH="${VSWINPATH}/VC/bin/Hostx64/x86:${VSWINPATH}/VC/bin/Hostx64/x64:${VSWINPATH}/SDK/bin/10.0.15063.0/x64:${VSWINPATH}/DIA SDK/bin:${PATH}"
+export PATH="${VSWINPATH}/VC/redist/x86/Microsoft.VC141.CRT:${VSWINPATH}/SDK/Redist/ucrt/DLLs/x86:${PATH}"
 
-export INCLUDE="${VSWINPATH}/VC/include:${VSWINPATH}/VC/atlmfc/include:${VSWINPATH}/SDK/Include/10.0.14393.0/ucrt:${VSWINPATH}/SDK/Include/10.0.14393.0/shared:${VSWINPATH}/SDK/Include/10.0.14393.0/um:${VSWINPATH}/SDK/Include/10.0.14393.0/winrt:${VSWINPATH}/DIA SDK/include"
-export LIB="${VSWINPATH}/VC/lib:${VSWINPATH}/VC/atlmfc/lib:${VSWINPATH}/SDK/lib/10.0.14393.0/ucrt/x86:${VSWINPATH}/SDK/lib/10.0.14393.0/um/x86:${VSWINPATH}/DIA SDK/lib"
+export INCLUDE="${VSWINPATH}/VC/include:${VSWINPATH}/VC/atlmfc/include:${VSWINPATH}/SDK/Include/10.0.15063.0/ucrt:${VSWINPATH}/SDK/Include/10.0.15063.0/shared:${VSWINPATH}/SDK/Include/10.0.15063.0/um:${VSWINPATH}/SDK/Include/10.0.15063.0/winrt:${VSWINPATH}/DIA SDK/include"
+export LIB="${VSWINPATH}/VC/lib/x86:${VSWINPATH}/VC/atlmfc/lib/x86:${VSWINPATH}/SDK/Lib/10.0.15063.0/ucrt/x86:${VSWINPATH}/SDK/Lib/10.0.15063.0/um/x86:${VSWINPATH}/DIA SDK/lib"
 
 export PATH="$(cd svn && pwd)/bin:${PATH}"
 export PATH="$(cd cmake && pwd)/bin:${PATH}"
 export PATH="$(cd ninja && pwd)/bin:${PATH}"
 
 # We use |mach python| to set up a virtualenv automatically for us.  We create
 # a dummy mozconfig, because the default machinery for config.guess-choosing
 # of the objdir doesn't work very well.
--- a/taskcluster/scripts/misc/build-clang-windows-helper64.sh
+++ b/taskcluster/scripts/misc/build-clang-windows-helper64.sh
@@ -11,29 +11,29 @@ TOOLTOOL_AUTH_FILE=/c/builds/relengapi.t
 if [ ! -e ${TOOLTOOL_AUTH_FILE} ]; then
     echo cannot find ${TOOLTOOL_AUTH_FILE}
     exit 1
 fi
 
 ./build/src/mach artifact toolchain -v --authentication-file="${TOOLTOOL_AUTH_FILE}" --tooltool-manifest "build/src/${TOOLTOOL_MANIFEST}"${TOOLTOOL_CACHE:+ --cache-dir ${TOOLTOOL_CACHE}}${MOZ_TOOLCHAINS:+ ${MOZ_TOOLCHAINS}}
 
 # Set up all the Visual Studio paths.
-MSVC_DIR=vs2015u3
+MSVC_DIR=vs2017_15.4.2
 VSWINPATH="$(cd ${MSVC_DIR} && pwd)"
 
 echo vswinpath ${VSWINPATH}
 
 export WINDOWSSDKDIR="${VSWINPATH}/SDK"
-export WIN32_REDIST_DIR="${VSWINPATH}/VC/redist/x64/Microsoft.VC140.CRT"
+export WIN32_REDIST_DIR="${VSWINPATH}/VC/redist/x64/Microsoft.VC141.CRT"
 export WIN_UCRT_REDIST_DIR="${VSWINPATH}/SDK/Redist/ucrt/DLLs/x64"
 
-export PATH="${VSWINPATH}/VC/bin/amd64:${VSWINPATH}/VC/bin:${VSWINPATH}/SDK/bin/x64:${VSWINPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSWINPATH}/SDK/Redist/ucrt/DLLs/x64:${VSWINPATH}/DIA SDK/bin/amd64:${PATH}"
+export PATH="${VSWINPATH}/VC/bin/Hostx64/x64:${VSWINPATH}/SDK/bin/10.0.15063.0/x64:${VSWINPATH}/VC/redist/x64/Microsoft.VC141.CRT:${VSWINPATH}/SDK/Redist/ucrt/DLLs/x64:${VSWINPATH}/DIA SDK/bin/amd64:${PATH}"
 
-export INCLUDE="${VSWINPATH}/VC/include:${VSWINPATH}/VC/atlmfc/include:${VSWINPATH}/SDK/Include/10.0.14393.0/ucrt:${VSWINPATH}/SDK/Include/10.0.14393.0/shared:${VSWINPATH}/SDK/Include/10.0.14393.0/um:${VSWINPATH}/SDK/Include/10.0.14393.0/winrt:${VSWINPATH}/DIA SDK/include"
-export LIB="${VSWINPATH}/VC/lib/amd64:${VSWINPATH}/VC/atlmfc/lib/amd64:${VSWINPATH}/SDK/lib/10.0.14393.0/ucrt/x64:${VSWINPATH}/SDK/lib/10.0.14393.0/um/x64:${VSWINPATH}/DIA SDK/lib/amd64"
+export INCLUDE="${VSWINPATH}/VC/include:${VSWINPATH}/VC/atlmfc/include:${VSWINPATH}/SDK/Include/10.0.15063.0/ucrt:${VSWINPATH}/SDK/Include/10.0.15063.0/shared:${VSWINPATH}/SDK/Include/10.0.15063.0/um:${VSWINPATH}/SDK/Include/10.0.15063.0/winrt:${VSWINPATH}/DIA SDK/include"
+export LIB="${VSWINPATH}/VC/lib/x64:${VSWINPATH}/VC/atlmfc/lib/x64:${VSWINPATH}/SDK/Lib/10.0.15063.0/ucrt/x64:${VSWINPATH}/SDK/Lib/10.0.15063.0/um/x64:${VSWINPATH}/DIA SDK/lib/amd64"
 
 export PATH="$(cd svn && pwd)/bin:${PATH}"
 export PATH="$(cd cmake && pwd)/bin:${PATH}"
 export PATH="$(cd ninja && pwd)/bin:${PATH}"
 
 # We use |mach python| to set up a virtualenv automatically for us.  We create
 # a dummy mozconfig, because the default machinery for config.guess-choosing
 # of the objdir doesn't work very well.
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -2647,17 +2647,23 @@ toolbar#nav-bar {
                 os.remove(self.leak_report_file)
 
             # then again to actually run mochitest
             if options.timeout:
                 timeout = options.timeout + 30
             elif options.debugger or not options.autorun:
                 timeout = None
             else:
-                timeout = 330.0  # default JS harness timeout is 300 seconds
+                # We generally want the JS harness or marionette to handle
+                # timeouts if they can.
+                # The default JS harness timeout is currently 300 seconds.
+                # The default Marionette socket timeout is currently 360 seconds.
+                # Wait a little (10 seconds) more before timing out here.
+                # See bug 479518 and bug 1414063.
+                timeout = 370.0
 
             # Detect shutdown leaks for m-bc runs if
             # code coverage is not enabled.
             detectShutdownLeaks = False
             if options.jscov_dir_prefix is None:
                 detectShutdownLeaks = mozinfo.info[
                     "debug"] and options.flavor == 'browser'
 
--- a/testing/mochitest/tests/SimpleTest/TestRunner.js
+++ b/testing/mochitest/tests/SimpleTest/TestRunner.js
@@ -83,17 +83,17 @@ TestRunner._lastTestFinished = -1;
 TestRunner._loopIsRestarting = false;
 TestRunner.currentTestURL = "";
 TestRunner.originalTestURL = "";
 TestRunner._urls = [];
 TestRunner._lastAssertionCount = 0;
 TestRunner._expectedMinAsserts = 0;
 TestRunner._expectedMaxAsserts = 0;
 
-TestRunner.timeout = 5 * 60 * 1000; // 5 minutes.
+TestRunner.timeout = 300 * 1000; // 5 minutes.
 TestRunner.maxTimeouts = 4; // halt testing after too many timeouts
 TestRunner.runSlower = false;
 TestRunner.dumpOutputDirectory = "";
 TestRunner.dumpAboutMemoryAfterTest = false;
 TestRunner.dumpDMDAfterTest = false;
 TestRunner.slowestTestTime = 0;
 TestRunner.slowestTestURL = "";
 TestRunner.interactiveDebugger = false;
--- a/toolkit/components/crashes/CrashService.js
+++ b/toolkit/components/crashes/CrashService.js
@@ -59,16 +59,20 @@ function runMinidumpAnalyzer(minidumpPat
       }
 
       process.runAsync(args, args.length, (subject, topic, data) => {
         switch (topic) {
           case "process-finished":
             gRunningProcesses.delete(process);
             resolve();
             break;
+          case "process-failed":
+            gRunningProcesses.delete(process);
+            reject();
+            break;
           default:
             reject(new Error("Unexpected topic received " + topic));
             break;
         }
       });
 
       gRunningProcesses.add(process);
     } catch (e) {
@@ -126,17 +130,19 @@ function processExtraFile(extraPath) {
       let extraData = await OS.File.read(extraPath);
       let keyValuePairs = parseKeyValuePairs(decoder.decode(extraData));
 
       // When reading from an .extra file literal '\\n' sequences are
       // automatically unescaped to two backslashes plus a newline, so we need
       // to re-escape them into '\\n' again so that the fields holding JSON
       // strings are valid.
       [ "TelemetryEnvironment", "StackTraces" ].forEach(field => {
-        keyValuePairs[field] = keyValuePairs[field].replace(/\n/g, "n");
+        if (field in keyValuePairs) {
+          keyValuePairs[field] = keyValuePairs[field].replace(/\n/g, "n");
+        }
       });
 
       return keyValuePairs;
     } catch (e) {
       Cu.reportError(e);
       return {};
     }
   })();
@@ -229,17 +235,22 @@ CrashService.prototype = Object.freeze({
     switch (topic) {
       case "profile-after-change":
         // Side-effect is the singleton is instantiated.
         Services.crashmanager;
         break;
       case "quit-application":
         gQuitting = true;
         gRunningProcesses.forEach((process) => {
-          process.kill();
+          try {
+            process.kill();
+          } catch (e) {
+            // If the process has already quit then kill() fails, but since
+            // this failure is benign it is safe to silently ignore it.
+          }
           Services.obs.notifyObservers(null, "test-minidump-analyzer-killed");
         });
         break;
     }
   },
 });
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([CrashService]);
--- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
@@ -259,16 +259,31 @@ function toHTML(test, opts) {
 function injectElements(tests, baseOpts) {
   window.addEventListener("load", () => {
     // Basic smoke test to check that SVG images do not try to create a document
     // with an expanded principal, which would cause a crash.
     let img = document.createElement("img");
     img.src = "data:image/svg+xml,%3Csvg%2F%3E";
     document.body.appendChild(img);
 
+    let rand = Math.random();
+
+    // Basic smoke test to check that we don't try to create stylesheets with an
+    // expanded principal, which would cause a crash when loading font sets.
+    let link = document.createElement("link");
+    link.rel = "stylesheet";
+    link.href = "data:text/css;base64," + btoa(`
+      @font-face {
+          font-family: "DoesNotExist${rand}";
+          src: url("fonts/DoesNotExist.${rand}.woff") format("woff");
+          font-weight: normal;
+          font-style: normal;
+      }`);
+    document.head.appendChild(link);
+
     let overrideOpts = opts => Object.assign({}, baseOpts, opts);
     let opts = baseOpts;
 
     // Build the full element with setAttr, then inject.
     for (let test of tests) {
       let {elem, srcElem, src} = createElement(test, opts);
       srcElem.setAttribute(test.srcAttr, src);
       document.body.appendChild(elem);
--- a/toolkit/components/telemetry/docs/data/main-ping.rst
+++ b/toolkit/components/telemetry/docs/data/main-ping.rst
@@ -183,19 +183,21 @@ js
 ~~
 This section contains a series of counters from the JavaScript engine.
 
 Structure:
 
 .. code-block:: js
 
     "js" : {
-      "setProto": <unsigned integer>, // Number of times __proto__ is set
+      // ...
     }
 
+As of Firefox 59 this section no longer contains any entries.
+
 maximalNumberOfConcurrentThreads
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 An integer representing the highest number of threads encountered so far during the session.
 
 startupSessionRestoreReadBytes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Windows-only integer representing the number of bytes read by the main process up until the session store has finished restoring the windows.
 
--- a/toolkit/components/terminator/nsTerminator.cpp
+++ b/toolkit/components/terminator/nsTerminator.cpp
@@ -223,17 +223,18 @@ void RunWriter(void* arg)
   NS_SetCurrentThreadName("Shutdown Statistics Writer");
 
   MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(arg);
   // Shutdown will generally complete before we have a chance to
   // deallocate. This is not a leak.
 
   // Setup destinationPath and tmpFilePath
 
-  nsCString destinationPath(static_cast<char*>(arg));
+  nsCString destinationPath;
+  destinationPath.Adopt(static_cast<char*>(arg));
   nsAutoCString tmpFilePath;
   tmpFilePath.Append(destinationPath);
   tmpFilePath.AppendLiteral(".tmp");
 
   // Cleanup any file leftover from a previous run
   Unused << PR_Delete(tmpFilePath.get());
   Unused << PR_Delete(destinationPath.get());
 
@@ -356,22 +357,22 @@ nsTerminator::SelfInit()
 }
 
 // Actually launch these threads. This takes place at the first sign of shutdown.
 void
 nsTerminator::Start()
 {
   MOZ_ASSERT(!mInitialized);
   StartWatchdog();
-#if !defined(DEBUG)
-  // Only allow nsTerminator to write on non-debug builds so we don't get leak warnings on
-  // shutdown for intentional leaks (see bug 1242084). This will be enabled again by bug
-  // 1255484 when 1255478 lands.
+#if !defined(NS_FREE_PERMANENT_DATA)
+  // Only allow nsTerminator to write on non-leak-checked builds so we don't
+  // get leak warnings on shutdown for intentional leaks (see bug 1242084).
+  // This will be enabled again by bug 1255484 when 1255478 lands.
   StartWriter();
-#endif // !defined(DEBUG)
+#endif // !defined(NS_FREE_PERMANENT_DATA)
   mInitialized = true;
 }
 
 // Prepare, allocate and start the watchdog thread.
 // By design, it will never finish, nor be deallocated.
 void
 nsTerminator::StartWatchdog()
 {
--- a/toolkit/content/widgets/datetimebox.xml
+++ b/toolkit/content/widgets/datetimebox.xml
@@ -1239,27 +1239,27 @@
         // includes padding area).
         this.mInputElement.addEventListener("click", this,
                                             { mozSystemGroup: true });
       ]]>
       </constructor>
 
       <destructor>
       <![CDATA[
-        this.mInputElement = null;
-
         this.EVENTS.forEach((eventName) => {
           this.removeEventListener(eventName, this, { mozSystemGroup: true });
         });
         this.removeEventListener("keypress", this, {
           capture: true,
           mozSystemGroup: true
         });
         this.mInputElement.removeEventListener("click", this,
                                                { mozSystemGroup: true });
+
+        this.mInputElement = null;
       ]]>
       </destructor>
 
       <property name="EVENTS" readonly="true">
         <getter>
         <![CDATA[
           return ["focus", "blur", "copy", "cut", "paste", "mousedown"];
         ]]>
--- a/toolkit/content/widgets/general.xml
+++ b/toolkit/content/widgets/general.xml
@@ -149,24 +149,16 @@
   <binding id="statusbarpanel-iconic-text" display="xul:button" role="xul:button"
            extends="chrome://global/content/bindings/general.xml#statusbarpanel">
     <content>
       <xul:image class="statusbarpanel-icon" xbl:inherits="src,src=image"/>
       <xul:label class="statusbarpanel-text" xbl:inherits="value=label,crop"/>
     </content>
   </binding>
 
-  <binding id="image" role="xul:image">
-    <implementation implements="nsIDOMXULImageElement">
-      <property name="src"
-                onget="return this.getAttribute('src');"
-                onset="this.setAttribute('src',val); return val;"/>
-    </implementation>
-  </binding>
-
   <binding id="deck">
     <implementation>
       <property name="selectedIndex"
                 onget="return this.getAttribute('selectedIndex') || '0'">
         <setter>
         <![CDATA[
           if (this.selectedIndex == val)
             return val;
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -208,22 +208,16 @@ notification.animated {
 popupnotification {
   -moz-binding: url("chrome://global/content/bindings/notification.xml#popup-notification");
 }
 
 .popup-notification-menubutton:not([label]) {
   display: none;
 }
 
-/********** image **********/
-
-image {
-  -moz-binding: url("chrome://global/content/bindings/general.xml#image");
-}
-
 /********** checkbox **********/
 
 checkbox {
   -moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox");
 }
 
 /********** radio **********/
 
--- a/toolkit/modules/DeferredTask.jsm
+++ b/toolkit/modules/DeferredTask.jsm
@@ -113,20 +113,16 @@ const Timer = Components.Constructor("@m
  *        The maximum time to wait for an idle slot on the main thread after
  *        aDelayMs have elapsed. If omitted, waits indefinitely for an idle
  *        callback.
  */
 this.DeferredTask = function(aTaskFn, aDelayMs, aIdleTimeoutMs) {
   this._taskFn = aTaskFn;
   this._delayMs = aDelayMs;
   this._timeoutMs = aIdleTimeoutMs;
-
-  if (aTaskFn.isGenerator()) {
-    Cu.reportError(new Error("Unexpected generator function passed to DeferredTask"));
-  }
 };
 
 this.DeferredTask.prototype = {
   /**
    * Function or generator function to execute.
    */
   _taskFn: null,
 
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -885,34 +885,16 @@ nsXREDirProvider::GetFilesInternal(const
     nsCOMArray<nsIFile> directories;
 
     LoadDirIntoArray(mXULAppDir, kAppendPrefDir, directories);
     LoadDirsIntoArray(mAppBundleDirectories,
                       kAppendPrefDir, directories);
 
     rv = NS_NewArrayEnumerator(aResult, directories);
   }
-  else if (!strcmp(aProperty, NS_EXT_PREFS_DEFAULTS_DIR_LIST)) {
-    nsCOMArray<nsIFile> directories;
-
-    LoadDirsIntoArray(AddonManagerStartup::GetSingleton().ExtensionPaths(),
-                      kAppendPrefDir, directories);
-
-    if (mProfileDir) {
-      nsCOMPtr<nsIFile> overrideFile;
-      mProfileDir->Clone(getter_AddRefs(overrideFile));
-      overrideFile->AppendNative(NS_LITERAL_CSTRING(PREF_OVERRIDE_DIRNAME));
-
-      bool exists;
-      if (NS_SUCCEEDED(overrideFile->Exists(&exists)) && exists)
-        directories.AppendObject(overrideFile);
-    }
-
-    rv = NS_NewArrayEnumerator(aResult, directories);
-  }
   else if (!strcmp(aProperty, NS_APP_CHROME_DIR_LIST)) {
     // NS_APP_CHROME_DIR_LIST is only used to get default (native) icons
     // for OS window decoration.
 
     static const char *const kAppendChromeDir[] = { "chrome", nullptr };
     nsCOMArray<nsIFile> directories;
     LoadDirIntoArray(mXULAppDir,
                      kAppendChromeDir,
@@ -1030,17 +1012,16 @@ nsXREDirProvider::DoStartup()
     // Init the Extension Manager
     nsCOMPtr<nsIObserver> em = do_GetService("@mozilla.org/addons/integration;1");
     if (em) {
       em->Observe(nullptr, "addons-startup", nullptr);
     } else {
       NS_WARNING("Failed to create Addons Manager.");
     }
 
-    obsSvc->NotifyObservers(nullptr, "load-extension-defaults", nullptr);
     obsSvc->NotifyObservers(nullptr, "profile-after-change", kStartup);
 
     // Any component that has registered for the profile-after-change category
     // should also be created at this time.
     (void)NS_CreateServicesFromCategory("profile-after-change", nullptr,
                                         "profile-after-change");
 
     if (gSafeMode && safeModeNecessary) {
--- a/uriloader/exthandler/moz.build
+++ b/uriloader/exthandler/moz.build
@@ -124,16 +124,17 @@ IPDL_SOURCES += [
     'PHandlerService.ipdl',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
+    '/docshell/base',
     '/dom/base',
     '/dom/ipc',
     '/netwerk/base',
     '/netwerk/protocol/http',
 ]
 
 if CONFIG['MOZ_ENABLE_DBUS']:
     CXXFLAGS += CONFIG['TK_CFLAGS']
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -51,16 +51,17 @@
 #include "nsIDocumentLoader.h" // XXX needed to get orig. channel and assoc. refresh uri
 #include "nsIHelperAppLauncherDialog.h"
 #include "nsIContentDispatchChooser.h"
 #include "nsNetUtil.h"
 #include "nsIPrivateBrowsingChannel.h"
 #include "nsIIOService.h"
 #include "nsNetCID.h"
 
+#include "nsDSURIContentListener.h"
 #include "nsMimeTypes.h"
 // used for header disposition information.
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIEncodedChannel.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIFileChannel.h"
 #include "nsIObserverService.h" // so we can be a profile change observer
@@ -1188,36 +1189,33 @@ NS_IMPL_ADDREF(nsExternalAppHandler)
 NS_IMPL_RELEASE(nsExternalAppHandler)
 
 NS_INTERFACE_MAP_BEGIN(nsExternalAppHandler)
    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener)
    NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
    NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
    NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher)
    NS_INTERFACE_MAP_ENTRY(nsICancelable)
-   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
    NS_INTERFACE_MAP_ENTRY(nsIBackgroundFileSaverObserver)
    NS_INTERFACE_MAP_ENTRY(nsINamed)
 NS_INTERFACE_MAP_END_THREADSAFE
 
 nsExternalAppHandler::nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo,
                                            const nsACString& aTempFileExtension,
                                            nsIInterfaceRequestor* aContentContext,
                                            nsIInterfaceRequestor* aWindowContext,
                                            nsExternalHelperAppService *aExtProtSvc,
                                            const nsAString& aSuggestedFilename,
                                            uint32_t aReason, bool aForceSave)
 : mMimeInfo(aMIMEInfo)
 , mContentContext(aContentContext)
 , mWindowContext(aWindowContext)
-, mWindowToClose(nullptr)
 , mSuggestedFileName(aSuggestedFilename)
 , mForceSave(aForceSave)
 , mCanceled(false)
-, mShouldCloseWindow(false)
 , mStopRequestIssued(false)
 , mReason(aReason)
 , mContentLength(-1)
 , mProgress(0)
 , mSaver(nullptr)
 , mDialogProgressListener(nullptr)
 , mTransfer(nullptr)
 , mRequest(nullptr)
@@ -1583,23 +1581,25 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
     mIsFileChannel = parent && parent->WasFileChannel();
   }
 
   // Get content length
   if (aChannel) {
     aChannel->GetContentLength(&mContentLength);
   }
 
+  mMaybeCloseWindowHelper = new MaybeCloseWindowHelper(mContentContext);
+
   nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(request, &rv));
   // Determine whether a new window was opened specifically for this request
   if (props) {
     bool tmp = false;
     props->GetPropertyAsBool(NS_LITERAL_STRING("docshell.newWindowTarget"),
                              &tmp);
-    mShouldCloseWindow = tmp;
+    mMaybeCloseWindowHelper->SetShouldCloseWindow(tmp);
   }
 
   // Now get the URI
   if (aChannel) {
     aChannel->GetURI(getter_AddRefs(mSourceUrl));
   }
 
   // retarget all load notifications to our docloader instead of the original window's docloader...
@@ -1608,24 +1608,24 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
   // Check to see if there is a refresh header on the original channel.
   if (mOriginalChannel) {
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mOriginalChannel));
     if (httpChannel) {
       nsAutoCString refreshHeader;
       Unused << httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("refresh"),
                                                refreshHeader);
       if (!refreshHeader.IsEmpty()) {
-        mShouldCloseWindow = false;
+        mMaybeCloseWindowHelper->SetShouldCloseWindow(false);
       }
     }
   }
 
   // Close the underlying DOMWindow if there is no refresh header
   // and it was opened specifically for the download
-  MaybeCloseWindow();
+  mContentContext = mMaybeCloseWindowHelper->MaybeCloseWindow();
 
   // In an IPC setting, we're allowing the child process, here, to make
   // decisions about decoding the channel (e.g. decompression).  It will
   // still forward the decoded (uncompressed) data back to the parent.
   // Con: Uncompressed data means more IPC overhead.
   // Pros: ExternalHelperAppParent doesn't need to implement nsIEncodedChannel.
   //       Parent process doesn't need to expect CPU time on decompression.
   MaybeApplyDecodingForExtension(aChannel);
@@ -2518,52 +2518,16 @@ bool nsExternalAppHandler::GetNeverAskFl
   NS_UnescapeURL(prefCString);
   nsACString::const_iterator start, end;
   prefCString.BeginReading(start);
   prefCString.EndReading(end);
   return !CaseInsensitiveFindInReadable(nsDependentCString(aContentType),
                                         start, end);
 }
 
-nsresult nsExternalAppHandler::MaybeCloseWindow()
-{
-  nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(mContentContext);
-  NS_ENSURE_STATE(window);
-
-  if (mShouldCloseWindow) {
-    // Reset the window context to the opener window so that the dependent
-    // dialogs have a parent
-    nsCOMPtr<nsPIDOMWindowOuter> opener = window->GetOpener();
-
-    if (opener && !opener->Closed()) {
-      mContentContext = do_GetInterface(opener);
-
-      // Now close the old window.  Do it on a timer so that we don't run
-      // into issues trying to close the window before it has fully opened.
-      NS_ASSERTION(!mTimer, "mTimer was already initialized once!");
-      MOZ_TRY_VAR(mTimer, NS_NewTimerWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT));
-      mWindowToClose = window;
-    }
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsExternalAppHandler::Notify(nsITimer* timer)
-{
-  NS_ASSERTION(mWindowToClose, "No window to close after timer fired");
-
-  mWindowToClose->Close();
-  mWindowToClose = nullptr;
-  mTimer = nullptr;
-
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsExternalAppHandler::GetName(nsACString& aName)
 {
   aName.AssignLiteral("nsExternalAppHandler");
   return NS_OK;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -20,32 +20,31 @@
 #include "nsIStreamListener.h"
 #include "nsIFile.h"
 #include "nsIFileStreams.h"
 #include "nsIOutputStream.h"
 #include "nsString.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIChannel.h"
-#include "nsITimer.h"
 #include "nsIBackgroundFileSaver.h"
 
 #include "nsIHandlerService.h"
 #include "nsCOMPtr.h"
 #include "nsIObserver.h"
 #include "nsCOMArray.h"
 #include "nsWeakReference.h"
 #include "nsIPrompt.h"
 #include "nsAutoPtr.h"
 #include "mozilla/Attributes.h"
 
 class nsExternalAppHandler;
 class nsIMIMEInfo;
 class nsITransfer;
-class nsPIDOMWindowOuter;
+class MaybeCloseWindowHelper;
 
 /**
  * The helper app service. Responsible for handling content that Mozilla
  * itself can not handle
  */
 class nsExternalHelperAppService
 : public nsIExternalHelperAppService,
   public nsPIExternalAppLauncher,
@@ -206,27 +205,25 @@ private:
  * a nsIStreamListener. It saves the incoming data into a temp file. The handler
  * is bound to an application when it is created. When it receives an
  * OnStopRequest it launches the application using the temp file it has
  * stored the data into.  We create a handler every time we have to process
  * data using a helper app.
  */
 class nsExternalAppHandler final : public nsIStreamListener,
                                    public nsIHelperAppLauncher,
-                                   public nsITimerCallback,
                                    public nsIBackgroundFileSaverObserver,
                                    public nsINamed
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSIHELPERAPPLAUNCHER
   NS_DECL_NSICANCELABLE
-  NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIBACKGROUNDFILESAVEROBSERVER
   NS_DECL_NSINAMED
 
   /**
    * @param aMIMEInfo       MIMEInfo object, representing the type of the
    *                        content that should be handled
    * @param aFileExtension  The extension we need to append to our temp file,
    *                        INCLUDING the ".". e.g. .mp3
@@ -292,18 +289,17 @@ protected:
    * should use in parenting. If null, we use mContentContext.
    */
   nsCOMPtr<nsIInterfaceRequestor> mWindowContext;
 
   /**
    * Used to close the window on a timer, to avoid any exceptions that are
    * thrown if we try to close the window before it's fully loaded.
    */
-  nsCOMPtr<nsPIDOMWindowOuter> mWindowToClose;
-  nsCOMPtr<nsITimer> mTimer;
+  RefPtr<MaybeCloseWindowHelper> mMaybeCloseWindowHelper;
 
   /**
    * The following field is set if we were processing an http channel that had
    * a content disposition header which specified the SUGGESTED file name we
    * should present to the user in the save to disk dialog. 
    */
   nsString mSuggestedFileName;
 
@@ -316,23 +312,16 @@ protected:
   
   /**
    * The canceled flag is set if the user canceled the launching of this
    * application before we finished saving the data to a temp file.
    */
   bool mCanceled;
 
   /**
-   * This is set based on whether the channel indicates that a new window
-   * was opened specifically for this download.  If so, then we
-   * close it.
-   */
-  bool mShouldCloseWindow;
-
-  /**
    * True if a stop request has been issued.
    */
   bool mStopRequestIssued; 
 
   bool mIsFileChannel;
 
   /**
    * One of the REASON_ constants from nsIHelperAppLauncherDialog. Indicates the
@@ -465,23 +454,16 @@ protected:
 
   typedef enum { kReadError, kWriteError, kLaunchError } ErrorType;
   /**
    * Utility function to send proper error notification to web progress listener
    */
   void SendStatusChange(ErrorType type, nsresult aStatus, nsIRequest *aRequest, const nsString& path);
 
   /**
-   * Closes the window context if it does not have a refresh header
-   * and it never displayed content before the external helper app
-   * service was invoked.
-   */
-  nsresult MaybeCloseWindow();
-
-  /**
    * Set in nsHelperDlgApp.js. This is always null after the user has chosen an
    * action.
    */
   nsCOMPtr<nsIWebProgressListener2> mDialogProgressListener;
   /**
    * Set once the user has chosen an action. This is null after the download
    * has been canceled or completes.
    */
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -607,17 +607,17 @@ PuppetWidget::GetLayerManager(PLayerTran
   return mLayerManager;
 }
 
 bool
 PuppetWidget::CreateRemoteLayerManager(const std::function<bool(LayerManager*)>& aInitializeFunc)
 {
   RefPtr<LayerManager> lm;
   MOZ_ASSERT(mTabChild);
-  if (gfxVars::UseWebRender()) {
+  if (mTabChild->GetCompositorOptions().UseWebRender()) {
     lm = new WebRenderLayerManager(this);
   } else {
     lm = new ClientLayerManager(this);
   }
 
   if (!aInitializeFunc(lm)) {
     return false;
   }
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1250,21 +1250,20 @@ nsBaseWidget::CreateCompositorSession(in
                                       int aHeight,
                                       CompositorOptions* aOptionsOut)
 {
   MOZ_ASSERT(aOptionsOut);
 
   do {
     CreateCompositorVsyncDispatcher();
 
-    bool enableWR = gfx::gfxVars::UseWebRender();
-    if (enableWR && !WidgetTypeSupportsAcceleration()) {
-      // fall back to basic
-      break;
-    }
+    // If widget type does not supports acceleration, we use ClientLayerManager
+    // even when gfxVars::UseWebRender() is true. WebRender could coexist only
+    // with BasicCompositor.
+    bool enableWR = gfx::gfxVars::UseWebRender() && WidgetTypeSupportsAcceleration();
     bool enableAPZ = UseAPZ();
     CompositorOptions options(enableAPZ, enableWR);
 
     bool enableAL = gfx::gfxConfig::IsEnabled(gfx::Feature::ADVANCED_LAYERS);
     options.SetUseAdvancedLayers(enableAL);
 
     RefPtr<LayerManager> lm;
     if (options.UseWebRender()) {
@@ -1298,18 +1297,16 @@ nsBaseWidget::CreateCompositorSession(in
 
     // We need to retry in a loop because the act of failing to create the
     // compositor can change our state (e.g. disable WebRender).
     if (mCompositorSession || !retry) {
       *aOptionsOut = options;
       return lm.forget();
     }
   } while (true);
-
-  return nullptr;
 }
 
 void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
 {
   // This makes sure that gfxPlatforms gets initialized if it hasn't by now.
   gfxPlatform::GetPlatform();
 
   MOZ_ASSERT(gfxPlatform::UsesOffMainThreadCompositing(),
--- a/xpcom/io/nsAppDirectoryServiceDefs.h
+++ b/xpcom/io/nsAppDirectoryServiceDefs.h
@@ -55,17 +55,16 @@
 // other users of the profile. Without this prefix, the consumer
 // has exclusive access to this location.
 
 #define NS_SHARED                               "SHARED"
 
 #define NS_APP_PREFS_50_DIR                     "PrefD"         // Directory which contains user prefs
 #define NS_APP_PREFS_50_FILE                    "PrefF"
 #define NS_APP_PREFS_DEFAULTS_DIR_LIST          "PrefDL"
-#define NS_EXT_PREFS_DEFAULTS_DIR_LIST          "ExtPrefDL"
 #define NS_APP_PREFS_OVERRIDE_DIR               "PrefDOverride" // Directory for per-profile defaults
 
 #define NS_APP_USER_PROFILE_50_DIR              "ProfD"
 #define NS_APP_USER_PROFILE_LOCAL_50_DIR        "ProfLD"
 
 #define NS_APP_USER_CHROME_DIR                  "UChrm"
 #define NS_APP_USER_SEARCH_DIR                  "UsrSrchPlugns"