Merge mozilla-central to autoland
authorIris Hsiao <ihsiao@mozilla.com>
Mon, 08 May 2017 11:19:04 +0800
changeset 356987 4c79f09831e75cabc6837dd391184b7a9932df24
parent 356986 35f1edbebb525881adf1533cc747dcf44c1868bd (current diff)
parent 356967 c3e5497cff1c995821b1c9320fa71f1ef9a8c30e (diff)
child 356988 81977c96c6ff49e4b70f88a55f38d47f5e54a08b
push id31777
push usercbook@mozilla.com
push dateMon, 08 May 2017 08:04:08 +0000
treeherdermozilla-central@81977c96c6ff [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland
browser/base/content/browser.js
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
image/ImageBlocker.cpp
image/ImageBlocker.h
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1357107 - Removing a directory from extensions/ requires re-running configure to update MOZ_EXTENSIONS
+Bug 1356927 - Mac builds in automation require a clobber for a change in which ranlib they use
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1022,17 +1022,17 @@ pref("security.sandbox.content.level", 1
 pref("security.sandbox.windows.log.stackTraceDepth", 0);
 #endif
 
 // This controls the strength of the Windows GPU process sandbox.  Changes
 // will require restart.
 // For information on what the level number means, see
 // SetSecurityLevelForGPUProcess() in
 // security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
-pref("security.sandbox.gpu.level", 1);
+pref("security.sandbox.gpu.level", 0);
 #endif
 
 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
 // This pref is discussed in bug 1083344, the naming is inspired from its
 // Windows counterpart, but on Mac it's an integer which means:
 // 0 -> "no sandbox"
 // 1 -> "preliminary content sandboxing enabled: write access to
 //       home directory is prevented"
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -322,49 +322,49 @@ toolbarpaletteitem:-moz-any([place="pale
 }
 
 toolbarpaletteitem > toolbaritem[sdkstylewidget="true"][cui-areatype="toolbar"] > .toolbarbutton-text {
   display: -moz-box;
 }
 
 @media not all and (min-resolution: 1.1dppx) {
   .webextension-browser-action {
-    list-style-image: var(--webextension-toolbar-image);
+    list-style-image: var(--webextension-toolbar-image, inherit);
   }
 
   .webextension-browser-action[cui-areatype="menu-panel"],
   toolbarpaletteitem[place="palette"] > .webextension-browser-action {
-    list-style-image: var(--webextension-menupanel-image);
+    list-style-image: var(--webextension-menupanel-image, inherit);
   }
 
   .webextension-page-action {
-    list-style-image: var(--webextension-urlbar-image);
+    list-style-image: var(--webextension-urlbar-image, inherit);
   }
 
   .webextension-menuitem {
-    list-style-image: var(--webextension-menuitem-image);
+    list-style-image: var(--webextension-menuitem-image, inherit);
   }
 }
 
 @media (min-resolution: 1.1dppx) {
   .webextension-browser-action {
-    list-style-image: var(--webextension-toolbar-image-2x);
+    list-style-image: var(--webextension-toolbar-image-2x, inherit);
   }
 
   .webextension-browser-action[cui-areatype="menu-panel"],
   toolbarpaletteitem[place="palette"] > .webextension-browser-action {
-    list-style-image: var(--webextension-menupanel-image-2x);
+    list-style-image: var(--webextension-menupanel-image-2x, inherit);
   }
 
   .webextension-page-action {
-    list-style-image: var(--webextension-urlbar-image-2x);
+    list-style-image: var(--webextension-urlbar-image-2x, inherit);
   }
 
   .webextension-menuitem {
-    list-style-image: var(--webextension-menuitem-image-2x);
+    list-style-image: var(--webextension-menuitem-image-2x, inherit);
   }
 }
 
 toolbarbutton.webextension-menuitem > .toolbarbutton-icon {
   width: 16px;
   height: 16px;
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3484,20 +3484,17 @@ function getPEMString(cert) {
 var PrintPreviewListener = {
   _printPreviewTab: null,
   _simplifiedPrintPreviewTab: null,
   _tabBeforePrintPreview: null,
   _simplifyPageTab: null,
   _lastRequestedPrintPreviewTab: null,
 
   _createPPBrowser() {
-    if (!this._tabBeforePrintPreview) {
-      this._tabBeforePrintPreview = gBrowser.selectedTab;
-    }
-    let browser = this._tabBeforePrintPreview.linkedBrowser;
+    let browser = this.getSourceBrowser();
     let preferredRemoteType = browser.remoteType;
     return gBrowser.loadOneTab("about:printpreview", {
       inBackground: true,
       preferredRemoteType,
       sameProcessAsFrameLoader: browser.frameLoader
     });
   },
   getPrintPreviewBrowser() {
@@ -3514,26 +3511,28 @@ var PrintPreviewListener = {
       this._simplifiedPrintPreviewTab = this._createPPBrowser();
     }
     gBrowser._allowTabChange = true;
     this._lastRequestedPrintPreviewTab = gBrowser.selectedTab = this._simplifiedPrintPreviewTab;
     gBrowser._allowTabChange = false;
     return gBrowser.getBrowserForTab(this._simplifiedPrintPreviewTab);
   },
   createSimplifiedBrowser() {
-    let browser = this._tabBeforePrintPreview.linkedBrowser;
+    let browser = this.getSourceBrowser();
     this._simplifyPageTab = gBrowser.loadOneTab("about:printpreview", {
       inBackground: true,
       sameProcessAsFrameLoader: browser.frameLoader
      });
     return this.getSimplifiedSourceBrowser();
   },
   getSourceBrowser() {
-    return this._tabBeforePrintPreview ?
-      this._tabBeforePrintPreview.linkedBrowser : gBrowser.selectedBrowser;
+    if (!this._tabBeforePrintPreview) {
+      this._tabBeforePrintPreview = gBrowser.selectedTab;
+    }
+    return this._tabBeforePrintPreview.linkedBrowser;
   },
   getSimplifiedSourceBrowser() {
     return this._simplifyPageTab ?
       gBrowser.getBrowserForTab(this._simplifyPageTab) : null;
   },
   getNavToolbox() {
     return gNavToolbox;
   },
--- a/browser/base/content/test/tabs/browser_tabSwitchPrintPreview.js
+++ b/browser/base/content/test/tabs/browser_tabSwitchPrintPreview.js
@@ -1,17 +1,11 @@
 const kURL1 = "data:text/html,Should I stay or should I go?";
 const kURL2 = "data:text/html,I shouldn't be here!";
 
-add_task(function* setup() {
-  yield SpecialPowers.pushPrefEnv({
-    set: [["dom.ipc.processCount", 1]]
-  });
-});
-
 /**
  * Verify that if we open a new tab and try to make it the selected tab while
  * print preview is up, that doesn't happen.
  */
 add_task(function* () {
   yield BrowserTestUtils.withNewTab(kURL1, function* (browser) {
     let tab = gBrowser.addTab(kURL2);
     document.getElementById("cmd_printPreview").doCommand();
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -14,16 +14,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyServiceGetter(this, "DOMUtils",
                                    "@mozilla.org/inspector/dom-utils;1",
                                    "inIDOMUtils");
 
 Cu.import("resource://gre/modules/EventEmitter.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
 var {
+  DefaultWeakMap,
   IconDetails,
 } = ExtensionUtils;
 
 const POPUP_PRELOAD_TIMEOUT_MS = 200;
 
 var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 function isAncestorOrSelf(target, node) {
@@ -52,16 +53,18 @@ this.browserAction = class extends Exten
     return browserActionMap.get(extension);
   }
 
   onManifestEntry(entryName) {
     let {extension} = this;
 
     let options = extension.manifest.browser_action;
 
+    this.iconData = new DefaultWeakMap(icons => this.getIconData(icons));
+
     let widgetId = makeWidgetId(extension.id);
     this.id = `${widgetId}-browser-action`;
     this.viewId = `PanelUI-webext-${widgetId}-browser-action-view`;
     this.widget = null;
 
     this.pendingPopup = null;
     this.pendingPopupTimeout = null;
 
@@ -362,68 +365,84 @@ this.browserAction = class extends Exten
       this.pendingPopupTimeout = null;
     }
   }
 
   // Update the toolbar button |node| with the tab context data
   // in |tabData|.
   updateButton(node, tabData) {
     let title = tabData.title || this.extension.name;
-    node.setAttribute("tooltiptext", title);
-    node.setAttribute("label", title);
+
+    node.ownerGlobal.requestAnimationFrame(() => {
+      node.setAttribute("tooltiptext", title);
+      node.setAttribute("label", title);
 
-    if (tabData.badgeText) {
-      node.setAttribute("badge", tabData.badgeText);
-    } else {
-      node.removeAttribute("badge");
-    }
+      if (tabData.badgeText) {
+        node.setAttribute("badge", tabData.badgeText);
+      } else {
+        node.removeAttribute("badge");
+      }
 
-    if (tabData.enabled) {
-      node.removeAttribute("disabled");
-    } else {
-      node.setAttribute("disabled", "true");
-    }
+      if (tabData.enabled) {
+        node.removeAttribute("disabled");
+      } else {
+        node.setAttribute("disabled", "true");
+      }
 
-    let badgeNode = node.ownerDocument.getAnonymousElementByAttribute(node,
-                                        "class", "toolbarbutton-badge");
-    if (badgeNode) {
-      let color = tabData.badgeBackgroundColor;
-      if (color) {
-        color = `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${color[3] / 255})`;
+      let badgeNode = node.ownerDocument.getAnonymousElementByAttribute(node,
+                                          "class", "toolbarbutton-badge");
+      if (badgeNode) {
+        let color = tabData.badgeBackgroundColor;
+        if (color) {
+          color = `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${color[3] / 255})`;
+        }
+        badgeNode.style.backgroundColor = color || "";
       }
-      badgeNode.style.backgroundColor = color || "";
-    }
+
+      let {style, legacy} = this.iconData.get(tabData.icon);
+      const LEGACY_CLASS = "toolbarbutton-legacy-addon";
+      if (legacy) {
+        node.classList.add(LEGACY_CLASS);
+      } else {
+        node.classList.remove(LEGACY_CLASS);
+      }
 
-    const LEGACY_CLASS = "toolbarbutton-legacy-addon";
-    node.classList.remove(LEGACY_CLASS);
+      node.setAttribute("style", style);
+    });
+  }
 
+  getIconData(icons) {
     let baseSize = 16;
-    let {icon, size} = IconDetails.getPreferredIcon(tabData.icon, this.extension, baseSize);
+    let {icon, size} = IconDetails.getPreferredIcon(icons, this.extension, baseSize);
+
+    let legacy = false;
 
     // If the best available icon size is not divisible by 16, check if we have
     // an 18px icon to fall back to, and trim off the padding instead.
     if (size % 16 && !icon.endsWith(".svg")) {
-      let result = IconDetails.getPreferredIcon(tabData.icon, this.extension, 18);
+      let result = IconDetails.getPreferredIcon(icons, this.extension, 18);
 
       if (result.size % 18 == 0) {
         baseSize = 18;
         icon = result.icon;
-        node.classList.add(LEGACY_CLASS);
+        legacy = true;
       }
     }
 
     let getIcon = size => IconDetails.escapeUrl(
-      IconDetails.getPreferredIcon(tabData.icon, this.extension, size).icon);
+      IconDetails.getPreferredIcon(icons, this.extension, size).icon);
 
-    node.setAttribute("style", `
+    let style = `
       --webextension-menupanel-image: url("${getIcon(32)}");
       --webextension-menupanel-image-2x: url("${getIcon(64)}");
       --webextension-toolbar-image: url("${IconDetails.escapeUrl(icon)}");
       --webextension-toolbar-image-2x: url("${getIcon(baseSize * 2)}");
-    `);
+    `;
+
+    return {style, legacy};
   }
 
   // Update the toolbar button for a given window.
   updateWindow(window) {
     let widget = this.widget.forWindow(window);
     if (widget) {
       let tab = window.gBrowser.selectedTab;
       this.updateButton(widget.node, this.tabContext.get(tab));
--- a/browser/components/extensions/ext-pageAction.js
+++ b/browser/components/extensions/ext-pageAction.js
@@ -3,31 +3,34 @@
 "use strict";
 
 XPCOMUtils.defineLazyModuleGetter(this, "PanelPopup",
                                   "resource:///modules/ExtensionPopups.jsm");
 
 Cu.import("resource://gre/modules/Task.jsm");
 
 var {
+  DefaultWeakMap,
   IconDetails,
 } = ExtensionUtils;
 
 // WeakMap[Extension -> PageAction]
 let pageActionMap = new WeakMap();
 
 this.pageAction = class extends ExtensionAPI {
   static for(extension) {
     return pageActionMap.get(extension);
   }
 
   onManifestEntry(entryName) {
     let {extension} = this;
     let options = extension.manifest.page_action;
 
+    this.iconData = new DefaultWeakMap(icons => this.getIconData(icons));
+
     this.id = makeWidgetId(extension.id) + "-page-action";
 
     this.tabManager = extension.tabManager;
 
     this.defaults = {
       show: false,
       title: options.default_title || extension.name,
       icon: IconDetails.normalize({path: options.default_icon}, extension),
@@ -99,41 +102,50 @@ this.pageAction = class extends Extensio
     let tabData = this.tabContext.get(window.gBrowser.selectedTab);
 
     if (!(tabData.show || this.buttons.has(window))) {
       // Don't bother creating a button for a window until it actually
       // needs to be shown.
       return;
     }
 
-    let button = this.getButton(window);
+    window.requestAnimationFrame(() => {
+      let button = this.getButton(window);
+
+      if (tabData.show) {
+        // Update the title and icon only if the button is visible.
 
-    if (tabData.show) {
-      // Update the title and icon only if the button is visible.
+        let title = tabData.title || this.extension.name;
+        button.setAttribute("tooltiptext", title);
+        button.setAttribute("aria-label", title);
+        button.classList.add("webextension-page-action");
 
-      let title = tabData.title || this.extension.name;
-      button.setAttribute("tooltiptext", title);
-      button.setAttribute("aria-label", title);
+        let {style} = this.iconData.get(tabData.icon);
+
+        button.setAttribute("style", style);
+      }
 
-      // These URLs should already be properly escaped, but make doubly sure CSS
-      // string escape characters are escaped here, since they could lead to a
-      // sandbox break.
-      let escape = str => str.replace(/[\\\s"]/g, encodeURIComponent);
-
-      let getIcon = size => escape(IconDetails.getPreferredIcon(tabData.icon, this.extension, size).icon);
+      button.hidden = !tabData.show;
+    });
+  }
 
-      button.setAttribute("style", `
-        --webextension-urlbar-image: url("${getIcon(16)}");
-        --webextension-urlbar-image-2x: url("${getIcon(32)}");
-      `);
+  getIconData(icons) {
+    // These URLs should already be properly escaped, but make doubly sure CSS
+    // string escape characters are escaped here, since they could lead to a
+    // sandbox break.
+    let escape = str => str.replace(/[\\\s"]/g, encodeURIComponent);
 
-      button.classList.add("webextension-page-action");
-    }
+    let getIcon = size => escape(IconDetails.getPreferredIcon(icons, this.extension, size).icon);
 
-    button.hidden = !tabData.show;
+    let style = `
+      --webextension-urlbar-image: url("${getIcon(16)}");
+      --webextension-urlbar-image-2x: url("${getIcon(32)}");
+    `;
+
+    return {style};
   }
 
   // Create an |image| node and add it to the |urlbar-icons|
   // container in the given window.
   addButton(window) {
     let document = window.document;
 
     let button = document.createElement("image");
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_context.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_context.js
@@ -119,17 +119,19 @@ function* runTests(options) {
       is(badgeColor, expectedColor, "badge color is correct");
     }
 
 
     // TODO: Popup URL.
   }
 
   let awaitFinish = new Promise(resolve => {
-    extension.onMessage("nextTest", (expecting, testsRemaining) => {
+    extension.onMessage("nextTest", async (expecting, testsRemaining) => {
+      await promiseAnimationFrame();
+
       checkDetails(expecting);
 
       if (testsRemaining) {
         extension.sendMessage("runNextTest");
       } else {
         resolve();
       }
     });
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon.js
@@ -263,16 +263,18 @@ add_task(function* testDetailsObjects() 
   let pageActionId = `${makeWidgetId(extension.id)}-page-action`;
   let browserActionWidget = getBrowserActionWidget(extension);
 
   let tests = yield extension.awaitMessage("ready");
   for (let test of tests) {
     extension.sendMessage("setIcon", test);
     yield extension.awaitMessage("iconSet");
 
+    yield promiseAnimationFrame();
+
     let browserActionButton = browserActionWidget.forWindow(window).node;
     let pageActionImage = document.getElementById(pageActionId);
 
 
     // Test icon sizes in the toolbar/urlbar.
     for (let resolution of Object.keys(test.resolutions)) {
       yield SpecialPowers.pushPrefEnv({set: [[RESOLUTION_PREF, resolution]]});
 
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon_permissions.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon_permissions.js
@@ -100,16 +100,18 @@ add_task(function* testDefaultDetails() 
       },
     });
 
     yield Promise.all([extension.startup(), extension.awaitMessage("ready")]);
 
     let browserActionId = makeWidgetId(extension.id) + "-browser-action";
     let pageActionId = makeWidgetId(extension.id) + "-page-action";
 
+    yield promiseAnimationFrame();
+
     let browserActionButton = document.getElementById(browserActionId);
     let image = getListStyleImage(browserActionButton);
 
     ok(expectedURL.test(image), `browser action image ${image} matches ${expectedURL}`);
 
     let pageActionImage = document.getElementById(pageActionId);
     image = getListStyleImage(pageActionImage);
 
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload.js
@@ -107,16 +107,17 @@ add_task(function* testBrowserActionDisa
         browser.test.fail("Should not get here");
       },
     },
   });
 
   yield extension.startup();
 
   yield extension.awaitMessage("browserAction-disabled");
+  yield promiseAnimationFrame();
 
   const {GlobalManager, Management: {global: {browserActionFor}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
 
   let ext = GlobalManager.extensionMap.get(extension.id);
   let browserAction = browserActionFor(ext);
 
   let widget = getBrowserActionWidget(extension).forWindow(window);
 
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -13,16 +13,17 @@
  *          openExtensionContextMenu closeExtensionContextMenu
  *          openActionContextMenu openSubmenu closeActionContextMenu
  *          openTabContextMenu closeTabContextMenu
  *          imageBuffer imageBufferFromDataURI
  *          getListStyleImage getPanelForNode
  *          awaitExtensionPanel awaitPopupResize
  *          promiseContentDimensions alterContent
  *          promisePrefChangeObserved openContextMenuInFrame
+ *          promiseAnimationFrame
  */
 
 const {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm", {});
 const {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", {});
 
 // We run tests under two different configurations, from browser.ini and
 // browser-remote.ini. When running from browser-remote.ini, the tests are
 // copied to the sub-directory "test-oop-extensions", which we detect here, and
@@ -78,16 +79,23 @@ var imageBuffer = imageBufferFromDataURI
 function getListStyleImage(button) {
   let style = button.ownerGlobal.getComputedStyle(button);
 
   let match = /^url\("(.*)"\)$/.exec(style.listStyleImage);
 
   return match && match[1];
 }
 
+async function promiseAnimationFrame(win = window) {
+  await new Promise(resolve => win.requestAnimationFrame(resolve));
+
+  let {mainThread} = Services.tm;
+  return new Promise(resolve => mainThread.dispatch(resolve, mainThread.DISPATCH_NORMAL));
+}
+
 function promisePopupShown(popup) {
   return new Promise(resolve => {
     if (popup.state == "open") {
       resolve();
     } else {
       let onPopupShown = event => {
         popup.removeEventListener("popupshown", onPopupShown);
         resolve();
@@ -212,16 +220,17 @@ var showBrowserAction = Task.async(funct
   if (group.areaType == CustomizableUI.TYPE_TOOLBAR) {
     ok(!widget.overflowed, "Expect widget not to be overflowed");
   } else if (group.areaType == CustomizableUI.TYPE_MENU_PANEL) {
     yield win.PanelUI.show();
   }
 });
 
 var clickBrowserAction = Task.async(function* (extension, win = window) {
+  yield promiseAnimationFrame(win);
   yield showBrowserAction(extension, win);
 
   let widget = getBrowserActionWidget(extension).forWindow(win);
 
   EventUtils.synthesizeMouseAtCenter(widget.node, {}, win);
 });
 
 function closeBrowserAction(extension, win = window) {
@@ -274,45 +283,45 @@ async function openContextMenu(selector 
 
 async function closeContextMenu(contextMenu) {
   let contentAreaContextMenu = contextMenu || document.getElementById("contentAreaContextMenu");
   let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
   contentAreaContextMenu.hidePopup();
   await popupHiddenPromise;
 }
 
-function* openExtensionContextMenu(selector = "#img1") {
-  let contextMenu = yield openContextMenu(selector);
+async function openExtensionContextMenu(selector = "#img1") {
+  let contextMenu = await openContextMenu(selector);
   let topLevelMenu = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");
 
   // Return null if the extension only has one item and therefore no extension menu.
   if (topLevelMenu.length == 0) {
     return null;
   }
 
   let extensionMenu = topLevelMenu[0].childNodes[0];
   let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
   EventUtils.synthesizeMouseAtCenter(extensionMenu, {});
-  yield popupShownPromise;
+  await popupShownPromise;
   return extensionMenu;
 }
 
-function* closeExtensionContextMenu(itemToSelect, modifiers = {}) {
+async function closeExtensionContextMenu(itemToSelect, modifiers = {}) {
   let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
   let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
   EventUtils.synthesizeMouseAtCenter(itemToSelect, modifiers);
-  yield popupHiddenPromise;
+  await popupHiddenPromise;
 }
 
-function* openChromeContextMenu(menuId, target, win = window) {
+async function openChromeContextMenu(menuId, target, win = window) {
   const node = win.document.querySelector(target);
   const menu = win.document.getElementById(menuId);
   const shown = BrowserTestUtils.waitForEvent(menu, "popupshown");
   EventUtils.synthesizeMouseAtCenter(node, {type: "contextmenu"}, win);
-  yield shown;
+  await shown;
   return menu;
 }
 
 function* openSubmenu(submenuItem, win = window) {
   const submenu = submenuItem.firstChild;
   const shown = BrowserTestUtils.waitForEvent(submenu, "popupshown");
   EventUtils.synthesizeMouseAtCenter(submenuItem, {}, win);
   yield shown;
@@ -325,19 +334,20 @@ function closeChromeContextMenu(menuId, 
   if (itemToSelect) {
     EventUtils.synthesizeMouseAtCenter(itemToSelect, {}, win);
   } else {
     menu.hidePopup();
   }
   return hidden;
 }
 
-function openActionContextMenu(extension, kind, win = window) {
+async function openActionContextMenu(extension, kind, win = window) {
   // See comment from clickPageAction below.
   SetPageProxyState("valid");
+  await promiseAnimationFrame(win);
   const id = `#${makeWidgetId(extension.id)}-${kind}-action`;
   return openChromeContextMenu("toolbar-context-menu", id, win);
 }
 
 function closeActionContextMenu(itemToSelect, win = window) {
   return closeChromeContextMenu("toolbar-context-menu", itemToSelect, win);
 }
 
@@ -349,26 +359,28 @@ function closeTabContextMenu(itemToSelec
   return closeChromeContextMenu("tabContextMenu", itemToSelect, win);
 }
 
 function getPageActionPopup(extension, win = window) {
   let panelId = makeWidgetId(extension.id) + "-panel";
   return win.document.getElementById(panelId);
 }
 
-function clickPageAction(extension, win = window) {
+async function clickPageAction(extension, win = window) {
   // This would normally be set automatically on navigation, and cleared
   // when the user types a value into the URL bar, to show and hide page
   // identity info and icons such as page action buttons.
   //
   // Unfortunately, that doesn't happen automatically in browser chrome
   // tests.
   /* globals SetPageProxyState */
   SetPageProxyState("valid");
 
+  await promiseAnimationFrame(win);
+
   let pageActionId = makeWidgetId(extension.id) + "-page-action";
   let elem = win.document.getElementById(pageActionId);
 
   EventUtils.synthesizeMouseAtCenter(elem, {}, win);
   return new Promise(SimpleTest.executeSoon);
 }
 
 function closePageAction(extension, win = window) {
--- a/browser/components/extensions/test/browser/head_pageAction.js
+++ b/browser/components/extensions/test/browser/head_pageAction.js
@@ -1,14 +1,14 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
 /* exported runTests */
-/* globals getListStyleImage */
+/* globals getListStyleImage, promiseAnimationFrame */
 
 function* runTests(options) {
   function background(getTests) {
     let tabs;
     let tests;
 
     // Gets the current details of the page action, and returns a
     // promise that resolves to an object containing them.
@@ -103,21 +103,23 @@ function* runTests(options) {
       is(image.getAttribute("aria-label"), title, "image aria-label is correct");
       // TODO: Popup URL.
     }
   }
 
   let testNewWindows = 1;
 
   let awaitFinish = new Promise(resolve => {
-    extension.onMessage("nextTest", (expecting, testsRemaining) => {
+    extension.onMessage("nextTest", async (expecting, testsRemaining) => {
       if (!pageActionId) {
         pageActionId = `${makeWidgetId(extension.id)}-page-action`;
       }
 
+      await promiseAnimationFrame();
+
       checkDetails(expecting);
 
       if (testsRemaining) {
         extension.sendMessage("runNextTest");
       } else if (testNewWindows) {
         testNewWindows--;
 
         BrowserTestUtils.openNewBrowserWindow().then(window => {
--- a/browser/config/mozconfigs/linux32/devedition
+++ b/browser/config/mozconfigs/linux32/devedition
@@ -1,8 +1,13 @@
+if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
+  MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1}
+  MOZ_AUTOMATION_UPDATE_PACKAGING=1
+fi
+
 . "$topsrcdir/browser/config/mozconfigs/linux32/common-opt"
 
 # Add-on signing is not required for DevEdition
 MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --enable-verify-mar
 
 # This will overwrite the default of stripping everything and keep the symbol table.
--- a/browser/config/mozconfigs/linux64/code-coverage
+++ b/browser/config/mozconfigs/linux64/code-coverage
@@ -2,13 +2,14 @@
 
 TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
 
 ac_add_options --disable-install-strip
 ac_add_options --disable-jemalloc
 ac_add_options --disable-crashreporter
 ac_add_options --disable-elf-hack
 ac_add_options --enable-debug
+ac_add_options --disable-sandbox
 
 MOZ_CODE_COVERAGE=1
 export CFLAGS="--coverage"
 export CXXFLAGS="--coverage"
 export LDFLAGS="--coverage -L$TOOLTOOL_DIR/gtk3/usr/local/lib"
--- a/browser/config/mozconfigs/linux64/devedition
+++ b/browser/config/mozconfigs/linux64/devedition
@@ -1,8 +1,13 @@
+if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
+  MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1}
+  MOZ_AUTOMATION_UPDATE_PACKAGING=1
+fi
+
 . "$topsrcdir/browser/config/mozconfigs/linux64/common-opt"
 
 # Add-on signing is not required for DevEdition
 MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --enable-verify-mar
 
 # This will overwrite the default of stripping everything and keep the symbol table.
--- a/browser/config/mozconfigs/macosx64/devedition
+++ b/browser/config/mozconfigs/macosx64/devedition
@@ -1,8 +1,13 @@
+if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
+  MOZ_AUTOMATION_UPLOAD_SYMBOLS=1
+  MOZ_AUTOMATION_UPDATE_PACKAGING=1
+fi
+
 . "$topsrcdir/browser/config/mozconfigs/macosx64/common-opt"
 
 # Add-on signing is not required for DevEdition
 MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --disable-install-strip
 ac_add_options --enable-verify-mar
 
--- a/browser/config/mozconfigs/win32/devedition
+++ b/browser/config/mozconfigs/win32/devedition
@@ -1,8 +1,13 @@
+if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
+  MOZ_AUTOMATION_UPLOAD_SYMBOLS=1
+  MOZ_AUTOMATION_UPDATE_PACKAGING=1
+fi
+
 . "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/win32/common-opt"
 
 # Add-on signing is not required for DevEdition
 MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --enable-verify-mar
 
--- a/browser/config/mozconfigs/win64/devedition
+++ b/browser/config/mozconfigs/win64/devedition
@@ -1,8 +1,13 @@
+if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
+  MOZ_AUTOMATION_UPLOAD_SYMBOLS=1
+  MOZ_AUTOMATION_UPDATE_PACKAGING=1
+fi
+
 . "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
 . "$topsrcdir/browser/config/mozconfigs/win64/common-opt"
 
 # Add-on signing is not required for DevEdition
 MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --enable-verify-mar
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -13,16 +13,17 @@ if test "$OS_ARCH" = "WINNT" -o \
   MOZ_BUNDLED_FONTS=1
 fi
 
 if test "$OS_ARCH" = "WINNT"; then
   MOZ_MAINTENANCE_SERVICE=1
   if ! test "$HAVE_64BIT_BUILD"; then
     if test "$MOZ_UPDATE_CHANNEL" = "nightly" -o \
             "$MOZ_UPDATE_CHANNEL" = "aurora" -o \
+            "$MOZ_UPDATE_CHANNEL" = "aurora-dev" -o \
             "$MOZ_UPDATE_CHANNEL" = "beta" -o \
             "$MOZ_UPDATE_CHANNEL" = "beta-dev" -o \
             "$MOZ_UPDATE_CHANNEL" = "release" -o \
             "$MOZ_UPDATE_CHANNEL" = "release-dev"; then
       if ! test "$MOZ_DEBUG"; then
         MOZ_STUB_INSTALLER=1
       fi
     fi
@@ -42,22 +43,27 @@ MOZ_APP_VERSION_DISPLAY=$FIREFOX_VERSION
 # MOZ_BRANDING_DIRECTORY is the default branding directory used when none is
 # specified. It should never point to the "official" branding directory.
 # For mozilla-beta, mozilla-release, or mozilla-central repositories, use
 # "unofficial" branding.
 # For the mozilla-aurora repository, use "aurora".
 MOZ_BRANDING_DIRECTORY=browser/branding/unofficial
 MOZ_OFFICIAL_BRANDING_DIRECTORY=browser/branding/official
 MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
-# This should usually be the same as the value MAR_CHANNEL_ID.
+# ACCEPTED_MAR_CHANNEL_IDS should usually be the same as the value MAR_CHANNEL_ID.
 # If more than one ID is needed, then you should use a comma separated list
 # of values.
-ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-central
 # The MAR_CHANNEL_ID must not contain the following 3 characters: ",\t "
-MAR_CHANNEL_ID=firefox-mozilla-central
+if test "$MOZ_UPDATE_CHANNEL" = "aurora"; then
+  ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora
+  MAR_CHANNEL_ID=firefox-mozilla-aurora
+else
+  ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-central
+  MAR_CHANNEL_ID=firefox-mozilla-central
+fi
 MOZ_PROFILE_MIGRATOR=1
 MOZ_JSDOWNLOADS=1
 
 # Enable checking that add-ons are signed by the trusted root
 MOZ_ADDON_SIGNING=1
 
 # Include the DevTools client, not just the server (which is the default)
 MOZ_DEVTOOLS=all
--- a/browser/extensions/formautofill/FormAutofillParent.jsm
+++ b/browser/extensions/formautofill/FormAutofillParent.jsm
@@ -99,17 +99,17 @@ FormAutofillParent.prototype = {
         let formAutofillPreferences = new FormAutofillPreferences({useOldOrganization});
         let document = subject.document;
         let prefGroup = formAutofillPreferences.init(document);
         let parentNode = useOldOrganization ?
                          document.getElementById("mainPrefPane") :
                          document.getElementById("passwordsGroup");
         let insertBeforeNode = useOldOrganization ?
                                document.getElementById("locationBarGroup") :
-                               null;
+                               document.getElementById("passwordGrid");
         parentNode.insertBefore(prefGroup, insertBeforeNode);
         break;
       }
 
       case "nsPref:changed": {
         // Observe pref changes and update _enabled cache if status is changed.
         let currentStatus = this._getStatus();
         if (currentStatus !== this._enabled) {
--- a/browser/extensions/formautofill/FormAutofillPreferences.jsm
+++ b/browser/extensions/formautofill/FormAutofillPreferences.jsm
@@ -79,16 +79,17 @@ FormAutofillPreferences.prototype = {
       formAutofillGroup.hidden = document.location.href != "about:preferences#privacy";
       // Use .setAttribute because HTMLElement.dataset is not available on XUL elements
       formAutofillGroup.setAttribute("data-category", "panePrivacy");
       formAutofillGroup.appendChild(caption);
       caption.appendChild(captionLabel);
       captionLabel.textContent = this.bundle.GetStringFromName("preferenceGroupTitle");
     } else {
       formAutofillGroup = document.createElementNS(XUL_NS, "vbox");
+      savedProfilesBtn.className = "accessory-button";
     }
 
     this.refs = {
       formAutofillGroup,
       profileAutofillCheckbox,
       savedProfilesBtn,
     };
 
--- a/browser/extensions/formautofill/content/editProfile.xhtml
+++ b/browser/extensions/formautofill/content/editProfile.xhtml
@@ -11,27 +11,27 @@
   <link rel="stylesheet" href="chrome://global/skin/in-content/common.css" />
   <link rel="stylesheet" href="chrome://browser/skin/preferences/in-content/dialog.css" />
   <link rel="stylesheet" href="chrome://formautofill-shared/skin/editProfile.css" />
   <link rel="stylesheet" href="chrome://formautofill/skin/editProfile.css" />
   <script src="chrome://formautofill/content/editProfile.js"></script>
 </head>
 <body>
   <form>
-    <label id="first-name-container">
+    <label id="given-name-container">
       <span>First Name</span>
-      <input id="first-name" type="text"/>
+      <input id="given-name" type="text"/>
     </label>
-    <label id="middle-name-container">
+    <label id="additional-name-container">
       <span>Middle Name</span>
-      <input id="middle-name" type="text"/>
+      <input id="additional-name" type="text"/>
     </label>
-    <label id="last-name-container">
+    <label id="family-name-container">
       <span>Last Name</span>
-      <input id="last-name" type="text"/>
+      <input id="family-name" type="text"/>
     </label>
     <label id="organization-container">
       <span>Company</span>
       <input id="organization" type="text"/>
     </label>
     <label id="street-address-container">
       <span>Street Address</span>
       <textarea id="street-address"/>
--- a/browser/extensions/formautofill/content/manageProfiles.js
+++ b/browser/extensions/formautofill/content/manageProfiles.js
@@ -134,16 +134,17 @@ ManageProfileDialog.prototype = {
    * @param  {object} profile
    * @returns {string}
    */
   getProfileLabel(profile) {
     // TODO: Implement a smarter way for deciding what to display
     //       as option text. Possibly improve the algorithm in
     //       ProfileAutoCompleteResult.jsm and reuse it here.
     const fieldOrder = [
+      "name",
       "street-address",  // Street address
       "address-level2",  // City/Town
       "organization",    // Company or organization name
       "address-level1",  // Province/State (Standardized code if possible)
       "country",         // Country
       "postal-code",     // Postal code
       "tel",             // Phone number
       "email",           // Email address
@@ -164,17 +165,17 @@ ManageProfileDialog.prototype = {
 
   /**
    * Open the edit profile dialog to create/edit a profile.
    *
    * @param  {object} profile [optional]
    */
   openEditDialog(profile) {
     window.openDialog(EDIT_PROFILE_URL, null,
-                      "chrome,centerscreen,modal,width=600,height=370",
+                      "chrome,centerscreen,modal,width=600,height=450",
                       profile);
   },
 
   /**
    * Enable/disable the Edit and Remove buttons based on number of selected
    * options.
    *
    * @param  {number} selectedCount
--- a/browser/extensions/formautofill/skin/shared/editProfile.css
+++ b/browser/extensions/formautofill/skin/shared/editProfile.css
@@ -47,49 +47,42 @@ textarea {
 button {
   padding: 3px 2em;
 }
 
 #country-container {
   width: 15em;
 }
 
-#first-name-container,
-#middle-name-container,
+#given-name-container,
+#additional-name-container,
 #address-level1-container,
 #postal-code-container,
 #country-container {
   flex: 0 1 50%;
 }
 
-#last-name-container,
+#family-name-container,
 #organization-container,
 #street-address-container,
 #address-level2-container,
 #email-container,
 #tel-container,
 #controls-container {
   flex: 0 1 100%;
 }
 
 #controls-container {
   justify-content: end;
 }
 
-#last-name,
+#family-name,
 #organization,
 #address-level2,
 #tel{
   flex: 0 0 auto;
   width: calc(50% - 10em);
 }
 
 #street-address,
 #email {
   flex: 1 0 auto;
 }
-
-#first-name-container,
-#middle-name-container,
-#last-name-container {
-  /* Hide until we support names */
-  display: none;
-}
--- a/browser/extensions/formautofill/test/browser/browser_editProfileDialog.js
+++ b/browser/extensions/formautofill/test/browser/browser_editProfileDialog.js
@@ -24,16 +24,22 @@ add_task(function* test_saveProfile() {
   yield new Promise(resolve => {
     let win = window.openDialog(EDIT_PROFILE_DIALOG_URL, null, null, null);
     win.addEventListener("load", () => {
       win.addEventListener("unload", () => {
         ok(true, "Edit profile dialog is closed");
         resolve();
       }, {once: true});
       EventUtils.synthesizeKey("VK_TAB", {}, win);
+      EventUtils.synthesizeKey(TEST_PROFILE_1["given-name"], {}, win);
+      EventUtils.synthesizeKey("VK_TAB", {}, win);
+      EventUtils.synthesizeKey(TEST_PROFILE_1["additional-name"], {}, win);
+      EventUtils.synthesizeKey("VK_TAB", {}, win);
+      EventUtils.synthesizeKey(TEST_PROFILE_1["family-name"], {}, win);
+      EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey(TEST_PROFILE_1.organization, {}, win);
       EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey(TEST_PROFILE_1["street-address"], {}, win);
       EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey(TEST_PROFILE_1["address-level2"], {}, win);
       EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey(TEST_PROFILE_1["address-level1"], {}, win);
       EventUtils.synthesizeKey("VK_TAB", {}, win);
@@ -41,30 +47,27 @@ add_task(function* test_saveProfile() {
       EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey(TEST_PROFILE_1.country, {}, win);
       EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey(TEST_PROFILE_1.email, {}, win);
       EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey(TEST_PROFILE_1.tel, {}, win);
       EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey("VK_TAB", {}, win);
+      info("saving profile");
       EventUtils.synthesizeKey("VK_RETURN", {}, win);
     }, {once: true});
   });
   let profiles = yield getProfiles();
 
   is(profiles.length, 1, "only one profile is in storage");
-  is(profiles[0].organization, TEST_PROFILE_1.organization, "match organization");
-  is(profiles[0]["street-address"], TEST_PROFILE_1["street-address"], "match street-address");
-  is(profiles[0]["address-level2"], TEST_PROFILE_1["address-level2"], "match address-level2");
-  is(profiles[0]["address-level1"], TEST_PROFILE_1["address-level1"], "match address-level1");
-  is(profiles[0]["postal-code"], TEST_PROFILE_1["postal-code"], "match postal-code");
-  is(profiles[0].country, TEST_PROFILE_1.country, "match country");
-  is(profiles[0].email, TEST_PROFILE_1.email, "match email");
-  is(profiles[0].tel, TEST_PROFILE_1.tel, "match tel");
+  is(Object.keys(TEST_PROFILE_1).length, 11, "Sanity check number of properties");
+  for (let [fieldName, fieldValue] of Object.entries(TEST_PROFILE_1)) {
+    is(profiles[0][fieldName], fieldValue, "check " + fieldName);
+  }
 });
 
 add_task(function* test_editProfile() {
   let profiles = yield getProfiles();
   yield new Promise(resolve => {
     let win = window.openDialog(EDIT_PROFILE_DIALOG_URL, null, null, profiles[0]);
     win.addEventListener("load", () => {
       win.addEventListener("unload", () => {
@@ -74,14 +77,14 @@ add_task(function* test_editProfile() {
       EventUtils.synthesizeKey("VK_TAB", {}, win);
       EventUtils.synthesizeKey("test", {}, win);
       win.document.querySelector("#save").click();
     }, {once: true});
   });
   profiles = yield getProfiles();
 
   is(profiles.length, 1, "only one profile is in storage");
-  is(profiles[0].organization, TEST_PROFILE_1.organization + "test", "organization changed");
+  is(profiles[0]["given-name"], TEST_PROFILE_1["given-name"] + "test", "given-name changed");
   yield removeProfiles([profiles[0].guid]);
 
   profiles = yield getProfiles();
   is(profiles.length, 0, "Profile storage is empty");
 });
--- a/browser/extensions/formautofill/test/browser/head.js
+++ b/browser/extensions/formautofill/test/browser/head.js
@@ -3,16 +3,19 @@
             getProfiles, saveProfile, removeProfiles */
 
 "use strict";
 
 const MANAGE_PROFILES_DIALOG_URL = "chrome://formautofill/content/manageProfiles.xhtml";
 const EDIT_PROFILE_DIALOG_URL = "chrome://formautofill/content/editProfile.xhtml";
 
 const TEST_PROFILE_1 = {
+  "given-name": "John",
+  "additional-name": "R.",
+  "family-name": "Smith",
   organization: "World Wide Web Consortium",
   "street-address": "32 Vassar Street\nMIT Room 32-G524",
   "address-level2": "Cambridge",
   "address-level1": "MA",
   "postal-code": "02139",
   country: "US",
   tel: "+1 617 253 5702",
   email: "timbl@w3.org",
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -988,23 +988,25 @@ cargo_linker_env_var := CARGO_TARGET_$(R
 
 # Don't define a custom linker on Windows, as it's difficult to have a
 # non-binary file that will get executed correctly by Cargo.  We don't
 # have to worry about a cross-compiling (besides x86-64 -> x86, which
 # already works with the current setup) setup on Windows, and we don't
 # have to pass in any special linker options on Windows.
 ifneq (WINNT,$(OS_ARCH))
 
-# Defining all of this for ASan builds results in crashes while running
+# Defining all of this for ASan/TSan builds results in crashes while running
 # some crates's build scripts (!), so disable it for now.
 ifndef MOZ_ASAN
+ifndef MOZ_TSAN
 target_cargo_env_vars := \
 	MOZ_CARGO_WRAP_LDFLAGS="$(LDFLAGS)" \
 	MOZ_CARGO_WRAP_LD="$(CC)" \
 	$(cargo_linker_env_var)=$(topsrcdir)/build/cargo-linker
+endif # MOZ_TSAN
 endif # MOZ_ASAN
 
 endif # ifneq WINNT
 
 ifdef RUST_LIBRARY_FILE
 
 ifdef RUST_LIBRARY_FEATURES
 rust_features_flag := --features "$(RUST_LIBRARY_FEATURES)"
--- a/devtools/server/tests/unit/head_dbg.js
+++ b/devtools/server/tests/unit/head_dbg.js
@@ -42,18 +42,19 @@ const { DebuggerServer: WorkerDebuggerSe
 const { DebuggerClient, ObjectClient } = require("devtools/shared/client/main");
 const { MemoryFront } = require("devtools/shared/fronts/memory");
 
 const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {});
 
 const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
                         .createInstance(Ci.nsIPrincipal);
 
-var { loadSubScript } = Cc["@mozilla.org/moz/jssubscript-loader;1"]
-                        .getService(Ci.mozIJSSubScriptLoader);
+var { loadSubScript, loadSubScriptWithOptions } =
+  Cc["@mozilla.org/moz/jssubscript-loader;1"]
+  .getService(Ci.mozIJSSubScriptLoader);
 
 /**
  * Initializes any test that needs to work with add-ons.
  */
 function startupAddonsManager() {
   // Create a directory for extensions.
   const profileDir = do_get_profile().clone();
   profileDir.append("extensions");
--- a/devtools/server/tests/unit/test_setBreakpoint-on-column-in-gcd-script.js
+++ b/devtools/server/tests/unit/test_setBreakpoint-on-column-in-gcd-script.js
@@ -2,17 +2,17 @@
 
 var SOURCE_URL = getFileUrl("setBreakpoint-on-column-in-gcd-script.js");
 
 function run_test() {
   return Task.spawn(function* () {
     do_test_pending();
 
     let global = testGlobal("test");
-    loadSubScript(SOURCE_URL, global);
+    loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
     Cu.forceGC(); Cu.forceGC(); Cu.forceGC();
 
     DebuggerServer.registerModule("xpcshell-test/testactors");
     DebuggerServer.init(() => true);
     DebuggerServer.addTestGlobal(global);
     let client = new DebuggerClient(DebuggerServer.connectPipe());
     yield connect(client);
 
@@ -28,17 +28,17 @@ function run_test() {
 
     let location = { line: 6, column: 17 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_true(packet.isPending);
     do_check_false("actualLocation" in packet);
 
     packet = yield executeOnNextTickAndWaitForPause(function () {
       reload(tabClient).then(function () {
-        loadSubScript(SOURCE_URL, global);
+        loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
       });
     }, client);
     do_check_eq(packet.type, "paused");
     let why = packet.why;
     do_check_eq(why.type, "breakpoint");
     do_check_eq(why.actors.length, 1);
     do_check_eq(why.actors[0], breakpointClient.actor);
     let frame = packet.frame;
--- a/devtools/server/tests/unit/test_setBreakpoint-on-line-in-gcd-script.js
+++ b/devtools/server/tests/unit/test_setBreakpoint-on-line-in-gcd-script.js
@@ -2,17 +2,17 @@
 
 var SOURCE_URL = getFileUrl("setBreakpoint-on-line-in-gcd-script.js");
 
 function run_test() {
   return Task.spawn(function* () {
     do_test_pending();
 
     let global = createTestGlobal("test");
-    loadSubScript(SOURCE_URL, global);
+    loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
     Cu.forceGC(); Cu.forceGC(); Cu.forceGC();
 
     DebuggerServer.registerModule("xpcshell-test/testactors");
     DebuggerServer.init(() => true);
     DebuggerServer.addTestGlobal(global);
     let client = new DebuggerClient(DebuggerServer.connectPipe());
     yield connect(client);
 
@@ -28,17 +28,17 @@ function run_test() {
 
     let location = { line: 7 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_true(packet.isPending);
     do_check_false("actualLocation" in packet);
 
     packet = yield executeOnNextTickAndWaitForPause(function () {
       reload(tabClient).then(function () {
-        loadSubScript(SOURCE_URL, global);
+        loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
       });
     }, client);
     do_check_eq(packet.type, "paused");
     let why = packet.why;
     do_check_eq(why.type, "breakpoint");
     do_check_eq(why.actors.length, 1);
     do_check_eq(why.actors[0], breakpointClient.actor);
     let frame = packet.frame;
--- a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets-in-gcd-script.js
+++ b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets-in-gcd-script.js
@@ -2,17 +2,17 @@
 
 var SOURCE_URL = getFileUrl("setBreakpoint-on-line-with-no-offsets-in-gcd-script.js");
 
 function run_test() {
   return Task.spawn(function* () {
     do_test_pending();
 
     let global = createTestGlobal("test");
-    loadSubScript(SOURCE_URL, global);
+    loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
     Cu.forceGC(); Cu.forceGC(); Cu.forceGC();
 
     DebuggerServer.registerModule("xpcshell-test/testactors");
     DebuggerServer.init(() => true);
     DebuggerServer.addTestGlobal(global);
 
     let client = new DebuggerClient(DebuggerServer.connectPipe());
     yield connect(client);
@@ -29,17 +29,17 @@ function run_test() {
 
     let location = { line: 7 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_true(packet.isPending);
     do_check_false("actualLocation" in packet);
 
     packet = yield executeOnNextTickAndWaitForPause(function () {
       reload(tabClient).then(function () {
-        loadSubScript(SOURCE_URL, global);
+        loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
       });
     }, client);
     do_check_eq(packet.type, "paused");
     let why = packet.why;
     do_check_eq(why.type, "breakpoint");
     do_check_eq(why.actors.length, 1);
     do_check_eq(why.actors[0], breakpointClient.actor);
     let frame = packet.frame;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9848,18 +9848,22 @@ nsDocShell::InternalLoad(nsIURI* aURI,
     isJavaScript = false;
   }
 
   bool isTargetTopLevelDocShell = false;
   nsCOMPtr<nsIDocShell> targetDocShell;
   if (!aWindowTarget.IsEmpty()) {
     // Locate the target DocShell.
     nsCOMPtr<nsIDocShellTreeItem> targetItem;
-    // Only _self, _parent, and _top are supported in noopener case.
-    if (!(aFlags & INTERNAL_LOAD_FLAGS_NO_OPENER) ||
+    // Only _self, _parent, and _top are supported in noopener case.  But we
+    // have to be careful to not apply that to the noreferrer case.  See bug
+    // 1358469.
+    bool allowNamedTarget = !(aFlags & INTERNAL_LOAD_FLAGS_NO_OPENER) ||
+                            (aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER);
+    if (allowNamedTarget ||
         aWindowTarget.LowerCaseEqualsLiteral("_self") ||
         aWindowTarget.LowerCaseEqualsLiteral("_parent") ||
         aWindowTarget.LowerCaseEqualsLiteral("_top")) {
       rv = FindItemWithName(aWindowTarget, nullptr, this, false,
                             getter_AddRefs(targetItem));
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
--- a/dom/base/Link.h
+++ b/dom/base/Link.h
@@ -110,17 +110,17 @@ public:
    * @returns boolean
    *          Defaults to true; should be overridden for specialised cases
    */
   virtual bool HasDeferredDNSPrefetchRequest() { return true; }
 
   virtual size_t
     SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
-  bool ElementHasHref() const;
+  virtual bool ElementHasHref() const;
 
   // This is called by HTMLAnchorElement.
   void TryDNSPrefetch();
   void CancelDNSPrefetch(nsWrapperCache::FlagsType aDeferredFlag,
                          nsWrapperCache::FlagsType aRequestedFlag);
 
   // This is called by HTMLLinkElement.
   void TryDNSPrefetchPreconnectOrPrefetchOrPrerender();
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -214,16 +214,17 @@
 #include "nsICookieService.h"
 #include "mozilla/EnumSet.h"
 #include "mozilla/BloomFilter.h"
 #include "TabChild.h"
 #include "mozilla/dom/DocGroup.h"
 #include "mozilla/dom/TabGroup.h"
 #include "nsIWebNavigationInfo.h"
 #include "nsPluginHost.h"
+#include "mozilla/HangAnnotations.h"
 
 #include "nsIBidiKeyboard.h"
 
 #if defined(XP_WIN)
 // Undefine LoadImage to prevent naming conflict with Windows.
 #undef LoadImage
 #endif
 
@@ -297,16 +298,19 @@ bool nsContentUtils::sAnimationsAPICoreE
 bool nsContentUtils::sAnimationsAPIElementAnimateEnabled = false;
 bool nsContentUtils::sGetBoxQuadsEnabled = false;
 bool nsContentUtils::sSkipCursorMoveForSameValueSet = false;
 bool nsContentUtils::sRequestIdleCallbackEnabled = false;
 
 int32_t nsContentUtils::sPrivacyMaxInnerWidth = 1000;
 int32_t nsContentUtils::sPrivacyMaxInnerHeight = 1000;
 
+nsContentUtils::UserInteractionObserver*
+nsContentUtils::sUserInteractionObserver = nullptr;
+
 uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
 
 uint32_t nsContentUtils::sCookiesLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
 uint32_t nsContentUtils::sCookiesBehavior = nsICookieService::BEHAVIOR_ACCEPT;
 
 nsHtml5StringParser* nsContentUtils::sHTMLFragmentParser = nullptr;
 nsIParser* nsContentUtils::sXMLFragmentParser = nullptr;
 nsIFragmentContentSink* nsContentUtils::sXMLFragmentSink = nullptr;
@@ -488,16 +492,42 @@ public:
   }
 
 private:
   nsCString mCharset;
 };
 
 } // namespace
 
+/**
+ * This class is used to determine whether or not the user is currently
+ * interacting with the browser. It listens to observer events to toggle the
+ * value of the sUserActive static.
+ *
+ * This class is an internal implementation detail.
+ * nsContentUtils::GetUserIsInteracting() should be used to access current
+ * user interaction status.
+ */
+class nsContentUtils::UserInteractionObserver final : public nsIObserver
+                                                    , public HangMonitor::Annotator
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+
+  void Init();
+  void Shutdown();
+  virtual void AnnotateHang(HangMonitor::HangAnnotations& aAnnotations) override;
+
+  static Atomic<bool> sUserActive;
+
+private:
+  ~UserInteractionObserver() {}
+};
+
 /* static */
 TimeDuration
 nsContentUtils::HandlingUserInputTimeout()
 {
   return TimeDuration::FromMilliseconds(sHandlingInputTimeout);
 }
 
 // static
@@ -656,16 +686,20 @@ nsContentUtils::Init()
 
   nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
     do_GetService("@mozilla.org/uuid-generator;1", &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   uuidGenerator.forget(&sUUIDGenerator);
 
+  RefPtr<UserInteractionObserver> uio = new UserInteractionObserver();
+  uio->Init();
+  uio.forget(&sUserInteractionObserver);
+
   sInitialized = true;
 
   return NS_OK;
 }
 
 void
 nsContentUtils::GetShiftText(nsAString& text)
 {
@@ -2022,16 +2056,21 @@ nsContentUtils::Shutdown()
   sOSText = nullptr;
   delete sAltText;
   sAltText = nullptr;
   delete sModifierSeparator;
   sModifierSeparator = nullptr;
 
   NS_IF_RELEASE(sSameOriginChecker);
 
+  if (sUserInteractionObserver) {
+    sUserInteractionObserver->Shutdown();
+    NS_RELEASE(sUserInteractionObserver);
+  }
+
   HTMLInputElement::Shutdown();
   nsMappedAttributes::Shutdown();
 }
 
 /**
  * Checks whether two nodes come from the same origin. aTrustedNode is
  * considered 'safe' in that a user can operate on it and that it isn't
  * a js-object that implements nsIDOMNode.
@@ -10377,10 +10416,76 @@ nsContentUtils::GenerateTabId()
   MOZ_RELEASE_ASSERT(processId < (uint64_t(1) << kTabIdProcessBits));
   uint64_t processBits = processId & ((uint64_t(1) << kTabIdProcessBits) - 1);
 
   uint64_t tabId = ++gNextTabId;
   MOZ_RELEASE_ASSERT(tabId < (uint64_t(1) << kTabIdTabBits));
   uint64_t tabBits = tabId & ((uint64_t(1) << kTabIdTabBits) - 1);
 
   return (processBits << kTabIdTabBits) | tabBits;
-
-}
+}
+
+/* static */ bool
+nsContentUtils::GetUserIsInteracting()
+{
+  return UserInteractionObserver::sUserActive;
+}
+
+static const char* kUserInteractionInactive = "user-interaction-inactive";
+static const char* kUserInteractionActive = "user-interaction-active";
+
+void
+nsContentUtils::UserInteractionObserver::Init()
+{
+  // Listen for the observer messages from EventStateManager which are telling
+  // us whether or not the user is interacting.
+  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+  obs->AddObserver(this, kUserInteractionInactive, false);
+  obs->AddObserver(this, kUserInteractionActive, false);
+
+  // Register ourselves as an annotator for the Background Hang Reporter, so
+  // that hang stacks are annotated with whether or not the user was
+  // interacting with the browser when the hang occurred.
+  HangMonitor::RegisterAnnotator(*this);
+}
+
+void
+nsContentUtils::UserInteractionObserver::Shutdown()
+{
+  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+  if (obs) {
+    obs->RemoveObserver(this, kUserInteractionInactive);
+    obs->RemoveObserver(this, kUserInteractionActive);
+  }
+
+  HangMonitor::UnregisterAnnotator(*this);
+}
+
+/**
+ * NB: This function is always called by the HangMonitor thread.
+ *     Plan accordingly
+ */
+void
+nsContentUtils::UserInteractionObserver::AnnotateHang(HangMonitor::HangAnnotations& aAnnotations)
+{
+  // NOTE: Only annotate the hang report if the user is known to be interacting.
+  if (sUserActive) {
+    aAnnotations.AddAnnotation(NS_LITERAL_STRING("UserInteracting"), true);
+  }
+}
+
+NS_IMETHODIMP
+nsContentUtils::UserInteractionObserver::Observe(nsISupports* aSubject,
+                                                 const char* aTopic,
+                                                 const char16_t* aData)
+{
+  if (!strcmp(aTopic, kUserInteractionInactive)) {
+    sUserActive = false;
+  } else if (!strcmp(aTopic, kUserInteractionActive)) {
+    sUserActive = true;
+  } else {
+    NS_WARNING("Unexpected observer notification");
+  }
+  return NS_OK;
+}
+
+Atomic<bool> nsContentUtils::UserInteractionObserver::sUserActive(false);
+NS_IMPL_ISUPPORTS(nsContentUtils::UserInteractionObserver, nsIObserver)
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2932,16 +2932,23 @@ public:
 
   /**
    * Check whether we should skip moving the cursor for a same-value .value set
    * on a text input or textarea.
    */
   static bool
   SkipCursorMoveForSameValueSet() { return sSkipCursorMoveForSameValueSet; }
 
+  /**
+   * Determine whether or not the user is currently interacting with the web
+   * browser. This method is safe to call from off of the main thread.
+   */
+  static bool
+  GetUserIsInteracting();
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
@@ -3063,16 +3070,19 @@ private:
   static bool sSkipCursorMoveForSameValueSet;
   static bool sRequestIdleCallbackEnabled;
   static uint32_t sCookiesLifetimePolicy;
   static uint32_t sCookiesBehavior;
 
   static int32_t sPrivacyMaxInnerWidth;
   static int32_t sPrivacyMaxInnerHeight;
 
+  class UserInteractionObserver;
+  static UserInteractionObserver* sUserInteractionObserver;
+
   static nsHtml5StringParser* sHTMLFragmentParser;
   static nsIParser* sXMLFragmentParser;
   static nsIFragmentContentSink* sXMLFragmentSink;
 
   /**
    * True if there's a fragment parser activation on the stack.
    */
   static bool sFragmentParsingActive;
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -4190,16 +4190,17 @@ nsDOMWindowUtils::IsTimeoutTracking(uint
 struct StateTableEntry
 {
   const char* mStateString;
   EventStates mState;
 };
 
 static constexpr StateTableEntry kManuallyManagedStates[] = {
   { "-moz-autofill", NS_EVENT_STATE_AUTOFILL },
+  { "-moz-autofill-preview", NS_EVENT_STATE_AUTOFILL_PREVIEW },
   { nullptr, EventStates() },
 };
 
 static_assert(!kManuallyManagedStates[ArrayLength(kManuallyManagedStates) - 1]
                .mStateString,
               "last kManuallyManagedStates entry must be a sentinel with "
               "mStateString == nullptr");
 
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -27,16 +27,17 @@
 #include "nsIMemoryReporter.h"
 #include "nsIProtocolHandler.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIDOMClassInfo.h"
 #include "xpcpublic.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/IntentionalCrash.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/ScriptPreloader.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/ProcessGlobal.h"
 #include "mozilla/dom/SameProcessMessageQueue.h"
 #include "mozilla/dom/ScriptSettings.h"
@@ -1593,84 +1594,96 @@ nsMessageManagerScriptExecutor::TryCache
   rv = NS_URIChainHasFlags(uri,
                            nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
                            &hasFlags);
   if (NS_FAILED(rv) || !hasFlags) {
     NS_WARNING("Will not load a frame script!");
     return;
   }
 
-  nsCOMPtr<nsIChannel> channel;
-  NS_NewChannel(getter_AddRefs(channel),
-                uri,
-                nsContentUtils::GetSystemPrincipal(),
-                nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
-                nsIContentPolicy::TYPE_OTHER);
-
-  if (!channel) {
+  // Compile the script in the compilation scope instead of the current global
+  // to avoid keeping the current compartment alive.
+  AutoJSAPI jsapi;
+  if (!jsapi.Init(xpc::CompilationScope())) {
     return;
   }
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JSScript*> script(cx);
 
-  nsCOMPtr<nsIInputStream> input;
-  rv = channel->Open2(getter_AddRefs(input));
-  NS_ENSURE_SUCCESS_VOID(rv);
-  nsString dataString;
-  char16_t* dataStringBuf = nullptr;
-  size_t dataStringLength = 0;
-  uint64_t avail64 = 0;
-  if (input && NS_SUCCEEDED(input->Available(&avail64)) && avail64) {
-    if (avail64 > UINT32_MAX) {
+  if (XRE_IsParentProcess()) {
+    script = ScriptPreloader::GetSingleton().GetCachedScript(cx, url);
+  }
+
+  if (!script) {
+    nsCOMPtr<nsIChannel> channel;
+    NS_NewChannel(getter_AddRefs(channel),
+                  uri,
+                  nsContentUtils::GetSystemPrincipal(),
+                  nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                  nsIContentPolicy::TYPE_OTHER);
+
+    if (!channel) {
       return;
     }
-    nsCString buffer;
-    uint32_t avail = (uint32_t)std::min(avail64, (uint64_t)UINT32_MAX);
-    if (NS_FAILED(NS_ReadInputStreamToString(input, buffer, avail))) {
+
+    nsCOMPtr<nsIInputStream> input;
+    rv = channel->Open2(getter_AddRefs(input));
+    NS_ENSURE_SUCCESS_VOID(rv);
+    nsString dataString;
+    char16_t* dataStringBuf = nullptr;
+    size_t dataStringLength = 0;
+    uint64_t avail64 = 0;
+    if (input && NS_SUCCEEDED(input->Available(&avail64)) && avail64) {
+      if (avail64 > UINT32_MAX) {
+        return;
+      }
+      nsCString buffer;
+      uint32_t avail = (uint32_t)std::min(avail64, (uint64_t)UINT32_MAX);
+      if (NS_FAILED(NS_ReadInputStreamToString(input, buffer, avail))) {
+        return;
+      }
+      nsScriptLoader::ConvertToUTF16(channel, (uint8_t*)buffer.get(), avail,
+                                     EmptyString(), nullptr,
+                                     dataStringBuf, dataStringLength);
+    }
+
+    JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength,
+                                  JS::SourceBufferHolder::GiveOwnership);
+
+    if (!dataStringBuf || dataStringLength == 0) {
       return;
     }
-    nsScriptLoader::ConvertToUTF16(channel, (uint8_t*)buffer.get(), avail,
-                                   EmptyString(), nullptr,
-                                   dataStringBuf, dataStringLength);
-  }
 
-  JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength,
-                                JS::SourceBufferHolder::GiveOwnership);
-
-  if (dataStringBuf && dataStringLength > 0) {
-    // Compile the script in the compilation scope instead of the current global
-    // to avoid keeping the current compartment alive.
-    AutoJSAPI jsapi;
-    if (!jsapi.Init(xpc::CompilationScope())) {
-      return;
-    }
-    JSContext* cx = jsapi.cx();
     JS::CompileOptions options(cx, JSVERSION_LATEST);
     options.setFileAndLine(url.get(), 1);
     options.setNoScriptRval(true);
-    JS::Rooted<JSScript*> script(cx);
 
     if (aRunInGlobalScope) {
       if (!JS::Compile(cx, options, srcBuf, &script)) {
         return;
       }
     // We're going to run these against some non-global scope.
     } else if (!JS::CompileForNonSyntacticScope(cx, options, srcBuf, &script)) {
       return;
     }
+  }
 
-    MOZ_ASSERT(script);
-    aScriptp.set(script);
+  MOZ_ASSERT(script);
+  aScriptp.set(script);
 
-    nsAutoCString scheme;
-    uri->GetScheme(scheme);
-    // We don't cache data: scripts!
-    if (aShouldCache && !scheme.EqualsLiteral("data")) {
-      // Root the object also for caching.
-      auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope);
-      sCachedScripts->Put(aURL, holder);
+  nsAutoCString scheme;
+  uri->GetScheme(scheme);
+  // We don't cache data: scripts!
+  if (aShouldCache && !scheme.EqualsLiteral("data")) {
+    if (XRE_IsParentProcess()) {
+      ScriptPreloader::GetSingleton().NoteScript(url, url, script);
     }
+    // Root the object also for caching.
+    auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope);
+    sCachedScripts->Put(aURL, holder);
   }
 }
 
 void
 nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
   const nsAString& aURL,
   bool aRunInGlobalScope)
 {
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -184,17 +184,16 @@ static uint32_t sRemovedPurples = 0;
 static uint32_t sForgetSkippableBeforeCC = 0;
 static uint32_t sPreviousSuspectedCount = 0;
 static uint32_t sCleanupsSinceLastGC = UINT32_MAX;
 static bool sNeedsFullCC = false;
 static bool sNeedsFullGC = false;
 static bool sNeedsGCAfterCC = false;
 static bool sIncrementalCC = false;
 static bool sDidPaintAfterPreviousICCSlice = false;
-static bool sUserActive = false;
 static int32_t sActiveIntersliceGCBudget = 0; // ms;
 static nsScriptNameSpaceManager *gNameSpaceManager;
 
 static PRTime sFirstCollectionTime;
 
 static JSContext* sContext;
 
 static bool sIsInitialized;
@@ -345,22 +344,20 @@ nsJSEnvironmentObserver::Observe(nsISupp
       nsJSContext::CycleCollectNow();
       if (NeedsGCAfterCC()) {
         nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
                                        nsJSContext::NonIncrementalGC,
                                        nsJSContext::ShrinkingGC);
       }
     }
   } else if (!nsCRT::strcmp(aTopic, "user-interaction-inactive")) {
-    sUserActive = false;
     if (sCompactOnUserInactive) {
       nsJSContext::PokeShrinkingGC();
     }
   } else if (!nsCRT::strcmp(aTopic, "user-interaction-active")) {
-    sUserActive = true;
     nsJSContext::KillShrinkingGCTimer();
     if (sIsCompactingOnUserInactive) {
       JS::AbortIncrementalGC(sContext);
     }
     MOZ_ASSERT(!sIsCompactingOnUserInactive);
   } else if (!nsCRT::strcmp(aTopic, "quit-application") ||
              !nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
     sShuttingDown = true;
@@ -1739,17 +1736,17 @@ nsJSContext::EndCycleCollectionCallback(
 }
 
 // static
 void
 InterSliceGCTimerFired(nsITimer *aTimer, void *aClosure)
 {
   nsJSContext::KillInterSliceGCTimer();
   bool e10sParent = XRE_IsParentProcess() && BrowserTabsRemoteAutostart();
-  int64_t budget = e10sParent && sUserActive && sActiveIntersliceGCBudget ?
+  int64_t budget = e10sParent && nsContentUtils::GetUserIsInteracting() && sActiveIntersliceGCBudget ?
     sActiveIntersliceGCBudget : NS_INTERSLICE_GC_BUDGET;
   nsJSContext::GarbageCollectNow(JS::gcreason::INTER_SLICE_GC,
                                  nsJSContext::IncrementalGC,
                                  nsJSContext::NonShrinkingGC,
                                  budget);
 }
 
 // static
--- a/dom/events/EventStates.h
+++ b/dom/events/EventStates.h
@@ -285,16 +285,18 @@ private:
 // Element has focus-within.
 #define NS_EVENT_STATE_FOCUS_WITHIN NS_DEFINE_EVENT_STATE_MACRO(43)
 // Element is ltr (for :dir pseudo-class)
 #define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(44)
 // Element is rtl (for :dir pseudo-class)
 #define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(45)
 // Element is filled by Autofill feature.
 #define NS_EVENT_STATE_AUTOFILL NS_DEFINE_EVENT_STATE_MACRO(50)
+// Element is filled with preview data by Autofill feature.
+#define NS_EVENT_STATE_AUTOFILL_PREVIEW NS_DEFINE_EVENT_STATE_MACRO(51)
 
 // Event state that is used for values that need to be parsed but do nothing.
 #define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63)
 
 /**
  * NOTE: do not go over 63 without updating EventStates::InternalType!
  */
 
@@ -303,17 +305,18 @@ private:
 // Event states that can be added and removed through
 // Element::{Add,Remove}ManuallyManagedStates.
 //
 // Take care when manually managing state bits.  You are responsible for
 // setting or clearing the bit when an Element is added or removed from a
 // document (e.g. in BindToTree and UnbindFromTree), if that is an
 // appropriate thing to do for your state bit.
 #define MANUALLY_MANAGED_STATES (             \
-  NS_EVENT_STATE_AUTOFILL                     \
+  NS_EVENT_STATE_AUTOFILL |                   \
+  NS_EVENT_STATE_AUTOFILL_PREVIEW             \
 )
 
 // Event states that are managed externally to an element (by the
 // EventStateManager, or by other code).  As opposed to those in
 // INTRINSIC_STATES, which are are computed by the element itself
 // and returned from Element::IntrinsicState.
 #define EXTERNALLY_MANAGED_STATES (           \
   MANUALLY_MANAGED_STATES |                   \
--- a/dom/interfaces/events/nsIDOMMutationEvent.idl
+++ b/dom/interfaces/events/nsIDOMMutationEvent.idl
@@ -7,16 +7,17 @@
 #include "nsIDOMNode.idl"
 
 [builtinclass, uuid(30c9997f-bc4c-4890-b890-febb6ae3051b)]
 interface nsIDOMMutationEvent : nsISupports
 {
   const unsigned short      MODIFICATION       = 1;
   const unsigned short      ADDITION           = 2;
   const unsigned short      REMOVAL            = 3;
+  const unsigned short      SMIL               = 4;
 
   readonly attribute nsIDOMNode       relatedNode;
   readonly attribute DOMString        prevValue;
   readonly attribute DOMString        newValue;
   readonly attribute DOMString        attrName;
   readonly attribute unsigned short   attrChange;
   void                      initMutationEvent(in DOMString typeArg,
                                               in boolean canBubbleArg,
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -30,16 +30,17 @@
 #include "mozilla/layers/APZCTreeManagerChild.h"
 #include "mozilla/layers/APZEventState.h"
 #include "mozilla/layers/ContentProcessController.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/DoubleTapToZoom.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/InputAPZContext.h"
+#include "mozilla/layers/PLayerTransactionChild.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/layout/RenderFrameChild.h"
 #include "mozilla/layout/RenderFrameParent.h"
 #include "mozilla/plugins/PPluginWidgetChild.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Move.h"
@@ -2708,21 +2709,19 @@ TabChild::InitRenderingState(const Textu
       ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
       gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
       InitAPZState();
     }
 
     if (lf) {
       nsTArray<LayersBackend> backends;
       backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
-      bool success;
       PLayerTransactionChild* shadowManager =
-          compositorChild->SendPLayerTransactionConstructor(backends,
-                                                            aLayersId, &mTextureFactoryIdentifier, &success);
-      if (shadowManager && success) {
+          compositorChild->SendPLayerTransactionConstructor(backends, aLayersId);
+      if (shadowManager) {
         lf->SetShadowManager(shadowManager);
         lf->IdentifyTextureHost(mTextureFactoryIdentifier);
         ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
         gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
         InitAPZState();
       }
     }
 
@@ -3095,30 +3094,30 @@ TabChild::ReinitRendering()
   RefPtr<CompositorBridgeChild> cb = CompositorBridgeChild::Get();
   if (gfxVars::UseWebRender()) {
     RefPtr<LayerManager> lm = mPuppetWidget->RecreateLayerManager(nullptr);
     MOZ_ASSERT(lm->AsWebRenderLayerManager());
     lm->AsWebRenderLayerManager()->Initialize(cb,
                                               wr::AsPipelineId(mLayersId),
                                               &mTextureFactoryIdentifier);
   } else {
-    bool success;
+    bool success = false;
     nsTArray<LayersBackend> ignored;
-    PLayerTransactionChild* shadowManager =
-      cb->SendPLayerTransactionConstructor(ignored, LayersId(), &mTextureFactoryIdentifier, &success);
+    PLayerTransactionChild* shadowManager = cb->SendPLayerTransactionConstructor(ignored, LayersId());
+    if (shadowManager &&
+        shadowManager->SendGetTextureFactoryIdentifier(&mTextureFactoryIdentifier) &&
+        mTextureFactoryIdentifier.mParentBackend != LayersBackend::LAYERS_NONE)
+    {
+      success = true;
+    }
     if (!success) {
       NS_WARNING("failed to re-allocate layer transaction");
       return;
     }
 
-    if (!shadowManager) {
-      NS_WARNING("failed to re-construct LayersChild");
-      return;
-    }
-
     RefPtr<LayerManager> lm = mPuppetWidget->RecreateLayerManager(shadowManager);
     ShadowLayerForwarder* lf = lm->AsShadowForwarder();
     lf->IdentifyTextureHost(mTextureFactoryIdentifier);
   }
 
   InitAPZState();
 
   nsCOMPtr<nsIDocument> doc(GetDocument());
--- a/dom/svg/SVGAElement.cpp
+++ b/dom/svg/SVGAElement.cpp
@@ -76,16 +76,26 @@ already_AddRefed<SVGAnimatedString>
 SVGAElement::Href()
 {
   return mStringAttributes[HREF].IsExplicitlySet()
          ? mStringAttributes[HREF].ToDOMAnimatedString(this)
          : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
 }
 
 //----------------------------------------------------------------------
+// Link methods
+
+bool
+SVGAElement::ElementHasHref() const
+{
+  return mStringAttributes[HREF].IsExplicitlySet() ||
+         mStringAttributes[XLINK_HREF].IsExplicitlySet();
+}
+
+//----------------------------------------------------------------------
 // nsINode methods
 
 nsresult
 SVGAElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
 {
   nsresult rv = Element::GetEventTargetParent(aVisitor);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -272,36 +282,32 @@ SVGAElement::IsLink(nsIURI** aURI) const
 
   static nsIContent::AttrValuesArray sShowVals[] =
     { &nsGkAtoms::_empty, &nsGkAtoms::_new, &nsGkAtoms::replace, nullptr };
 
   static nsIContent::AttrValuesArray sActuateVals[] =
     { &nsGkAtoms::_empty, &nsGkAtoms::onRequest, nullptr };
 
   // Optimization: check for href first for early return
-  bool useXLink = !HasAttr(kNameSpaceID_None, nsGkAtoms::href);
-  const nsAttrValue* href =
-    useXLink
-    ? mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink)
-    : mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_None);
+  bool useBareHref = mStringAttributes[HREF].IsExplicitlySet();
 
-  if (href &&
+  if ((useBareHref || mStringAttributes[XLINK_HREF].IsExplicitlySet()) &&
       FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::type,
                       sTypeVals, eCaseMatters) !=
                       nsIContent::ATTR_VALUE_NO_MATCH &&
       FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::show,
                       sShowVals, eCaseMatters) !=
                       nsIContent::ATTR_VALUE_NO_MATCH &&
       FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::actuate,
                       sActuateVals, eCaseMatters) !=
                       nsIContent::ATTR_VALUE_NO_MATCH) {
     nsCOMPtr<nsIURI> baseURI = GetBaseURI();
     // Get absolute URI
     nsAutoString str;
-    const uint8_t idx = useXLink ? XLINK_HREF : HREF;
+    const uint8_t idx = useBareHref ? HREF : XLINK_HREF;
     mStringAttributes[idx].GetAnimValue(str, this);
     nsContentUtils::NewURIWithDocumentCharset(aURI, str, OwnerDoc(), baseURI);
     // must promise out param is non-null if we return true
     return !!*aURI;
   }
 
   *aURI = nullptr;
   return false;
@@ -368,19 +374,17 @@ SVGAElement::UnsetAttr(int32_t aNameSpac
   // The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
   // is important here!  The attribute is not unset until UnsetAttr returns, and
   // we will need the updated attribute value because notifying the document
   // that content states have changed will call IntrinsicState, which will try
   // to get updated information about the visitedness from Link.
   if (aAttr == nsGkAtoms::href &&
       (aNameSpaceID == kNameSpaceID_XLink ||
        aNameSpaceID == kNameSpaceID_None)) {
-    bool hasHref = HasAttr(kNameSpaceID_None, nsGkAtoms::href) ||
-                   HasAttr(kNameSpaceID_XLink, nsGkAtoms::href);
-    Link::ResetLinkState(!!aNotify, hasHref);
+    Link::ResetLinkState(!!aNotify, Link::ElementHasHref());
   }
 
   return rv;
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
--- a/dom/svg/SVGAElement.h
+++ b/dom/svg/SVGAElement.h
@@ -63,16 +63,19 @@ public:
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
                            bool aNotify) override;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify) override;
 
+  // Link
+  virtual bool ElementHasHref() const override;
+
   // WebIDL
   already_AddRefed<SVGAnimatedString> Href();
   already_AddRefed<SVGAnimatedString> Target();
   void GetDownload(nsAString & aDownload);
   void SetDownload(const nsAString & aDownload, ErrorResult& rv);
 
   virtual void NodeInfoChanged(nsIDocument* aOldDoc) final override
   {
--- a/dom/svg/SVGFEImageElement.cpp
+++ b/dom/svg/SVGFEImageElement.cpp
@@ -120,26 +120,20 @@ SVGFEImageElement::IsAttributeMapped(con
 nsresult
 SVGFEImageElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify)
 {
   if (aName == nsGkAtoms::href &&
       (aNamespaceID == kNameSpaceID_XLink ||
        aNamespaceID == kNameSpaceID_None)) {
 
-    // If there isn't a frame we still need to load the image in case
-    // the frame is created later e.g. by attaching to a document.
-    // If there is a frame then it should deal with loading as the image
-    // url may be animated.
-    if (!GetPrimaryFrame()) {
-      if (aValue) {
-        LoadSVGImage(true, aNotify);
-      } else {
-        CancelImageRequests(aNotify);
-      }
+    if (aValue) {
+      LoadSVGImage(true, aNotify);
+    } else {
+      CancelImageRequests(aNotify);
     }
   }
 
   return SVGFEImageElementBase::AfterSetAttr(aNamespaceID, aName,
                                              aValue, aNotify);
 }
 
 void
--- a/dom/svg/SVGImageElement.cpp
+++ b/dom/svg/SVGImageElement.cpp
@@ -151,26 +151,20 @@ SVGImageElement::AsyncEventRunning(Async
 nsresult
 SVGImageElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                               const nsAttrValue* aValue, bool aNotify)
 {
   if (aName == nsGkAtoms::href &&
       (aNamespaceID == kNameSpaceID_None ||
        aNamespaceID == kNameSpaceID_XLink)) {
 
-    // If there isn't a frame we still need to load the image in case
-    // the frame is created later e.g. by attaching to a document.
-    // If there is a frame then it should deal with loading as the image
-    // url may be animated
-    if (!GetPrimaryFrame()) {
-      if (aValue) {
-        LoadSVGImage(true, aNotify);
-      } else {
-        CancelImageRequests(aNotify);
-      }
+    if (aValue) {
+      LoadSVGImage(true, aNotify);
+    } else {
+      CancelImageRequests(aNotify);
     }
   }
   return SVGImageElementBase::AfterSetAttr(aNamespaceID, aName,
                                            aValue, aNotify);
 }
 
 void
 SVGImageElement::MaybeLoadSVGImage()
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -1607,17 +1607,17 @@ nsSVGElement::DidAnimateLength(uint8_t a
   ClearAnyCachedPath();
 
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     LengthAttributesInfo info = GetLengthInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mLengthInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsSVGLength2*
 nsSVGElement::GetAnimatedLength(const nsIAtom *aAttrName)
 {
   LengthAttributesInfo lengthInfo = GetLengthInfo();
 
@@ -1704,17 +1704,17 @@ void
 nsSVGElement::DidAnimateLengthList(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     LengthListAttributesInfo info = GetLengthListInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mLengthListInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 void
 nsSVGElement::GetAnimatedLengthListValues(SVGUserUnitList *aFirst, ...)
 {
   LengthListAttributesInfo info = GetLengthListInfo();
 
@@ -1792,17 +1792,17 @@ nsSVGElement::DidAnimateNumberList(uint8
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     NumberListAttributesInfo info = GetNumberListInfo();
     MOZ_ASSERT(aAttrEnum < info.mNumberListCount, "aAttrEnum out of range");
 
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mNumberListInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 SVGAnimatedNumberList*
 nsSVGElement::GetAnimatedNumberList(uint8_t aAttrEnum)
 {
   NumberListAttributesInfo info = GetNumberListInfo();
   if (aAttrEnum < info.mNumberListCount) {
@@ -1853,17 +1853,17 @@ nsSVGElement::DidAnimatePointList()
 
   ClearAnyCachedPath();
 
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     frame->AttributeChanged(kNameSpaceID_None,
                             GetPointListAttrName(),
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsAttrValue
 nsSVGElement::WillChangePathSegList()
 {
   MOZ_ASSERT(GetPathDataAttrName(),
              "Changing non-existent path seg list?");
@@ -1890,17 +1890,17 @@ nsSVGElement::DidAnimatePathSegList()
 
   ClearAnyCachedPath();
 
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     frame->AttributeChanged(kNameSpaceID_None,
                             GetPathDataAttrName(),
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsSVGElement::NumberAttributesInfo
 nsSVGElement::GetNumberInfo()
 {
   return NumberAttributesInfo(nullptr, nullptr, 0);
 }
@@ -1931,17 +1931,17 @@ void
 nsSVGElement::DidAnimateNumber(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     NumberAttributesInfo info = GetNumberInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mNumberInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 void
 nsSVGElement::GetAnimatedNumberValues(float *aFirst, ...)
 {
   NumberAttributesInfo info = GetNumberInfo();
 
@@ -2001,17 +2001,17 @@ void
 nsSVGElement::DidAnimateNumberPair(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     NumberPairAttributesInfo info = GetNumberPairInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mNumberPairInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsSVGElement::IntegerAttributesInfo
 nsSVGElement::GetIntegerInfo()
 {
   return IntegerAttributesInfo(nullptr, nullptr, 0);
 }
@@ -2042,17 +2042,17 @@ void
 nsSVGElement::DidAnimateInteger(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
   
   if (frame) {
     IntegerAttributesInfo info = GetIntegerInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mIntegerInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 void
 nsSVGElement::GetAnimatedIntegerValues(int32_t *aFirst, ...)
 {
   IntegerAttributesInfo info = GetIntegerInfo();
 
@@ -2113,17 +2113,17 @@ void
 nsSVGElement::DidAnimateIntegerPair(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
   
   if (frame) {
     IntegerPairAttributesInfo info = GetIntegerPairInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mIntegerPairInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsSVGElement::AngleAttributesInfo
 nsSVGElement::GetAngleInfo()
 {
   return AngleAttributesInfo(nullptr, nullptr, 0);
 }
@@ -2161,17 +2161,17 @@ void
 nsSVGElement::DidAnimateAngle(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     AngleAttributesInfo info = GetAngleInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mAngleInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsSVGElement::BooleanAttributesInfo
 nsSVGElement::GetBooleanInfo()
 {
   return BooleanAttributesInfo(nullptr, nullptr, 0);
 }
@@ -2200,17 +2200,17 @@ void
 nsSVGElement::DidAnimateBoolean(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
   
   if (frame) {
     BooleanAttributesInfo info = GetBooleanInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mBooleanInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsSVGElement::EnumAttributesInfo
 nsSVGElement::GetEnumInfo()
 {
   return EnumAttributesInfo(nullptr, nullptr, 0);
 }
@@ -2239,17 +2239,17 @@ void
 nsSVGElement::DidAnimateEnum(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     EnumAttributesInfo info = GetEnumInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mEnumInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsSVGViewBox *
 nsSVGElement::GetViewBox()
 {
   return nullptr;
 }
@@ -2276,17 +2276,17 @@ nsSVGElement::DidChangeViewBox(const nsA
 void
 nsSVGElement::DidAnimateViewBox()
 {
   nsIFrame* frame = GetPrimaryFrame();
   
   if (frame) {
     frame->AttributeChanged(kNameSpaceID_None,
                             nsGkAtoms::viewBox,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 SVGAnimatedPreserveAspectRatio *
 nsSVGElement::GetPreserveAspectRatio()
 {
   return nullptr;
 }
@@ -2316,17 +2316,17 @@ nsSVGElement::DidChangePreserveAspectRat
 void
 nsSVGElement::DidAnimatePreserveAspectRatio()
 {
   nsIFrame* frame = GetPrimaryFrame();
   
   if (frame) {
     frame->AttributeChanged(kNameSpaceID_None,
                             nsGkAtoms::preserveAspectRatio,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsAttrValue
 nsSVGElement::WillChangeTransformList()
 {
   return WillChangeValue(GetTransformListAttrName());
 }
@@ -2414,17 +2414,17 @@ void
 nsSVGElement::DidAnimateString(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     StringAttributesInfo info = GetStringInfo();
     frame->AttributeChanged(info.mStringInfo[aAttrEnum].mNamespaceID,
                             *info.mStringInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::MODIFICATION);
+                            nsIDOMMutationEvent::SMIL);
   }
 }
 
 nsSVGElement::StringListAttributesInfo
 nsSVGElement::GetStringListInfo()
 {
   return StringListAttributesInfo(nullptr, nullptr, 0);
 }
new file mode 100644
--- /dev/null
+++ b/extensions/permissions/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+UNIFIED_SOURCES += [
+    'nsContentBlocker.cpp',
+    'nsModuleFactory.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
+
+with Files('**'):
+    BUG_COMPONENT = ('Core', 'DOM')
new file mode 100644
--- /dev/null
+++ b/extensions/permissions/nsContentBlocker.cpp
@@ -0,0 +1,384 @@
+/* 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 "nsContentBlocker.h"
+#include "nsIContent.h"
+#include "nsIURI.h"
+#include "nsIServiceManager.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsIDocShell.h"
+#include "nsString.h"
+#include "nsContentPolicyUtils.h"
+#include "nsIObjectLoadingContent.h"
+#include "mozilla/ArrayUtils.h"
+#include "nsContentUtils.h"
+
+// Possible behavior pref values
+// Those map to the nsIPermissionManager values where possible
+#define BEHAVIOR_ACCEPT nsIPermissionManager::ALLOW_ACTION
+#define BEHAVIOR_REJECT nsIPermissionManager::DENY_ACTION
+#define BEHAVIOR_NOFOREIGN 3
+
+// From nsIContentPolicy
+static const char *kTypeString[] = {
+                                    "other",
+                                    "script",
+                                    "image",
+                                    "stylesheet",
+                                    "object",
+                                    "document",
+                                    "subdocument",
+                                    "refresh",
+                                    "xbl",
+                                    "ping",
+                                    "xmlhttprequest",
+                                    "objectsubrequest",
+                                    "dtd",
+                                    "font",
+                                    "media",
+                                    "websocket",
+                                    "csp_report",
+                                    "xslt",
+                                    "beacon",
+                                    "fetch",
+                                    "image",
+                                    "manifest",
+                                    "", // TYPE_INTERNAL_SCRIPT
+                                    "", // TYPE_INTERNAL_WORKER
+                                    "", // TYPE_INTERNAL_SHARED_WORKER
+                                    "", // TYPE_INTERNAL_EMBED
+                                    "", // TYPE_INTERNAL_OBJECT
+                                    "", // TYPE_INTERNAL_FRAME
+                                    "", // TYPE_INTERNAL_IFRAME
+                                    "", // TYPE_INTERNAL_AUDIO
+                                    "", // TYPE_INTERNAL_VIDEO
+                                    "", // TYPE_INTERNAL_TRACK
+                                    "", // TYPE_INTERNAL_XMLHTTPREQUEST
+                                    "", // TYPE_INTERNAL_EVENTSOURCE
+                                    "", // TYPE_INTERNAL_SERVICE_WORKER
+                                    "", // TYPE_INTERNAL_SCRIPT_PRELOAD
+                                    "", // TYPE_INTERNAL_IMAGE
+                                    "", // TYPE_INTERNAL_IMAGE_PRELOAD
+                                    "", // TYPE_INTERNAL_STYLESHEET
+                                    "", // TYPE_INTERNAL_STYLESHEET_PRELOAD
+                                    "", // TYPE_INTERNAL_IMAGE_FAVICON
+                                    "", // TYPE_INTERNAL_WORKERS_IMPORT_SCRIPTS
+};
+
+#define NUMBER_OF_TYPES MOZ_ARRAY_LENGTH(kTypeString)
+uint8_t nsContentBlocker::mBehaviorPref[NUMBER_OF_TYPES];
+
+NS_IMPL_ISUPPORTS(nsContentBlocker, 
+                  nsIContentPolicy,
+                  nsIObserver,
+                  nsISupportsWeakReference)
+
+nsContentBlocker::nsContentBlocker()
+{
+  memset(mBehaviorPref, BEHAVIOR_ACCEPT, NUMBER_OF_TYPES);
+}
+
+nsresult
+nsContentBlocker::Init()
+{
+  nsresult rv;
+  mPermissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIPrefBranch> prefBranch;
+  rv = prefService->GetBranch("permissions.default.", getter_AddRefs(prefBranch));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Migrate old image blocker pref
+  nsCOMPtr<nsIPrefBranch> oldPrefBranch;
+  oldPrefBranch = do_QueryInterface(prefService);
+  int32_t oldPref;
+  rv = oldPrefBranch->GetIntPref("network.image.imageBehavior", &oldPref);
+  if (NS_SUCCEEDED(rv) && oldPref) {
+    int32_t newPref;
+    switch (oldPref) {
+      default:
+        newPref = BEHAVIOR_ACCEPT;
+        break;
+      case 1:
+        newPref = BEHAVIOR_NOFOREIGN;
+        break;
+      case 2:
+        newPref = BEHAVIOR_REJECT;
+        break;
+    }
+    prefBranch->SetIntPref("image", newPref);
+    oldPrefBranch->ClearUserPref("network.image.imageBehavior");
+  }
+
+
+  // The branch is not a copy of the prefservice, but a new object, because
+  // it is a non-default branch. Adding obeservers to it will only work if
+  // we make sure that the object doesn't die. So, keep a reference to it.
+  mPrefBranchInternal = do_QueryInterface(prefBranch, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = mPrefBranchInternal->AddObserver("", this, true);
+  PrefChanged(prefBranch, nullptr);
+
+  return rv;
+}
+
+#undef  LIMIT
+#define LIMIT(x, low, high, default) ((x) >= (low) && (x) <= (high) ? (x) : (default))
+
+void
+nsContentBlocker::PrefChanged(nsIPrefBranch *aPrefBranch,
+                              const char    *aPref)
+{
+  int32_t val;
+
+#define PREF_CHANGED(_P) (!aPref || !strcmp(aPref, _P))
+
+  for(uint32_t i = 0; i < NUMBER_OF_TYPES; ++i) {
+    if (*kTypeString[i] &&
+        PREF_CHANGED(kTypeString[i]) &&
+        NS_SUCCEEDED(aPrefBranch->GetIntPref(kTypeString[i], &val)))
+      mBehaviorPref[i] = LIMIT(val, 1, 3, 1);
+  }
+
+}
+
+// nsIContentPolicy Implementation
+NS_IMETHODIMP 
+nsContentBlocker::ShouldLoad(uint32_t          aContentType,
+                             nsIURI           *aContentLocation,
+                             nsIURI           *aRequestingLocation,
+                             nsISupports      *aRequestingContext,
+                             const nsACString &aMimeGuess,
+                             nsISupports      *aExtra,
+                             nsIPrincipal     *aRequestPrincipal,
+                             int16_t          *aDecision)
+{
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
+  *aDecision = nsIContentPolicy::ACCEPT;
+  nsresult rv;
+
+  // Ony support NUMBER_OF_TYPES content types. that all there is at the
+  // moment, but you never know...
+  if (aContentType > NUMBER_OF_TYPES)
+    return NS_OK;
+  
+  // we can't do anything without this
+  if (!aContentLocation)
+    return NS_OK;
+
+  // The final type of an object tag may mutate before it reaches
+  // shouldProcess, so we cannot make any sane blocking decisions here
+  if (aContentType == nsIContentPolicy::TYPE_OBJECT)
+    return NS_OK;
+  
+  // we only want to check http, https, ftp
+  // for chrome:// and resources and others, no need to check.
+  nsAutoCString scheme;
+  aContentLocation->GetScheme(scheme);
+  if (!scheme.LowerCaseEqualsLiteral("ftp") &&
+      !scheme.LowerCaseEqualsLiteral("http") &&
+      !scheme.LowerCaseEqualsLiteral("https"))
+    return NS_OK;
+
+  bool shouldLoad, fromPrefs;
+  rv = TestPermission(aContentLocation, aRequestingLocation, aContentType,
+                      &shouldLoad, &fromPrefs);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!shouldLoad) {
+    if (fromPrefs) {
+      *aDecision = nsIContentPolicy::REJECT_TYPE;
+    } else {
+      *aDecision = nsIContentPolicy::REJECT_SERVER;
+    }
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsContentBlocker::ShouldProcess(uint32_t          aContentType,
+                                nsIURI           *aContentLocation,
+                                nsIURI           *aRequestingLocation,
+                                nsISupports      *aRequestingContext,
+                                const nsACString &aMimeGuess,
+                                nsISupports      *aExtra,
+                                nsIPrincipal     *aRequestPrincipal,
+                                int16_t          *aDecision)
+{
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
+  // For loads where aRequestingContext is chrome, we should just
+  // accept.  Those are most likely toplevel loads in windows, and
+  // chrome generally knows what it's doing anyway.
+  nsCOMPtr<nsIDocShellTreeItem> item =
+    do_QueryInterface(NS_CP_GetDocShellFromContext(aRequestingContext));
+
+  if (item && item->ItemType() == nsIDocShellTreeItem::typeChrome) {
+    *aDecision = nsIContentPolicy::ACCEPT;
+    return NS_OK;
+  }
+
+  // For objects, we only check policy in shouldProcess, as the final type isn't
+  // determined until the channel is open -- We don't want to block images in
+  // object tags because plugins are disallowed.
+  // NOTE that this bypasses the aContentLocation checks in ShouldLoad - this is
+  // intentional, as aContentLocation may be null for plugins that load by type
+  // (e.g. java)
+  if (aContentType == nsIContentPolicy::TYPE_OBJECT) {
+    *aDecision = nsIContentPolicy::ACCEPT;
+
+    bool shouldLoad, fromPrefs;
+    nsresult rv = TestPermission(aContentLocation, aRequestingLocation,
+                                 aContentType, &shouldLoad, &fromPrefs);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (!shouldLoad) {
+      if (fromPrefs) {
+        *aDecision = nsIContentPolicy::REJECT_TYPE;
+      } else {
+        *aDecision = nsIContentPolicy::REJECT_SERVER;
+      }
+    }
+    return NS_OK;
+  }
+  
+  // This isn't a load from chrome or an object tag - Just do a ShouldLoad()
+  // check -- we want the same answer here
+  return ShouldLoad(aContentType, aContentLocation, aRequestingLocation,
+                    aRequestingContext, aMimeGuess, aExtra, aRequestPrincipal,
+                    aDecision);
+}
+
+nsresult
+nsContentBlocker::TestPermission(nsIURI *aCurrentURI,
+                                 nsIURI *aFirstURI,
+                                 int32_t aContentType,
+                                 bool *aPermission,
+                                 bool *aFromPrefs)
+{
+  *aFromPrefs = false;
+
+  if (!*kTypeString[aContentType - 1]) {
+    // Disallow internal content policy types, they should not be used here.
+    *aPermission = false;
+    return NS_OK;
+  }
+
+  // This default will also get used if there is an unknown value in the
+  // permission list, or if the permission manager returns unknown values.
+  *aPermission = true;
+
+  // check the permission list first; if we find an entry, it overrides
+  // default prefs.
+  // Don't forget the aContentType ranges from 1..8, while the
+  // array is indexed 0..7
+  uint32_t permission;
+  nsresult rv = mPermissionManager->TestPermission(aCurrentURI, 
+                                                   kTypeString[aContentType - 1],
+                                                   &permission);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // If there is nothing on the list, use the default.
+  if (!permission) {
+    permission = mBehaviorPref[aContentType - 1];
+    *aFromPrefs = true;
+  }
+
+  // Use the fact that the nsIPermissionManager values map to 
+  // the BEHAVIOR_* values above.
+  switch (permission) {
+  case BEHAVIOR_ACCEPT:
+    *aPermission = true;
+    break;
+  case BEHAVIOR_REJECT:
+    *aPermission = false;
+    break;
+
+  case BEHAVIOR_NOFOREIGN:
+    // Third party checking
+
+    // Need a requesting uri for third party checks to work.
+    if (!aFirstURI)
+      return NS_OK;
+
+    bool trustedSource = false;
+    rv = aFirstURI->SchemeIs("chrome", &trustedSource);
+    NS_ENSURE_SUCCESS(rv,rv);
+    if (!trustedSource) {
+      rv = aFirstURI->SchemeIs("resource", &trustedSource);
+      NS_ENSURE_SUCCESS(rv,rv);
+    }
+    if (trustedSource)
+      return NS_OK;
+
+    // compare tails of names checking to see if they have a common domain
+    // we do this by comparing the tails of both names where each tail 
+    // includes at least one dot
+    
+    // A more generic method somewhere would be nice
+
+    nsAutoCString currentHost;
+    rv = aCurrentURI->GetAsciiHost(currentHost);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // Search for two dots, starting at the end.
+    // If there are no two dots found, ++dot will turn to zero,
+    // that will return the entire string.
+    int32_t dot = currentHost.RFindChar('.');
+    dot = currentHost.RFindChar('.', dot-1);
+    ++dot;
+
+    // Get the domain, ie the last part of the host (www.domain.com -> domain.com)
+    // This will break on co.uk
+    const nsCSubstring &tail =
+      Substring(currentHost, dot, currentHost.Length() - dot);
+
+    nsAutoCString firstHost;
+    rv = aFirstURI->GetAsciiHost(firstHost);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // If the tail is longer then the whole firstHost, it will never match
+    if (firstHost.Length() < tail.Length()) {
+      *aPermission = false;
+      return NS_OK;
+    }
+    
+    // Get the last part of the firstUri with the same length as |tail|
+    const nsCSubstring &firstTail = 
+      Substring(firstHost, firstHost.Length() - tail.Length(), tail.Length());
+
+    // Check that both tails are the same, and that just before the tail in
+    // |firstUri| there is a dot. That means both url are in the same domain
+    if ((firstHost.Length() > tail.Length() && 
+         firstHost.CharAt(firstHost.Length() - tail.Length() - 1) != '.') || 
+        !tail.Equals(firstTail)) {
+      *aPermission = false;
+    }
+    break;
+  }
+  
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsContentBlocker::Observe(nsISupports     *aSubject,
+                          const char      *aTopic,
+                          const char16_t *aData)
+{
+  NS_ASSERTION(!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic),
+               "unexpected topic - we only deal with pref changes!");
+
+  if (mPrefBranchInternal)
+    PrefChanged(mPrefBranchInternal, NS_LossyConvertUTF16toASCII(aData).get());
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/extensions/permissions/nsContentBlocker.h
@@ -0,0 +1,53 @@
+/* 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 nsContentBlocker_h__
+#define nsContentBlocker_h__
+
+#include "nsIContentPolicy.h"
+#include "nsIObserver.h"
+#include "nsWeakReference.h"
+#include "nsIPermissionManager.h"
+#include "nsIPrefBranch.h"
+#include "mozilla/Attributes.h"
+
+class nsIPrefBranch;
+
+////////////////////////////////////////////////////////////////////////////////
+
+class nsContentBlocker final : public nsIContentPolicy,
+                               public nsIObserver,
+                               public nsSupportsWeakReference
+{
+public:
+
+  // nsISupports
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSICONTENTPOLICY
+  NS_DECL_NSIOBSERVER
+
+  nsContentBlocker();
+  nsresult Init();
+
+private:
+  ~nsContentBlocker() {}
+
+  void PrefChanged(nsIPrefBranch *, const char *);
+  nsresult TestPermission(nsIURI *aCurrentURI,
+                          nsIURI *aFirstURI,
+                          int32_t aContentType,
+                          bool *aPermission,
+                          bool *aFromPrefs);
+
+  nsCOMPtr<nsIPermissionManager> mPermissionManager;
+  nsCOMPtr<nsIPrefBranch> mPrefBranchInternal;
+  static uint8_t mBehaviorPref[];
+};
+
+#define NS_CONTENTBLOCKER_CID \
+{ 0x4ca6b67b, 0x5cc7, 0x4e71, \
+  { 0xa9, 0x8a, 0x97, 0xaf, 0x1c, 0x13, 0x48, 0x62 } }
+
+#define NS_CONTENTBLOCKER_CONTRACTID "@mozilla.org/permissions/contentblocker;1"
+
+#endif /* nsContentBlocker_h__ */
new file mode 100644
--- /dev/null
+++ b/extensions/permissions/nsModuleFactory.cpp
@@ -0,0 +1,37 @@
+/* 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/ModuleUtils.h"
+#include "nsIServiceManager.h"
+#include "nsContentBlocker.h"
+#include "nsXPIDLString.h"
+
+// Define the constructor function for the objects
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsContentBlocker, Init)
+
+NS_DEFINE_NAMED_CID(NS_CONTENTBLOCKER_CID);
+
+static const mozilla::Module::CIDEntry kPermissionsCIDs[] = {
+  { &kNS_CONTENTBLOCKER_CID, false, nullptr, nsContentBlockerConstructor },
+  { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kPermissionsContracts[] = {
+  { NS_CONTENTBLOCKER_CONTRACTID, &kNS_CONTENTBLOCKER_CID },
+  { nullptr }
+};
+
+static const mozilla::Module::CategoryEntry kPermissionsCategories[] = {
+  { "content-policy", NS_CONTENTBLOCKER_CONTRACTID, NS_CONTENTBLOCKER_CONTRACTID },
+  { nullptr }
+};
+
+static const mozilla::Module kPermissionsModule = {
+  mozilla::Module::kVersion,
+  kPermissionsCIDs,
+  kPermissionsContracts,
+  kPermissionsCategories
+};
+
+NSMODULE_DEFN(nsPermissionsModule) = &kPermissionsModule;
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -325,20 +325,17 @@ CompositorBridgeChild::CompositorIsInGPU
   if (!bridge) {
     return false;
   }
 
   return bridge->OtherPid() != dom::ContentChild::GetSingleton()->OtherPid();
 }
 
 PLayerTransactionChild*
-CompositorBridgeChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
-                                                   const uint64_t& aId,
-                                                   TextureFactoryIdentifier*,
-                                                   bool*)
+CompositorBridgeChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints, const uint64_t& aId)
 {
   LayerTransactionChild* c = new LayerTransactionChild(aId);
   c->AddIPDLReference();
 
   TabChild* tabChild = TabChild::GetFrom(c->GetId());
 
   // Do the DOM Labeling.
   if (tabChild) {
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -244,19 +244,17 @@ private:
   // Private destructor, to discourage deletion outside of Release():
   virtual ~CompositorBridgeChild();
 
   void InitIPDL();
   void DeallocPCompositorBridgeChild() override;
 
   virtual PLayerTransactionChild*
     AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
-                                const uint64_t& aId,
-                                TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                bool* aSuccess) override;
+                                const uint64_t& aId) override;
 
   virtual bool DeallocPLayerTransactionChild(PLayerTransactionChild *aChild) override;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual mozilla::ipc::IPCResult RecvSharedCompositorFrameMetrics(const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
                                                                    const CrossProcessMutexHandle& handle,
                                                                    const uint64_t& aLayersId,
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1438,36 +1438,31 @@ CompositorBridgeParent::NewCompositor(co
 #endif
   }
 
   return nullptr;
 }
 
 PLayerTransactionParent*
 CompositorBridgeParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
-                                                     const uint64_t& aId,
-                                                     TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                               bool *aSuccess)
+                                                     const uint64_t& aId)
 {
   MOZ_ASSERT(aId == 0);
 
   InitializeLayerManager(aBackendHints);
 
   if (!mLayerManager) {
     NS_WARNING("Failed to initialise Compositor");
-    *aSuccess = false;
     LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0);
     p->AddIPDLReference();
     return p;
   }
 
   mCompositionManager = new AsyncCompositionManager(this, mLayerManager);
-  *aSuccess = true;
 
-  *aTextureFactoryIdentifier = mLayerManager->GetTextureFactoryIdentifier();
   LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
   p->AddIPDLReference();
   return p;
 }
 
 bool
 CompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* actor)
 {
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -506,19 +506,17 @@ private:
 protected:
   // Protected destructor, to discourage deletion outside of Release():
   virtual ~CompositorBridgeParent();
 
   void DeferredDestroy();
 
   virtual PLayerTransactionParent*
     AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
-                                 const uint64_t& aId,
-                                 TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                 bool* aSuccess) override;
+                                 const uint64_t& aId) override;
   virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) override;
   virtual void ScheduleTask(already_AddRefed<CancelableRunnable>, int);
 
   void SetEGLSurfaceSize(int width, int height);
 
   void InitializeLayerManager(const nsTArray<LayersBackend>& aBackendHints);
 
 public:
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -57,19 +57,17 @@ CrossProcessCompositorBridgeParent::Acto
   // We must keep this object alive untill the code handling message
   // reception is finished on this thread.
   MessageLoop::current()->PostTask(NewRunnableMethod(this, &CrossProcessCompositorBridgeParent::DeferredDestroy));
 }
 
 PLayerTransactionParent*
 CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent(
   const nsTArray<LayersBackend>&,
-  const uint64_t& aId,
-  TextureFactoryIdentifier* aTextureFactoryIdentifier,
-  bool *aSuccess)
+  const uint64_t& aId)
 {
   MOZ_ASSERT(aId != 0);
 
   // Check to see if this child process has access to this layer tree.
   if (!LayerTreeOwnerTracker::Get()->IsMapped(aId, OtherPid())) {
     NS_ERROR("Unexpected layers id in AllocPLayerTransactionParent; dropping message...");
     return nullptr;
   }
@@ -80,29 +78,26 @@ CrossProcessCompositorBridgeParent::Allo
   LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
   if (sIndirectLayerTrees.end() != itr) {
     state = &itr->second;
   }
 
   if (state && state->mLayerManager) {
     state->mCrossProcessParent = this;
     HostLayerManager* lm = state->mLayerManager;
-    *aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
-    *aSuccess = true;
     LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
     p->AddIPDLReference();
     sIndirectLayerTrees[aId].mLayerTree = p;
     if (state->mPendingCompositorUpdate) {
       p->SetPendingCompositorUpdate(state->mPendingCompositorUpdate.value());
     }
     return p;
   }
 
   NS_WARNING("Created child without a matching parent?");
-  *aSuccess = false;
   LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId);
   p->AddIPDLReference();
   return p;
 }
 
 bool
 CrossProcessCompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
 {
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
@@ -87,19 +87,17 @@ public:
 
   /**
    * Tells this CompositorBridgeParent to send a message when the compositor has received the transaction.
    */
   virtual mozilla::ipc::IPCResult RecvRequestNotifyAfterRemotePaint() override;
 
   virtual PLayerTransactionParent*
     AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
-                                 const uint64_t& aId,
-                                 TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                 bool *aSuccess) override;
+                                 const uint64_t& aId) override;
 
   virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) override;
 
   virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
                                    const TransactionInfo& aInfo,
                                    bool aHitTestUpdate) override;
   virtual void ForceComposite(LayerTransactionParent* aLayerTree) override;
   virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) override;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -1048,10 +1048,22 @@ LayerTransactionParent::RecvRecordPaintT
   // we could be smarter and use paint timings from the UI process, either
   // as a separate overlay or if no remote layers are attached.
   if (mLayerManager && mCompositorBridge->IsRemote()) {
     mLayerManager->RecordPaintTimes(aTiming);
   }
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+LayerTransactionParent::RecvGetTextureFactoryIdentifier(TextureFactoryIdentifier* aIdentifier)
+{
+  if (!mLayerManager) {
+    // Default constructor sets mParentBackend to LAYERS_NONE.
+    return IPC_OK();
+  }
+
+  *aIdentifier = mLayerManager->GetTextureFactoryIdentifier();
+  return IPC_OK();
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -136,16 +136,17 @@ protected:
   virtual mozilla::ipc::IPCResult RecvSetAsyncZoom(const FrameMetrics::ViewID& aId,
                                                    const float& aValue) override;
   virtual mozilla::ipc::IPCResult RecvFlushApzRepaints() override;
   virtual mozilla::ipc::IPCResult RecvGetAPZTestData(APZTestData* aOutData) override;
   virtual mozilla::ipc::IPCResult RecvRequestProperty(const nsString& aProperty, float* aValue) override;
   virtual mozilla::ipc::IPCResult RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
                                                              nsTArray<ScrollableLayerGuid>&& aTargets) override;
   virtual mozilla::ipc::IPCResult RecvRecordPaintTimes(const PaintTiming& aTiming) override;
+  virtual mozilla::ipc::IPCResult RecvGetTextureFactoryIdentifier(TextureFactoryIdentifier* aIdentifier) override;
 
   bool SetLayerAttributes(const OpSetLayerAttributes& aOp);
 
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   template <typename T>
   bool BindLayer(const RefPtr<Layer>& aLayer, const T& aCreateOp) {
     return BindLayerToHandle(aLayer, aCreateOp.layer());
--- a/gfx/layers/ipc/PCompositorBridge.ipdl
+++ b/gfx/layers/ipc/PCompositorBridge.ipdl
@@ -217,18 +217,17 @@ parent:
     returns (uint32_t startIndex);
 
   sync StopFrameTimeRecording(uint32_t startIndex)
     returns (float[] intervals);
 
   // layersBackendHints is an ordered list of preffered backends where
   // layersBackendHints[0] is the best backend. If any hints are LayersBackend::LAYERS_NONE
   // that hint is ignored.
-  sync PLayerTransaction(LayersBackend[] layersBackendHints, uint64_t id)
-    returns (TextureFactoryIdentifier textureFactoryIdentifier, bool success);
+  async PLayerTransaction(LayersBackend[] layersBackendHints, uint64_t id);
 
   // Notify the compositor that a region of the screen has been invalidated.
   async NotifyRegionInvalidated(nsIntRegion region);
 
   /**
    * The child (content/chrome thread) requests that the parent inform it when
    * the graphics objects are ready to display.
    * @see PBrowser
--- a/gfx/layers/ipc/PLayerTransaction.ipdl
+++ b/gfx/layers/ipc/PLayerTransaction.ipdl
@@ -13,16 +13,17 @@ include protocol PTexture;
 
 include "mozilla/GfxMessageUtils.h";
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using class mozilla::layers::APZTestData from "mozilla/layers/APZTestData.h";
 using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
 using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
+using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::LayerHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
 
 /**
  * The layers protocol is spoken between thread contexts that manage
  * layer (sub)trees.  The protocol comprises atomically publishing
  * layer subtrees to a "shadow" thread context (which grafts the
@@ -113,16 +114,19 @@ parent:
 
   // Get a copy of the compositor-side APZ test data instance for this
   // layers id.
   sync GetAPZTestData() returns (APZTestData data);
 
   // Query a named property from the last frame
   sync RequestProperty(nsString property) returns (float value);
 
+  // Return the TextureFactoryIdentifier for this compositor.
+  sync GetTextureFactoryIdentifier() returns (TextureFactoryIdentifier aIdentifier);
+
   // Tell the compositor to notify APZ that a layer has been confirmed for an
   // input event.
   async SetConfirmedTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);
 
   async RecordPaintTimes(PaintTiming timing);
 
   async Shutdown();
 child:
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -845,16 +845,25 @@ ChooseFontSize(gfxFontconfigFontEntry* a
                               FC_PIXEL_SIZE, v, &size) == FcResultMatch) {
         ++v;
         double dist = fabs(size - requestedSize);
         if (bestDist < 0.0 || dist < bestDist) {
             bestDist = dist;
             bestSize = size;
         }
     }
+    // If the font has bitmaps but wants to be scaled, then let it scale.
+    if (bestSize >= 0.0) {
+        FcBool scalable;
+        if (FcPatternGetBool(aEntry->GetPattern(),
+                             FC_SCALABLE, 0, &scalable) == FcResultMatch &&
+            scalable) {
+            return requestedSize;
+        }
+    }
     return bestSize;
 }
 
 gfxFont*
 gfxFontconfigFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle,
                                            bool aNeedsBold)
 {
     nsAutoRef<FcPattern> pattern(FcPatternCreate());
@@ -1007,45 +1016,53 @@ gfxFontconfigFontFamily::AddFontPattern(
 {
     NS_ASSERTION(!mHasStyles,
                  "font patterns must not be added to already enumerated families");
 
     FcBool outline;
     if (FcPatternGetBool(aFontPattern, FC_OUTLINE, 0, &outline) != FcResultMatch ||
         !outline) {
         mHasNonScalableFaces = true;
+
+        FcBool scalable;
+        if (FcPatternGetBool(aFontPattern, FC_SCALABLE, 0, &scalable) == FcResultMatch &&
+            scalable) {
+            mForceScalable = true;
+        }
     }
 
     nsCountedRef<FcPattern> pattern(aFontPattern);
     mFontPatterns.AppendElement(pattern);
 }
 
 static const double kRejectDistance = 10000.0;
 
 // Calculate a distance score representing the size disparity between the
 // requested style's size and the font entry's size.
 static double
-SizeDistance(gfxFontconfigFontEntry* aEntry, const gfxFontStyle& aStyle)
+SizeDistance(gfxFontconfigFontEntry* aEntry,
+             const gfxFontStyle& aStyle,
+             bool aForceScalable)
 {
     double requestedSize = SizeForStyle(aEntry, aStyle);
     double bestDist = -1.0;
     double size;
     int v = 0;
     while (FcPatternGetDouble(aEntry->GetPattern(),
                               FC_PIXEL_SIZE, v, &size) == FcResultMatch) {
         ++v;
         double dist = fabs(size - requestedSize);
         if (bestDist < 0.0 || dist < bestDist) {
             bestDist = dist;
         }
     }
     if (bestDist < 0.0) {
         // No size means scalable
         return -1.0;
-    } else if (5.0 * bestDist < requestedSize) {
+    } else if (aForceScalable || 5.0 * bestDist < requestedSize) {
         // fontconfig prefers a matching family or lang to pixelsize of bitmap
         // fonts. CSS suggests a tolerance of 20% on pixelsize.
         return bestDist;
     } else {
         // Reject any non-scalable fonts that are not within tolerance.
         return kRejectDistance;
     }
 }
@@ -1069,17 +1086,17 @@ gfxFontconfigFontFamily::FindAllFontsFor
     // available size is rejected for being outside tolernace, then the
     // entire group will be skipped.
     size_t skipped = 0;
     gfxFontconfigFontEntry* bestEntry = nullptr;
     double bestDist = -1.0;
     for (size_t i = 0; i < aFontEntryList.Length(); i++) {
         gfxFontconfigFontEntry* entry =
             static_cast<gfxFontconfigFontEntry*>(aFontEntryList[i]);
-        double dist = SizeDistance(entry, aFontStyle);
+        double dist = SizeDistance(entry, aFontStyle, mForceScalable);
         // If the entry is scalable or has a style that does not match
         // the group of unscalable fonts, then start a new group.
         if (dist < 0.0 ||
             !bestEntry ||
             bestEntry->Stretch() != entry->Stretch() ||
             bestEntry->Weight() != entry->Weight() ||
             bestEntry->mStyle != entry->mStyle) {
             // If the best entry in this group is still outside the tolerance,
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -190,17 +190,18 @@ protected:
     UnscaledFontCache mUnscaledFontCache;
 };
 
 class gfxFontconfigFontFamily : public gfxFontFamily {
 public:
     explicit gfxFontconfigFontFamily(const nsAString& aName) :
         gfxFontFamily(aName),
         mContainsAppFonts(false),
-        mHasNonScalableFaces(false)
+        mHasNonScalableFaces(false),
+        mForceScalable(false)
     { }
 
     void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) override;
 
     // Families are constructed initially with just references to patterns.
     // When necessary, these are enumerated within FindStyleVariations.
     void AddFontPattern(FcPattern* aFontPattern);
 
@@ -216,16 +217,17 @@ public:
 
 protected:
     virtual ~gfxFontconfigFontFamily();
 
     nsTArray<nsCountedRef<FcPattern> > mFontPatterns;
 
     bool      mContainsAppFonts;
     bool      mHasNonScalableFaces;
+    bool      mForceScalable;
 };
 
 class gfxFontconfigFont : public gfxFontconfigFontBase {
 public:
     gfxFontconfigFont(const RefPtr<mozilla::gfx::UnscaledFontFontconfig> &aUnscaledFont,
                       cairo_scaled_font_t *aScaledFont,
                       FcPattern *aPattern,
                       gfxFloat aAdjustedSize,
--- a/gfx/thebes/gfxHarfBuzzShaper.cpp
+++ b/gfx/thebes/gfxHarfBuzzShaper.cpp
@@ -43,16 +43,17 @@ using namespace mozilla::unicode; // for
 /*
  * Creation and destruction; on deletion, release any font tables we're holding
  */
 
 gfxHarfBuzzShaper::gfxHarfBuzzShaper(gfxFont *aFont)
     : gfxFontShaper(aFont),
       mHBFace(aFont->GetFontEntry()->GetHBFace()),
       mHBFont(nullptr),
+      mBuffer(nullptr),
       mKernTable(nullptr),
       mHmtxTable(nullptr),
       mVmtxTable(nullptr),
       mVORGTable(nullptr),
       mLocaTable(nullptr),
       mGlyfTable(nullptr),
       mCmapTable(nullptr),
       mCmapFormat(-1),
@@ -93,16 +94,19 @@ gfxHarfBuzzShaper::~gfxHarfBuzzShaper()
         hb_blob_destroy(mGlyfTable);
     }
     if (mHBFont) {
         hb_font_destroy(mHBFont);
     }
     if (mHBFace) {
         hb_face_destroy(mHBFace);
     }
+    if (mBuffer) {
+        hb_buffer_destroy(mBuffer);
+    }
 }
 
 #define UNICODE_BMP_LIMIT 0x10000
 
 hb_codepoint_t
 gfxHarfBuzzShaper::GetNominalGlyph(hb_codepoint_t unicode) const
 {
     hb_codepoint_t gid = 0;
@@ -1284,16 +1288,21 @@ gfxHarfBuzzShaper::Initialize()
     if (!mUseFontGlyphWidths) {
         // If font doesn't implement GetGlyphWidth, we will be reading
         // the metrics table directly, so make sure we can load it.
         if (!LoadHmtxTable()) {
             return false;
         }
     }
 
+    mBuffer = hb_buffer_create();
+    hb_buffer_set_unicode_funcs(mBuffer, sHBUnicodeFuncs);
+    hb_buffer_set_cluster_level(mBuffer,
+                                HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
+
     mHBFont = hb_font_create(mHBFace);
     hb_font_set_funcs(mHBFont, sHBFontFuncs, &mCallbackData, nullptr);
     hb_font_set_ppem(mHBFont, mFont->GetAdjustedSize(), mFont->GetAdjustedSize());
     uint32_t scale = FloatToFixed(mFont->GetAdjustedSize()); // 16.16 fixed-point
     hb_font_set_scale(mHBFont, scale, scale);
 
     return true;
 }
@@ -1469,84 +1478,79 @@ gfxHarfBuzzShaper::ShapeText(DrawTarget 
                       entry->mFeatureSettings,
                       aShapedText->DisableLigatures(),
                       entry->FamilyName(),
                       addSmallCaps,
                       AddOpenTypeFeature,
                       &features);
 
     bool isRightToLeft = aShapedText->IsRightToLeft();
-    hb_buffer_t *buffer = hb_buffer_create();
-    hb_buffer_set_unicode_funcs(buffer, sHBUnicodeFuncs);
 
-    hb_buffer_set_direction(buffer,
+    hb_buffer_set_direction(mBuffer,
                             aVertical ? HB_DIRECTION_TTB :
                                         (isRightToLeft ? HB_DIRECTION_RTL :
                                                          HB_DIRECTION_LTR));
     hb_script_t scriptTag;
     if (aShapedText->GetFlags() & gfx::ShapedTextFlags::TEXT_USE_MATH_SCRIPT) {
         scriptTag = sMathScript;
     } else {
         scriptTag = GetHBScriptUsedForShaping(aScript);
     }
-    hb_buffer_set_script(buffer, scriptTag);
+    hb_buffer_set_script(mBuffer, scriptTag);
 
     hb_language_t language;
     if (style->languageOverride) {
         language = hb_ot_tag_to_language(style->languageOverride);
     } else if (entry->mLanguageOverride) {
         language = hb_ot_tag_to_language(entry->mLanguageOverride);
     } else if (style->explicitLanguage) {
         nsCString langString;
         style->language->ToUTF8String(langString);
         language =
             hb_language_from_string(langString.get(), langString.Length());
     } else {
         language = hb_ot_tag_to_language(HB_OT_TAG_DEFAULT_LANGUAGE);
     }
-    hb_buffer_set_language(buffer, language);
+    hb_buffer_set_language(mBuffer, language);
 
     uint32_t length = aLength;
-    hb_buffer_add_utf16(buffer,
+    hb_buffer_add_utf16(mBuffer,
                         reinterpret_cast<const uint16_t*>(aText),
                         length, 0, length);
 
-    hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
-
-    hb_shape(mHBFont, buffer, features.Elements(), features.Length());
+    hb_shape(mHBFont, mBuffer, features.Elements(), features.Length());
 
     if (isRightToLeft) {
-        hb_buffer_reverse(buffer);
+        hb_buffer_reverse(mBuffer);
     }
 
     nsresult rv = SetGlyphsFromRun(aShapedText, aOffset, aLength,
-                                   aText, buffer, aVertical, aRounding);
+                                   aText, aVertical, aRounding);
 
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
                          "failed to store glyphs into gfxShapedWord");
-    hb_buffer_destroy(buffer);
+    hb_buffer_clear_contents(mBuffer);
 
     return NS_SUCCEEDED(rv);
 }
 
 #define SMALL_GLYPH_RUN 128 // some testing indicates that 90%+ of text runs
                             // will fit without requiring separate allocation
                             // for charToGlyphArray
 
 nsresult
 gfxHarfBuzzShaper::SetGlyphsFromRun(gfxShapedText  *aShapedText,
                                     uint32_t        aOffset,
                                     uint32_t        aLength,
                                     const char16_t *aText,
-                                    hb_buffer_t    *aBuffer,
                                     bool            aVertical,
                                     RoundingFlags   aRounding)
 {
     uint32_t numGlyphs;
-    const hb_glyph_info_t *ginfo = hb_buffer_get_glyph_infos(aBuffer, &numGlyphs);
+    const hb_glyph_info_t *ginfo = hb_buffer_get_glyph_infos(mBuffer, &numGlyphs);
     if (numGlyphs == 0) {
         return NS_OK;
     }
 
     AutoTArray<gfxTextRun::DetailedGlyph,1> detailedGlyphs;
 
     uint32_t wordLength = aLength;
     static const int32_t NO_GLYPH = -1;
@@ -1598,17 +1602,17 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxS
     // The value of the residual is the part of the desired distance that has
     // not been included in integer offsets.
     hb_position_t residual = 0;
 
     // keep track of y-position to set glyph offsets if needed
     nscoord bPos = 0;
 
     const hb_glyph_position_t *posInfo =
-        hb_buffer_get_glyph_positions(aBuffer, nullptr);
+        hb_buffer_get_glyph_positions(mBuffer, nullptr);
 
     while (glyphStart < int32_t(numGlyphs)) {
 
         int32_t charEnd = ginfo[glyphStart].cluster;
         int32_t glyphEnd = glyphStart;
         int32_t charLimit = wordLength;
         while (charEnd < charLimit) {
             // This is normally executed once for each iteration of the outer loop,
--- a/gfx/thebes/gfxHarfBuzzShaper.h
+++ b/gfx/thebes/gfxHarfBuzzShaper.h
@@ -95,24 +95,22 @@ public:
         return hbScript;
     }
 
 protected:
     nsresult SetGlyphsFromRun(gfxShapedText  *aShapedText,
                               uint32_t        aOffset,
                               uint32_t        aLength,
                               const char16_t *aText,
-                              hb_buffer_t    *aBuffer,
                               bool            aVertical,
                               RoundingFlags   aRounding);
 
     // retrieve glyph positions, applying advance adjustments and attachments
     // returns results in appUnits
     nscoord GetGlyphPositions(gfxContext *aContext,
-                              hb_buffer_t *aBuffer,
                               nsTArray<nsPoint>& aPositions,
                               uint32_t aAppUnitsPerDevUnit);
 
     bool InitializeVertical();
     bool LoadHmtxTable();
 
     struct Glyf { // we only need the bounding-box at the beginning
                   // of the glyph record, not the actual outline data
@@ -127,16 +125,19 @@ protected:
 
     // harfbuzz face object: we acquire a reference from the font entry
     // on shaper creation, and release it in our destructor
     hb_face_t         *mHBFace;
 
     // size-specific font object, owned by the gfxHarfBuzzShaper
     hb_font_t         *mHBFont;
 
+    // harfbuzz buffer for the shaping process
+    hb_buffer_t       *mBuffer;
+
     FontCallbackData   mCallbackData;
 
     // Following table references etc are declared "mutable" because the
     // harfbuzz callback functions take a const ptr to the shaper, but
     // wish to cache tables here to avoid repeatedly looking them up
     // in the font.
 
     // Old-style TrueType kern table, if we're not doing GPOS kerning
--- a/image/FrameAnimator.cpp
+++ b/image/FrameAnimator.cpp
@@ -420,16 +420,17 @@ FrameAnimator::RequestRefresh(AnimationS
     if (!frameRes.mFrameAdvanced && (*currentFrameEndTime == oldFrameEndTime)) {
       break;
     }
   }
 
   // Advanced to the correct frame, the composited frame is now valid to be drawn.
   if (*currentFrameEndTime > aTime) {
     aState.mCompositedFrameInvalid = false;
+    ret.mDirtyRect = IntRect(IntPoint(0,0), mSize);
   }
 
   MOZ_ASSERT(!aState.mIsCurrentlyDecoded || !aState.mCompositedFrameInvalid);
 
   return ret;
 }
 
 LookupResult
deleted file mode 100644
--- a/image/ImageBlocker.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 "ImageBlocker.h"
-#include "nsIPermissionManager.h"
-#include "nsContentUtils.h"
-#include "mozilla/Unused.h"
-
-using namespace mozilla;
-using namespace mozilla::image;
-
-bool ImageBlocker::sInitialized = false;
-int32_t ImageBlocker::sImagePermission = nsIPermissionManager::ALLOW_ACTION;
-
-NS_IMPL_ISUPPORTS(ImageBlocker, nsIContentPolicy)
-
-ImageBlocker::ImageBlocker()
-{
-  if (!sInitialized) {
-    Preferences::AddIntVarCache(&sImagePermission,
-                                "permissions.default.image");
-    sInitialized = true;
-  }
-}
-
-NS_IMETHODIMP
-ImageBlocker::ShouldLoad(uint32_t aContentType,
-                         nsIURI* aContentLocation,
-                         nsIURI* aRequestOrigin,
-                         nsISupports* aContext,
-                         const nsACString& aMimeTypeGuess,
-                         nsISupports* aExtra,
-                         nsIPrincipal* aRequestPrincipal,
-                         int16_t* aShouldLoad)
-{
-  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
-             "We should only see external content policy types here.");
-
-  *aShouldLoad = nsIContentPolicy::ACCEPT;
-  if (!aContentLocation) {
-    return NS_OK;
-  }
-
-  nsAutoCString scheme;
-  Unused << aContentLocation->GetScheme(scheme);
-  if (!scheme.LowerCaseEqualsLiteral("ftp") &&
-      !scheme.LowerCaseEqualsLiteral("http") &&
-      !scheme.LowerCaseEqualsLiteral("https")) {
-    return NS_OK;
-  }
-
-
-  // Block loading images depending on the permissions.default.image pref.
-  if (aContentType == nsIContentPolicy::TYPE_IMAGE ||
-      aContentType == nsIContentPolicy::TYPE_IMAGESET) {
-    *aShouldLoad = (sImagePermission == nsIPermissionManager::ALLOW_ACTION) ?
-                     nsIContentPolicy::ACCEPT :
-                     nsIContentPolicy::REJECT_TYPE;
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-ImageBlocker::ShouldProcess(uint32_t aContentType,
-                            nsIURI* aContentLocation,
-                            nsIURI* aRequestOrigin,
-                            nsISupports* aRequestingContext,
-                            const nsACString& aMimeTypeGuess,
-                            nsISupports* aExtra,
-                            nsIPrincipal* aRequestPrincipal,
-                            int16_t* aShouldProcess)
-{
-  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
-             "We should only see external content policy types here.");
-
-  return ShouldLoad(aContentType, aContentLocation, aRequestOrigin,
-                    aRequestingContext, aMimeTypeGuess, aExtra,
-                    aRequestPrincipal, aShouldProcess);
-}
deleted file mode 100644
--- a/image/ImageBlocker.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 mozilla_image_ImageBlocker_h
-#define mozilla_image_ImageBlocker_h
-
-#include "nsIContentPolicy.h"
-
-namespace mozilla {
-namespace image {
-
-#define IMAGEBLOCKER_CONTRACTID "@mozilla.org/image-blocker-content-policy;1"
-#define IMAGEBLOCKER_CID \
-{ /* f6fcd651-164b-4416-b001-9c8c393fd93b */         \
-     0xf6fcd651,                                     \
-     0x164b,                                         \
-     0x4416,                                         \
-    {0xb0, 0x01, 0x9c, 0x8c, 0x39, 0x3f, 0xd9, 0x3b} \
-}
-
-class ImageBlocker final : public nsIContentPolicy
-{
-  ~ImageBlocker() = default;
-
-public:
-  ImageBlocker();
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSICONTENTPOLICY
-
-private:
-  static bool sInitialized;
-  static int32_t sImagePermission;
-};
-
-}
-}
-
-#endif // mozilla_image_ImageBlocker_h
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -1257,27 +1257,30 @@ RasterImage::Decode(const IntSize& aSize
 
   // Create a decoder.
   RefPtr<IDecodingTask> task;
   if (mAnimationState && aPlaybackType == PlaybackType::eAnimated) {
     task = DecoderFactory::CreateAnimationDecoder(mDecoderType, WrapNotNull(this),
                                                   mSourceBuffer, mSize,
                                                   decoderFlags, surfaceFlags);
     // We may not be able to send an invalidation right here because of async
-    // notifications but that's not a problem because the first frame
-    // invalidation (when it comes) will invalidate for us. So we can ignore
-    // the return value of UpdateState. This also handles the invalidation
-    // from setting the composited frame as valid below.
-    mAnimationState->UpdateState(mAnimationFinished, this, mSize);
-    // If the animation is finished we can draw right away because we just draw
-    // the final frame all the time from now on. See comment in
-    // AnimationState::UpdateState.
-    if (mAnimationFinished) {
-      mAnimationState->SetCompositedFrameInvalid(false);
-    }
+    // notifications but that shouldn't be a problem because we shouldn't be
+    // getting a non-empty rect back from UpdateState. This is because UpdateState
+    // will only return a non-empty rect if we are currently decoded, or the
+    // animation is finished. We can't be decoded because we are creating a decoder
+    // here. If the animation is finished then the composited frame would have
+    // been valid when the animation finished, and it's not possible to mark
+    // the composited frame as invalid when the animation is finished. So
+    // the composited frame can't change from invalid to valid in this UpdateState
+    // call, and hence no rect can be returned.
+#ifdef DEBUG
+    gfx::IntRect rect =
+#endif
+      mAnimationState->UpdateState(mAnimationFinished, this, mSize);
+    MOZ_ASSERT(rect.IsEmpty());
   } else {
     task = DecoderFactory::CreateDecoder(mDecoderType, WrapNotNull(this),
                                          mSourceBuffer, mSize, aSize,
                                          decoderFlags, surfaceFlags);
   }
 
   // Make sure DecoderFactory was able to create a decoder successfully.
   if (!task) {
--- a/image/build/nsImageModule.cpp
+++ b/image/build/nsImageModule.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsImageModule.h"
 
 #include "mozilla/ModuleUtils.h"
 #include "nsMimeTypes.h"
 
 #include "DecodePool.h"
-#include "ImageBlocker.h"
 #include "ImageFactory.h"
 #include "ShutdownTracker.h"
 #include "SurfaceCache.h"
 #include "SurfacePipe.h"
 
 #include "gfxPrefs.h"
 #include "imgLoader.h"
 #include "imgRequest.h"
@@ -34,48 +33,44 @@ using namespace mozilla::image;
 // comment documenting the imgLoader constructor.
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(imgLoader, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequestProxy)
 NS_GENERIC_FACTORY_CONSTRUCTOR(imgTools)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsICOEncoder)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGEncoder)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGEncoder)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBMPEncoder)
-NS_GENERIC_FACTORY_CONSTRUCTOR(ImageBlocker)
 NS_DEFINE_NAMED_CID(NS_IMGLOADER_CID);
 NS_DEFINE_NAMED_CID(NS_IMGREQUESTPROXY_CID);
 NS_DEFINE_NAMED_CID(NS_IMGTOOLS_CID);
 NS_DEFINE_NAMED_CID(NS_ICOENCODER_CID);
 NS_DEFINE_NAMED_CID(NS_JPEGENCODER_CID);
 NS_DEFINE_NAMED_CID(NS_PNGENCODER_CID);
 NS_DEFINE_NAMED_CID(NS_BMPENCODER_CID);
-NS_DEFINE_NAMED_CID(IMAGEBLOCKER_CID);
 
 static const mozilla::Module::CIDEntry kImageCIDs[] = {
   { &kNS_IMGLOADER_CID, false, nullptr, imgLoaderConstructor, },
   { &kNS_IMGREQUESTPROXY_CID, false, nullptr, imgRequestProxyConstructor, },
   { &kNS_IMGTOOLS_CID, false, nullptr, imgToolsConstructor, },
   { &kNS_ICOENCODER_CID, false, nullptr, nsICOEncoderConstructor, },
   { &kNS_JPEGENCODER_CID, false, nullptr, nsJPEGEncoderConstructor, },
   { &kNS_PNGENCODER_CID, false, nullptr, nsPNGEncoderConstructor, },
   { &kNS_BMPENCODER_CID, false, nullptr, nsBMPEncoderConstructor, },
-  { &kIMAGEBLOCKER_CID, false, nullptr, ImageBlockerConstructor, },
   { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kImageContracts[] = {
   { "@mozilla.org/image/cache;1", &kNS_IMGLOADER_CID },
   { "@mozilla.org/image/loader;1", &kNS_IMGLOADER_CID },
   { "@mozilla.org/image/request;1", &kNS_IMGREQUESTPROXY_CID },
   { "@mozilla.org/image/tools;1", &kNS_IMGTOOLS_CID },
   { "@mozilla.org/image/encoder;2?type=" IMAGE_ICO_MS, &kNS_ICOENCODER_CID },
   { "@mozilla.org/image/encoder;2?type=" IMAGE_JPEG, &kNS_JPEGENCODER_CID },
   { "@mozilla.org/image/encoder;2?type=" IMAGE_PNG, &kNS_PNGENCODER_CID },
   { "@mozilla.org/image/encoder;2?type=" IMAGE_BMP, &kNS_BMPENCODER_CID },
-  { IMAGEBLOCKER_CONTRACTID, &kIMAGEBLOCKER_CID },
   { nullptr }
 };
 
 static const mozilla::Module::CategoryEntry kImageCategories[] = {
   { "Gecko-Content-Viewers", IMAGE_GIF, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_JPEG, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_PJPEG, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_JPG, "@mozilla.org/content/document-loader-factory;1" },
@@ -83,17 +78,16 @@ static const mozilla::Module::CategoryEn
   { "Gecko-Content-Viewers", IMAGE_ICO_MS, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_BMP, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_BMP_MS, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_ICON_MS, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_PNG, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_APNG, "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", IMAGE_X_PNG, "@mozilla.org/content/document-loader-factory;1" },
   { "content-sniffing-services", "@mozilla.org/image/loader;1", "@mozilla.org/image/loader;1" },
-  { "content-policy", IMAGEBLOCKER_CONTRACTID, IMAGEBLOCKER_CONTRACTID },
   { nullptr }
 };
 
 static bool sInitialized = false;
 nsresult
 mozilla::image::EnsureModuleInitialized()
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/image/imgRequestProxy.cpp
+++ b/image/imgRequestProxy.cpp
@@ -612,17 +612,17 @@ static imgRequestProxy* NewProxy(imgRequ
 {
   return new imgRequestProxy();
 }
 
 imgRequestProxy* NewStaticProxy(imgRequestProxy* aThis)
 {
   nsCOMPtr<nsIPrincipal> currentPrincipal;
   aThis->GetImagePrincipal(getter_AddRefs(currentPrincipal));
-  RefPtr<Image> image = aThis->GetImage();
+  RefPtr<image::Image> image = aThis->GetImage();
   return new imgRequestProxyStatic(image, currentPrincipal);
 }
 
 NS_IMETHODIMP
 imgRequestProxy::Clone(imgINotificationObserver* aObserver,
                        imgIRequest** aClone)
 {
   nsresult result;
--- a/image/moz.build
+++ b/image/moz.build
@@ -58,17 +58,16 @@ UNIFIED_SOURCES += [
     'DecodePool.cpp',
     'Decoder.cpp',
     'DecoderFactory.cpp',
     'DynamicImage.cpp',
     'FrameAnimator.cpp',
     'FrozenImage.cpp',
     'IDecodingTask.cpp',
     'Image.cpp',
-    'ImageBlocker.cpp',
     'ImageCacheKey.cpp',
     'ImageFactory.cpp',
     'ImageOps.cpp',
     'ImageWrapper.cpp',
     'imgFrame.cpp',
     'imgLoader.cpp',
     'imgRequest.cpp',
     'imgRequestProxy.cpp',
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -996,18 +996,16 @@ description =
 [PCompositorBridge::MakeSnapshot]
 description =
 [PCompositorBridge::FlushRendering]
 description =
 [PCompositorBridge::StartFrameTimeRecording]
 description =
 [PCompositorBridge::StopFrameTimeRecording]
 description =
-[PCompositorBridge::PLayerTransaction]
-description =
 [PCompositorBridge::SyncWithCompositor]
 description =
 [PCompositorBridge::PWebRenderBridge]
 description =
 [PCompositorWidget::EnterPresentLock]
 description =
 platform = win
 [PCompositorWidget::LeavePresentLock]
@@ -1031,16 +1029,18 @@ description =
 [PLayerTransaction::SetAsyncScrollOffset]
 description =
 [PLayerTransaction::SetAsyncZoom]
 description =
 [PLayerTransaction::GetAPZTestData]
 description =
 [PLayerTransaction::RequestProperty]
 description =
+[PLayerTransaction::GetTextureFactoryIdentifier]
+description = bug 1350634
 [PUiCompositorController::Pause]
 description =
 [PUiCompositorController::Resume]
 description =
 [PUiCompositorController::ResumeAndResize]
 description =
 [PWebRenderBridge::Create]
 description =
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -676,18 +676,18 @@ frontend::CompileLazyFunction(JSContext*
     Parser<FullParseHandler, char16_t> parser(cx, cx->tempLifoAlloc(), options, chars, length,
                                               /* foldConstants = */ true, usedNames, nullptr,
                                               lazy);
     if (!parser.checkOptions())
         return false;
 
     Rooted<JSFunction*> fun(cx, lazy->functionNonDelazifying());
     MOZ_ASSERT(!lazy->isLegacyGenerator());
-    ParseNode* pn = parser.standaloneLazyFunction(fun, lazy->strict(), lazy->generatorKind(),
-                                                  lazy->asyncKind());
+    ParseNode* pn = parser.standaloneLazyFunction(fun, lazy->toStringStart() + lazy->column(),
+                                                  lazy->strict(), lazy->generatorKind(), lazy->asyncKind());
     if (!pn)
         return false;
 
     RootedScriptSource sourceObject(cx, lazy->sourceObject());
     MOZ_ASSERT(sourceObject);
 
     Rooted<JSScript*> script(cx, JSScript::Create(cx, options, sourceObject,
                                                   lazy->begin(), lazy->end(),
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -164,36 +164,70 @@ ParseContext::Scope::dump(ParseContext* 
                 DeclarationKindString(info.kind()),
                 bytes.ptr(),
                 info.closedOver() ? " (closed over)" : "");
     }
 
     fprintf(stdout, "\n");
 }
 
-/* static */ void
-ParseContext::Scope::removeVarForAnnexBLexicalFunction(ParseContext* pc, JSAtom* name)
-{
-    // Local strict mode is allowed, e.g., a class binding removing a
-    // synthesized Annex B binding.
-    MOZ_ASSERT(!pc->sc()->strictScript);
-
-    for (ParseContext::Scope* scope = pc->innermostScope();
-         scope != pc->varScope().enclosing();
-         scope = scope->enclosing())
+bool
+ParseContext::Scope::addPossibleAnnexBFunctionBox(ParseContext* pc, FunctionBox* funbox)
+{
+    if (!possibleAnnexBFunctionBoxes_) {
+        if (!possibleAnnexBFunctionBoxes_.acquire(pc->sc()->context))
+            return false;
+    }
+
+    return possibleAnnexBFunctionBoxes_->append(funbox);
+}
+
+bool
+ParseContext::Scope::propagateAndMarkAnnexBFunctionBoxes(ParseContext* pc)
+{
+    // Strict mode doesn't have wack Annex B function semantics.
+    if (pc->sc()->strict() ||
+        !possibleAnnexBFunctionBoxes_ ||
+        possibleAnnexBFunctionBoxes_->empty())
     {
-        if (DeclaredNamePtr p = scope->declared_->lookup(name)) {
-            if (p->value()->kind() == DeclarationKind::VarForAnnexBLexicalFunction)
-                scope->declared_->remove(p);
-        }
-    }
-
-    // Annex B semantics no longer applies to any functions with this name, as
-    // an early error would have occurred.
-    pc->removeInnerFunctionBoxesForAnnexB(name);
+        return true;
+    }
+
+    if (this == &pc->varScope()) {
+        // Base case: actually declare the Annex B vars and mark applicable
+        // function boxes as Annex B.
+        RootedPropertyName name(pc->sc()->context);
+        Maybe<DeclarationKind> redeclaredKind;
+        uint32_t unused;
+        for (FunctionBox* funbox : *possibleAnnexBFunctionBoxes_) {
+            if (pc->annexBAppliesToLexicalFunctionInInnermostScope(funbox)) {
+                name = funbox->function()->explicitName()->asPropertyName();
+                if (!pc->tryDeclareVar(name,
+                                       DeclarationKind::VarForAnnexBLexicalFunction,
+                                       DeclaredNameInfo::npos, &redeclaredKind, &unused))
+                {
+                    return false;
+                }
+
+                MOZ_ASSERT(!redeclaredKind);
+                funbox->isAnnexB = true;
+            }
+        }
+    } else {
+        // Inner scope case: propagate still applicable function boxes to the
+        // enclosing scope.
+        for (FunctionBox* funbox : *possibleAnnexBFunctionBoxes_) {
+            if (pc->annexBAppliesToLexicalFunctionInInnermostScope(funbox)) {
+                if (!enclosing()->addPossibleAnnexBFunctionBox(pc, funbox))
+                    return false;
+            }
+        }
+    }
+
+    return true;
 }
 
 static bool
 DeclarationKindIsCatchParameter(DeclarationKind kind)
 {
     return kind == DeclarationKind::SimpleCatchParameter ||
            kind == DeclarationKind::CatchParameter;
 }
@@ -362,70 +396,20 @@ ParseContext::init()
 
         if (!positionalFormalParameterNames_.acquire(cx))
             return false;
     }
 
     if (!closedOverBindingsForLazy_.acquire(cx))
         return false;
 
-    if (!sc()->strict()) {
-        if (!innerFunctionBoxesForAnnexB_.acquire(cx))
-            return false;
-    }
-
     return true;
 }
 
 bool
-ParseContext::addInnerFunctionBoxForAnnexB(FunctionBox* funbox)
-{
-    for (uint32_t i = 0; i < innerFunctionBoxesForAnnexB_->length(); i++) {
-        if (!innerFunctionBoxesForAnnexB_[i]) {
-            innerFunctionBoxesForAnnexB_[i] = funbox;
-            return true;
-        }
-    }
-    return innerFunctionBoxesForAnnexB_->append(funbox);
-}
-
-void
-ParseContext::removeInnerFunctionBoxesForAnnexB(JSAtom* name)
-{
-    for (uint32_t i = 0; i < innerFunctionBoxesForAnnexB_->length(); i++) {
-        if (FunctionBox* funbox = innerFunctionBoxesForAnnexB_[i]) {
-            if (funbox->function()->explicitName() == name)
-                innerFunctionBoxesForAnnexB_[i] = nullptr;
-        }
-    }
-}
-
-void
-ParseContext::finishInnerFunctionBoxesForAnnexB()
-{
-    // Strict mode doesn't have wack Annex B function semantics. Or we
-    // could've failed to initialize ParseContext.
-    if (sc()->strict() || !innerFunctionBoxesForAnnexB_)
-        return;
-
-    for (uint32_t i = 0; i < innerFunctionBoxesForAnnexB_->length(); i++) {
-        if (FunctionBox* funbox = innerFunctionBoxesForAnnexB_[i])
-            funbox->isAnnexB = true;
-    }
-}
-
-ParseContext::~ParseContext()
-{
-    // Any funboxes still in the list at the end of parsing means no early
-    // error would have occurred for declaring a binding in the nearest var
-    // scope. Mark them as needing extra assignments to this var binding.
-    finishInnerFunctionBoxesForAnnexB();
-}
-
-bool
 UsedNameTracker::noteUse(JSContext* cx, JSAtom* name, uint32_t scriptId, uint32_t scopeId)
 {
     if (UsedNameMap::AddPtr p = map_.lookupForAdd(name)) {
         if (!p->value().noteUsedInScope(scriptId, scopeId))
             return false;
     } else {
         UsedNameInfo info(cx);
         if (!info.noteUsedInScope(scriptId, scopeId))
@@ -911,21 +895,19 @@ ParserBase::newObjectBox(JSObject* obj)
 
     return objbox;
 }
 
 template <template <typename CharT> class ParseHandler, typename CharT>
 FunctionBox*
 Parser<ParseHandler, CharT>::newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart,
                                             Directives inheritedDirectives,
-                                            GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
-                                            bool tryAnnexB)
+                                            GeneratorKind generatorKind, FunctionAsyncKind asyncKind)
 {
     MOZ_ASSERT(fun);
-    MOZ_ASSERT_IF(tryAnnexB, !pc->sc()->strict());
 
     /*
      * We use JSContext.tempLifoAlloc to allocate parsed objects and place them
      * on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
      * arenas containing the entries must be alive until we are done with
      * scanning, parsing and code generation for the whole script or top-level
      * function.
      */
@@ -937,19 +919,16 @@ Parser<ParseHandler, CharT>::newFunction
         ReportOutOfMemory(context);
         return nullptr;
     }
 
     traceListHead = funbox;
     if (fn)
         handler.setFunctionBox(fn, funbox);
 
-    if (tryAnnexB && !pc->addInnerFunctionBoxForAnnexB(funbox))
-        return nullptr;
-
     return funbox;
 }
 
 ModuleSharedContext::ModuleSharedContext(JSContext* cx, ModuleObject* module,
                                          Scope* enclosingScope, ModuleBuilder& builder)
   : SharedContext(cx, Kind::Module, Directives(true), false),
     module_(cx, module),
     enclosingScope_(cx, enclosingScope),
@@ -1195,31 +1174,30 @@ static bool
 DeclarationKindIsVar(DeclarationKind kind)
 {
     return kind == DeclarationKind::Var ||
            kind == DeclarationKind::BodyLevelFunction ||
            kind == DeclarationKind::VarForAnnexBLexicalFunction ||
            kind == DeclarationKind::ForOfVar;
 }
 
-template <template <typename CharT> class ParseHandler, typename CharT>
 Maybe<DeclarationKind>
-Parser<ParseHandler, CharT>::isVarRedeclaredInEval(HandlePropertyName name, DeclarationKind kind)
+ParseContext::isVarRedeclaredInEval(HandlePropertyName name, DeclarationKind kind)
 {
     MOZ_ASSERT(DeclarationKindIsVar(kind));
-    MOZ_ASSERT(pc->sc()->isEvalContext());
+    MOZ_ASSERT(sc()->isEvalContext());
 
     // In the case of eval, we also need to check enclosing VM scopes to see
     // if the var declaration is allowed in the context.
     //
     // This check is necessary in addition to
     // js::CheckEvalDeclarationConflicts because we only know during parsing
     // if a var is bound by for-of.
-    Scope* enclosingScope = pc->sc()->compilationEnclosingScope();
-    Scope* varScope = EvalScope::nearestVarScopeForDirectEval(enclosingScope);
+    js::Scope* enclosingScope = sc()->compilationEnclosingScope();
+    js::Scope* varScope = EvalScope::nearestVarScopeForDirectEval(enclosingScope);
     MOZ_ASSERT(varScope);
     for (ScopeIter si(enclosingScope); si; si++) {
         for (js::BindingIter bi(si.scope()); bi; bi++) {
             if (bi.name() != name)
                 continue;
 
             switch (bi.kind()) {
               case BindingKind::Let: {
@@ -1249,46 +1227,64 @@ Parser<ParseHandler, CharT>::isVarRedecl
 
         if (si.scope() == varScope)
             break;
     }
 
     return Nothing();
 }
 
+Maybe<DeclarationKind>
+ParseContext::isVarRedeclaredInInnermostScope(HandlePropertyName name, DeclarationKind kind)
+{
+    Maybe<DeclarationKind> redeclaredKind;
+    uint32_t unused;
+    MOZ_ALWAYS_TRUE(tryDeclareVarHelper<DryRunInnermostScopeOnly>(name, kind,
+                                                                  DeclaredNameInfo::npos,
+                                                                  &redeclaredKind, &unused));
+    return redeclaredKind;
+}
+
+bool
+ParseContext::tryDeclareVar(HandlePropertyName name, DeclarationKind kind,
+                            uint32_t beginPos, Maybe<DeclarationKind>* redeclaredKind,
+                            uint32_t* prevPos)
+{
+    return tryDeclareVarHelper<NotDryRun>(name, kind, beginPos, redeclaredKind, prevPos);
+}
+
 static bool
 DeclarationKindIsParameter(DeclarationKind kind)
 {
     return kind == DeclarationKind::PositionalFormalParameter ||
            kind == DeclarationKind::FormalParameter;
 }
 
-template <template <typename CharT> class ParseHandler, typename CharT>
+template <ParseContext::DryRunOption dryRunOption>
 bool
-Parser<ParseHandler, CharT>::tryDeclareVar(HandlePropertyName name, DeclarationKind kind,
-                                           uint32_t beginPos,
-                                           Maybe<DeclarationKind>* redeclaredKind,
-                                           uint32_t* prevPos)
+ParseContext::tryDeclareVarHelper(HandlePropertyName name, DeclarationKind kind,
+                                  uint32_t beginPos, Maybe<DeclarationKind>* redeclaredKind,
+                                  uint32_t* prevPos)
 {
     MOZ_ASSERT(DeclarationKindIsVar(kind));
 
     // It is an early error if a 'var' declaration appears inside a
     // scope contour that has a lexical declaration of the same name. For
     // example, the following are early errors:
     //
     //   { let x; var x; }
     //   { { var x; } let x; }
     //
     // And the following are not:
     //
     //   { var x; var x; }
     //   { { let x; } var x; }
 
-    for (ParseContext::Scope* scope = pc->innermostScope();
-         scope != pc->varScope().enclosing();
+    for (ParseContext::Scope* scope = innermostScope();
+         scope != varScope().enclosing();
          scope = scope->enclosing())
     {
         if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
             DeclarationKind declaredKind = p->value()->kind();
             if (DeclarationKindIsVar(declaredKind)) {
                 // Any vars that are redeclared as body-level functions must
                 // be recorded as body-level functions.
                 //
@@ -1303,117 +1299,111 @@ Parser<ParseHandler, CharT>::tryDeclareV
                 //
                 // For a var previously declared as ForOfVar, this previous
                 // DeclarationKind is used only to check for if the
                 // 'arguments' binding should be declared. Since body-level
                 // functions shadow 'arguments' [5], it is correct to alter
                 // the kind to BodyLevelFunction. See
                 // declareFunctionArgumentsObject.
                 //
-                // For a var previously declared as
-                // VarForAnnexBLexicalFunction, this previous DeclarationKind
-                // is used so that vars synthesized solely for Annex B.3.3 may
-                // be removed if an early error would occur. If a synthesized
-                // Annex B.3.3 var has the same name as a body-level function,
-                // this is not a redeclaration, and indeed, because the
-                // body-level function binds the name, this name should not be
-                // removed should a redeclaration occur in the future. Thus it
-                // is also correct to alter the kind to BodyLevelFunction.
+                // VarForAnnexBLexicalFunction declarations are declared when
+                // the var scope exits. It is not possible for a var to be
+                // previously declared as VarForAnnexBLexicalFunction and
+                // checked for redeclaration.
                 //
                 // [1] ES 15.1.11
                 // [2] ES 18.2.1.3
                 // [3] ES 8.1.1.4.15
                 // [4] ES 8.1.1.4.16
                 // [5] ES 9.2.12
-                if (kind == DeclarationKind::BodyLevelFunction)
+                if (dryRunOption == NotDryRun && kind == DeclarationKind::BodyLevelFunction) {
+                    MOZ_ASSERT(declaredKind != DeclarationKind::VarForAnnexBLexicalFunction);
                     p->value()->alterKind(kind);
+                }
             } else if (!DeclarationKindIsParameter(declaredKind)) {
                 // Annex B.3.5 allows redeclaring simple (non-destructured)
                 // catch parameters with var declarations, except when it
                 // appears in a for-of.
                 bool annexB35Allowance = declaredKind == DeclarationKind::SimpleCatchParameter &&
                                          kind != DeclarationKind::ForOfVar;
 
                 // Annex B.3.3 allows redeclaring functions in the same block.
                 bool annexB33Allowance = declaredKind == DeclarationKind::LexicalFunction &&
                                          kind == DeclarationKind::VarForAnnexBLexicalFunction &&
-                                         scope == pc->innermostScope();
+                                         scope == innermostScope();
 
                 if (!annexB35Allowance && !annexB33Allowance) {
                     *redeclaredKind = Some(declaredKind);
                     *prevPos = p->value()->pos();
                     return true;
                 }
             } else if (kind == DeclarationKind::VarForAnnexBLexicalFunction) {
                 MOZ_ASSERT(DeclarationKindIsParameter(declaredKind));
 
                 // Annex B.3.3.1 disallows redeclaring parameter names.
                 // We don't need to set *prevPos here since this case is not
                 // an error.
                 *redeclaredKind = Some(declaredKind);
                 return true;
             }
-        } else {
-            if (!scope->addDeclaredName(pc, p, name, kind, beginPos))
+        } else if (dryRunOption == NotDryRun) {
+            if (!scope->addDeclaredName(this, p, name, kind, beginPos))
                 return false;
         }
-    }
-
-    if (!pc->sc()->strict() && pc->sc()->isEvalContext()) {
+
+        // DryRunOption is used for propagating Annex B functions: we don't
+        // want to declare the synthesized Annex B vars until we exit the var
+        // scope and know that no early errors would have occurred. In order
+        // to avoid quadratic search, we only check for var redeclarations in
+        // the innermost scope when doing a dry run.
+        if (dryRunOption == DryRunInnermostScopeOnly)
+            break;
+    }
+
+    if (!sc()->strict() && sc()->isEvalContext() &&
+        (dryRunOption == NotDryRun || innermostScope() == &varScope()))
+    {
         *redeclaredKind = isVarRedeclaredInEval(name, kind);
         // We don't have position information at runtime.
         *prevPos = DeclaredNameInfo::npos;
     }
 
     return true;
 }
 
-template <template <typename CharT> class ParseHandler, typename CharT>
 bool
-Parser<ParseHandler, CharT>::tryDeclareVarForAnnexBLexicalFunction(HandlePropertyName name,
-                                                                   uint32_t beginPos,
-                                                                   bool* tryAnnexB)
-{
-    Maybe<DeclarationKind> redeclaredKind;
-    uint32_t unused;
-    if (!tryDeclareVar(name, DeclarationKind::VarForAnnexBLexicalFunction, beginPos,
-                       &redeclaredKind, &unused))
-    {
-        return false;
-    }
-
-    if (!redeclaredKind && pc->isFunctionBox()) {
-        ParseContext::Scope& funScope = pc->functionScope();
-        ParseContext::Scope& varScope = pc->varScope();
-        if (&funScope != &varScope) {
+ParseContext::annexBAppliesToLexicalFunctionInInnermostScope(FunctionBox* funbox)
+{
+    MOZ_ASSERT(!sc()->strict());
+
+    RootedPropertyName name(sc()->context, funbox->function()->explicitName()->asPropertyName());
+    Maybe<DeclarationKind> redeclaredKind =
+        isVarRedeclaredInInnermostScope(name, DeclarationKind::VarForAnnexBLexicalFunction);
+
+    if (!redeclaredKind && isFunctionBox()) {
+        Scope& funScope = functionScope();
+        if (&funScope != &varScope()) {
             // Annex B.3.3.1 disallows redeclaring parameter names. In the
             // presence of parameter expressions, parameter names are on the
-            // function scope, which encloses the var scope. This means
-            // tryDeclareVar call above would not catch this case, so test it
-            // manually.
+            // function scope, which encloses the var scope. This means the
+            // isVarRedeclaredInInnermostScope call above would not catch this
+            // case, so test it manually.
             if (AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(name)) {
                 DeclarationKind declaredKind = p->value()->kind();
                 if (DeclarationKindIsParameter(declaredKind))
                     redeclaredKind = Some(declaredKind);
                 else
-                    MOZ_ASSERT(FunctionScope::isSpecialName(context, name));
+                    MOZ_ASSERT(FunctionScope::isSpecialName(sc()->context, name));
             }
         }
     }
 
-    if (redeclaredKind) {
-        // If an early error would have occurred, undo all the
-        // VarForAnnexBLexicalFunction declarations.
-        *tryAnnexB = false;
-        ParseContext::Scope::removeVarForAnnexBLexicalFunction(pc, name);
-    } else {
-        *tryAnnexB = true;
-    }
-
-    return true;
+    // If an early error would have occurred already, this function should not
+    // exhibit Annex B.3.3 semantics.
+    return !redeclaredKind;
 }
 
 template <template <typename CharT> class ParseHandler, typename CharT>
 bool
 Parser<ParseHandler, CharT>::checkLexicalDeclarationDirectlyWithinBlock(ParseContext::Statement& stmt,
                                                                         DeclarationKind kind,
                                                                         TokenPos pos)
 {
@@ -1446,17 +1436,17 @@ Parser<ParseHandler, CharT>::noteDeclare
         return true;
 
     switch (kind) {
       case DeclarationKind::Var:
       case DeclarationKind::BodyLevelFunction:
       case DeclarationKind::ForOfVar: {
         Maybe<DeclarationKind> redeclaredKind;
         uint32_t prevPos;
-        if (!tryDeclareVar(name, kind, pos.begin, &redeclaredKind, &prevPos))
+        if (!pc->tryDeclareVar(name, kind, pos.begin, &redeclaredKind, &prevPos))
             return false;
 
         if (redeclaredKind) {
             reportRedeclaration(name, *redeclaredKind, pos, prevPos);
             return false;
         }
 
         break;
@@ -1504,27 +1494,20 @@ Parser<ParseHandler, CharT>::noteDeclare
 
         ParseContext::Scope* scope = pc->innermostScope();
         if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
             // It is usually an early error if there is another declaration
             // with the same name in the same scope.
             //
             // In sloppy mode, lexical functions may redeclare other lexical
             // functions for web compatibility reasons.
-            if (pc->sc()->strict() ||
-                (p->value()->kind() != DeclarationKind::LexicalFunction &&
-                 p->value()->kind() != DeclarationKind::VarForAnnexBLexicalFunction))
-            {
+            if (pc->sc()->strict() || p->value()->kind() != DeclarationKind::LexicalFunction) {
                 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
                 return false;
             }
-
-            // Update the DeclarationKind to make a LexicalFunction
-            // declaration that shadows the VarForAnnexBLexicalFunction.
-            p->value()->alterKind(kind);
         } else {
             if (!scope->addDeclaredName(pc, p, name, kind, pos.begin))
                 return false;
         }
 
         break;
       }
 
@@ -1565,30 +1548,21 @@ Parser<ParseHandler, CharT>::noteDeclare
                 return false;
             }
         }
 
         // It is an early error if there is another declaration with the same
         // name in the same scope.
         AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
         if (p) {
-            // If the early error would have occurred due to Annex B.3.3
-            // semantics, remove the synthesized Annex B var declaration, do
-            // not report the redeclaration, and declare the lexical name.
-            if (p->value()->kind() == DeclarationKind::VarForAnnexBLexicalFunction) {
-                ParseContext::Scope::removeVarForAnnexBLexicalFunction(pc, name);
-                p = scope->lookupDeclaredNameForAdd(name);
-                MOZ_ASSERT(!p);
-            } else {
-                reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
-                return false;
-            }
-        }
-
-        if (!p && !scope->addDeclaredName(pc, p, name, kind, pos.begin))
+            reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
+            return false;
+        }
+
+        if (!scope->addDeclaredName(pc, p, name, kind, pos.begin))
             return false;
 
         break;
       }
 
       case DeclarationKind::CoverArrowParameter:
         // CoverArrowParameter is only used as a placeholder declaration kind.
         break;
@@ -1640,16 +1614,21 @@ Parser<ParseHandler, CharT>::hasUsedName
         return p->value().isUsedInScript(pc->scriptId());
     return false;
 }
 
 template <template <typename CharT> class ParseHandler, typename CharT>
 bool
 Parser<ParseHandler, CharT>::propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope)
 {
+    // Now that we have all the declared names in the scope, check which
+    // functions should exhibit Annex B semantics.
+    if (!scope.propagateAndMarkAnnexBFunctionBoxes(pc))
+        return false;
+
     if (handler.canSkipLazyClosedOverBindings()) {
         // Scopes are nullptr-delimited in the LazyScript closed over bindings
         // array.
         while (JSAtom* name = handler.nextLazyClosedOverBinding())
             scope.lookupDeclaredName(name)->value()->setClosedOver();
         return true;
     }
 
@@ -2168,16 +2147,22 @@ Parser<FullParseHandler, char16_t>::eval
         MOZ_ASSERT(!si.done(),
                    "Eval must have found an enclosing function box scope that allows super.property");
     }
 #endif
 
     if (!FoldConstants(context, &body, this))
         return nullptr;
 
+    // For eval scripts, since all bindings are automatically considered
+    // closed over, we don't need to call propagateFreeNamesAndMarkClosed-
+    // OverBindings. However, Annex B.3.3 functions still need to be marked.
+    if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc))
+        return nullptr;
+
     Maybe<EvalScope::Data*> bindings = newEvalScopeData(pc->varScope());
     if (!bindings)
         return nullptr;
     evalsc->bindings = *bindings;
 
     return body;
 }
 
@@ -2198,16 +2183,22 @@ Parser<FullParseHandler, char16_t>::glob
         return nullptr;
 
     if (!checkStatementsEOF())
         return nullptr;
 
     if (!FoldConstants(context, &body, this))
         return nullptr;
 
+    // For global scripts, whether bindings are closed over or not doesn't
+    // matter, so no need to call propagateFreeNamesAndMarkClosedOver-
+    // Bindings. However, Annex B.3.3 functions still need to be marked.
+    if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc))
+        return nullptr;
+
     Maybe<GlobalScope::Data*> bindings = newGlobalScopeData(pc->varScope());
     if (!bindings)
         return nullptr;
     globalsc->bindings = *bindings;
 
     return body;
 }
 
@@ -2541,17 +2532,17 @@ Parser<FullParseHandler, char16_t>::stan
         return null();
 
     ParseNode* argsbody = handler.newList(PNK_PARAMSBODY, pos());
     if (!argsbody)
         return null();
     fn->pn_body = argsbody;
 
     FunctionBox* funbox = newFunctionBox(fn, fun, /* toStringStart = */ 0, inheritedDirectives,
-                                         generatorKind, asyncKind, /* tryAnnexB = */ false);
+                                         generatorKind, asyncKind);
     if (!funbox)
         return null();
     funbox->initStandaloneFunction(enclosingScope);
 
     ParseContext funpc(this, funbox, newDirectives);
     if (!funpc.init())
         return null();
     funpc.setIsStandaloneFunctionBody();
@@ -3214,17 +3205,17 @@ Parser<FullParseHandler, char16_t>::skip
     // When a lazily-parsed function is called, we only fully parse (and emit)
     // that function, not any of its nested children. The initial syntax-only
     // parse recorded the free variables of nested functions and their extents,
     // so we can skip over them after accounting for their free variables.
 
     RootedFunction fun(context, handler.nextLazyInnerFunction());
     MOZ_ASSERT(!fun->isLegacyGenerator());
     FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, Directives(/* strict = */ false),
-                                         fun->generatorKind(), fun->asyncKind(), tryAnnexB);
+                                         fun->generatorKind(), fun->asyncKind());
     if (!funbox)
         return false;
 
     LazyScript* lazy = fun->lazyScript();
     if (lazy->needsHomeObject())
         funbox->setNeedsHomeObject();
     if (lazy->isExprBody())
         funbox->setIsExprBody();
@@ -3245,16 +3236,20 @@ Parser<FullParseHandler, char16_t>::skip
     // If we remove expression closure, we can remove isExprBody flag from
     // LazyScript and JSScript.
     if (kind == Statement && funbox->isExprBody()) {
         if (!matchOrInsertSemicolonAfterExpression())
             return false;
     }
 #endif
 
+    // Append possible Annex B function box only upon successfully parsing.
+    if (tryAnnexB && !pc->innermostScope()->addPossibleAnnexBFunctionBox(pc, funbox))
+        return false;
+
     return true;
 }
 
 template <>
 bool
 Parser<SyntaxParseHandler, char16_t>::skipLazyInnerFunction(Node pn, uint32_t toStringStart,
                                                             FunctionSyntaxKind kind,
                                                             bool tryAnnexB)
@@ -3441,17 +3436,17 @@ Parser<FullParseHandler, char16_t>::tryS
         tokenStream.tell(&position);
         if (!parser->tokenStream.seek(position, tokenStream))
             return false;
 
         // Make a FunctionBox before we enter the syntax parser, because |pn|
         // still expects a FunctionBox to be attached to it during BCE, and
         // the syntax parser cannot attach one to it.
         FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, inheritedDirectives,
-                                             generatorKind, asyncKind, tryAnnexB);
+                                             generatorKind, asyncKind);
         if (!funbox)
             return false;
         funbox->initWithEnclosingParseContext(pc, kind);
 
         if (!parser->innerFunction(SyntaxParseHandlerBase::NodeGeneric, pc, funbox, toStringStart,
                                    inHandling, yieldHandling, kind,
                                    inheritedDirectives, newDirectives))
         {
@@ -3470,16 +3465,21 @@ Parser<FullParseHandler, char16_t>::tryS
 
         // Advance this parser over tokens processed by the syntax parser.
         parser->tokenStream.tell(&position);
         if (!tokenStream.seek(position, parser->tokenStream))
             return false;
 
         // Update the end position of the parse node.
         pn->pn_pos.end = tokenStream.currentToken().pos.end;
+
+        // Append possible Annex B function box only upon successfully parsing.
+        if (tryAnnexB && !pc->innermostScope()->addPossibleAnnexBFunctionBox(pc, funbox))
+            return false;
+
         return true;
     } while (false);
 
     // We failed to do a syntax parse above, so do the full parse.
     return innerFunction(pn, pc, fun, toStringStart, inHandling, yieldHandling, kind,
                          generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
 }
 
@@ -3538,23 +3538,32 @@ Parser<ParseHandler, CharT>::innerFuncti
                                            Directives* newDirectives)
 {
     // Note that it is possible for outerpc != this->pc, as we may be
     // attempting to syntax parse an inner function from an outer full
     // parser. In that case, outerpc is a ParseContext from the full parser
     // instead of the current top of the stack of the syntax parser.
 
     FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, inheritedDirectives,
-                                         generatorKind, asyncKind, tryAnnexB);
+                                         generatorKind, asyncKind);
     if (!funbox)
         return false;
     funbox->initWithEnclosingParseContext(outerpc, kind);
 
-    return innerFunction(pn, outerpc, funbox, toStringStart, inHandling, yieldHandling, kind,
-                         inheritedDirectives, newDirectives);
+    if (!innerFunction(pn, outerpc, funbox, toStringStart, inHandling, yieldHandling, kind,
+                       inheritedDirectives, newDirectives))
+    {
+        return false;
+    }
+
+    // Append possible Annex B function box only upon successfully parsing.
+    if (tryAnnexB && !pc->innermostScope()->addPossibleAnnexBFunctionBox(pc, funbox))
+        return false;
+
+    return true;
 }
 
 template <template <typename CharT> class ParseHandler, typename CharT>
 bool
 Parser<ParseHandler, CharT>::appendToCallSiteObj(Node callSiteObj)
 {
     Node cookedNode = noSubstitutionTaggedTemplate();
     if (!cookedNode)
@@ -3568,29 +3577,31 @@ Parser<ParseHandler, CharT>::appendToCal
         return false;
 
     handler.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
     return true;
 }
 
 template <>
 ParseNode*
-Parser<FullParseHandler, char16_t>::standaloneLazyFunction(HandleFunction fun, bool strict,
+Parser<FullParseHandler, char16_t>::standaloneLazyFunction(HandleFunction fun,
+                                                           uint32_t toStringStart,
+                                                           bool strict,
                                                            GeneratorKind generatorKind,
                                                            FunctionAsyncKind asyncKind)
 {
     MOZ_ASSERT(checkOptionsCalled);
 
     Node pn = handler.newFunctionStatement(pos());
     if (!pn)
         return null();
 
     Directives directives(strict);
-    FunctionBox* funbox = newFunctionBox(pn, fun, /* toStringStart = */ 0, directives,
-                                         generatorKind, asyncKind, /* tryAnnexB = */ false);
+    FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, directives, generatorKind,
+                                         asyncKind);
     if (!funbox)
         return null();
     funbox->initFromLazyFunction();
 
     Directives newDirectives = directives;
     ParseContext funpc(this, funbox, &newDirectives);
     if (!funpc.init())
         return null();
@@ -3754,24 +3765,24 @@ Parser<ParseHandler, CharT>::functionFor
         if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling))
             return false;
     }
 
     if (bodyType == StatementListBody) {
         MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::Operand,
                                          reportMissingClosing(JSMSG_CURLY_AFTER_BODY,
                                                               JSMSG_CURLY_OPENED, openedPos));
-        funbox->setEnd(pos().end);
+        funbox->setEnd(tokenStream);
     } else {
 #if !JS_HAS_EXPR_CLOSURES
         MOZ_ASSERT(kind == Arrow);
 #endif
         if (tokenStream.hadError())
             return false;
-        funbox->setEnd(pos().end);
+        funbox->setEnd(tokenStream);
         if (kind == Statement && !matchOrInsertSemicolonAfterExpression())
             return false;
     }
 
     if (IsMethodDefinitionKind(kind) && pc->superScopeNeedsHomeObject())
         funbox->setNeedsHomeObject();
 
     if (!finishFunction(isStandaloneFunction))
@@ -3849,18 +3860,20 @@ Parser<ParseHandler, CharT>::functionStm
         MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
 
         if (!pc->sc()->strict() && generatorKind == NotGenerator && asyncKind == SyncFunction) {
             // Under sloppy mode, try Annex B.3.3 semantics. If making an
             // additional 'var' binding of the same name does not throw an
             // early error, do so. This 'var' binding would be assigned
             // the function object when its declaration is reached, not at
             // the start of the block.
-            if (!tryDeclareVarForAnnexBLexicalFunction(name, pos().begin, &tryAnnexB))
-                return null();
+            //
+            // This semantics is implemented upon Scope exit in
+            // Scope::propagateAndMarkAnnexBFunctionBoxes.
+            tryAnnexB = true;
         }
 
         if (!noteDeclaredName(name, DeclarationKind::LexicalFunction, pos()))
             return null();
     } else {
         DeclarationKind kind = pc->atModuleLevel()
                                ? DeclarationKind::ModuleBodyLevelFunction
                                : DeclarationKind::BodyLevelFunction;
@@ -8589,17 +8602,17 @@ Parser<ParseHandler, CharT>::generatorCo
     RootedFunction fun(context, newFunction(/* atom = */ nullptr, Expression,
                                             StarGenerator, SyncFunction, proto));
     if (!fun)
         return null();
 
     // Create box for fun->object early to root it.
     Directives directives(/* strict = */ outerpc->sc()->strict());
     FunctionBox* genFunbox = newFunctionBox(genfn, fun, /* toStringStart = */ 0, directives,
-                                            StarGenerator, SyncFunction, /* tryAnnexB = */ false);
+                                            StarGenerator, SyncFunction);
     if (!genFunbox)
         return null();
     genFunbox->isGenexpLambda = true;
     genFunbox->initWithEnclosingParseContext(outerpc, Expression);
 
     ParseContext genpc(this, genFunbox, /* newDirectives = */ nullptr);
     if (!genpc.init())
         return null();
@@ -8624,17 +8637,17 @@ Parser<ParseHandler, CharT>::generatorCo
     if (!comp)
         return null();
 
     MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
 
     uint32_t end = pos().end;
     handler.setBeginPosition(comp, begin);
     handler.setEndPosition(comp, end);
-    genFunbox->setEnd(end);
+    genFunbox->setEnd(tokenStream);
     handler.addStatementToList(body, comp);
     handler.setEndPosition(body, end);
     handler.setBeginPosition(genfn, begin);
     handler.setEndPosition(genfn, end);
 
     Node generator = newDotGeneratorName();
     if (!generator)
         return null();
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -113,16 +113,21 @@ class ParseContext : public Nestable<Par
         //
         // A 'var' declared name is a member of the declared name set of every
         // scope in its scope contour.
         //
         // A lexically declared name is a member only of the declared name set of
         // the scope in which it is declared.
         PooledMapPtr<DeclaredNameMap> declared_;
 
+        // FunctionBoxes in this scope that need to be considered for Annex
+        // B.3.3 semantics. This is checked on Scope exit, as by then we have
+        // all the declared names and would know if Annex B.3.3 is applicable.
+        PooledVectorPtr<FunctionBoxVector> possibleAnnexBFunctionBoxes_;
+
         // Monotonically increasing id.
         uint32_t id_;
 
         bool maybeReportOOM(ParseContext* pc, bool result) {
             if (!result)
                 ReportOutOfMemory(pc->sc()->context);
             return result;
         }
@@ -159,19 +164,22 @@ class ParseContext : public Nestable<Par
         }
 
         MOZ_MUST_USE bool addDeclaredName(ParseContext* pc, AddDeclaredNamePtr& p, JSAtom* name,
                                           DeclarationKind kind, uint32_t pos)
         {
             return maybeReportOOM(pc, declared_->add(p, name, DeclaredNameInfo(kind, pos)));
         }
 
-        // Remove all VarForAnnexBLexicalFunction declarations of a certain
-        // name from all scopes in pc's scope stack.
-        static void removeVarForAnnexBLexicalFunction(ParseContext* pc, JSAtom* name);
+        // Add a FunctionBox as a possible candidate for Annex B.3.3 semantics.
+        MOZ_MUST_USE bool addPossibleAnnexBFunctionBox(ParseContext* pc, FunctionBox* funbox);
+
+        // Check if the candidate function boxes for Annex B.3.3 should in
+        // fact get Annex B semantics. Checked on Scope exit.
+        MOZ_MUST_USE bool propagateAndMarkAnnexBFunctionBoxes(ParseContext* pc);
 
         // Add and remove catch parameter names. Used to implement the odd
         // semantics of catch bodies.
         bool addCatchParameters(ParseContext* pc, Scope& catchParamScope);
         void removeCatchParameters(ParseContext* pc, Scope& catchParamScope);
 
         void useAsVarScope(ParseContext* pc) {
             MOZ_ASSERT(!pc->varScope_);
@@ -292,20 +300,16 @@ class ParseContext : public Nestable<Par
     // ('.this', 'arguments') and the formal parameers.
     mozilla::Maybe<Scope> functionScope_;
 
     // The body-level scope. This always exists, but not necessarily at the
     // beginning of parsing the script in the case of functions with parameter
     // expressions.
     Scope* varScope_;
 
-    // Inner function boxes in this context to try Annex B.3.3 semantics
-    // on. Only used when full parsing.
-    PooledVectorPtr<FunctionBoxVector> innerFunctionBoxesForAnnexB_;
-
     // Simple formal parameter names, in order of appearance. Only used when
     // isFunctionBox().
     PooledVectorPtr<AtomVector> positionalFormalParameterNames_;
 
     // Closed over binding names, in order of appearance. Null-delimited
     // between scopes. Only used when syntax parsing.
     PooledVectorPtr<AtomVector> closedOverBindingsForLazy_;
 
@@ -356,17 +360,16 @@ class ParseContext : public Nestable<Par
                   ? TraceLogger_ParsingFull
                   : TraceLogger_ParsingSyntax,
                   prs->tokenStream),
         sc_(sc),
         tokenStream_(prs->tokenStream),
         innermostStatement_(nullptr),
         innermostScope_(nullptr),
         varScope_(nullptr),
-        innerFunctionBoxesForAnnexB_(prs->context->frontendCollectionPool()),
         positionalFormalParameterNames_(prs->context->frontendCollectionPool()),
         closedOverBindingsForLazy_(prs->context->frontendCollectionPool()),
         scriptId_(prs->usedNames.nextScriptId()),
         isStandaloneFunctionBody_(false),
         superScopeNeedsHomeObject_(false),
         lastYieldOffset(NoYieldOffset),
         lastAwaitOffset(NoAwaitOffset),
         innerFunctionsForLazy(prs->context, GCVector<JSFunction*, 8>(prs->context)),
@@ -376,18 +379,16 @@ class ParseContext : public Nestable<Par
     {
         if (isFunctionBox()) {
             if (functionBox()->function()->isNamedLambda())
                 namedLambdaScope_.emplace(prs);
             functionScope_.emplace(prs);
         }
     }
 
-    ~ParseContext();
-
     MOZ_MUST_USE bool init();
 
     SharedContext* sc() {
         return sc_;
     }
 
     bool isFunctionBox() const {
         return sc_->isFunctionBox();
@@ -445,20 +446,16 @@ class ParseContext : public Nestable<Par
     AtomVector& positionalFormalParameterNames() {
         return *positionalFormalParameterNames_;
     }
 
     AtomVector& closedOverBindingsForLazy() {
         return *closedOverBindingsForLazy_;
     }
 
-    MOZ_MUST_USE bool addInnerFunctionBoxForAnnexB(FunctionBox* funbox);
-    void removeInnerFunctionBoxesForAnnexB(JSAtom* name);
-    void finishInnerFunctionBoxesForAnnexB();
-
     // True if we are at the topmost level of a entire script or function body.
     // For example, while parsing this code we would encounter f1 and f2 at
     // body level, but we would not encounter f3 or f4 at body level:
     //
     //   function f1() { function f2() { } }
     //   if (cond) { function f3() { if (cond) { function f4() { } } } }
     //
     bool atBodyLevel() {
@@ -528,16 +525,33 @@ class ParseContext : public Nestable<Par
 
     bool isMethod() const {
         return sc_->isFunctionBox() && sc_->asFunctionBox()->function()->isMethod();
     }
 
     uint32_t scriptId() const {
         return scriptId_;
     }
+
+    bool annexBAppliesToLexicalFunctionInInnermostScope(FunctionBox* funbox);
+
+    bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos,
+                       mozilla::Maybe<DeclarationKind>* redeclaredKind, uint32_t* prevPos);
+
+  private:
+    mozilla::Maybe<DeclarationKind> isVarRedeclaredInInnermostScope(HandlePropertyName name,
+                                                                    DeclarationKind kind);
+    mozilla::Maybe<DeclarationKind> isVarRedeclaredInEval(HandlePropertyName name,
+                                                          DeclarationKind kind);
+
+    enum DryRunOption { NotDryRun, DryRunInnermostScopeOnly };
+    template <DryRunOption dryRunOption>
+    bool tryDeclareVarHelper(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos,
+                             mozilla::Maybe<DeclarationKind>* redeclaredKind, uint32_t* prevPos);
+
 };
 
 template <>
 inline bool
 ParseContext::Statement::is<ParseContext::LabelStatement>() const
 {
     return kind_ == StatementKind::Label;
 }
@@ -958,16 +972,17 @@ class ParserBase : public StrictModeGett
     enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
     enum ForInitLocation { InForInit, NotInForInit };
 };
 
 inline
 ParseContext::Scope::Scope(ParserBase* parser)
   : Nestable<Scope>(&parser->pc->innermostScope_),
     declared_(parser->context->frontendCollectionPool()),
+    possibleAnnexBFunctionBoxes_(parser->context->frontendCollectionPool()),
     id_(parser->usedNames.nextScopeId())
 { }
 
 inline
 ParseContext::VarScope::VarScope(ParserBase* parser)
   : Scope(parser)
 {
     useAsVarScope(parser->pc);
@@ -1128,18 +1143,17 @@ class Parser final : public ParserBase, 
 
     /*
      * Parse a top-level JS script.
      */
     Node parse();
 
     FunctionBox* newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart,
                                 Directives directives,
-                                GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
-                                bool tryAnnexB);
+                                GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
 
     void trace(JSTracer* trc);
 
   private:
     Parser* thisForCtor() { return this; }
 
     Node stringLiteral();
     Node noSubstitutionTaggedTemplate();
@@ -1180,17 +1194,17 @@ class Parser final : public ParserBase, 
     // AsyncFunction constructors.
     Node standaloneFunction(HandleFunction fun, HandleScope enclosingScope,
                             const mozilla::Maybe<uint32_t>& parameterListEnd,
                             GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
                             Directives inheritedDirectives, Directives* newDirectives);
 
     // Parse a function, given only its arguments and body. Used for lazily
     // parsed functions.
-    Node standaloneLazyFunction(HandleFunction fun, bool strict,
+    Node standaloneLazyFunction(HandleFunction fun, uint32_t toStringStart, bool strict,
                                 GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
 
     // Parse an inner function given an enclosing ParseContext and a
     // FunctionBox for the inner function.
     bool innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox, uint32_t toStringStart,
                        InHandling inHandling, YieldHandling yieldHandling,
                        FunctionSyntaxKind kind,
                        Directives inheritedDirectives, Directives* newDirectives);
@@ -1507,22 +1521,17 @@ class Parser final : public ParserBase, 
 
     void reportMissingClosing(unsigned errorNumber, unsigned noteNumber, uint32_t openedPos);
 
     void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind, TokenPos pos,
                              uint32_t prevPos);
     bool notePositionalFormalParameter(Node fn, HandlePropertyName name, uint32_t beginPos,
                                        bool disallowDuplicateParams, bool* duplicatedParam);
     bool noteDestructuredPositionalFormalParameter(Node fn, Node destruct);
-    mozilla::Maybe<DeclarationKind> isVarRedeclaredInEval(HandlePropertyName name,
-                                                          DeclarationKind kind);
-    bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos,
-                       mozilla::Maybe<DeclarationKind>* redeclaredKind, uint32_t* prevPos);
-    bool tryDeclareVarForAnnexBLexicalFunction(HandlePropertyName name, uint32_t beginPos,
-                                               bool* tryAnnexB);
+
     bool checkLexicalDeclarationDirectlyWithinBlock(ParseContext::Statement& stmt,
                                                     DeclarationKind kind, TokenPos pos);
     bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind, TokenPos pos);
     bool noteUsedName(HandlePropertyName name);
     bool hasUsedName(HandlePropertyName name);
 
     // Required on Scope exit.
     bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -556,26 +556,38 @@ class FunctionBox : public ObjectBox, pu
     // while the function is being reparsed. This flag can be used to disable
     // certain parsing features that are necessary in general, but unnecessary
     // for validated asm.js.
     bool useAsmOrInsideUseAsm() const {
         return useAsm || insideUseAsm;
     }
 
     void setStart(const TokenStream& tokenStream) {
-        bufStart = tokenStream.currentToken().pos.begin;
-        tokenStream.srcCoords.lineNumAndColumnIndex(bufStart, &startLine, &startColumn);
+        // Token positions are already offset from the start column in
+        // CompileOptions. bufStart and toStringStart, however, refer to
+        // absolute positions within the ScriptSource buffer, and need to
+        // de-offset from the starting column.
+        uint32_t offset = tokenStream.currentToken().pos.begin;
+        MOZ_ASSERT(offset >= tokenStream.options().column);
+        MOZ_ASSERT(toStringStart >= tokenStream.options().column);
+        toStringStart -= tokenStream.options().column;
+        bufStart = offset - tokenStream.options().column;
+        tokenStream.srcCoords.lineNumAndColumnIndex(offset, &startLine, &startColumn);
     }
 
-    void setEnd(uint32_t end) {
+    void setEnd(const TokenStream& tokenStream) {
         // For all functions except class constructors, the buffer and
         // toString ending positions are the same. Class constructors override
         // the toString ending position with the end of the class definition.
-        bufEnd = end;
-        toStringEnd = end;
+        //
+        // Offsets are de-offset for the same reason as in setStart above.
+        uint32_t offset = tokenStream.currentToken().pos.end;
+        MOZ_ASSERT(offset >= tokenStream.options().column);
+        bufEnd = offset - tokenStream.options().column;
+        toStringEnd = bufEnd;
     }
 
     void trace(JSTracer* trc) override;
 };
 
 inline FunctionBox*
 SharedContext::asFunctionBox()
 {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/parser/bug-1161312.js
@@ -0,0 +1,3 @@
+// Test that lazy scripts can handle OOB column numbers.
+
+assertEq(evaluate(`var f = x=>saveStack().column; f()`, { columnNumber: 1729 }), 1741);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4204,18 +4204,28 @@ JS::CancelOffThreadModule(JSContext* cx,
     HelperThreadState().cancelParseTask(cx->runtime(), ParseTaskKind::Module, token);
 }
 
 JS_PUBLIC_API(bool)
 JS::DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
                           mozilla::Vector<uint8_t>& buffer /* TranscodeBuffer& */, size_t cursor,
                           OffThreadCompileCallback callback, void* callbackData)
 {
-    MOZ_ASSERT(CanCompileOffThread(cx, options, buffer.length() - cursor));
-    return StartOffThreadDecodeScript(cx, options, buffer, cursor, callback, callbackData);
+    JS::TranscodeRange range(buffer.begin() + cursor, buffer.length() - cursor);
+    MOZ_ASSERT(CanCompileOffThread(cx, options, range.length()));
+    return StartOffThreadDecodeScript(cx, options, range, callback, callbackData);
+}
+
+JS_PUBLIC_API(bool)
+JS::DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
+                          const mozilla::Range<uint8_t>& range /* TranscodeRange& */,
+                          OffThreadCompileCallback callback, void* callbackData)
+{
+    MOZ_ASSERT(CanCompileOffThread(cx, options, range.length()));
+    return StartOffThreadDecodeScript(cx, options, range, callback, callbackData);
 }
 
 JS_PUBLIC_API(JSScript*)
 JS::FinishOffThreadScriptDecoder(JSContext* cx, void* token)
 {
     MOZ_ASSERT(cx);
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
     return HelperThreadState().finishScriptDecodeTask(cx, token);
@@ -4575,16 +4585,33 @@ JS::CloneAndExecuteScript(JSContext* cx,
         if (!script)
             return false;
 
         js::Debugger::onNewScript(cx, script);
     }
     return ExecuteScript(cx, globalLexical, script, rval.address());
 }
 
+JS_PUBLIC_API(bool)
+JS::CloneAndExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
+                          HandleScript scriptArg,
+                          JS::MutableHandleValue rval)
+{
+    CHECK_REQUEST(cx);
+    RootedScript script(cx, scriptArg);
+    if (script->compartment() != cx->compartment()) {
+        script = CloneGlobalScript(cx, ScopeKind::NonSyntactic, script);
+        if (!script)
+            return false;
+
+        js::Debugger::onNewScript(cx, script);
+    }
+    return ExecuteScript(cx, envChain, script, rval.address());
+}
+
 static const unsigned LARGE_SCRIPT_LENGTH = 500*1024;
 
 static bool
 Evaluate(JSContext* cx, ScopeKind scopeKind, HandleObject env,
          const ReadOnlyCompileOptions& optionsArg,
          SourceBufferHolder& srcBuf, MutableHandleValue rval)
 {
     CompileOptions options(cx, optionsArg);
@@ -7026,16 +7053,25 @@ JS::DecodeScript(JSContext* cx, Transcod
 {
     XDRDecoder decoder(cx, buffer, cursorIndex);
     decoder.codeScript(scriptp);
     MOZ_ASSERT(bool(scriptp) == (decoder.resultCode() == TranscodeResult_Ok));
     return decoder.resultCode();
 }
 
 JS_PUBLIC_API(JS::TranscodeResult)
+JS::DecodeScript(JSContext* cx, const TranscodeRange& range, JS::MutableHandleScript scriptp)
+{
+    XDRDecoder decoder(cx, range);
+    decoder.codeScript(scriptp);
+    MOZ_ASSERT(bool(scriptp) == (decoder.resultCode() == TranscodeResult_Ok));
+    return decoder.resultCode();
+}
+
+JS_PUBLIC_API(JS::TranscodeResult)
 JS::DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer,
                               JS::MutableHandleFunction funp,
                               size_t cursorIndex)
 {
     XDRDecoder decoder(cx, buffer, cursorIndex);
     decoder.codeFunction(funp);
     MOZ_ASSERT(bool(funp) == (decoder.resultCode() == TranscodeResult_Ok));
     return decoder.resultCode();
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4273,16 +4273,21 @@ FinishOffThreadModule(JSContext* cx, voi
 extern JS_PUBLIC_API(void)
 CancelOffThreadModule(JSContext* cx, void* token);
 
 extern JS_PUBLIC_API(bool)
 DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
                       mozilla::Vector<uint8_t>& buffer /* TranscodeBuffer& */, size_t cursor,
                       OffThreadCompileCallback callback, void* callbackData);
 
+extern JS_PUBLIC_API(bool)
+DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
+                      const mozilla::Range<uint8_t>& range /* TranscodeRange& */,
+                      OffThreadCompileCallback callback, void* callbackData);
+
 extern JS_PUBLIC_API(JSScript*)
 FinishOffThreadScriptDecoder(JSContext* cx, void* token);
 
 extern JS_PUBLIC_API(void)
 CancelOffThreadScriptDecoder(JSContext* cx, void* token);
 
 /**
  * Compile a function with envChain plus the global as its scope chain.
@@ -4373,16 +4378,25 @@ namespace JS {
 /**
  * Like the above, but handles a cross-compartment script. If the script is
  * cross-compartment, it is cloned into the current compartment before executing.
  */
 extern JS_PUBLIC_API(bool)
 CloneAndExecuteScript(JSContext* cx, JS::Handle<JSScript*> script,
                       JS::MutableHandleValue rval);
 
+/**
+ * Like CloneAndExecuteScript above, but allows executing under a non-syntactic
+ * environment chain.
+ */
+extern JS_PUBLIC_API(bool)
+CloneAndExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
+                      JS::Handle<JSScript*> script,
+                      JS::MutableHandleValue rval);
+
 } /* namespace JS */
 
 namespace JS {
 
 /**
  * Evaluate the given source buffer in the scope of the current global of cx.
  */
 extern JS_PUBLIC_API(bool)
@@ -6154,16 +6168,17 @@ class MOZ_RAII AutoHideScriptedCaller
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 /*
  * Encode/Decode interpreted scripts and functions to/from memory.
  */
 
 typedef mozilla::Vector<uint8_t> TranscodeBuffer;
+typedef mozilla::Range<uint8_t> TranscodeRange;
 
 enum TranscodeResult
 {
     // Successful encoding / decoding.
     TranscodeResult_Ok = 0,
 
     // A warning message, is set to the message out-param.
     TranscodeResult_Failure = 0x100,
@@ -6184,16 +6199,19 @@ EncodeScript(JSContext* cx, TranscodeBuf
 extern JS_PUBLIC_API(TranscodeResult)
 EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj);
 
 extern JS_PUBLIC_API(TranscodeResult)
 DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp,
              size_t cursorIndex = 0);
 
 extern JS_PUBLIC_API(TranscodeResult)
+DecodeScript(JSContext* cx, const TranscodeRange& range, JS::MutableHandleScript scriptp);
+
+extern JS_PUBLIC_API(TranscodeResult)
 DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp,
                           size_t cursorIndex = 0);
 
 // Register an encoder on the given script source, such that all functions can
 // be encoded as they are parsed. This strategy is used to avoid blocking the
 // active thread in a non-interruptible way.
 //
 // The |script| argument of |StartIncrementalEncoding| and
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1444,16 +1444,19 @@ JSVersion
 JSContext::findVersion()
 {
     if (JSScript* script = currentScript(nullptr, ALLOW_CROSS_COMPARTMENT))
         return script->getVersion();
 
     if (compartment() && compartment()->behaviors().version() != JSVERSION_UNKNOWN)
         return compartment()->behaviors().version();
 
+    if (!CurrentThreadCanAccessRuntime(runtime()))
+        return JSVERSION_DEFAULT;
+
     return runtime()->defaultVersion();
 }
 
 #ifdef DEBUG
 
 JS::AutoCheckRequestDepth::AutoCheckRequestDepth(JSContext* cxArg)
   : cx(cxArg->helperThread() ? nullptr : cxArg)
 {
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/LexicalEnvironment/block-scoped-functions-annex-b-arguments.js
@@ -0,0 +1,10 @@
+// Test that Annex B function interaction with 'arguments'.
+
+(function() {
+  assertEq(typeof arguments, "object");
+  { function arguments() {} }
+  assertEq(typeof arguments, "function");
+})();
+
+if (typeof reportCompare === "function")
+  reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/LexicalEnvironment/block-scoped-functions-annex-b-notapplicable.js
@@ -0,0 +1,14 @@
+// Test that functions in block that do not exhibit Annex B do not override
+// previous functions that do exhibit Annex B.
+
+function f() {
+  var outerX;
+  { function x() {1} outerX = x; }
+  { { function x() {2}; } let x; }
+  { let x; { function x() {3}; } }
+  assertEq(x, outerX);
+}
+f();
+
+if (typeof reportCompare === "function")
+  reportCompare(0, 0);
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -295,35 +295,37 @@ static const JSClassOps parseTaskGlobalC
 static const JSClass parseTaskGlobalClass = {
     "internal-parse-task-global", JSCLASS_GLOBAL_FLAGS,
     &parseTaskGlobalClassOps
 };
 
 ParseTask::ParseTask(ParseTaskKind kind, JSContext* cx, JSObject* parseGlobal,
                      const char16_t* chars, size_t length,
                      JS::OffThreadCompileCallback callback, void* callbackData)
-  : kind(kind), options(cx), chars(chars), length(length),
+  : kind(kind), options(cx),
     alloc(JSContext::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
     parseGlobal(parseGlobal),
     callback(callback), callbackData(callbackData),
     script(nullptr), sourceObject(nullptr),
     overRecursed(false), outOfMemory(false)
 {
+    data.construct<TwoByteChars>(chars, length);
 }
 
 ParseTask::ParseTask(ParseTaskKind kind, JSContext* cx, JSObject* parseGlobal,
-                     JS::TranscodeBuffer& buffer, size_t cursor,
+                     const JS::TranscodeRange& range,
                      JS::OffThreadCompileCallback callback, void* callbackData)
-  : kind(kind), options(cx), buffer(&buffer), cursor(cursor),
+  : kind(kind), options(cx),
     alloc(JSContext::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
     parseGlobal(parseGlobal),
     callback(callback), callbackData(callbackData),
     script(nullptr), sourceObject(nullptr),
     overRecursed(false), outOfMemory(false)
 {
+    data.construct<const JS::TranscodeRange>(range);
 }
 
 bool
 ParseTask::init(JSContext* cx, const ReadOnlyCompileOptions& options)
 {
     if (!this->options.copy(cx, options))
         return false;
 
@@ -380,53 +382,55 @@ ScriptParseTask::ScriptParseTask(JSConte
   : ParseTask(ParseTaskKind::Script, cx, parseGlobal, chars, length, callback,
               callbackData)
 {
 }
 
 void
 ScriptParseTask::parse(JSContext* cx)
 {
-    SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
+    auto& range = data.ref<TwoByteChars>();
+    SourceBufferHolder srcBuf(range.begin().get(), range.length(), SourceBufferHolder::NoOwnership);
     script = frontend::CompileGlobalScript(cx, alloc, ScopeKind::Global,
                                            options, srcBuf,
                                            /* sourceObjectOut = */ &sourceObject);
 }
 
 ModuleParseTask::ModuleParseTask(JSContext* cx, JSObject* parseGlobal,
                                  const char16_t* chars, size_t length,
                                  JS::OffThreadCompileCallback callback, void* callbackData)
   : ParseTask(ParseTaskKind::Module, cx, parseGlobal, chars, length, callback,
               callbackData)
 {
 }
 
 void
 ModuleParseTask::parse(JSContext* cx)
 {
-    SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
+    auto& range = data.ref<TwoByteChars>();
+    SourceBufferHolder srcBuf(range.begin().get(), range.length(), SourceBufferHolder::NoOwnership);
     ModuleObject* module = frontend::CompileModule(cx, options, srcBuf, alloc, &sourceObject);
     if (module)
         script = module->script();
 }
 
 ScriptDecodeTask::ScriptDecodeTask(JSContext* cx, JSObject* parseGlobal,
-                                   JS::TranscodeBuffer& buffer, size_t cursor,
+                                   const JS::TranscodeRange& range,
                                    JS::OffThreadCompileCallback callback, void* callbackData)
   : ParseTask(ParseTaskKind::ScriptDecode, cx, parseGlobal,
-              buffer, cursor, callback, callbackData)
+              range, callback, callbackData)
 {
 }
 
 void
 ScriptDecodeTask::parse(JSContext* cx)
 {
     RootedScript resultScript(cx);
     XDROffThreadDecoder decoder(cx, alloc, &options, /* sourceObjectOut = */ &sourceObject,
-                                *buffer, cursor);
+                                data.ref<const JS::TranscodeRange>());
     decoder.codeScript(&resultScript);
     MOZ_ASSERT(bool(resultScript) == (decoder.resultCode() == JS::TranscodeResult_Ok));
     if (decoder.resultCode() == JS::TranscodeResult_Ok) {
         script = resultScript.get();
     } else {
         sourceObject = nullptr;
     }
 }
@@ -648,22 +652,21 @@ js::StartOffThreadParseModule(JSContext*
         return cx->new_<ModuleParseTask>(cx, global, chars, length,
                                          callback, callbackData);
     };
     return StartOffThreadParseTask(cx, options, ParseTaskKind::Module, functor);
 }
 
 bool
 js::StartOffThreadDecodeScript(JSContext* cx, const ReadOnlyCompileOptions& options,
-                               JS::TranscodeBuffer& buffer, size_t cursor,
+                               const JS::TranscodeRange& range,
                                JS::OffThreadCompileCallback callback, void* callbackData)
 {
     auto functor = [&](JSObject* global) -> ScriptDecodeTask* {
-        return cx->new_<ScriptDecodeTask>(cx, global, buffer, cursor,
-                                          callback, callbackData);
+        return cx->new_<ScriptDecodeTask>(cx, global, range, callback, callbackData);
     };
     return StartOffThreadParseTask(cx, options, ParseTaskKind::ScriptDecode, functor);
 }
 
 void
 js::EnqueuePendingParseTasksAfterGC(JSRuntime* rt)
 {
     MOZ_ASSERT(!OffThreadParsingMustWaitForGC(rt));
--- a/js/src/vm/HelperThreads.h
+++ b/js/src/vm/HelperThreads.h
@@ -10,16 +10,17 @@
  * and are distinct from e.g. web workers.
  */
 
 #ifndef vm_HelperThreads_h
 #define vm_HelperThreads_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/GuardObjects.h"
+#include "mozilla/MaybeOneOf.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Variant.h"
 
 #include "jsapi.h"
 #include "jscntxt.h"
 
 #include "jit/Ion.h"
@@ -529,17 +530,17 @@ StartOffThreadParseScript(JSContext* cx,
 
 bool
 StartOffThreadParseModule(JSContext* cx, const ReadOnlyCompileOptions& options,
                           const char16_t* chars, size_t length,
                           JS::OffThreadCompileCallback callback, void* callbackData);
 
 bool
 StartOffThreadDecodeScript(JSContext* cx, const ReadOnlyCompileOptions& options,
-                           JS::TranscodeBuffer& buffer, size_t cursor,
+                           const JS::TranscodeRange& range,
                            JS::OffThreadCompileCallback callback, void* callbackData);
 
 /*
  * Called at the end of GC to enqueue any Parse tasks that were waiting on an
  * atoms-zone GC to finish.
  */
 void
 EnqueuePendingParseTasksAfterGC(JSRuntime* rt);
@@ -588,31 +589,19 @@ class MOZ_RAII AutoUnlockHelperThreadSta
         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     }
 };
 
 struct ParseTask
 {
     ParseTaskKind kind;
     OwningCompileOptions options;
-    // Anonymous union, the only correct interpretation is provided by the
-    // ParseTaskKind value, or from the virtual parse function.
-    union {
-        struct {
-            const char16_t* chars;
-            size_t length;
-        };
-        struct {
-            // This should be a reference, but C++ prevents us from using union
-            // with references as it assumes the reference constness might be
-            // violated.
-            JS::TranscodeBuffer* const buffer;
-            size_t cursor;
-        };
-    };
+
+    mozilla::MaybeOneOf<const JS::TranscodeRange, JS::TwoByteChars> data;
+
     LifoAlloc alloc;
 
     // Rooted pointer to the global object to use while parsing.
     JSObject* parseGlobal;
 
     // Callback invoked off thread when the parse finishes.
     JS::OffThreadCompileCallback callback;
     void* callbackData;
@@ -630,17 +619,17 @@ struct ParseTask
     Vector<CompileError*, 0, SystemAllocPolicy> errors;
     bool overRecursed;
     bool outOfMemory;
 
     ParseTask(ParseTaskKind kind, JSContext* cx, JSObject* parseGlobal,
               const char16_t* chars, size_t length,
               JS::OffThreadCompileCallback callback, void* callbackData);
     ParseTask(ParseTaskKind kind, JSContext* cx, JSObject* parseGlobal,
-              JS::TranscodeBuffer& buffer, size_t cursor,
+              const JS::TranscodeRange& range,
               JS::OffThreadCompileCallback callback, void* callbackData);
     bool init(JSContext* cx, const ReadOnlyCompileOptions& options);
 
     void activate(JSRuntime* rt);
     virtual void parse(JSContext* cx) = 0;
     bool finish(JSContext* cx);
 
     bool runtimeMatches(JSRuntime* rt) {
@@ -666,17 +655,17 @@ struct ModuleParseTask : public ParseTas
                     const char16_t* chars, size_t length,
                     JS::OffThreadCompileCallback callback, void* callbackData);
     void parse(JSContext* cx) override;
 };
 
 struct ScriptDecodeTask : public ParseTask
 {
     ScriptDecodeTask(JSContext* cx, JSObject* parseGlobal,
-                     JS::TranscodeBuffer& buffer, size_t cursor,
+                     const JS::TranscodeRange& range,
                      JS::OffThreadCompileCallback callback, void* callbackData);
     void parse(JSContext* cx) override;
 };
 
 // Return whether, if a new parse task was started, it would need to wait for
 // an in-progress GC to complete before starting.
 extern bool
 OffThreadParsingMustWaitForGC(JSRuntime* rt);
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -10,60 +10,106 @@
 #include "mozilla/EndianUtils.h"
 #include "mozilla/TypeTraits.h"
 
 #include "jsatom.h"
 #include "jsfriendapi.h"
 
 namespace js {
 
-class XDRBuffer {
+class XDRBufferBase
+{
   public:
-    XDRBuffer(JSContext* cx, JS::TranscodeBuffer& buffer, size_t cursor = 0)
-      : context_(cx), buffer_(buffer), cursor_(cursor) { }
+    explicit XDRBufferBase(JSContext* cx, size_t cursor = 0)
+      : context_(cx), cursor_(cursor) { }
 
     JSContext* cx() const {
         return context_;
     }
 
-    const uint8_t* read(size_t n) {
-        MOZ_ASSERT(cursor_ < buffer_.length());
-        uint8_t* ptr = &buffer_[cursor_];
-        cursor_ += n;
-        return ptr;
+    size_t cursor() const {
+        return cursor_;
     }
 
-    const char* readCString() {
-        char* ptr = reinterpret_cast<char*>(&buffer_[cursor_]);
-        uint8_t* end = reinterpret_cast<uint8_t*>(strchr(ptr, '\0')) + 1;
-        MOZ_ASSERT(buffer_.begin() < end);
-        MOZ_ASSERT(end <= buffer_.end());
-        cursor_ = end - buffer_.begin();
-        return ptr;
-    }
+  protected:
+    JSContext* const context_;
+    size_t cursor_;
+};
+
+template <XDRMode mode>
+class XDRBuffer;
+
+template <>
+class XDRBuffer<XDR_ENCODE> : public XDRBufferBase
+{
+  public:
+    XDRBuffer(JSContext* cx, JS::TranscodeBuffer& buffer, size_t cursor = 0)
+      : XDRBufferBase(cx, cursor),
+        buffer_(buffer) { }
 
     uint8_t* write(size_t n) {
         MOZ_ASSERT(n != 0);
         if (!buffer_.growByUninitialized(n)) {
             ReportOutOfMemory(cx());
             return nullptr;
         }
         uint8_t* ptr = &buffer_[cursor_];
         cursor_ += n;
         return ptr;
     }
 
-    size_t cursor() const {
-        return cursor_;
+    const char* readCString() {
+        MOZ_CRASH("Should never read in encode mode");
+        return nullptr;
+    }
+
+    const uint8_t* read(size_t n) {
+        MOZ_CRASH("Should never read in encode mode");
+        return nullptr;
     }
 
   private:
-    JSContext* const context_;
     JS::TranscodeBuffer& buffer_;
-    size_t cursor_;
+};
+
+template <>
+class XDRBuffer<XDR_DECODE> : public XDRBufferBase
+{
+  public:
+    XDRBuffer(JSContext* cx, const JS::TranscodeRange& range)
+      : XDRBufferBase(cx),
+        buffer_(range) { }
+
+    XDRBuffer(JSContext* cx, JS::TranscodeBuffer& buffer, size_t cursor = 0)
+      : XDRBufferBase(cx, cursor),
+        buffer_(buffer.begin(), buffer.length()) { }
+
+    const char* readCString() {
+        char* ptr = reinterpret_cast<char*>(&buffer_[cursor_]);
+        uint8_t* end = reinterpret_cast<uint8_t*>(strchr(ptr, '\0')) + 1;
+        MOZ_ASSERT(buffer_.begin().get() < end);
+        MOZ_ASSERT(end <= buffer_.end().get());
+        cursor_ = end - buffer_.begin().get();
+        return ptr;
+    }
+
+    const uint8_t* read(size_t n) {
+        MOZ_ASSERT(cursor_ < buffer_.length());
+        uint8_t* ptr = &buffer_[cursor_];
+        cursor_ += n;
+        return ptr;
+    }
+
+    uint8_t* write(size_t n) {
+        MOZ_CRASH("Should never write in decode mode");
+        return nullptr;
+    }
+
+  private:
+    const JS::TranscodeRange buffer_;
 };
 
 class XDRCoderBase;
 class XDRIncrementalEncoder;
 
 // An AutoXDRTree is used to identify section encoded by an XDRIncrementalEncoder.
 //
 // Its primary goal is to identify functions, such that we can first encode them
@@ -119,27 +165,34 @@ class XDRCoderBase
 
 /*
  * XDR serialization state.  All data is encoded in little endian.
  */
 template <XDRMode mode>
 class XDRState : public XDRCoderBase
 {
   public:
-    XDRBuffer buf;
+    XDRBuffer<mode> buf;
   private:
     JS::TranscodeResult resultCode_;
 
   public:
     XDRState(JSContext* cx, JS::TranscodeBuffer& buffer, size_t cursor = 0)
       : buf(cx, buffer, cursor),
         resultCode_(JS::TranscodeResult_Ok)
     {
     }
 
+    template <typename RangeType>
+    XDRState(JSContext* cx, const RangeType& range)
+      : buf(cx, range),
+        resultCode_(JS::TranscodeResult_Ok)
+    {
+    }
+
     virtual ~XDRState() {};
 
     JSContext* cx() const {
         return buf.cx();
     }
     virtual LifoAlloc& lifoAlloc() const;
 
     virtual bool hasOptions() const { return false; }
@@ -302,18 +355,18 @@ class XDROffThreadDecoder : public XDRDe
     // initialization with ScriptSourceObject::initFromOptions after the
     // decoding.
     //
     // When providing a sourceObjectOut pointer, you have to ensure that it is
     // marked by the GC to avoid dangling pointers.
     XDROffThreadDecoder(JSContext* cx, LifoAlloc& alloc,
                         const ReadOnlyCompileOptions* options,
                         ScriptSourceObject** sourceObjectOut,
-                        JS::TranscodeBuffer& buffer, size_t cursor = 0)
-      : XDRDecoder(cx, buffer, cursor),
+                        const JS::TranscodeRange& range)
+      : XDRDecoder(cx, range),
         options_(options),
         sourceObjectOut_(sourceObjectOut),
         alloc_(alloc)
     {
         MOZ_ASSERT(options);
         MOZ_ASSERT(sourceObjectOut);
         MOZ_ASSERT(*sourceObjectOut == nullptr);
     }
--- a/js/src/wasm/AsmJS.cpp
+++ b/js/src/wasm/AsmJS.cpp
@@ -7093,18 +7093,17 @@ ParseFunction(ModuleValidator& m, ParseN
 
     RootedFunction& fun = m.dummyFunction();
     fun->setAtom(name);
     fun->setArgCount(0);
 
     ParseContext* outerpc = m.parser().pc;
     Directives directives(outerpc);
     FunctionBox* funbox = m.parser().newFunctionBox(fn, fun, toStringStart, directives,
-                                                    NotGenerator, SyncFunction,
-                                                    /* tryAnnexB = */ false);
+                                                    NotGenerator, SyncFunction);
     if (!funbox)
         return false;
     funbox->initWithEnclosingParseContext(outerpc, frontend::Statement);
 
     Directives newDirectives = directives;
     ParseContext funpc(&m.parser(), funbox, &newDirectives);
     if (!funpc.init())
         return false;
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/loader/AutoMemMap.cpp
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=99: */
+/* 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 "AutoMemMap.h"
+#include "ScriptPreloader-inl.h"
+
+#include "mozilla/Unused.h"
+#include "nsIFile.h"
+
+namespace mozilla {
+namespace loader {
+
+AutoMemMap::~AutoMemMap()
+{
+    if (fileMap) {
+        if (addr) {
+            Unused << NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS);
+            addr = nullptr;
+        }
+
+        Unused << NS_WARN_IF(PR_CloseFileMap(fileMap) != PR_SUCCESS);
+        fileMap = nullptr;
+    }
+}
+
+Result<Ok, nsresult>
+AutoMemMap::init(nsIFile* file, int flags, int mode, PRFileMapProtect prot)
+{
+    MOZ_ASSERT(!fd);
+    MOZ_ASSERT(!fileMap);
+    MOZ_ASSERT(!addr);
+
+    int64_t fileSize;
+    NS_TRY(file->GetFileSize(&fileSize));
+
+    if (fileSize > UINT32_MAX)
+        return Err(NS_ERROR_INVALID_ARG);
+
+    NS_TRY(file->OpenNSPRFileDesc(flags, mode, &fd.rwget()));
+
+    fileMap = PR_CreateFileMap(fd, 0, prot);
+    if (!fileMap)
+        return Err(NS_ERROR_FAILURE);
+
+    size_ = fileSize;
+    addr = PR_MemMap(fileMap, 0, size_);
+    if (!addr)
+        return Err(NS_ERROR_FAILURE);
+
+    return Ok();
+}
+
+} // namespace loader
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/loader/AutoMemMap.h
@@ -0,0 +1,67 @@
+/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4; -*- */
+/* 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 loader_AutoMemMap_h
+#define loader_AutoMemMap_h
+
+#include "mozilla/FileUtils.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/RangedPtr.h"
+#include "mozilla/Result.h"
+#include "nsIMemoryReporter.h"
+
+#include <prio.h>
+
+class nsIFile;
+
+namespace mozilla {
+namespace loader {
+
+class AutoMemMap
+{
+    public:
+        AutoMemMap() = default;
+
+        ~AutoMemMap();
+
+        Result<Ok, nsresult>
+        init(nsIFile* file, int flags = PR_RDONLY, int mode = 0,
+             PRFileMapProtect prot = PR_PROT_READONLY);
+
+        bool initialized() { return addr; }
+
+        uint32_t size() const { MOZ_ASSERT(fd); return size_; }
+
+        template<typename T = void>
+        const RangedPtr<T> get()
+        {
+            MOZ_ASSERT(addr);
+            return { static_cast<T*>(addr), size_ };
+        }
+
+        template<typename T = void>
+        const RangedPtr<T> get() const
+        {
+            MOZ_ASSERT(addr);
+            return { static_cast<T*>(addr), size_ };
+        }
+
+        size_t nonHeapSizeOfExcludingThis() { return size_; }
+
+    private:
+        AutoFDClose fd;
+        PRFileMap* fileMap = nullptr;
+
+        uint32_t size_ = 0;
+        void* addr = nullptr;
+
+        AutoMemMap(const AutoMemMap&) = delete;
+        void operator=(const AutoMemMap&) = delete;
+};
+
+} // namespace loader
+} // namespace mozilla
+
+#endif // loader_AutoMemMap_h
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/loader/ScriptPreloader-inl.h
@@ -0,0 +1,169 @@
+/* -*-  Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; -*- */
+/* 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 ScriptPreloader_inl_h
+#define ScriptPreloader_inl_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/Range.h"
+#include "mozilla/Result.h"
+#include "mozilla/Unused.h"
+#include "nsString.h"
+#include "nsTArray.h"
+
+#include <prio.h>
+
+namespace mozilla {
+namespace loader {
+
+static inline Result<Ok, nsresult>
+WrapNSResult(PRStatus aRv)
+{
+    if (aRv != PR_SUCCESS) {
+        return Err(NS_ERROR_FAILURE);
+    }
+    return Ok();
+}
+
+static inline Result<Ok, nsresult>
+WrapNSResult(nsresult aRv)
+{
+    if (NS_FAILED(aRv)) {
+        return Err(aRv);
+    }
+    return Ok();
+}
+
+#define NS_TRY(expr) MOZ_TRY(WrapNSResult(expr))
+
+
+class OutputBuffer
+{
+public:
+    OutputBuffer()
+    {}
+
+    uint8_t*
+    write(size_t size)
+    {
+        auto buf = data.AppendElements(size);
+        cursor_ += size;
+        return buf;
+    }
+
+    void
+    codeUint16(const uint16_t& val)
+    {
+        LittleEndian::writeUint16(write(sizeof val), val);
+    }
+
+    void
+    codeUint32(const uint32_t& val)
+    {
+        LittleEndian::writeUint32(write(sizeof val), val);
+    }
+
+    void
+    codeString(const nsCString& str)
+    {
+        auto len = CheckedUint16(str.Length()).value();
+
+        codeUint16(len);
+        memcpy(write(len), str.BeginReading(), len);
+    }
+
+    size_t cursor() const { return cursor_; }
+
+
+    uint8_t* Get() { return data.Elements(); }
+
+    const uint8_t* Get() const { return data.Elements(); }
+
+private:
+    nsTArray<uint8_t> data;
+    size_t cursor_ = 0;
+};
+
+class InputBuffer
+{
+public:
+    explicit InputBuffer(const Range<uint8_t>& buffer)
+        : data(buffer)
+    {}
+
+    const uint8_t*
+    read(size_t size)
+    {
+        MOZ_ASSERT(checkCapacity(size));
+
+        auto buf = &data[cursor_];
+        cursor_ += size;
+        return buf;
+    }
+
+    bool
+    codeUint16(uint16_t& val)
+    {
+        if (checkCapacity(sizeof val)) {
+            val = LittleEndian::readUint16(read(sizeof val));
+        }
+        return !error_;
+    }
+
+    bool
+    codeUint32(uint32_t& val)
+    {
+        if (checkCapacity(sizeof val)) {
+            val = LittleEndian::readUint32(read(sizeof val));
+        }
+        return !error_;
+    }
+
+    bool
+    codeString(nsCString& str)
+    {
+        uint16_t len;
+        if (codeUint16(len)) {
+            if (checkCapacity(len)) {
+                str.SetLength(len);
+                memcpy(str.BeginWriting(), read(len), len);
+            }
+        }
+        return !error_;
+    }
+
+    bool error() { return error_; }
+
+    bool finished() { return error_ || !remainingCapacity(); }
+
+    size_t remainingCapacity() { return data.length() - cursor_; }
+
+    size_t cursor() const { return cursor_; }
+
+    const uint8_t* Get() const { return data.begin().get(); }
+
+private:
+    bool
+    checkCapacity(size_t size)
+    {
+        if (size > remainingCapacity()) {
+            error_ = true;
+        }
+        return !error_;
+    }
+
+    bool error_ = false;
+
+public:
+    const Range<uint8_t>& data;
+    size_t cursor_ = 0;
+};
+
+}; // namespace loader
+}; // namespace mozilla
+
+#endif // ScriptPreloader_inl_h
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/loader/ScriptPreloader.cpp
@@ -0,0 +1,737 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=99: */
+/* 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/ScriptPreloader.h"
+#include "ScriptPreloader-inl.h"
+
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/FileUtils.h"
+#include "mozilla/Logging.h"
+#include "mozilla/Services.h"
+#include "mozilla/Unused.h"
+#include "mozilla/dom/ScriptSettings.h"
+
+#include "MainThreadUtils.h"
+#include "nsDebug.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsIFile.h"
+#include "nsIObserverService.h"
+#include "nsJSUtils.h"
+#include "nsProxyRelease.h"
+#include "nsThreadUtils.h"
+#include "nsXULAppAPI.h"
+#include "xpcpublic.h"
+
+#define DELAYED_STARTUP_TOPIC "browser-delayed-startup-finished"
+#define CLEANUP_TOPIC "xpcom-shutdown"
+#define SHUTDOWN_TOPIC "quit-application-granted"
+#define CACHE_FLUSH_TOPIC "startupcache-invalidate"
+
+namespace mozilla {
+namespace {
+static LazyLogModule gLog("ScriptPreloader");
+
+#define LOG(level, ...) MOZ_LOG(gLog, LogLevel::level, (__VA_ARGS__))
+}
+
+using mozilla::dom::AutoJSAPI;
+using namespace mozilla::loader;
+
+nsresult
+ScriptPreloader::CollectReports(nsIHandleReportCallback* aHandleReport,
+                                nsISupports* aData, bool aAnonymize)
+{
+    MOZ_COLLECT_REPORT(
+        "explicit/script-preloader/heap/saved-scripts", KIND_HEAP, UNITS_BYTES,
+        SizeOfLinkedList(mSavedScripts, MallocSizeOf),
+        "Memory used to hold the scripts which have been executed in this "
+        "session, and will be written to the startup script cache file.");
+
+    MOZ_COLLECT_REPORT(
+        "explicit/script-preloader/heap/restored-scripts", KIND_HEAP, UNITS_BYTES,
+        SizeOfLinkedList(mRestoredScripts, MallocSizeOf),
+        "Memory used to hold the scripts which have been restored from the "
+        "startup script cache file, but have not been executed in this session.");
+
+    MOZ_COLLECT_REPORT(
+        "explicit/script-preloader/heap/other", KIND_HEAP, UNITS_BYTES,
+        ShallowHeapSizeOfIncludingThis(MallocSizeOf),
+        "Memory used by the script cache service itself.");
+
+    MOZ_COLLECT_REPORT(
+        "explicit/script-preloader/non-heap/memmapped-cache", KIND_NONHEAP, UNITS_BYTES,
+        mCacheData.nonHeapSizeOfExcludingThis(),
+        "The memory-mapped startup script cache file.");
+
+    return NS_OK;
+}
+
+
+ScriptPreloader&
+ScriptPreloader::GetSingleton()
+{
+    static RefPtr<ScriptPreloader> singleton;
+
+    if (!singleton) {
+        singleton = new ScriptPreloader();
+        ClearOnShutdown(&singleton);
+    }
+
+    return *singleton;
+}
+
+
+namespace {
+
+struct MOZ_RAII AutoSafeJSAPI : public AutoJSAPI
+{
+    AutoSafeJSAPI() { Init(); }
+};
+
+
+static void
+TraceOp(JSTracer* trc, void* data)
+{
+    auto preloader = static_cast<ScriptPreloader*>(data);
+
+    preloader->Trace(trc);
+}
+
+} // anonymous namespace
+
+void
+ScriptPreloader::Trace(JSTracer* trc)
+{
+    for (auto script : mSavedScripts) {
+        JS::TraceEdge(trc, &script->mScript, "ScriptPreloader::CachedScript.mScript");
+    }
+
+    for (auto script : mRestoredScripts) {
+        JS::TraceEdge(trc, &script->mScript, "ScriptPreloader::CachedScript.mScript");
+    }
+}
+
+
+ScriptPreloader::ScriptPreloader()
+  : mMonitor("[ScriptPreloader.mMonitor]")
+  , mSaveMonitor("[ScriptPreloader.mSaveMonitor]")
+{
+    nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+    MOZ_RELEASE_ASSERT(obs);
+    obs->AddObserver(this, DELAYED_STARTUP_TOPIC, false);
+    obs->AddObserver(this, SHUTDOWN_TOPIC, false);
+    obs->AddObserver(this, CLEANUP_TOPIC, false);
+    obs->AddObserver(this, CACHE_FLUSH_TOPIC, false);
+
+    AutoSafeJSAPI jsapi;
+    JS_AddExtraGCRootsTracer(jsapi.cx(), TraceOp, this);
+}
+
+void
+ScriptPreloader::ForceWriteCacheFile()
+{
+    if (mSaveThread) {
+        MonitorAutoLock mal(mSaveMonitor);
+
+        // Unblock the save thread, so it can start saving before we get to
+        // XPCOM shutdown.
+        mal.Notify();
+    }
+}
+
+void
+ScriptPreloader::Cleanup()
+{
+    if (mSaveThread) {
+        MonitorAutoLock mal(mSaveMonitor);
+
+        while (!mSaveComplete && mSaveThread) {
+            mal.Wait();
+        }
+    }
+
+    mSavedScripts.clear();
+    mRestoredScripts.clear();
+
+    AutoSafeJSAPI jsapi;
+    JS_RemoveExtraGCRootsTracer(jsapi.cx(), TraceOp, this);
+
+    UnregisterWeakMemoryReporter(this);
+}
+
+void
+ScriptPreloader::FlushScripts(LinkedList<CachedScript>& scripts)
+{
+    for (auto next = scripts.getFirst(); next; ) {
+        auto script = next;
+        next = script->getNext();
+
+        // We can only purge finished scripts here. Async scripts that are
+        // still being parsed off-thread have a non-refcounted reference to
+        // this script, which needs to stay alive until they finish parsing.
+        if (script->mReadyToExecute) {
+            script->Cancel();
+            script->remove();
+            delete script;
+        }
+    }
+}
+
+void
+ScriptPreloader::FlushCache()
+{
+    MonitorAutoLock mal(mMonitor);
+
+    FlushScripts(mSavedScripts);
+    FlushScripts(mRestoredScripts);
+
+    // If we've already finished saving the cache at this point, start a new
+    // delayed save operation. This will write out an empty cache file in place
+    // of any cache file we've already written out this session, which will
+    // prevent us from falling back to the current session's cache file on the
+    // next startup.
+    if (mSaveComplete) {
+        mSaveComplete = false;
+
+        Unused << NS_NewNamedThread("SaveScripts",
+                                    getter_AddRefs(mSaveThread), this);
+    }
+}
+
+nsresult
+ScriptPreloader::Observe(nsISupports* subject, const char* topic, const char16_t* data)
+{
+    if (!strcmp(topic, DELAYED_STARTUP_TOPIC)) {
+        nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+        obs->RemoveObserver(this, DELAYED_STARTUP_TOPIC);
+
+        mStartupFinished = true;
+
+        if (XRE_IsParentProcess()) {
+            Unused << NS_NewNamedThread("SaveScripts",
+                                        getter_AddRefs(mSaveThread), this);
+        }
+    } else if (!strcmp(topic, SHUTDOWN_TOPIC)) {
+        ForceWriteCacheFile();
+    } else if (!strcmp(topic, CLEANUP_TOPIC)) {
+        Cleanup();
+    } else if (!strcmp(topic, CACHE_FLUSH_TOPIC)) {
+        FlushCache();
+    }
+
+    return NS_OK;
+}
+
+
+Result<nsCOMPtr<nsIFile>, nsresult>
+ScriptPreloader::GetCacheFile(const char* leafName)
+{
+    nsCOMPtr<nsIFile> cacheFile;
+    NS_TRY(mProfD->Clone(getter_AddRefs(cacheFile)));
+
+    NS_TRY(cacheFile->AppendNative(NS_LITERAL_CSTRING("startupCache")));
+    Unused << cacheFile->Create(nsIFile::DIRECTORY_TYPE, 0777);
+
+    NS_TRY(cacheFile->AppendNative(nsDependentCString(leafName)));
+
+    return Move(cacheFile);
+}
+
+static const uint8_t MAGIC[] = "mozXDRcache";
+
+Result<Ok, nsresult>
+ScriptPreloader::OpenCache()
+{
+    NS_TRY(NS_GetSpecialDirectory("ProfLDS", getter_AddRefs(mProfD)));
+
+    nsCOMPtr<nsIFile> cacheFile;
+    MOZ_TRY_VAR(cacheFile, GetCacheFile("scriptCache.bin"));
+
+    bool exists;
+    NS_TRY(cacheFile->Exists(&exists));
+    if (exists) {
+        NS_TRY(cacheFile->MoveTo(nullptr, NS_LITERAL_STRING("scriptCache-current.bin")));
+    } else {
+        NS_TRY(cacheFile->SetLeafName(NS_LITERAL_STRING("scriptCache-current.bin")));
+        NS_TRY(cacheFile->Exists(&exists));
+        if (!exists) {
+            return Err(NS_ERROR_FILE_NOT_FOUND);
+        }
+    }
+
+    MOZ_TRY(mCacheData.init(cacheFile));
+
+    return Ok();
+}
+
+// Opens the script cache file for this session, and initializes the script
+// cache based on its contents. See WriteCache for details of the cache file.
+Result<Ok, nsresult>
+ScriptPreloader::InitCache()
+{
+    mCacheInitialized = true;
+
+    RegisterWeakMemoryReporter(this);
+
+    if (!XRE_IsParentProcess()) {
+        return Ok();
+    }
+
+    MOZ_TRY(OpenCache());
+
+    auto size = mCacheData.size();
+
+    uint32_t headerSize;
+    if (size < sizeof(MAGIC) + sizeof(headerSize)) {
+        return Err(NS_ERROR_UNEXPECTED);
+    }
+
+    auto data = mCacheData.get<uint8_t>();
+    auto end = data + size;
+
+    if (memcmp(MAGIC, data.get(), sizeof(MAGIC))) {
+        return Err(NS_ERROR_UNEXPECTED);
+    }
+    data += sizeof(MAGIC);
+
+    headerSize = LittleEndian::readUint32(data.get());
+    data += sizeof(headerSize);
+
+    if (data + headerSize > end) {
+        return Err(NS_ERROR_UNEXPECTED);
+    }
+
+    {
+        AutoCleanLinkedList<CachedScript> scripts;
+
+        Range<uint8_t> header(data, data + headerSize);
+        data += headerSize;
+
+        InputBuffer buf(header);
+
+        size_t offset = 0;
+        while (!buf.finished()) {
+            auto script = MakeUnique<CachedScript>(buf);
+
+            auto scriptData = data + script->mOffset;
+            if (scriptData + script->mSize > end) {
+                return Err(NS_ERROR_UNEXPECTED);
+            }
+
+            // Make sure offsets match what we'd expect based on script ordering and
+            // size, as a basic sanity check.
+            if (script->mOffset != offset) {
+                return Err(NS_ERROR_UNEXPECTED);
+            }
+            offset += script->mSize;
+
+            script->mXDRRange.emplace(scriptData, scriptData + script->mSize);
+
+            scripts.insertBack(script.release());
+        }
+
+        if (buf.error()) {
+            return Err(NS_ERROR_UNEXPECTED);
+        }
+
+        for (auto script : scripts) {
+            mScripts.Put(script->mCachePath, script);
+        }
+        mRestoredScripts = Move(scripts);
+    }
+
+    AutoJSAPI jsapi;
+    MOZ_RELEASE_ASSERT(jsapi.Init(xpc::CompilationScope()));
+    JSContext* cx = jsapi.cx();
+
+    auto start = TimeStamp::Now();
+    LOG(Info, "Off-thread decoding scripts...\n");
+
+    JS::CompileOptions options(cx, JSVERSION_LATEST);
+    for (auto script : mRestoredScripts) {
+        if (script->mSize > MIN_OFFTHREAD_SIZE &&
+            JS::CanCompileOffThread(cx, options, script->mSize)) {
+            DecodeScriptOffThread(cx, script);
+        } else {
+            script->mReadyToExecute = true;
+        }
+    }
+
+    LOG(Info, "Initialized decoding in %fms\n",
+        (TimeStamp::Now() - start).ToMilliseconds());
+
+    return Ok();
+}
+
+static inline Result<Ok, nsresult>
+Write(PRFileDesc* fd, const void* data, int32_t len)
+{
+    if (PR_Write(fd, data, len) != len) {
+        return Err(NS_ERROR_FAILURE);
+    }
+    return Ok();
+}
+
+void
+ScriptPreloader::PrepareCacheWrite()
+{
+    MOZ_ASSERT(NS_IsMainThread());
+
+    if (mDataPrepared) {
+        return;
+    }
+
+    if (mRestoredScripts.isEmpty()) {
+        // Check for any new scripts that we need to save. If there aren't
+        // any, and there aren't any saved scripts that we need to remove,
+        // don't bother writing out a new cache file.
+        bool found = false;
+        for (auto script : mSavedScripts) {
+            if (script->mXDRRange.isNothing()) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            mSaveComplete = true;
+            return;
+        }
+    }
+
+    AutoSafeJSAPI jsapi;
+
+    LinkedList<CachedScript> asyncScripts;
+
+    for (CachedScript* next = mSavedScripts.getFirst(); next; ) {
+        CachedScript* script = next;
+        next = script->getNext();
+
+        if (!script->mSize && !script->XDREncode(jsapi.cx())) {
+            script->remove();
+            delete script;
+        } else {
+            script->mSize = script->Range().length();
+
+            if (script->mSize > MIN_OFFTHREAD_SIZE) {
+                script->remove();
+                asyncScripts.insertBack(script);
+            }
+        }
+    }
+
+    // Store async-decoded scripts contiguously, since they're loaded
+    // immediately at startup.
+    while (CachedScript* s = asyncScripts.popLast()) {
+        mSavedScripts.insertFront(s);
+    }
+
+    mDataPrepared = true;
+}
+
+// Writes out a script cache file for the scripts accessed during early
+// startup in this session. The cache file is a little-endian binary file with
+// the following format:
+//
+// - A uint32 containing the size of the header block.
+//
+// - A header entry for each file stored in the cache containing:
+//   - The URL that the script was originally read from.
+//   - Its cache key.
+//   - The offset of its XDR data within the XDR data block.
+//   - The size of its XDR data in the XDR data block.
+//
+// - A block of XDR data for the encoded scripts, with each script's data at
+//   an offset from the start of the block, as specified above.
+Result<Ok, nsresult>
+ScriptPreloader::WriteCache()
+{
+    MOZ_ASSERT(!NS_IsMainThread());
+
+    if (!mDataPrepared && !mSaveComplete) {
+        MonitorAutoUnlock mau(mSaveMonitor);
+
+        NS_DispatchToMainThread(
+            NewRunnableMethod(this, &ScriptPreloader::PrepareCacheWrite),
+            NS_DISPATCH_SYNC);
+    }
+
+    if (mSaveComplete) {
+        // If we don't have anything we need to save, we're done.
+        return Ok();
+    }
+
+    nsCOMPtr<nsIFile> cacheFile;
+    MOZ_TRY_VAR(cacheFile, GetCacheFile("scriptCache-new.bin"));
+
+    bool exists;
+    NS_TRY(cacheFile->Exists(&exists));
+    if (exists) {
+        NS_TRY(cacheFile->Remove(false));
+    }
+
+    AutoFDClose fd;
+    NS_TRY(cacheFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE, 0644, &fd.rwget()));
+
+    OutputBuffer buf;
+    size_t offset = 0;
+    for (auto script : mSavedScripts) {
+        script->mOffset = offset;
+        script->Code(buf);
+
+        offset += script->mSize;
+    }
+
+    uint8_t headerSize[4];
+    LittleEndian::writeUint32(headerSize, buf.cursor());
+
+    MOZ_TRY(Write(fd, MAGIC, sizeof(MAGIC)));
+    MOZ_TRY(Write(fd, headerSize, sizeof(headerSize)));
+    MOZ_TRY(Write(fd, buf.Get(), buf.cursor()));
+
+    for (auto script : mSavedScripts) {
+        MOZ_TRY(Write(fd, script->Range().begin().get(), script->mSize));
+        script->mXDRData.reset();
+    }
+
+    NS_TRY(cacheFile->MoveTo(nullptr, NS_LITERAL_STRING("scriptCache.bin")));
+
+    return Ok();
+}
+
+// Runs in the mSaveThread thread, and writes out the cache file for the next
+// session after a reasonable delay.
+nsresult
+ScriptPreloader::Run()
+{
+    MonitorAutoLock mal(mSaveMonitor);
+
+    // Ideally wait about 10 seconds before saving, to avoid unnecessary IO
+    // during early startup.
+    mal.Wait(10000);
+
+    Unused << WriteCache();
+
+    mSaveComplete = true;
+    NS_ReleaseOnMainThread(mSaveThread.forget());
+
+    mal.NotifyAll();
+    return NS_OK;
+}
+
+/* static */ ScriptPreloader::CachedScript*
+ScriptPreloader::FindScript(LinkedList<CachedScript>& scripts, const nsCString& cachePath)
+{
+    for (auto script : scripts) {
+        if (script->mCachePath == cachePath) {
+            return script;
+        }
+    }
+    return nullptr;
+}
+
+void
+ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
+                            JS::HandleScript script)
+{
+    if (mStartupFinished || !mCacheInitialized) {
+        return;
+    }
+    // Don't bother trying to cache any URLs with cache-busting query
+    // parameters.
+    if (cachePath.FindChar('?') >= 0) {
+        return;
+    }
+
+    // Don't bother caching files that belong to the mochitest harness.
+    NS_NAMED_LITERAL_CSTRING(mochikitPrefix, "chrome://mochikit/");
+    if (StringHead(url, mochikitPrefix.Length()) == mochikitPrefix) {
+        return;
+    }
+
+    bool exists = mScripts.Get(cachePath);
+
+    CachedScript* restored = nullptr;
+    if (exists) {
+        restored = FindScript(mRestoredScripts, cachePath);
+    }
+
+    if (restored) {
+        restored->remove();
+        mSavedScripts.insertBack(restored);
+
+        MOZ_ASSERT(script);
+        restored->mScript = script;
+        restored->mReadyToExecute = true;
+    } else if (!exists) {
+        auto cachedScript = new CachedScript(url, cachePath, script);
+        mSavedScripts.insertBack(cachedScript);
+        mScripts.Put(cachePath, cachedScript);
+    }
+}
+
+JSScript*
+ScriptPreloader::GetCachedScript(JSContext* cx, const nsCString& path)
+{
+    auto script = mScripts.Get(path);
+    if (script) {
+        return WaitForCachedScript(cx, script);
+    }
+
+    return nullptr;
+}
+
+JSScript*
+ScriptPreloader::WaitForCachedScript(JSContext* cx, CachedScript* script)
+{
+    if (!script->mReadyToExecute) {
+        LOG(Info, "Must wait for async script load: %s\n", script->mURL.get());
+        auto start = TimeStamp::Now();
+
+        MonitorAutoLock mal(mMonitor);
+
+        if (!script->mReadyToExecute && script->mSize < MAX_MAINTHREAD_DECODE_SIZE) {
+            LOG(Info, "Script is small enough to recompile on main thread\n");
+
+            script->mReadyToExecute = true;
+        } else {
+            while (!script->mReadyToExecute) {
+                mal.Wait();
+            }
+        }
+
+        LOG(Info, "Waited %fms\n", (TimeStamp::Now() - start).ToMilliseconds());
+    }
+
+    return script->GetJSScript(cx);
+}
+
+
+void
+ScriptPreloader::DecodeScriptOffThread(JSContext* cx, CachedScript* script)
+{
+    JS::CompileOptions options(cx, JSVERSION_LATEST);
+
+    options.setNoScriptRval(true)
+           .setFileAndLine(script->mURL.get(), 1);
+
+    if (!JS::DecodeOffThreadScript(cx, options, script->Range(),
+                                   OffThreadDecodeCallback,
+                                   static_cast<void*>(script))) {
+        script->mReadyToExecute = true;
+    }
+}
+
+void
+ScriptPreloader::CancelOffThreadParse(void* token)
+{
+    AutoSafeJSAPI jsapi;
+    JS::CancelOffThreadScriptDecoder(jsapi.cx(), token);
+}
+
+/* static */ void
+ScriptPreloader::OffThreadDecodeCallback(void* token, void* context)
+{
+    auto script = static_cast<CachedScript*>(context);
+
+    MonitorAutoLock mal(GetSingleton().mMonitor);
+
+    if (script->mReadyToExecute) {
+        // We've already executed this script on the main thread, and opted to
+        // main thread decode it rather waiting for off-thread decoding to
+        // finish. So just cancel the off-thread parse rather than completing
+        // it.
+        NS_DispatchToMainThread(
+            NewRunnableMethod<void*>(&GetSingleton(),
+                                     &ScriptPreloader::CancelOffThreadParse,
+                                     token));
+        return;
+    }
+
+    script->mToken = token;
+    script->mReadyToExecute = true;
+
+    mal.NotifyAll();
+}
+
+inline
+ScriptPreloader::CachedScript::CachedScript(InputBuffer& buf)
+{
+    Code(buf);
+}
+
+bool
+ScriptPreloader::CachedScript::XDREncode(JSContext* cx)
+{
+    JSAutoCompartment ac(cx, mScript);
+    JS::RootedScript jsscript(cx, mScript);
+
+    mXDRData.emplace();
+
+    JS::TranscodeResult code = JS::EncodeScript(cx, Data(), jsscript);
+    if (code == JS::TranscodeResult_Ok) {
+        mXDRRange.emplace(Data().begin(), Data().length());
+        return true;
+    }
+    JS_ClearPendingException(cx);
+    return false;
+}
+
+void
+ScriptPreloader::CachedScript::Cancel()
+{
+    if (mToken) {
+        GetSingleton().mMonitor.AssertCurrentThreadOwns();
+
+        AutoSafeJSAPI jsapi;
+        JS::CancelOffThreadScriptDecoder(jsapi.cx(), mToken);
+
+        mReadyToExecute = true;
+        mToken = nullptr;
+    }
+}
+
+JSScript*
+ScriptPreloader::CachedScript::GetJSScript(JSContext* cx)
+{
+    MOZ_ASSERT(mReadyToExecute);
+    if (mScript) {
+        return mScript;
+    }
+
+    // If we have no token at this point, the script was too small to decode
+    // off-thread, or it was needed before the off-thread compilation was
+    // finished, and is small enough to decode on the main thread rather than
+    // wait for the off-thread decoding to finish. In either case, we decode
+    // it synchronously the first time it's needed.
+    if (!mToken) {
+        MOZ_ASSERT(mXDRRange.isSome());
+
+        JS::RootedScript script(cx);
+        if (JS::DecodeScript(cx, Range(), &script)) {
+            mScript = script;
+        }
+
+        return mScript;
+    }
+
+    Maybe<JSAutoCompartment> ac;
+    if (JS::CompartmentCreationOptionsRef(cx).addonIdOrNull()) {
+        // Make sure we never try to finish the parse in a compartment with an
+        // add-on ID, it wasn't started in one.
+        ac.emplace(cx, xpc::CompilationScope());
+    }
+
+    mScript = JS::FinishOffThreadScriptDecoder(cx, mToken);
+    mToken = nullptr;
+    return mScript;
+}
+
+NS_IMPL_ISUPPORTS(ScriptPreloader, nsIObserver, nsIRunnable, nsIMemoryReporter)
+
+#undef LOG
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/loader/ScriptPreloader.h
@@ -0,0 +1,292 @@
+/* -*-  Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; -*- */
+/* 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 ScriptPreloader_h
+#define ScriptPreloader_h
+
+#include "mozilla/LinkedList.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/Monitor.h"
+#include "mozilla/Range.h"
+#include "mozilla/Vector.h"
+#include "mozilla/Result.h"
+#include "mozilla/loader/AutoMemMap.h"
+#include "nsDataHashtable.h"
+#include "nsIFile.h"
+#include "nsIMemoryReporter.h"
+#include "nsIObserver.h"
+#include "nsIThread.h"
+
+#include "jsapi.h"
+
+#include <prio.h>
+
+namespace mozilla {
+namespace loader {
+    class InputBuffer;
+}
+
+using namespace mozilla::loader;
+
+class ScriptPreloader : public nsIObserver
+                      , public nsIMemoryReporter
+                      , public nsIRunnable
+{
+    MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
+
+public:
+    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_NSIOBSERVER
+    NS_DECL_NSIMEMORYREPORTER
+    NS_DECL_NSIRUNNABLE
+
+    static ScriptPreloader& GetSingleton();
+
+    // Retrieves the script with the given cache key from the script cache.
+    // Returns null if the script is not cached.
+    JSScript* GetCachedScript(JSContext* cx, const nsCString& name);
+
+    // Notes the execution of a script with the given URL and cache key.
+    // Depending on the stage of startup, the script may be serialized and
+    // stored to the startup script cache.
+    void NoteScript(const nsCString& url, const nsCString& cachePath, JS::HandleScript script);
+
+    // Initializes the script cache from the startup script cache file.
+    Result<Ok, nsresult> InitCache();
+
+    void Trace(JSTracer* trc);
+
+protected:
+    virtual ~ScriptPreloader() = default;
+
+private:
+    // Represents a cached JS script, either initially read from the script
+    // cache file, to be added to the next session's script cache file, or
+    // both.
+    //
+    // A script which was read from the cache file may be in any of the
+    // following states:
+    //
+    //  - Read from the cache, and being compiled off thread. In this case,
+    //    mReadyToExecute is false, and mToken is null.
+    //  - Off-thread compilation has finished, but the script has not yet been
+    //    executed. In this case, mReadyToExecute is true, and mToken has a non-null
+    //    value.
+    //  - Read from the cache, but too small or needed to immediately to be
+    //    compiled off-thread. In this case, mReadyToExecute is true, and both mToken
+    //    and mScript are null.
+    //  - Fully decoded, and ready to be added to the next session's cache
+    //    file. In this case, mReadyToExecute is true, and mScript is non-null.
+    //
+    // A script to be added to the next session's cache file always has a
+    // non-null mScript value. If it was read from the last session's cache
+    // file, it also has a non-empty mXDRRange range, which will be stored in
+    // the next session's cache file. If it was compiled in this session, its
+    // mXDRRange will initially be empty, and its mXDRData buffer will be
+    // populated just before it is written to the cache file.
+    class CachedScript : public LinkedListElement<CachedScript>
+    {
+    public:
+        CachedScript(CachedScript&&) = default;
+
+        CachedScript(const nsCString& url, const nsCString& cachePath, JSScript* script)
+            : mURL(url)
+            , mCachePath(cachePath)
+            , mScript(script)
+            , mReadyToExecute(true)
+        {}
+
+        explicit inline CachedScript(InputBuffer& buf);
+
+        ~CachedScript()
+        {
+            auto& cache = GetSingleton();
+#ifdef DEBUG
+            auto hashValue = cache.mScripts.Get(mCachePath);
+            MOZ_ASSERT_IF(hashValue, hashValue == this);
+#endif
+            cache.mScripts.Remove(mCachePath);
+        }
+
+        void Cancel();
+
+        // Encodes this script into XDR data, and stores the result in mXDRData.
+        // Returns true on success, false on failure.
+        bool XDREncode(JSContext* cx);
+
+        // Encodes or decodes this script, in the storage format required by the
+        // script cache file.
+        template<typename Buffer>
+        void Code(Buffer& buffer)
+        {
+            buffer.codeString(mURL);
+            buffer.codeString(mCachePath);
+            buffer.codeUint32(mOffset);
+            buffer.codeUint32(mSize);
+        }
+
+        // Returns the XDR data generated for this script during this session. See
+        // mXDRData.
+        JS::TranscodeBuffer& Data()
+        {
+            MOZ_ASSERT(mXDRData.isSome());
+            return mXDRData.ref();
+        }
+
+        // Returns the read-only XDR data for this script. See mXDRRange.
+        const JS::TranscodeRange& Range()
+        {
+            MOZ_ASSERT(mXDRRange.isSome());
+            return mXDRRange.ref();
+        }
+
+        JSScript* GetJSScript(JSContext* cx);
+
+        size_t HeapSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
+        {
+            auto size = mallocSizeOf(this);
+            if (mXDRData.isSome()) {
+                size += (mXDRData->sizeOfExcludingThis(mallocSizeOf) +
+                         mURL.SizeOfExcludingThisEvenIfShared(mallocSizeOf) +
+                         mCachePath.SizeOfExcludingThisEvenIfShared(mallocSizeOf));
+            }
+            return size;
+        }
+
+        // The URL from which this script was initially read and compiled.
+        nsCString mURL;
+        // A unique identifier for this script's filesystem location, used as a
+        // primary cache lookup value.
+        nsCString mCachePath;
+
+        // The offset of this script in the cache file, from the start of the XDR
+        // data block.
+        uint32_t mOffset = 0;
+        // The size of this script's encoded XDR data.
+        uint32_t mSize = 0;
+
+        JS::Heap<JSScript*> mScript;
+
+        // True if this script is ready to be executed. This means that either the
+        // off-thread portion of an off-thread decode has finished, or the script
+        // is too small to be decoded off-thread, and may be immediately decoded
+        // whenever it is first executed.
+        bool mReadyToExecute = false;
+
+        // The off-thread decode token for a completed off-thread decode, which
+        // has not yet been finalized on the main thread.
+        void* mToken = nullptr;
+
+        // The read-only XDR data for this script, which was either read from an
+        // existing cache file, or generated by encoding a script which was
+        // compiled during this session.
+        Maybe<JS::TranscodeRange> mXDRRange;
+
+        // XDR data which was generated from a script compiled during this
+        // session, and will be written to the cache file.
+        Maybe<JS::TranscodeBuffer> mXDRData;
+    };
+
+    // There's a trade-off between the time it takes to setup an off-thread
+    // decode and the time we save by doing the decode off-thread. At this
+    // point, the setup is quite expensive, and 20K is about where we start to
+    // see an improvement rather than a regression.
+    //
+    // This also means that we get much better performance loading one big
+    // script than several small scripts, since the setup is per-script, and the
+    // OMT compile is almost always complete by the time we need a given script.
+    static constexpr int MIN_OFFTHREAD_SIZE = 20 * 1024;
+
+    // The maximum size of scripts to re-decode on the main thread if off-thread
+    // decoding hasn't finished yet. In practice, we don't hit this very often,
+    // but when we do, re-decoding some smaller scripts on the main thread gives
+    // the background decoding a chance to catch up without blocking the main
+    // thread for quite as long.
+    static constexpr int MAX_MAINTHREAD_DECODE_SIZE = 50 * 1024;
+
+    ScriptPreloader();
+
+    void ForceWriteCacheFile();
+    void Cleanup();
+
+    void FlushCache();
+    void FlushScripts(LinkedList<CachedScript>& scripts);
+
+    // Opens the cache file for reading.
+    Result<Ok, nsresult> OpenCache();
+
+    // Writes a new cache file to disk. Must not be called on the main thread.
+    Result<Ok, nsresult> WriteCache();
+
+    // Prepares scripts for writing to the cache, serializing new scripts to
+    // XDR, and calculating their size-based offsets.
+    void PrepareCacheWrite();
+
+    // Returns a file pointer for the cache file with the given name in the
+    // current profile.
+    Result<nsCOMPtr<nsIFile>, nsresult>
+    GetCacheFile(const char* leafName);
+
+    static CachedScript* FindScript(LinkedList<CachedScript>& scripts, const nsCString& cachePath);
+
+    // Waits for the given cached script to finish compiling off-thread, or
+    // decodes it synchronously on the main thread, as appropriate.
+    JSScript* WaitForCachedScript(JSContext* cx, CachedScript* script);
+
+    // Begins decoding the given script in a background thread.
+    void DecodeScriptOffThread(JSContext* cx, CachedScript* script);
+
+    static void OffThreadDecodeCallback(void* token, void* context);
+    void CancelOffThreadParse(void* token);
+
+    size_t ShallowHeapSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
+    {
+        return (mallocSizeOf(this) + mScripts.ShallowSizeOfExcludingThis(mallocSizeOf) +
+                mallocSizeOf(mSaveThread.get()) + mallocSizeOf(mProfD.get()));
+    }
+
+    template<typename T>
+    static size_t SizeOfLinkedList(LinkedList<T>& list, mozilla::MallocSizeOf mallocSizeOf)
+    {
+        size_t size = 0;
+        for (auto elem : list) {
+            size += elem->HeapSizeOfIncludingThis(mallocSizeOf);
+        }
+        return size;
+    }
+
+    // The list of scripts executed during this session, and being saved for
+    // potential reuse, and to be written to the next session's cache file.
+    AutoCleanLinkedList<CachedScript> mSavedScripts;
+
+    // The list of scripts restored from the cache file at the start of this
+    // session. Scripts are removed from this list and moved to mSavedScripts
+    // the first time they're used during this session.
+    AutoCleanLinkedList<CachedScript> mRestoredScripts;
+
+    nsDataHashtable<nsCStringHashKey, CachedScript*> mScripts;
+
+    // True after we've shown the first window, and are no longer adding new
+    // scripts to the cache.
+    bool mStartupFinished = false;
+
+    bool mCacheInitialized = false;
+    bool mSaveComplete = false;
+    bool mDataPrepared = false;
+
+    nsCOMPtr<nsIFile> mProfD;
+    nsCOMPtr<nsIThread> mSaveThread;
+
+    // The mmapped cache data from this session's cache file.
+    AutoMemMap mCacheData;
+
+    Monitor mMonitor;
+    Monitor mSaveMonitor;
+};
+
+} // namespace mozilla
+
+#endif // ScriptPreloader_h
--- a/js/xpconnect/loader/moz.build
+++ b/js/xpconnect/loader/moz.build
@@ -1,30 +1,40 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 UNIFIED_SOURCES += [
+    'AutoMemMap.cpp',
     'ChromeScriptLoader.cpp',
     'mozJSLoaderUtils.cpp',
     'mozJSSubScriptLoader.cpp',
+    'ScriptPreloader.cpp',
 ]
 
 # mozJSComponentLoader.cpp cannot be built in unified mode because it uses
 # windows.h
 SOURCES += [
     'mozJSComponentLoader.cpp'
 ]
 
+EXPORTS.mozilla += [
+    'ScriptPreloader.h',
+]
+
 EXPORTS.mozilla.dom += [
     'PrecompiledScript.h',
 ]
 
+EXPORTS.mozilla.loader += [
+    'AutoMemMap.h',
+]
+
 EXTRA_JS_MODULES += [
     'ISO8601DateUtils.jsm',
     'XPCOMUtils.jsm',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -39,16 +39,17 @@
 #include "nsXULAppAPI.h"
 #include "WrapperFactory.h"
 
 #include "mozilla/AddonPathService.h"
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 #include "mozilla/MacroForEach.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/ScriptPreloader.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/UniquePtrExtensions.h"
 #include "mozilla/Unused.h"
 
 using namespace mozilla;
 using namespace mozilla::scache;
 using namespace xpc;
 using namespace JS;
@@ -679,17 +680,20 @@ mozJSComponentLoader::ObjectForLocation(
     StartupCache* cache = StartupCache::GetSingleton();
 
     nsAutoCString cachePath(kJSCachePrefix);
     rv = PathifyURI(aInfo.URI(), cachePath);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (cache) {
         if (!mReuseLoaderGlobal) {
-            rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
+            script = ScriptPreloader::GetSingleton().GetCachedScript(cx, cachePath);
+            if (!script) {
+                rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
+            }
         } else {
             rv = ReadCachedFunction(cache, cachePath, cx, mSystemPrincipal,
                                     function.address());
         }
 
         if (NS_SUCCEEDED(rv)) {
             LOG(("Successfully loaded %s from startupcache\n", nativePath.get()));
         } else {
@@ -843,16 +847,20 @@ mozJSComponentLoader::ObjectForLocation(
     }
 
     // We must have a script or a function (but not both!) here.  We have a
     // script when we're not reusing the loader global, and a function
     // otherwise.
     MOZ_ASSERT(!!script != !!function);
     MOZ_ASSERT(!!script == JS_IsGlobalObject(obj));
 
+    if (script) {
+        ScriptPreloader::GetSingleton().NoteScript(nativePath, cachePath, script);
+    }
+
     if (writeToCache) {
         // We successfully compiled the script, so cache it.
         if (script) {
             rv = WriteCachedScript(cache, cachePath, cx, mSystemPrincipal,
                                    script);
         } else {
             rv = WriteCachedFunction(cache, cachePath, cx, mSystemPrincipal,
                                      function);
@@ -885,17 +893,18 @@ mozJSComponentLoader::ObjectForLocation(
         // We're going to run script via JS_ExecuteScript or
         // JS_CallFunction, so we need an AutoEntryScript.
         // This is Gecko-specific and not in any spec.
         dom::AutoEntryScript aes(CurrentGlobalOrNull(cx),
                                  "component loader load module");
         JSContext* aescx = aes.cx();
         bool ok;
         if (script) {
-            ok = JS_ExecuteScript(aescx, script);
+            JS::RootedValue rval(cx);
+            ok = JS::CloneAndExecuteScript(aescx, script, &rval);
         } else {
             RootedValue rval(cx);
             ok = JS_CallFunction(aescx, obj, function,
                                  JS::HandleValueArray::empty(), &rval);
         }
 
         if (!ok) {
             if (aPropagateExceptions && aes.HasException()) {
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -23,16 +23,17 @@
 #include "jsfriendapi.h"
 #include "nsJSPrincipals.h"
 #include "xpcprivate.h" // For xpc::OptionsBase
 #include "jswrapper.h"
 
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/HoldDropJSObjects.h"
+#include "mozilla/ScriptPreloader.h"
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 #include "mozilla/Unused.h"
 #include "nsContentUtils.h"
 #include "nsStringGlue.h"
 #include "nsCycleCollectionParticipant.h"
 
 using namespace mozilla::scache;
@@ -188,50 +189,51 @@ PrepareScript(nsIURI* uri,
                                buf, len, function);
 }
 
 static bool
 EvalScript(JSContext* cx,
            HandleObject targetObj,
            MutableHandleValue retval,
            nsIURI* uri,
-           bool cache,
+           bool startupCache,
+           bool preloadCache,
            MutableHandleScript script,
            HandleFunction function)
 {
     if (function) {
         script.set(JS_GetFunctionScript(cx, function));
     }
 
     if (function) {
         if (!JS_CallFunction(cx, targetObj, function, JS::HandleValueArray::empty(), retval)) {
             return false;
         }
     } else {
         if (JS_IsGlobalObject(targetObj)) {
-            if (!JS_ExecuteScript(cx, script, retval)) {
+            if (!JS::CloneAndExecuteScript(cx, script, retval)) {
                 return false;
             }
         } else {
             JS::AutoObjectVector envChain(cx);
             if (!envChain.append(targetObj)) {
                 return false;
             }
-            if (!JS_ExecuteScript(cx, envChain, script, retval)) {
+            if (!JS::CloneAndExecuteScript(cx, envChain, script, retval)) {
                 return false;
             }
         }
     }
 
     JSAutoCompartment rac(cx, targetObj);
     if (!JS_WrapValue(cx, retval)) {
         return false;
     }
 
-    if (cache && !!script) {
+    if (script && (startupCache || preloadCache)) {
         nsAutoCString cachePath;
         JSVersion version = JS_GetVersion(cx);
         cachePath.AppendPrintf("jssubloader/%d", version);
         PathifyURI(uri, cachePath);
 
         nsCOMPtr<nsIScriptSecurityManager> secman =
             do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
         if (!secman) {
@@ -240,18 +242,26 @@ EvalScript(JSContext* cx,
 
         nsCOMPtr<nsIPrincipal> principal;
         nsresult rv = secman->GetSystemPrincipal(getter_AddRefs(principal));
         if (NS_FAILED(rv) || !principal) {
             ReportError(cx, LOAD_ERROR_NOPRINCIPALS, uri);
             return false;
         }
 
-        WriteCachedScript(StartupCache::GetSingleton(),
-                          cachePath, cx, principal, script);
+        nsCString uriStr;
+        if (preloadCache && NS_SUCCEEDED(uri->GetSpec(uriStr))) {
+            ScriptPreloader::GetSingleton().NoteScript(uriStr, cachePath, script);
+        }
+
+        if (startupCache) {
+            JSAutoCompartment ac(cx, script);
+            WriteCachedScript(StartupCache::GetSingleton(),
+                              cachePath, cx, principal, script);
+        }
     }
 
     return true;
 }
 
 class AsyncScriptLoader : public nsIIncrementalStreamLoaderObserver
 {
 public:
@@ -395,17 +405,19 @@ AsyncScriptLoader::OnStreamComplete(nsII
     if (!PrepareScript(uri, cx, targetObj, spec.get(), mCharset,
                        reinterpret_cast<const char*>(aBuf), aLength,
                        mReuseGlobal, mWantReturnValue, &script, &function))
     {
         return NS_OK;
     }
 
     JS::Rooted<JS::Value> retval(cx);
-    if (EvalScript(cx, targetObj, &retval, uri, mCache, &script, function)) {
+    if (EvalScript(cx, targetObj, &retval, uri, mCache,
+                   mCache && !mWantReturnValue,
+                   &script, function)) {
         autoPromise.ResolvePromise(retval);
     }
 
     return NS_OK;
 }
 
 nsresult
 mozJSSubScriptLoader::ReadScriptAsync(nsIURI* uri,
@@ -626,19 +638,19 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
     if (!JS::DescribeScriptedCaller(cx, &filename)) {
         // No scripted frame means we don't know who's calling, bail.
         return NS_ERROR_FAILURE;
     }
 
     JSAutoCompartment ac(cx, targetObj);
 
     // Suppress caching if we're compiling as content.
-    StartupCache* cache = (principal == mSystemPrincipal)
-                          ? StartupCache::GetSingleton()
-                          : nullptr;
+    bool ignoreCache = options.ignoreCache || principal != mSystemPrincipal;
+    StartupCache* cache = ignoreCache ? nullptr : StartupCache::GetSingleton();
+
     nsCOMPtr<nsIIOService> serv = do_GetService(NS_IOSERVICE_CONTRACTID);
     if (!serv) {
         ReportError(cx, NS_LITERAL_CSTRING(LOAD_ERROR_NOSERVICE));
         return NS_OK;
     }
 
     // Make sure to explicitly create the URI, since we'll need the
     // canonicalized spec.
@@ -681,18 +693,21 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
     JSVersion version = JS_GetVersion(cx);
     nsAutoCString cachePath;
     cachePath.AppendPrintf("jssubloader/%d", version);
     PathifyURI(uri, cachePath);
 
     RootedFunction function(cx);
     RootedScript script(cx);
     if (cache && !options.ignoreCache) {
-        rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
-        if (NS_FAILED(rv)) {
+        if (!options.wantReturnValue)
+            script = ScriptPreloader::GetSingleton().GetCachedScript(cx, cachePath);
+        if (!script)
+            rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
+        if (NS_FAILED(rv) || !script) {
             // ReadCachedScript may have set a pending exception.
             JS_ClearPendingException(cx);
         }
     }
 
     // If we are doing an async load, trigger it and bail out.
     if (!script && options.async) {
         return ReadScriptAsync(uri, targetObj, options.charset, serv,
@@ -707,17 +722,19 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
                         &function))
         {
             return NS_OK;
         }
     } else {
         cache = nullptr;
     }
 
-    Unused << EvalScript(cx, targetObj, retval, uri, !!cache, &script, function);
+    Unused << EvalScript(cx, targetObj, retval, uri, !!cache,
+                         !ignoreCache && !options.wantReturnValue,
+                         &script, function);
     return NS_OK;
 }
 
 /**
   * Let us compile scripts from a URI off the main thread.
   */
 
 class ScriptPrecompiler : public nsIIncrementalStreamLoaderObserver
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/smil/anim-targethref-10.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+  <animate href="#x" attributeName="href" values="https://www.google.com"/>
+  <a id="x" fill="red"><rect x="15" y="15" width="200" height="200"/></a>
+  <style>
+    a:any-link {
+      fill: blue;
+    }
+  </style>
+</svg>
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -200,16 +200,17 @@ fails-if(!stylo) == anim-strokecolor-1.s
 == anim-targethref-2.svg anim-standard-ref.svg
 == anim-targethref-3.svg anim-standard-ref.svg
 == anim-targethref-4.svg anim-standard-ref.svg
 == anim-targethref-5.svg anim-standard-ref.svg
 == anim-targethref-6.svg anim-standard-ref.svg
 == anim-targethref-7.svg anim-standard-ref.svg
 == anim-targethref-8.svg anim-standard-ref.svg
 == anim-targethref-9.svg anim-standard-ref.svg
+== anim-targethref-10.svg anim-standard-ref.svg
 
 == anim-text-rotate-01.svg anim-text-rotate-01-ref.svg
 == anim-feFuncR-tableValues-01.svg anim-feFuncR-tableValues-01-ref.svg
 
 skip == anim-text-x-y-dx-dy-01.svg anim-text-x-y-dx-dy-01-ref.svg # bug 579588
 
 == anim-width-done-1a.svg anim-standard-ref.svg
 == anim-width-done-1b.svg anim-standard-ref.svg
--- a/layout/style/nsCSSPseudoClassList.h
+++ b/layout/style/nsCSSPseudoClassList.h
@@ -206,16 +206,19 @@ CSS_STATE_PSEUDO_CLASS(mozHandlerCrashed
 
 CSS_STATE_PSEUDO_CLASS(mozMathIncrementScriptLevel,
                        ":-moz-math-increment-script-level", 0, "",
                        NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL)
 
 CSS_STATE_PSEUDO_CLASS(mozAutofill, ":-moz-autofill",
                        CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
                        NS_EVENT_STATE_AUTOFILL)
+CSS_STATE_PSEUDO_CLASS(mozAutofillPreview, ":-moz-autofill-preview",
+                       CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
+                       NS_EVENT_STATE_AUTOFILL_PREVIEW)
 
 // CSS 3 UI
 // http://www.w3.org/TR/2004/CR-css3-ui-20040511/#pseudo-classes
 CSS_STATE_PSEUDO_CLASS(required, ":required", 0, "", NS_EVENT_STATE_REQUIRED)
 CSS_STATE_PSEUDO_CLASS(optional, ":optional", 0, "", NS_EVENT_STATE_OPTIONAL)
 CSS_STATE_PSEUDO_CLASS(valid, ":valid", 0, "", NS_EVENT_STATE_VALID)
 CSS_STATE_PSEUDO_CLASS(invalid, ":invalid", 0, "", NS_EVENT_STATE_INVALID)
 CSS_STATE_PSEUDO_CLASS(inRange, ":in-range", 0, "", NS_EVENT_STATE_INRANGE)
--- a/layout/style/res/forms.css
+++ b/layout/style/res/forms.css
@@ -1199,11 +1199,14 @@ input[type=number]::-moz-number-spin-dow
   border-bottom-right-radius: 4px;
 }
 
 input[type="number"] > div > div > div:hover {
   /* give some indication of hover state for the up/down buttons */
   background-color: lightblue;
 }
 
-:-moz-autofill {
+:-moz-autofill, :-moz-autofill-preview {
   filter: grayscale(21%) brightness(88%) contrast(161%) invert(10%) sepia(40%) saturate(206%);
 }
+:-moz-autofill-preview {
+  color: GrayText;
+}
--- a/layout/svg/SVGFEImageFrame.cpp
+++ b/layout/svg/SVGFEImageFrame.cpp
@@ -3,16 +3,17 @@
  * 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/. */
 
 // Keep in (case-insensitive) order:
 #include "nsContainerFrame.h"
 #include "nsContentUtils.h"
 #include "nsFrame.h"
 #include "nsGkAtoms.h"
+#include "nsIDOMMutationEvent.h"
 #include "nsLiteralString.h"
 #include "nsSVGEffects.h"
 #include "nsSVGFilters.h"
 #include "mozilla/dom/SVGFEImageElement.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
@@ -115,25 +116,30 @@ SVGFEImageFrame::Init(nsIContent*       
   }
 }
 
 nsresult
 SVGFEImageFrame::AttributeChanged(int32_t  aNameSpaceID,
                                   nsIAtom* aAttribute,
                                   int32_t  aModType)
 {
-  SVGFEImageElement *element = static_cast<SVGFEImageElement*>(mContent);
+  SVGFEImageElement* element = static_cast<SVGFEImageElement*>(mContent);
   if (element->AttributeAffectsRendering(aNameSpaceID, aAttribute)) {
     MOZ_ASSERT(GetParent()->IsSVGFilterFrame(),
                "Observers observe the filter, so that's what we must invalidate");
     nsSVGEffects::InvalidateDirectRenderingObservers(GetParent());
   }
-  if ((aNameSpaceID == kNameSpaceID_XLink ||
-       aNameSpaceID == kNameSpaceID_None) &&
-      aAttribute == nsGkAtoms::href) {
+
+  // Currently our SMIL implementation does not modify the DOM attributes. Once
+  // we implement the SVG 2 SMIL behaviour this can be removed
+  // SVGFEImageElement::AfterSetAttr's implementation will be sufficient.
+  if (aModType == nsIDOMMutationEvent::SMIL &&
+      aAttribute == nsGkAtoms::href &&
+      (aNameSpaceID == kNameSpaceID_XLink ||
+       aNameSpaceID == kNameSpaceID_None)) {
     bool hrefIsSet =
       element->mStringAttributes[SVGFEImageElement::HREF].IsExplicitlySet() ||
       element->mStringAttributes[SVGFEImageElement::XLINK_HREF]
         .IsExplicitlySet();
     if (hrefIsSet) {
       element->LoadSVGImage(true, true);
     } else {
       element->CancelImageRequests(true);
--- a/layout/svg/nsSVGAFrame.cpp
+++ b/layout/svg/nsSVGAFrame.cpp
@@ -2,16 +2,17 @@
 /* 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/. */
 
 // Keep in (case-insensitive) order:
 #include "gfxMatrix.h"
 #include "mozilla/dom/SVGAElement.h"
 #include "nsAutoPtr.h"
+#include "nsIDOMMutationEvent.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGUtils.h"
 #include "SVGLengthList.h"
 
 using namespace mozilla;
 
 class nsSVGAFrame : public nsSVGDisplayContainerFrame
@@ -89,16 +90,31 @@ nsSVGAFrame::AttributeChanged(int32_t   
       aAttribute == nsGkAtoms::transform) {
     // We don't invalidate for transform changes (the layers code does that).
     // Also note that SVGTransformableElement::GetAttributeChangeHint will
     // return nsChangeHint_UpdateOverflow for "transform" attribute changes
     // and cause DoApplyRenderingChangeToTree to make the SchedulePaint call.
     NotifySVGChanged(TRANSFORM_CHANGED);
   }
 
+  // Currently our SMIL implementation does not modify the DOM attributes. Once
+  // we implement the SVG 2 SMIL behaviour this can be removed
+  // SVGAElement::SetAttr/UnsetAttr's ResetLinkState() call will be sufficient.
+  if (aModType == nsIDOMMutationEvent::SMIL &&
+      aAttribute == nsGkAtoms::href &&
+      (aNameSpaceID == kNameSpaceID_None ||
+       aNameSpaceID == kNameSpaceID_XLink)) {
+
+    dom::SVGAElement* content = static_cast<dom::SVGAElement*>(mContent);
+
+    // SMIL may change whether an <a> element is a link, in which case we will
+    // need to update the link state.
+    content->ResetLinkState(true, content->ElementHasHref());
+  }
+
  return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // nsSVGDisplayableFrame methods
 
 void
 nsSVGAFrame::NotifySVGChanged(uint32_t aFlags)
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Keep in (case-insensitive) order:
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "mozilla/gfx/2D.h"
 #include "imgIContainer.h"
 #include "nsContainerFrame.h"
+#include "nsIDOMMutationEvent.h"
 #include "nsIImageLoadingContent.h"
 #include "nsLayoutUtils.h"
 #include "imgINotificationObserver.h"
 #include "nsSVGEffects.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "nsSVGUtils.h"
 #include "SVGContentUtils.h"
 #include "SVGGeometryFrame.h"
@@ -221,20 +222,25 @@ nsSVGImageFrame::AttributeChanged(int32_
       // We don't paint the content of the image using display lists, therefore
       // we have to invalidate for this children-only transform changes since
       // there is no layer tree to notice that the transform changed and
       // recomposite.
       InvalidateFrame();
       return NS_OK;
     }
   }
-  if ((aNameSpaceID == kNameSpaceID_XLink ||
-       aNameSpaceID == kNameSpaceID_None) &&
-      aAttribute == nsGkAtoms::href) {
-    SVGImageElement *element = static_cast<SVGImageElement*>(mContent);
+
+  // Currently our SMIL implementation does not modify the DOM attributes. Once
+  // we implement the SVG 2 SMIL behaviour this can be removed
+  // SVGImageElement::AfterSetAttr's implementation will be sufficient.
+  if (aModType == nsIDOMMutationEvent::SMIL &&
+      aAttribute == nsGkAtoms::href &&
+      (aNameSpaceID == kNameSpaceID_XLink ||
+       aNameSpaceID == kNameSpaceID_None)) {
+    SVGImageElement* element = static_cast<SVGImageElement*>(mContent);
 
     bool hrefIsSet =
       element->mStringAttributes[SVGImageElement::HREF].IsExplicitlySet() ||
       element->mStringAttributes[SVGImageElement::XLINK_HREF].IsExplicitlySet();
     if (hrefIsSet) {
       element->LoadSVGImage(true, true);
     } else {
       element->CancelImageRequests(true);
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -643,16 +643,27 @@ private:
 };
 
 template <typename T>
 class AutoCleanLinkedList : public LinkedList<T>
 {
 public:
   ~AutoCleanLinkedList()
   {
+    clear();
+  }
+
+  AutoCleanLinkedList& operator=(AutoCleanLinkedList&& aOther)
+  {
+    LinkedList<T>::operator=(Forward<LinkedList<T>>(aOther));
+    return *this;
+  }
+
+  void clear()
+  {
     while (T* element = this->popFirst()) {
       delete element;
     }
   }
 };
 
 } /* namespace mozilla */
 
--- a/old-configure.in
+++ b/old-configure.in
@@ -3135,19 +3135,17 @@ MOZ_ANGLE_RENDERER=
 MOZ_D3D_CPU_SUFFIX=
 MOZ_HAS_WINSDK_WITH_D3D=
 MOZ_D3DCOMPILER_VISTA_DLL=
 MOZ_D3DCOMPILER_VISTA_DLL_PATH=
 
 if test "$COMPILE_ENVIRONMENT" ; then
 case "$target_os" in
 *mingw*)
-    if test "$OS_ARCH" = "$HOST_OS_ARCH"; then
-      MOZ_ANGLE_RENDERER=1
-    fi
+    MOZ_ANGLE_RENDERER=1
     ;;
 esac
 
 # The DirectX SDK libraries are split into x86 and x64 sub-directories
 case "${target_cpu}" in
 i*86)
   MOZ_D3D_CPU_SUFFIX=x86
   ;;
@@ -3189,17 +3187,21 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
         AC_MSG_RESULT([MOZ_D3DCOMPILER_VISTA_DLL_PATH doesn't exist: $MOZ_D3DCOMPILER_VISTA_DLL_PATH])
         AC_MSG_ERROR([Windows SDK at "$WINDOWSSDKDIR" appears broken. Try updating to MozillaBuild 1.9 final or higher.])
         MOZ_D3DCOMPILER_VISTA_DLL_PATH=
       fi
     else
       AC_MSG_RESULT([Windows SDK not found.])
     fi
   else
-    AC_MSG_ERROR([Couldn't find Windows SDK 8.1 or higher needed for ANGLE.])
+    if test "$OS_ARCH" = "$HOST_OS_ARCH"; then
+      AC_MSG_ERROR([Couldn't find Windows SDK 8.1 or higher needed for ANGLE.])
+    else
+      AC_MSG_RESULT([Windows SDK not needed for ANGLE in Linux MinGW build.])
+    fi
   fi
 
   if test -z "$MOZ_D3DCOMPILER_VISTA_DLL_PATH"; then
     MOZ_D3DCOMPILER_VISTA_DLL=
   fi
 
   # On mingw, check if headers are provided by toolchain.
   if test -n "$GNU_CC"; then
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1155,9 +1155,9 @@ static const TransportSecurityPreload kP
   { "za.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
   { "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
 };
 
 // Pinning Preload List Length = 479;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1502463680810000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1502636333424000);
--- a/security/manager/ssl/nsSTSPreloadList.errors
+++ b/security/manager/ssl/nsSTSPreloadList.errors
@@ -1,12 +1,11 @@
 007sascha.de: did not receive HSTS header
 00f.net: did not receive HSTS header
 020wifi.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
-0513c.com: could not connect to host
 0g.org.uk: could not connect to host
 0o0.ooo: could not connect to host
 0p.no: did not receive HSTS header
 0x0a.net: could not connect to host
 0x1337.eu: could not connect to host
 0x44.net: did not receive HSTS header
 0x65.net: could not connect to host
 0x90.fi: could not connect to host
@@ -50,27 +49,27 @@ 300mbmovies4u.cc: did not receive HSTS h
 301.website: could not connect to host
 302.nyc: could not connect to host
 314chan.org: could not connect to host
 33drugstore.com: did not receive HSTS header
 360ds.co.in: could not connect to host
 360gradus.com: did not receive HSTS header
 365.or.jp: could not connect to host
 368mibn.com: could not connect to host
+3ags.de: did not receive HSTS header
 3chit.cf: could not connect to host
 3click-loan.com: could not connect to host
 3delivered.com: could not connect to host
 3dproteinimaging.com: did not receive HSTS header
 3sreporting.com: did not receive HSTS header
 3yearloans.com: max-age too low: 0
 404.sh: max-age too low: 0
 404404.info: could not connect to host
 420dongstorm.com: could not connect to host
 42ms.org: could not connect to host
-441jj.com: did not receive HSTS header
 4455software.com: did not receive HSTS header
 4679.space: could not connect to host
 47ronin.com: could not connect to host
 4cclothing.com: could not connect to host
 4elements.com: did not receive HSTS header
 4eyes.ch: did not receive HSTS header
 4miners.net: could not connect to host
 4ourty2.org: could not connect to host
@@ -129,19 +128,19 @@ acr.im: could not connect to host
 acslimited.co.uk: did not receive HSTS header
 activateplay.com: did not receive HSTS header
 activeweb.top: could not connect to host
 activiti.alfresco.com: did not receive HSTS header
 actu-medias.com: did not receive HSTS header
 acuve.jp: could not connect to host
 ada.is: max-age too low: 2592000
 adajwells.me: could not connect to host
+adamgold.net: could not connect to host
 adams.net: max-age too low: 0
 adamwk.com: did not receive HSTS header
-adboos.com: did not receive HSTS header
 addaxpetroleum.com: could not connect to host
 addvocate.com: could not connect to host
 adelevie.com: could not connect to host
 adequatetechnology.com: could not connect to host
 aderal.io: could not connect to host
 adfa-1.com: did not receive HSTS header
 adhs-chaoten.net: did not receive HSTS header
 adindexr.com: could not connect to host
@@ -150,16 +149,17 @@ admitcard.co.in: did not receive HSTS he
 admsel.ec: could not connect to host
 adopteunsiteflash.com: did not receive HSTS header
 adquisitio.co.uk: could not connect to host
 adquisitio.de: could not connect to host
 adquisitio.es: could not connect to host
 adquisitio.fr: could not connect to host
 adquisitio.it: could not connect to host
 adrianseo.ro: did not receive HSTS header
+adrienkohlbecker.com: could not connect to host
 adrl.ca: could not connect to host
 adsfund.org: could not connect to host
 aduedu.de: did not receive HSTS header
 advancedstudio.ro: did not receive HSTS header
 adver.top: could not connect to host
 adviespuntklokkenluiders.nl: could not connect to host
 aemoria.com: could not connect to host
 aerialmediapro.net: could not connect to host
@@ -187,25 +187,25 @@ aidanwoods.com: did not receive HSTS hea
 airbnb.com: did not receive HSTS header
 aircomms.com: did not receive HSTS header
 airlea.com: could not connect to host
 airproto.com: could not connect to host
 aishnair.com: could not connect to host
 aiticon.de: did not receive HSTS header
 aiw-thkoeln.online: could not connect to host
 ajmahal.com: could not connect to host
-akay.me: did not receive HSTS header
 akboy.pw: could not connect to host
 akclinics.org: did not receive HSTS header
 akerek.hu: could not connect to host
 akombakom.net: did not receive HSTS header
 akselimedia.fi: did not receive HSTS header
 aktivist.in: did not receive HSTS header
 al-shami.net: could not connect to host
 aladdin.ie: did not receive HSTS header
+alainwolf.ch: could not connect to host
 alainwolf.net: could not connect to host
 alanlee.net: could not connect to host
 alanrickmanflipstable.com: could not connect to host
 alariel.de: did not receive HSTS header
 alarmsystemreviews.com: did not receive HSTS header
 albertopimienta.com: did not receive HSTS header
 alcazaar.com: could not connect to host
 alecvannoten.be: did not receive HSTS header
@@ -213,17 +213,17 @@ alenan.org: could not connect to host
 alessandro.pw: did not receive HSTS header
 alethearose.com: did not receive HSTS header
 alexandre.sh: did not receive HSTS header
 alfa24.pro: could not connect to host
 alinode.com: could not connect to host
 alisync.com: could not connect to host
 alittlebitcheeky.com: did not receive HSTS header
 alkami.com: did not receive HSTS header
-all-subtitles.com: did not receive HSTS header
+all-subtitles.com: could not connect to host
 all.tf: did not receive HSTS header
 alldaymonitoring.com: could not connect to host
 allforyou.at: could not connect to host
 allinnote.com: could not connect to host
 allmbw.com: could not connect to host
 allods-zone.ru: could not connect to host
 alloinformatique.net: could not connect to host
 allstarswithus.com: could not connect to host
@@ -310,16 +310,17 @@ antocom.com: did not receive HSTS header
 antoinedeschenes.com: could not connect to host
 antoniomarques.eu: did not receive HSTS header
 antoniorequena.com.ve: could not connect to host
 antscript.com: did not receive HSTS header
 anycoin.me: could not connect to host
 aocast.info: could not connect to host
 aojf.fr: could not connect to host
 apachelounge.com: did not receive HSTS header
+apadvantage.com: max-age too low: 2592000
 apeasternpower.com: could not connect to host
 api.mega.co.nz: could not connect to host
 apibot.de: could not connect to host
 apis.google.com: did not receive HSTS header (error ignored - included regardless)
 apis.world: could not connect to host
 apmg-certified.com: did not receive HSTS header
 apmg-cyber.com: did not receive HSTS header
 apnakliyat.com: did not receive HSTS header
@@ -448,17 +449,16 @@ awg-mode.de: did not receive HSTS header
 awxg.com: could not connect to host
 axado.com.br: did not receive HSTS header
 axeny.com: did not receive HSTS header
 az.search.yahoo.com: did not receive HSTS header
 azino777.ru: could not connect to host
 azprep.us: did not receive HSTS header
 b-rickroll-e.pw: could not connect to host
 b3orion.com: max-age too low: 0
-b422edu.com: could not connect to host
 baby-click.de: did not receive HSTS header
 babybic.hu: did not receive HSTS header
 babyhouse.xyz: could not connect to host
 babymasaze.cz: did not receive HSTS header
 babysaying.me: could not connect to host
 bacchanallia.com: could not connect to host
 back-bone.nl: did not receive HSTS header
 backschues.net: did not receive HSTS header
@@ -582,16 +582,17 @@ billkiss.com: could not connect to host
 billninja.com: did not receive HSTS header
 billrusling.com: could not connect to host
 binderapp.net: could not connect to host
 bingcheung.com: did not receive HSTS header
 biofam.ru: did not receive HSTS header
 bioknowme.com: did not receive HSTS header
 bionicspirit.com: could not connect to host
 biophysik-ssl.de: did not receive HSTS header
+biou.me: could not connect to host
 birkman.com: did not receive HSTS header
 bisterfeldt.com: could not connect to host
 bitchan.it: could not connect to host
 bitcoinprivacy.net: did not receive HSTS header
 bitcoinworld.me: could not connect to host
 bitconcepts.co.uk: did not receive HSTS header
 bitf.ly: could not connect to host
 bitfactory.ws: could not connect to host
@@ -603,31 +604,33 @@ bitnet.io: did not receive HSTS header
 bitrage.de: did not receive HSTS header
 bitraum.io: could not connect to host
 bitsafe.systems: did not receive HSTS header
 bitvigor.com: could not connect to host
 bityes.org: could not connect to host
 bivsi.com: could not connect to host
 bizcms.com: did not receive HSTS header
 bizon.sk: did not receive HSTS header
+bjornhelmersson.se: could not connect to host
 bkb-skandal.ch: did not receive HSTS header
 black-armada.com.pl: could not connect to host
 black-armada.pl: could not connect to host
 blackburn.link: could not connect to host
 blacklane.com: did not receive HSTS header
 blackly.uk: max-age too low: 0
 blackpayment.ru: could not connect to host
 blackscytheconsulting.com: could not connect to host
 blackunicorn.wtf: could not connect to host
 blakerandall.xyz: could not connect to host
 blendle.nl: did not receive HSTS header
 blendlecdn.com: could not connect to host
 blenheimchalcot.com: did not receive HSTS header
 blha303.com.au: could not connect to host
 blindsexdate.nl: could not connect to host
+blingsparkleshine.com: could not connect to host
 blitzprog.org: could not connect to host
 blocksatz-medien.de: did not receive HSTS header
 blog-ritaline.com: could not connect to host
 blog.cyveillance.com: did not receive HSTS header
 blogabout.ru: did not receive HSTS header
 bloglikepro.com: could not connect to host
 blubbablasen.de: could not connect to host
 blucas.org: did not receive HSTS header
@@ -635,17 +638,17 @@ blueglobalmedia.com: could not connect t
 blueliv.com: did not receive HSTS header
 bluescloud.xyz: could not connect to host
 bluetenmeer.com: did not receive HSTS header
 bluketing.com: could not connect to host
 blupig.net: did not receive HSTS header
 bluserv.net: did not receive HSTS header
 bm-trading.nl: did not receive HSTS header
 bnhlibrary.com: did not receive HSTS header
-bobiji.com: could not connect to host
+bobiji.com: did not receive HSTS header
 bodo-wolff.de: could not connect to host
 bodyblog.nl: did not receive HSTS header
 bodybuilding-legends.com: could not connect to host
 bodyweightsolution.com: could not connect to host
 boensou.com: did not receive HSTS header
 bogosity.se: could not connect to host
 bohan.life: could not connect to host
 boiadeirodeberna.com: could not connect to host
@@ -664,19 +667,22 @@ bookourdjs.com: max-age too low: 0
 boomerang.com: did not receive HSTS header
 boosterlearnpro.com: did not receive HSTS header
 bootjp.me: did not receive HSTS header
 borderlinegroup.com: max-age too low: 0
 boringsecurity.net: could not connect to host
 boris.one: did not receive HSTS header
 botox.bz: did not receive HSTS header
 bouwbedrijfpurmerend.nl: did not receive HSTS header
+bowling.com: did not receive HSTS header
 bowlroll.net: max-age too low: 0
 boxcryptor.com: did not receive HSTS header
+bqtoolbox.com: could not connect to host
 br3in.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
+bragasoft.com.br: could not connect to host
 brage.info: did not receive HSTS header
 braineet.com: did not receive HSTS header
 brainfork.ml: could not connect to host
 braintreegateway.com: did not receive HSTS header
 braintreepayments.com: did not receive HSTS header
 brainvation.de: did not receive HSTS header
 bran.cc: could not connect to host
 branchtrack.com: did not receive HSTS header
@@ -788,24 +794,24 @@ cancelmyprofile.com: did not receive HST
 candicontrols.com: did not receive HSTS header
 candratech.com: could not connect to host
 candylion.rocks: could not connect to host
 canfly.org: could not connect to host
 canyonshoa.com: did not receive HSTS header
 capecycles.co.za: did not receive HSTS header
 capeyorkfire.com.au: did not receive HSTS header
 capitaltg.com: could not connect to host
+capogna.com: could not connect to host
 captchatheprize.com: could not connect to host
 captivatedbytabrett.com: did not receive HSTS header
 capturethepen.co.uk: could not connect to host
 car-navi.ph: did not receive HSTS header
 carano-service.de: did not receive HSTS header
 caraudio69.cz: could not connect to host
 carboneselectricosnettosl.info: max-age too low: 0
-carck.co.uk: did not receive HSTS header
 cardoni.net: did not receive HSTS header
 cardstream.com: did not receive HSTS header
 cardurl.com: did not receive HSTS header
 cargobay.net: could not connect to host
 caringladies.org: could not connect to host
 carlolly.co.uk: could not connect to host
 carlosalves.info: could not connect to host
 carroarmato0.be: could not connect to host
@@ -852,16 +858,17 @@ cesidianroot.eu: could not connect to ho
 cevrimici.com: could not connect to host
 cfcproperties.com: did not receive HSTS header
 cfetengineering.com: could not connect to host
 cfoitplaybook.com: could not connect to host
 cg.search.yahoo.com: did not receive HSTS header
 cganx.org: could not connect to host
 chahub.com: could not connect to host
 chainmonitor.com: could not connect to host
+chamilo.org: could not connect to host
 championsofregnum.com: did not receive HSTS header
 champserver.net: did not receive HSTS header
 chandlerredding.com: did not receive HSTS header
 changetip.com: did not receive HSTS header
 chaos.fail: did not receive HSTS header
 chaoswebs.net: did not receive HSTS header
 charityclear.com: did not receive HSTS header
 charitystreet.co.uk: could not connect to host
@@ -880,65 +887,65 @@ cheapdns.org: could not connect to host
 cheazey.net: did not receive HSTS header
 chebedara.com: could not connect to host
 checkout.google.com: did not receive HSTS header (error ignored - included regardless)
 cheerflow.com: could not connect to host
 cheesetart.my: could not connect to host
 cheetah85.de: could not connect to host
 chejianer.cn: did not receive HSTS header
 chensir.net: could not connect to host
+chepaofen.com: did not receive HSTS header
 cherekerry.com: could not connect to host
 cherysunzhang.com: did not receive HSTS header
 chicolawfirm.com: did not receive HSTS header
-chihiro.xyz: could not connect to host
+chihiro.xyz: did not receive HSTS header
 chijiokeindustries.co.uk: could not connect to host
 childcaresolutionscny.org: did not receive HSTS header
 chinacdn.org: could not connect to host
 chinawhale.com: did not receive HSTS header
 chirgui.eu: could not connect to host
 chlouis.net: could not connect to host
 chm.vn: did not receive HSTS header
 chontalpa.pw: could not connect to host
 choruscrowd.com: could not connect to host
+chosenplaintext.org: could not connect to host
 chotu.net: could not connect to host
 chris-web.info: could not connect to host
 chrisandsarahinasia.com: did not receive HSTS header
 chrisfaber.com: could not connect to host
-chriskyrouac.com: could not connect to host
 chrisopperwall.com: did not receive HSTS header
 christiaandruif.nl: could not connect to host
 christianbargon.de: did not receive HSTS header
 christianbro.gq: could not connect to host
 christiangaetano.com: could not connect to host
 christophercolumbusfoundation.gov: did not receive HSTS header
 christophheich.me: could not connect to host
 chrisu3050.at: could not connect to host
 chrisupjohn.com: could not connect to host
 chrome-devtools-frontend.appspot.com: did not receive HSTS header (error ignored - included regardless)
 chrome.google.com: did not receive HSTS header (error ignored - included regardless)
 chroniclesofgeorge.com: did not receive HSTS header
 chua.cf: could not connect to host
 chulado.com: did not receive HSTS header
-chxdf.net: could not connect to host
+churchthemes.com: did not receive HSTS header
 cianmawhinney.xyz: could not connect to host
 cidr.ml: could not connect to host
 cigarblogs.net: could not connect to host
 cigi.site: could not connect to host
 cim2b.de: could not connect to host
 cimalando.eu: could not connect to host
 cintdirect.com: could not connect to host
 ciplanutrition.com: did not receive HSTS header
 ciscommerce.net: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
 citiagent.cz: could not connect to host
 cityoflaurel.org: did not receive HSTS header
 ciuciucadou.ro: could not connect to host
 cium.ru: could not connect to host
 cjcaron.org: could not connect to host
 claimconnect.us: could not connect to host
-clanrose.org.uk: max-age too low: 10
 clara-baumert.de: could not connect to host
 claralabs.com: did not receive HSTS header
 classicsandexotics.com: did not receive HSTS header
 classicspublishing.com: could not connect to host
 classifiedssa.co.za: could not connect to host
 clcleaningco.com: could not connect to host
 cleanexperts.co.uk: could not connect to host
 cleaningsquad.ca: max-age too low: 0
@@ -952,16 +959,17 @@ clickgram.biz: did not receive HSTS head
 clicn.bio: could not connect to host
 clicnbio.com: did not receive HSTS header
 clientboss.com: could not connect to host
 clientsecure.me: could not connect to host
 clint.id.au: max-age too low: 0
 clintonbloodworth.com: could not connect to host
 clintonbloodworth.io: could not connect to host
 clintwilson.technology: max-age too low: 2592000
+clip.ovh: could not connect to host
 cloud-project.com: did not receive HSTS header
 cloud.wtf: could not connect to host
 cloudapi.vc: could not connect to host
 cloudbleed.info: could not connect to host
 cloudcert.org: did not receive HSTS header
 cloudcy.net: could not connect to host
 clouddesktop.co.nz: could not connect to host
 cloudey.net: did not receive HSTS header
@@ -1014,29 +1022,28 @@ coffeestrategies.com: max-age too low: 0
 coiffeurschnittstelle.ch: did not receive HSTS header
 coindam.com: could not connect to host
 coldlostsick.net: could not connect to host
 collegepulse.org: did not receive HSTS header
 collies.eu: max-age too low: 3
 collins.kg: did not receive HSTS header
 collins.press: did not receive HSTS header
 colmexpro.com: did not receive HSTS header
-colo-tech.com: could not connect to host
 colognegaming.net: could not connect to host
 coloradocomputernetworking.net: could not connect to host
 colorlib.com: did not receive HSTS header
-combron.nl: did not receive HSTS header
 comfortdom.ua: did not receive HSTS header
 comfortticket.de: did not receive HSTS header
 comicspines.com: could not connect to host
 comotalk.com: could not connect to host
 compalytics.com: could not connect to host
 compareinsurance.com.au: did not receive HSTS header
 comparejewelleryprices.co.uk: could not connect to host
 comparetravelinsurance.com.au: did not receive HSTS header
+compiledworks.com: could not connect to host
 completeid.com: max-age too low: 86400
 completionist.audio: could not connect to host
 compraneta.com: could not connect to host
 compucorner.com.mx: could not connect to host
 computeremergency.com.au: did not receive HSTS header
 computersystems.guru: did not receive HSTS header
 concord-group.co.jp: did not receive HSTS header
 confirm365.com: could not connect to host
@@ -1083,42 +1090,44 @@ covenantbank.net: could not connect to h
 coverduck.ru: could not connect to host
 cpuvinf.eu.org: could not connect to host
 cr.search.yahoo.com: did not receive HSTS header
 cracking.org: did not receive HSTS header
 craftbeerbarn.co.uk: could not connect to host
 craftedge.xyz: could not connect to host
 craftmain.eu: could not connect to host
 craftmine.cz: did not receive HSTS header
+craftyguy.net: could not connect to host
 cranems.com.ua: did not receive HSTS header
 crate.io: did not receive HSTS header
 cravelyrics.com: could not connect to host
 crazifyngers.com: could not connect to host
 crazy-crawler.de: did not receive HSTS header
 crazycen.com: did not receive HSTS header
-crazycraftland.de: could not connect to host
 crazyhotseeds.com: could not connect to host
 create-test-publish.co.uk: could not connect to host
 creativephysics.ml: could not connect to host
 creativeplayuk.com: did not receive HSTS header
 crendontech.com: could not connect to host
+crestasantos.com: could not connect to host
 crestoncottage.com: could not connect to host
 crimewatch.net.za: could not connect to host
 crizk.com: could not connect to host
 crockett.io: did not receive HSTS header
 croome.no-ip.org: could not connect to host
 crosscom.ch: could not connect to host
 crosssec.com: did not receive HSTS header
 crowd.supply: did not receive HSTS header
 crowdcurity.com: did not receive HSTS header
 crowdjuris.com: could not connect to host
 crtvmgmt.com: could not connect to host
 crudysql.com: could not connect to host
 crufad.org: did not receive HSTS header
 cruzr.xyz: could not connect to host
+crvv.me: could not connect to host
 crypt.guru: could not connect to host
 crypticshell.co.uk: could not connect to host
 cryptify.eu: could not connect to host
 cryptobin.org: could not connect to host
 cryptojar.io: did not receive HSTS header
 cryptolab.pro: could not connect to host
 cryptolab.tk: could not connect to host
 cryptonit.net: did not receive HSTS header
@@ -1186,18 +1195,18 @@ dancerdates.net: could not connect to ho
 daniel-steuer.de: could not connect to host
 danielcowie.me: could not connect to host
 danieldk.eu: did not receive HSTS header
 danielheal.net: could not connect to host
 danieliancu.com: could not connect to host
 danielworthy.com: did not receive HSTS header
 danijobs.com: could not connect to host
 danishenanigans.com: could not connect to host
-danjesensky.com: could not connect to host
 danrl.de: could not connect to host
+danwillenberg.com: did not receive HSTS header
 daolerp.xyz: could not connect to host
 dargasia.is: could not connect to host
 dario.im: could not connect to host
 darisni.me: could not connect to host
 dark-x.cf: could not connect to host
 darkengine.io: could not connect to host
 darkhole.cn: could not connect to host
 darkkeepers.dk: did not receive HSTS header
@@ -1214,32 +1223,32 @@ datarank.com: max-age too low: 0
 dataretention.solutions: could not connect to host
 datatekniikka.com: could not connect to host
 datenkeks.de: did not receive HSTS header
 dateno1.com: max-age too low: 0
 datenreiter.cf: could not connect to host
 datenreiter.gq: could not connect to host
 datenreiter.ml: could not connect to host
 datenreiter.tk: could not connect to host
-davidglidden.eu: could not connect to host
+davidglidden.eu: did not receive HSTS header
 davidhunter.scot: did not receive HSTS header
 davidnoren.com: did not receive HSTS header
 davidreinhardt.de: could not connect to host
-dawson-floridavilla.co.uk: max-age too low: 10
 daylightcompany.com: did not receive HSTS header
 daytonaseaside.com: did not receive HSTS header
 db.gy: could not connect to host
 dbx.ovh: could not connect to host
 dccode.gov: could not connect to host
 dcl.re: did not receive HSTS header
 dcuofriends.net: could not connect to host
 dcurt.is: did not receive HSTS header
 dden.ca: could not connect to host
 dden.website: could not connect to host
 dden.xyz: could not connect to host
+deanjerkovich.com: could not connect to host
 debank.tv: did not receive HSTS header
 debatch.se: could not connect to host
 debian-vhost.de: did not receive HSTS header
 debiton.dk: could not connect to host
 debtkit.co.uk: did not receive HSTS header
 decafu.co: could not connect to host
 decesus.com: could not connect to host
 decibelios.li: could not connect to host
@@ -1259,17 +1268,16 @@ deltaconcepts.de: did not receive HSTS h
 deltanet-production.de: max-age too low: 0
 deltasmart.ch: did not receive HSTS header
 delvj.org: could not connect to host
 demdis.org: could not connect to host
 demilitarized.ninja: could not connect to host
 demo.swedbank.se: did not receive HSTS header
 democracychronicles.com: did not receive HSTS header
 demotops.com: did not receive HSTS header
-dengchangdong.com: could not connect to host
 dengyong.org: could not connect to host
 denh.am: did not receive HSTS header
 denisjean.fr: could not connect to host
 dentaldomain.org: did not receive HSTS header
 dentaldomain.ph: could not connect to host
 depeche-mode.moscow: max-age too low: 7200
 depijl-mz.nl: did not receive HSTS header
 depixion.agency: could not connect to host
@@ -1287,26 +1295,30 @@ detector.exposed: could not connect to h
 detest.org: could not connect to host
 deuxvia.com: could not connect to host
 devafterdark.com: could not connect to host
 devcu.com: could not connect to host
 devcu.net: could not connect to host
 devincrow.me: could not connect to host
 devmsg.com: did not receive HSTS header
 devnsec.com: could not connect to host
+devnull.team: could not connect to host
 devopps.me: did not receive HSTS header
+devpsy.info: did not receive HSTS header
 devtub.com: did not receive HSTS header
 devuan.org: did not receive HSTS header
 dfviana.com.br: did not receive HSTS header
 dhome.at: did not receive HSTS header
 dhpcs.com: did not receive HSTS header
 dhpiggott.net: did not receive HSTS header
 diablotine.rocks: could not connect to host
 diarbag.us: max-age too low: 0
 dicando.com: max-age too low: 2592000
+dicionariofinanceiro.com: did not receive HSTS header
+die-blahuts.de: did not receive HSTS header
 diedrich.co: could not connect to host
 dierenkruiden.nl: could not connect to host
 diezel.com: could not connect to host
 digioccumss.ddns.net: could not connect to host
 digitalbank.kz: could not connect to host
 digitaldaddy.net: could not connect to host
 digitalero.rip: did not receive HSTS header
 digitalriver.tk: could not connect to host
@@ -1333,16 +1345,17 @@ dizihocasi.com: could not connect to hos
 dizorg.net: could not connect to host
 dj4et.de: could not connect to host
 djxmmx.net: max-age too low: 0
 djz4music.com: did not receive HSTS header
 dkniss.de: could not connect to host
 dl.google.com: did not receive HSTS header (error ignored - included regardless)
 dlc.viasinc.com: could not connect to host
 dlemper.de: did not receive HSTS header
+dlitz.net: could not connect to host
 dlscomputers.com.au: did not receive HSTS header
 dmcibulldog.com: did not receive HSTS header
 dmtry.me: did not receive HSTS header
 dmz.ninja: could not connect to host
 dns.google.com: did not receive HSTS header (error ignored - included regardless)
 dnsknowledge.com: did not receive HSTS header
 do-do.tk: could not connect to host
 do.search.yahoo.com: did not receive HSTS header
@@ -1361,17 +1374,16 @@ dohosting.ru: could not connect to host
 dokan.online: did not receive HSTS header
 doked.io: could not connect to host
 dokuboard.com: could not connect to host
 dolevik.com: could not connect to host
 dollarstore24.com: could not connect to host
 dollywiki.co.uk: could not connect to host
 dolphin-cloud.com: could not connect to host
 dolphincorp.co.uk: could not connect to host
-domadillo.com: could not connect to host
 domaris.de: did not receive HSTS header
 dominicpratt.de: did not receive HSTS header
 dominioanimal.com: could not connect to host
 dominique-mueller.de: did not receive HSTS header
 donmez.uk: could not connect to host
 donmez.ws: could not connect to host
 donttrustrobots.nl: could not connect to host
 donzelot.co.uk: max-age too low: 3600
@@ -1417,17 +1429,16 @@ drumbandesperanto.nl: could not connect 
 ds-christiansen.de: did not receive HSTS header
 dshiv.io: could not connect to host
 dtub.co: did not receive HSTS header
 dubrovskiy.net: could not connect to host
 dubrovskiy.pro: could not connect to host
 duesee.org: could not connect to host
 dullsir.com: did not receive HSTS header
 dungi.org: could not connect to host
-dutchessuganda.com: did not receive HSTS header
 dutchrank.com: did not receive HSTS header
 dworzak.ch: could not connect to host
 dycontrol.de: could not connect to host
 dyktig.as: did not receive HSTS header
 dylanscott.com.au: did not receive HSTS header
 dymersion.com: did not receive HSTS header
 dynamic-innovations.net: could not connect to host
 dzimejl.sk: did not receive HSTS header
@@ -1436,17 +1447,16 @@ dzndk.com: could not connect to host
 dzndk.net: could not connect to host
 dzndk.org: could not connect to host
 e-aut.net: could not connect to host
 e-biografias.net: did not receive HSTS header
 e-deca2.org: did not receive HSTS header
 e-rickroll-r.pw: could not connect to host
 e-sa.com: did not receive HSTS header
 e3amn2l.com: could not connect to host
-eames-clayton.us: could not connect to host
 earga.sm: could not connect to host
 earlybirdsnacks.com: could not connect to host
 earthrise16.com: could not connect to host
 easez.net: did not receive HSTS header
 eason-yang.com: could not connect to host
 easychiller.org: could not connect to host
 easyplane.it: could not connect to host
 eatlowcarb.de: did not receive HSTS header
@@ -1501,22 +1511,24 @@ eksik.com: could not connect to host
 elaintehtaat.fi: did not receive HSTS header
 elan-organics.com: did not receive HSTS header
 elanguest.pl: could not connect to host
 elanguest.ro: did not receive HSTS header
 elanguest.ru: could not connect to host
 elbetech.net: could not connect to host
 electricianforum.co.uk: did not receive HSTS header
 electromc.com: could not connect to host
+element-43.com: did not receive HSTS header
 elemenx.com: did not receive HSTS header
 elemprendedor.com.ve: could not connect to host
 elenag.ga: could not connect to host
 elenoon.ir: did not receive HSTS header
 elgacien.de: could not connect to host
-elimdengelen.com: could not connect to host
+elimdengelen.com: did not receive HSTS header
+eliott.be: could not connect to host
 elitefishtank.com: could not connect to host
 elnutricionista.es: did not receive HSTS header
 eloanpersonal.com: max-age too low: 0
 elpo.xyz: could not connect to host
 elsamakhin.com: could not connect to host
 elsitar.com: did not receive HSTS header
 email.lookout.com: could not connect to host
 emanatepixels.com: could not connect to host
@@ -1527,28 +1539,28 @@ emjimadhu.com: could not connect to host
 emmable.com: could not connect to host
 emnitech.com: could not connect to host
 empleosentorreon.mx: could not connect to host
 empleostampico.com: did not receive HSTS header
 empty-r.com: could not connect to host
 enaah.de: could not connect to host
 enargia.jp: max-age too low: 0
 encode.host: did not receive HSTS header
-encode.space: did not receive HSTS header
 encoder.pw: could not connect to host
 encontrebarato.com.br: did not receive HSTS header
 encrypted.google.com: did not receive HSTS header (error ignored - included regardless)
 encryptio.com: could not connect to host
 end.pp.ua: could not connect to host
 endlessdark.net: max-age too low: 600
 endlessdiy.ca: could not connect to host
 endlesshorizon.net: could not connect to host
 endlesstone.com: did not receive HSTS header
 enefan.jp: could not connect to host
 engelwerbung.com: did not receive HSTS header
+engg.ca: could not connect to host
 enginsight.com: did not receive HSTS header
 englishyamal.ru: did not receive HSTS header
 enigmacpt.com: did not receive HSTS header
 enigmail.net: did not receive HSTS header
 enjoy-nepal.de: max-age too low: 0
 enskat.de: could not connect to host
 enskatson-sippe.de: could not connect to host
 enteente.club: could not connect to host
@@ -1563,22 +1575,20 @@ enum.eu.org: could not connect to host
 enumify.com: could not connect to host
 envygeeks.com: did not receive HSTS header
 envygeeks.io: did not receive HSTS header
 eol34.com: did not receive HSTS header
 epanurse.com: could not connect to host
 ephry.com: could not connect to host
 epicpages.com: could not connect to host
 epoxate.com: could not connect to host
-epublibre.org: could not connect to host
 eq8.net.au: could not connect to host
 equate.net.au: could not connect to host
 equatetechnologies.com.au: could not connect to host
 equilibre-yoga-jennifer-will.com: could not connect to host
-equitee.co: could not connect to host
 erawanarifnugroho.com: did not receive HSTS header
 eressea.xyz: could not connect to host
 ericbond.net: could not connect to host
 eridanus.uk: could not connect to host
 ernaehrungsberatung-zurich.ch: could not connect to host
 ernesto.at: could not connect to host
 eromixx.com: did not receive HSTS header
 erotalia.es: could not connect to host
@@ -1598,66 +1608,66 @@ esln.org: did not receive HSTS header
 esn-ypci.com: could not connect to host
 esoterikerforum.de: did not receive HSTS header
 especificosba.com.mx: could not connect to host
 espra.com: could not connect to host
 esquonic.com: could not connect to host
 essexcosmeticdentists.co.uk: did not receive HSTS header
 essexghosthunters.co.uk: did not receive HSTS header
 estaciona.guru: could not connect to host
-estan.cn: could not connect to host
 estateczech-eu.ru: did not receive HSTS header
 estebanborges.com: did not receive HSTS header
 estilosapeca.com: could not connect to host
 et-buchholz.de: could not connect to host
 et180.com: could not connect to host
 etdonline.co.uk: could not connect to host
 eternitylove.us: could not connect to host
 eth9.net: could not connect to host
 ethicalexploiting.com: could not connect to host
 ethil-faer.fr: could not connect to host
 etmirror.top: could not connect to host
 etmirror.xyz: could not connect to host
 etproxy.tech: could not connect to host
+etrker.com: could not connect to host
 ets2mp.de: did not receive HSTS header
 etsysecure.com: could not connect to host
 etula.ga: could not connect to host
 etula.me: could not connect to host
 euanbaines.com: did not receive HSTS header
 eucl3d.com: did not receive HSTS header
 euclideanpostulates.xyz: could not connect to host
 eupho.me: could not connect to host
 euren.se: could not connect to host
 eurocamping.se: could not connect to host
 euroshop24.net: could not connect to host
 evafojtova.cz: did not receive HSTS header
-evangelosm.com: could not connect to host
 evdenevenakliyatankara.pw: did not receive HSTS header
+events12.com: did not receive HSTS header
 everybooks.com: max-age too low: 60
 everylab.org: could not connect to host
 everything.place: could not connect to host
 evin.ml: could not connect to host
 evites.me: could not connect to host
 evomon.com: could not connect to host
 evossd.tk: could not connect to host
-ewex.org: could not connect to host
 ewuchuan.com: could not connect to host
 excelgum.ca: did not receive HSTS header
 exceptionalservers.com: could not connect to host
 exfiles.cz: did not receive HSTS header
 exgravitus.com: could not connect to host
 exitus.jp: max-age too low: 0
 exno.co: could not connect to host
 exousiakaidunamis.xyz: could not connect to host
 expertmile.com: did not receive HSTS header
 expoundite.net: did not receive HSTS header
 expressfinance.co.za: did not receive HSTS header
 extrathemeshowcase.net: could not connect to host
 extratorrentlive.xyz: could not connect to host
 extreemhost.nl: did not receive HSTS header
+extrememanual.net: max-age too low: 2592000
 extremenetworking.net: could not connect to host
 exy.pw: could not connect to host
 eyedarts.com: did not receive HSTS header
 eyeglassuniverse.com: did not receive HSTS header
 ez.fi: could not connect to host
 ezimoeko.net: could not connect to host
 ezmod.org: could not connect to host
 eztv.ch: did not receive HSTS header
@@ -1665,16 +1675,17 @@ f-rickroll-g.pw: could not connect to ho
 f-s-u.co.uk: could not connect to host
 f00.ca: did not receive HSTS header
 faber.io: could not connect to host
 fabhub.io: could not connect to host
 fabianasantiago.com: could not connect to host
 fabianfischer.de: did not receive HSTS header
 factorable.net: did not receive HSTS header
 factorygw.com: did not receive HSTS header
+fadednet.com: could not connect to host
 fadilus.com: did not receive HSTS header
 faesser.com: did not receive HSTS header
 fail4free.de: did not receive HSTS header
 failforward.org: did not receive HSTS header
 fairkey.dk: did not receive HSTS header
 fairlyoddtreasures.com: did not receive HSTS header
 faizan.net: did not receive HSTS header
 faizan.xyz: could not connect to host
@@ -1763,16 +1774,17 @@ fjruiz.es: did not receive HSTS header
 fkcovering.be: could not connect to host
 flags.ninja: could not connect to host
 flamewall.net: could not connect to host
 flareon.net: could not connect to host
 flawcheck.com: did not receive HSTS header
 fliexer.com: could not connect to host
 flirchi.com: did not receive HSTS header
 floless.co.uk: did not receive HSTS header
+florafiora.com.br: did not receive HSTS header
 florian-lillpopp.de: max-age too low: 10
 florianlillpopp.de: max-age too low: 10
 floridaescapes.co.uk: did not receive HSTS header
 floseed.fr: could not connect to host
 flouartistique.ch: could not connect to host
 flow.pe: could not connect to host
 flow.su: could not connect to host
 flowersandclouds.com: could not connect to host
@@ -1802,17 +1814,17 @@ forex-dan.com: did not receive HSTS head
 forgix.com: could not connect to host
 formazioneopen.it: could not connect to host
 formula.cf: could not connect to host
 fotiu.com: could not connect to host
 fotm.net: max-age too low: 30000
 fotocerita.net: could not connect to host
 fotografosexpertos.com: did not receive HSTS header
 fotopasja.info: could not connect to host
-fourchin.net: could not connect to host
+fourchin.net: did not receive HSTS header
 foxdev.io: did not receive HSTS header
 foxley-farm.co.uk: did not receive HSTS header
 foxley-seeds.co.uk: did not receive HSTS header
 foxleyseeds.co.uk: could not connect to host
 foxtrot.pw: could not connect to host
 fr33d0m.link: could not connect to host
 fralef.me: did not receive HSTS header
 francevpn.xyz: could not connect to host
@@ -1882,49 +1894,49 @@ gaiserik.com: could not connect to host
 gakkainavi-epsilon.net: did not receive HSTS header
 gakkainavi.jp: did not receive HSTS header
 gakkainavi4.com: could not connect to host
 gakkainavi4.net: did not receive HSTS header
 galardi.org: could not connect to host
 galenskap.eu: could not connect to host
 gallery44.org: did not receive HSTS header
 galoisvpn.xyz: could not connect to host
-game-files.net: did not receive HSTS header
+game-files.net: could not connect to host
 game.yt: could not connect to host
 gamecave.de: could not connect to host
 gamechasm.com: could not connect to host
 gamefund.me: did not receive HSTS header
 gamehacks.me: could not connect to host
 gameink.net: max-age too low: 0
 gamek.es: did not receive HSTS header
 gamenected.com: could not connect to host
 gamenected.de: could not connect to host
 gameofpwnz.com: did not receive HSTS header
 gamepad.vg: could not connect to host
 gamepader.com: could not connect to host
 gameparade.de: could not connect to host
 gamepiece.com: could not connect to host
 gamers-life.fr: could not connect to host
 gamerslair.org: did not receive HSTS header
-gamerz-point.de: did not receive HSTS header
+gamerz-point.de: could not connect to host
 gamesdepartment.co.uk: did not receive HSTS header
 gameserver-sponsor.de: could not connect to host
 gamingmedia.eu: did not receive HSTS header
 gampenhof.de: did not receive HSTS header
 gaptek.id: did not receive HSTS header
 garciamartin.me: could not connect to host
 garden.trade: max-age too low: 0
 gatapro.net: could not connect to host
 gatorsa.es: did not receive HSTS header
 gdegem.org: did not receive HSTS header
 gdpventure.com: max-age too low: 0
-gdz.tv: did not receive HSTS header
 gedankenbude.info: could not connect to host
 geekcast.co.uk: did not receive HSTS header
 geeky.software: could not connect to host
+geemo.top: could not connect to host
 geli-graphics.com: did not receive HSTS header
 gem-indonesia.net: could not connect to host
 genuu.com: could not connect to host
 genuxation.com: could not connect to host
 genyaa.com: could not connect to host
 genyhitch.com: did not receive HSTS header
 geofox.org: did not receive HSTS header
 georgesonarthurs.com.au: did not receive HSTS header
@@ -1988,18 +2000,18 @@ global-adult-webcams.com: did not receiv
 globalado.com: could not connect to host
 globalexpert.co.nz: could not connect to host
 globalittech.com: could not connect to host
 globalmusic.ga: could not connect to host
 globalsites.nl: did not receive HSTS header
 gm-assicurazioni.it: could not connect to host
 gm.search.yahoo.com: did not receive HSTS header
 gmail.com: did not receive HSTS header (error ignored - included regardless)
-gmantra.org: could not connect to host
 gmoes.at: max-age too low: 600000
+gnylf.com: did not receive HSTS header
 go.ax: did not receive HSTS header
 go2sh.de: did not receive HSTS header
 goabonga.com: could not connect to host
 goalsetup.com: did not receive HSTS header
 goaltree.ch: did not receive HSTS header
 goarmy.eu: could not connect to host
 goat.chat: did not receive HSTS header
 goat.xyz: did not receive HSTS header
@@ -2031,17 +2043,17 @@ gorilla-gym.site: could not connect to h
 gothamlimo.com: could not connect to host
 goto.google.com: did not receive HSTS header (error ignored - included regardless)
 gotocloud.ru: could not connect to host
 gotspot.com: could not connect to host
 gottcode.org: did not receive HSTS header
 gov.ax: could not connect to host
 goverage.org: could not connect to host
 govillemo.ca: did not receive HSTS header
-gozel.com.tr: did not receive HSTS header
+gozel.com.tr: could not connect to host
 gparent.org: did not receive HSTS header
 gpsfix.cz: did not receive HSTS header
 gpstuner.com: did not receive HSTS header
 grabi.ga: could not connect to host
 gracesofgrief.com: could not connect to host
 gradienthosting.co.uk: did not receive HSTS header
 grana.com: could not connect to host
 grandmascookieblog.com: did not receive HSTS header
@@ -2065,16 +2077,17 @@ greplin.com: could not connect to host
 gresb.com: did not receive HSTS header
 greyline.se: could not connect to host
 gribani.com: could not connect to host
 grid2osm.org: could not connect to host
 grigalanzsoftware.com: could not connect to host
 gripopgriep.net: could not connect to host
 groetzner.net: did not receive HSTS header
 grossmann.gr: could not connect to host
+groupe-cassous.com: did not receive HSTS header
 groups.google.com: did not receive HSTS header (error ignored - included regardless)
 grunex.com: did not receive HSTS header
 grupopgn.com.br: could not connect to host
 gryffin.ga: could not connect to host
 gryffin.ml: could not connect to host
 gryffin.tk: could not connect to host
 gsm-map.com: could not connect to host
 gsnort.com: could not connect to host
@@ -2084,16 +2097,17 @@ gtech.work: did not receive HSTS header
 gtldna.com: could not connect to host
 gtlfsonlinepay.com: did not receive HSTS header
 gtraxapp.com: could not connect to host
 gts-schulsoftware.de: did not receive HSTS header
 guava.studio: did not receive HSTS header
 guenthernoack.de: could not connect to host
 guge.gq: could not connect to host
 gugga.dk: did not receive HSTS header
+guguke.net: could not connect to host
 guilde-vindicta.fr: did not receive HSTS header
 gulenet.com: could not connect to host
 gunnarhafdal.com: did not receive HSTS header
 gunnaro.com: could not connect to host
 guntbert.net: could not connect to host
 guoqiang.info: could not connect to host
 gurom.lv: could not connect to host
 gurusupe.com: could not connect to host
@@ -2143,17 +2157,17 @@ halo.red: could not connect to host
 hancc.net: could not connect to host
 handicapindeles.nl: did not receive HSTS header
 handiworker.com: could not connect to host
 hanfu.la: could not connect to host
 hanimalis.fr: could not connect to host
 hansen.hn: could not connect to host
 hao2taiwan.com: max-age too low: 0
 haoyugao.com: could not connect to host
-haozi.me: did not receive HSTS header
+haozi.me: could not connect to host
 hapijs.cn: could not connect to host
 hapissl.com: could not connect to host
 hapivm.com: could not connect to host
 happix.nl: did not receive HSTS header
 happyfabric.me: did not receive HSTS header
 happygastro.com: could not connect to host
 hapvm.com: could not connect to host
 harabuhouse.com: did not receive HSTS header
@@ -2238,16 +2252,17 @@ hittipps.com: did not receive HSTS heade
 hlyue.com: did not receive HSTS header
 hmm.nyc: could not connect to host
 hn.search.yahoo.com: did not receive HSTS header
 hodne.io: could not connect to host
 hoerbuecher-und-hoerspiele.de: could not connect to host
 hofiprojekt.cz: did not receive HSTS header
 hogar123.es: could not connect to host
 holifestival-freyung.de: could not connect to host
+holo.ovh: could not connect to host
 holymoly.lu: could not connect to host
 homa.website: could not connect to host
 homeclouding.de: could not connect to host
 homedna.com: did not receive HSTS header
 hometownmall.com: did not receive HSTS header
 homeyantra.com: max-age too low: 86400
 hongzhaxiaofendui.com: could not connect to host
 honoo.com: could not connect to host
@@ -2339,16 +2354,17 @@ identitylabs.uk: could not connect to ho
 idgsupply.com: could not connect to host
 idlekernel.com: could not connect to host
 idontexist.me: could not connect to host
 ie.search.yahoo.com: did not receive HSTS header
 ierna.com: did not receive HSTS header
 ies-italia.it: did not receive HSTS header
 ies.id.lv: could not connect to host
 ifad.org: did not receive HSTS header
+ifastuniversity.com: did not receive HSTS header
 ifleurs.com: could not connect to host
 ifx.ee: could not connect to host
 ignatisd.gr: did not receive HSTS header
 igule.net: could not connect to host
 ihrlotto.de: could not connect to host
 ihrnationalrat.ch: could not connect to host
 ihsbsd.me: could not connect to host
 ihsbsd.tk: could not connect to host
@@ -2399,16 +2415,17 @@ infinitudecloud.com: could not connect t
 infinitusgaming.eu: could not connect to host
 infinity-freedom.com: could not connect to host
 infinity-freedom.de: did not receive HSTS header
 infinity-lifestyle.de: did not receive HSTS header
 inflation.ml: could not connect to host
 info-screen.me: did not receive HSTS header
 info-sys.tk: could not connect to host
 infogrfx.com: did not receive HSTS header
+inforichjapan.com: max-age too low: 0
 infosec.rip: could not connect to host
 infosoph.org: did not receive HSTS header
 infotics.es: did not receive HSTS header
 injigo.com: did not receive HSTS header
 inkable.com.au: did not receive HSTS header
 inked-guy.de: could not connect to host
 inkedguy.de: could not connect to host
 inkstory.gr: did not receive HSTS header
@@ -2424,16 +2441,17 @@ inspire-av.com: did not receive HSTS hea
 inspiroinc.com: could not connect to host
 instacart.com: did not receive HSTS header
 instantdev.io: could not connect to host
 institutoflordelavida.com: could not connect to host
 intel.li: did not receive HSTS header
 interference.io: could not connect to host
 interhosts.co.za: could not connect to host
 interlun.com: could not connect to host
+internect.co.za: did not receive HSTS header
 internetcasinos.de: could not connect to host
 internetcensus.org: could not connect to host
 interserved.com: did not receive HSTS header
 intex.es: max-age too low: 0
 intim-uslugi-kazan.net: could not connect to host
 intimtoy.com.ua: could not connect to host
 intranetsec.fr: could not connect to host
 intrp.net: did not receive HSTS header
@@ -2442,16 +2460,17 @@ inverselink.com: could not connect to ho
 invite24.pro: could not connect to host
 ionx.co.uk: did not receive HSTS header
 iop.intuit.com: max-age too low: 86400
 iora.fr: could not connect to host
 iosmods.com: did not receive HSTS header
 iostips.ru: could not connect to host
 iotsms.io: could not connect to host
 ip6.im: did not receive HSTS header
+iphoneunlock.nu: did not receive HSTS header
 ipmimagazine.com: did not receive HSTS header
 iprice.co.id: did not receive HSTS header
 iprice.hk: did not receive HSTS header
 iprice.my: did not receive HSTS header
 iprice.ph: did not receive HSTS header
 iprice.sg: did not receive HSTS header
 iprice.vn: did not receive HSTS header
 ipricethailand.com: did not receive HSTS header
@@ -2471,34 +2490,33 @@ irmtrudjurke.de: did not receive HSTS he
 irukandjilabs.com: could not connect to host
 is-a-furry.org: did not receive HSTS header
 ischool.co.jp: did not receive HSTS header
 isdf.me: could not connect to host
 iseek.biz: max-age too low: 0
 ishillaryclintoninprisonyet.com: could not connect to host
 isitamor.pm: could not connect to host
 iskaz.rs: did not receive HSTS header
-isntall.us: could not connect to host
 isogen5.com: could not connect to host
 isogram.nl: could not connect to host
+ispweb.es: could not connect to host
 israkurort.com: did not receive HSTS header
 isslshop.com: could not connect to host
 istanbultravelguide.info: could not connect to host
 istaspirtslietas.lv: did not receive HSTS header
 it-go.net: did not receive HSTS header
 itechgeek.com: max-age too low: 0
 ithakama.com: did not receive HSTS header
 ithakama.cz: did not receive HSTS header
 itos.asia: did not receive HSTS header
 itos.pl: did not receive HSTS header
-itpros.ru: did not receive HSTS header
 itriskltd.com: could not connect to host
-its4living.com: could not connect to host
 itsadog.co.uk: did not receive HSTS header
 itsamurai.ru: max-age too low: 2592000
+itsatrap.nl: could not connect to host
 itsecurityassurance.pw: could not connect to host
 itsg-faq.de: could not connect to host
 itshost.ru: could not connect to host
 ivi-fertility.com: max-age too low: 0
 ivi.es: max-age too low: 0
 ivk.website: could not connect to host
 ivklombard.ru: could not connect to host
 ixec2.tk: could not connect to host
@@ -2537,27 +2555,29 @@ janbrodda.de: max-age too low: 2592000
 jangho.me: could not connect to host
 jannyrijneveld.nl: did not receive HSTS header
 janus-engineering.de: did not receive HSTS header
 japan-foods.co.uk: did not receive HSTS header
 japaripark.com: could not connect to host
 japlex.com: could not connect to host
 jaqen.ch: could not connect to host
 jaroslavtrsek.cz: did not receive HSTS header
+jarrettgraham.com: could not connect to host
 jasl.works: did not receive HSTS header
 jasmineconseil.com: could not connect to host
 jasonroe.me: did not receive HSTS header
 jasonsansone.com: max-age too low: 0
 jastoria.pl: could not connect to host
 jayblock.com: did not receive HSTS header
 jayharris.ca: max-age too low: 86400
 jaylen.com.ar: did not receive HSTS header
 jayschulman.com: did not receive HSTS header
 jayscoaching.com: did not receive HSTS header
 jayshao.com: did not receive HSTS header
+jazzysumi.com: could not connect to host
 jbn.mx: could not connect to host
 jcch.de: could not connect to host
 jcor.me: did not receive HSTS header
 jcoscia.com: could not connect to host
 jctf.io: could not connect to host
 jdav-leipzig.de: could not connect to host
 jdcdirectsales.com.ph: did not receive HSTS header
 jebengotai.com: did not receive HSTS header
@@ -2592,17 +2612,16 @@ jimmycai.org: could not connect to host
 jingyuesi.com: could not connect to host
 jirav.io: could not connect to host
 jkb.pics: could not connect to host
 jkbuster.com: could not connect to host
 jm-bea.net: did not receive HSTS header
 joakimalgroy.com: could not connect to host
 jobmedic.com: did not receive HSTS header
 jobss.co.uk: did not receive HSTS header
-joduska.me: could not connect to host
 joedavison.me: could not connect to host
 johannes-sprink.de: could not connect to host
 johnbrownphotography.ch: did not receive HSTS header
 johners.me: could not connect to host
 johnrom.com: did not receive HSTS header
 jonas-keidel.de: did not receive HSTS header
 jonasgroth.se: did not receive HSTS header
 jonathan.ir: could not connect to host
@@ -2623,37 +2642,36 @@ jotpics.com: could not connect to host
 jottit.com: could not connect to host
 jpbike.cz: could not connect to host
 jrc9.ca: did not receive HSTS header
 jrgold.me: could not connect to host
 jrmd.io: could not connect to host
 jrvar.com: did not receive HSTS header
 jsanders.us: did not receive HSTS header
 jsg-technologies.de: did not receive HSTS header
-jslay.net: could not connect to host
 jualautoclave.com: did not receive HSTS header
 jualssh.com: could not connect to host
 julian-kipka.de: could not connect to host
-julibear.com: could not connect to host
 julido.de: did not receive HSTS header
 jumbox.xyz: could not connect to host
 junaos.xyz: did not receive HSTS header
 junge-selbsthilfe.info: could not connect to host
 junjung.me: max-age too low: 0
 junqtion.com: could not connect to host
 jupp0r.de: could not connect to host
 justanothercompany.name: could not connect to host
 justinlemay.com: did not receive HSTS header
 justlikethat.hosting: did not receive HSTS header
 justnaw.co.uk: could not connect to host
 justudin.com: did not receive HSTS header
 jutella.de: did not receive HSTS header
 juwairen.cn: did not receive HSTS header
 jvoice.net: could not connect to host
 jwilsson.me: could not connect to host
+jxm.in: could not connect to host
 jym.fit: did not receive HSTS header
 jznet.org: max-age too low: 86400
 k-dev.de: could not connect to host
 k-rickroll-g.pw: could not connect to host
 ka-clan.com: could not connect to host
 kabinapp.com: could not connect to host
 kabuabc.com: did not receive HSTS header
 kadioglumakina.com.tr: did not receive HSTS header
@@ -2661,16 +2679,17 @@ kaela.design: could not connect to host
 kahopoon.net: could not connect to host
 kaisers.de: did not receive HSTS header
 kaiyuewu.com: could not connect to host
 kalami.nl: could not connect to host
 kamikano.com: could not connect to host
 kamitech.ch: could not connect to host
 kanar.nl: could not connect to host
 kaneo-gmbh.de: did not receive HSTS header
+kaohub.com: could not connect to host
 kaplatz.is: could not connect to host
 kapucini.si: max-age too low: 0
 karaoketonight.com: could not connect to host
 karlis-kavacis.id.lv: did not receive HSTS header
 karpanhellas.com: did not receive HSTS header
 kasilag.me: did not receive HSTS header
 katiaetdavid.fr: could not connect to host
 katproxy.online: could not connect to host
@@ -2695,35 +2714,37 @@ keepassa.co: could not connect to host
 keepclean.me: could not connect to host
 kellyandantony.com: did not receive HSTS header
 kerangalam.com: could not connect to host
 kerksanders.nl: did not receive HSTS header
 kermadec.net: could not connect to host
 kernl.us: did not receive HSTS header
 kevinbowers.me: did not receive HSTS header
 kevinbusse.de: could not connect to host
+keybored.me: could not connect to host
 keymaster.lookout.com: did not receive HSTS header
 keys.fedoraproject.org: could not connect to host
 kfbrussels.be: could not connect to host
 kg-rating.com: could not connect to host
 kgxtech.com: max-age too low: 2592000
 ki-on.net: did not receive HSTS header
 kickass.al: could not connect to host
 kid-dachau.de: did not receive HSTS header
 kiel-media.de: did not receive HSTS header
 killerit.in: could not connect to host
+kimberg.co.uk: could not connect to host
 kimpost.org: could not connect to host
 kinderly.co.uk: did not receive HSTS header
 kinderwagen-test24.de: could not connect to host
 kindof.ninja: could not connect to host
 kingmanhall.org: could not connect to host
+kini24.ru: could not connect to host
 kinkdr.com: could not connect to host
 kinnon.enterprises: could not connect to host
 kionetworks.com: did not receive HSTS header
-kirbear.com: could not connect to host
 kirkforcongress.com: could not connect to host
 kirkforsenate.com: could not connect to host
 kirkpatrickdavis.com: could not connect to host
 kisa.io: could not connect to host
 kisalt.im: did not receive HSTS header
 kissart.net: could not connect to host
 kisstyle.ru: did not receive HSTS header
 kisun.co.jp: could not connect to host
@@ -2751,44 +2772,44 @@ knowledgesnap.com: could not connect to 
 knowledgesnapsites.com: could not connect to host
 kodexplorer.ml: could not connect to host
 kodiaklabs.org: could not connect to host
 kodokushi.fr: could not connect to host
 koen.io: did not receive HSTS header
 koenrouwhorst.nl: did not receive HSTS header
 koenvdheuvel.me: did not receive HSTS header
 koha.be: could not connect to host
+koik.io: could not connect to host
 kokenmetaanbiedingen.nl: did not receive HSTS header
 kolaykaydet.com: did not receive HSTS header
 kolozsvaricsuhe.hu: did not receive HSTS header
 komikito.com: could not connect to host
 kompetenzwerft.de: did not receive HSTS header
 konsertoversikt.no: could not connect to host
 kontaxis.network: could not connect to host
 kontorhaus-schlachte.de: could not connect to host
 koopjesnel.nl: did not receive HSTS header
 koordinate.net: could not connect to host
 korni22.org: did not receive HSTS header
 korsanparti.org: could not connect to host
 kostuumstore.nl: could not connect to host
 kotonehoko.net: could not connect to host
 kotovstyle.ru: could not connect to host
+kottur.is: could not connect to host
 koukni.cz: could not connect to host
 kourpe.online: could not connect to host
 kprog.net: could not connect to host
 kr.search.yahoo.com: did not receive HSTS header
 kralik.xyz: could not connect to host
-krasovsky.me: could not connect to host
 krayx.com: did not receive HSTS header
 kreavis.com: did not receive HSTS header
 kreb.io: could not connect to host
 kredite.sale: could not connect to host
 krestanskydarek.cz: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
 kriegt.es: did not receive HSTS header
-kristikala.nl: could not connect to host
 krizevci.info: did not receive HSTS header
 kroetenfuchs.de: could not connect to host
 kroodle.nl: did not receive HSTS header
 kropkait.pl: could not connect to host
 krunut.com: did not receive HSTS header
 krypteia.org: could not connect to host
 kryptomech.com: could not connect to host
 ksfh-mail.de: could not connect to host
@@ -2796,35 +2817,39 @@ kstan.me: could not connect to host
 kswriter.com: could not connect to host
 kucom.it: did not receive HSTS header
 kueulangtahunanak.net: could not connect to host
 kummerlaender.eu: did not receive HSTS header
 kupelne-ptacek.sk: did not receive HSTS header
 kuppingercole.com: did not receive HSTS header
 kura.io: could not connect to host
 kurehun.org: could not connect to host
+kuro346.moe: could not connect to host
 kurtmclester.com: did not receive HSTS header
 kurz.pw: could not connect to host
 kusaka-abacus.jp: max-age too low: 0
+kuschku.de: could not connect to host
+kusdaryanto.web.id: did not receive HSTS header
 kweddingplanning.com: did not receive HSTS header
 kwok.tv: could not connect to host
 kwondratsch.com: could not connect to host
+kxind.cn: could not connect to host
 kyanite.co: could not connect to host
 kylapps.com: did not receive HSTS header
 kylinj.com: could not connect to host
 kyochon.fr: could not connect to host
 kz.search.yahoo.com: did not receive HSTS header
 kzjnet.com: could not connect to host
 l-rickroll-i.pw: could not connect to host
 la-cave-a-nodo.fr: did not receive HSTS header
 la-flora-negra.de: could not connect to host
 labaia.info: could not connect to host
 labina.com.tr: did not receive HSTS header
 laboiteapc.fr: did not receive HSTS header
-labordata.io: did not receive HSTS header
+labordata.io: could not connect to host
 laborie.io: could not connect to host
 labrador-retrievers.com.au: did not receive HSTS header
 labs.directory: could not connect to host
 labs.moscow: did not receive HSTS header
 lachlankidson.net: did not receive HSTS header
 lacledeslan.ninja: could not connect to host
 lacocinadelila.com: did not receive HSTS header
 ladbroke.net: did not receive HSTS header
@@ -2872,16 +2897,17 @@ leermotorrijden.nl: max-age too low: 300
 lefebvristes.com: could not connect to host
 lefebvristes.fr: could not connect to host
 legarage.org: did not receive HSTS header
 leinir.dk: did not receive HSTS header
 leitner.com.au: did not receive HSTS header
 leiyun.me: did not receive HSTS header
 lellyboi.ml: could not connect to host
 lelongbank.com: did not receive HSTS header
+lemondrops.xyz: could not connect to host
 lemp.io: did not receive HSTS header
 lenovogaming.com: did not receive HSTS header
 lentri.com: did not receive HSTS header
 leob.in: did not receive HSTS header
 leon-jaekel.com: could not connect to host
 leopold.email: could not connect to host
 leopoldina.net: could not connect to host
 leopotamgroup.com: could not connect to host
@@ -2912,17 +2938,16 @@ lianye3.cc: could not connect to host
 lianye4.cc: could not connect to host
 lianye5.cc: could not connect to host
 lianye6.cc: could not connect to host
 lianyexiuchang.in: could not connect to host
 liaoshuma.com: could not connect to host
 libanco.com: could not connect to host
 libertyrp.org: could not connect to host
 library.linode.com: did not receive HSTS header
-libraryfreedomproject.org: could not connect to host
 libreboot.org: did not receive HSTS header
 librechan.net: could not connect to host
 libreduca.com: could not connect to host
 lidl-selection.at: could not connect to host
 lidlovajogurteka.si: could not connect to host
 lifecoach.tw: did not receive HSTS header
 lifecoachproviders.com: did not receive HSTS header
 lifeguard.aecom.com: did not receive HSTS header
@@ -2937,17 +2962,17 @@ lijero.co: could not connect to host
 lila.pink: did not receive HSTS header
 lillpopp.eu: max-age too low: 10
 lilpwny.com: could not connect to host
 lim-light.com: did not receive HSTS header
 limalama.eu: max-age too low: 1
 limeyeti.com: could not connect to host
 limiteddata.co.uk: could not connect to host
 limpido.it: could not connect to host
-lincolncollege.edu: did not receive HSTS header
+lincolncollege.edu: max-age too low: 0
 lincolnwayflorist.com: could not connect to host
 lindberg.io: did not receive HSTS header
 lingros-test.tk: could not connect to host
 linguaquote.com: did not receive HSTS header
 linhaoyi.com: did not receive HSTS header
 link.ba: could not connect to host
 link2serve.com: did not receive HSTS header
 linkycat.com: could not connect to host
@@ -2955,22 +2980,23 @@ linmi.cc: did not receive HSTS header
 linno.me: could not connect to host
 linorman1997.me: could not connect to host
 linuxeyecandy.com: could not connect to host
 linuxfixed.it: could not connect to host
 linuxforyou.com: could not connect to host
 linuxgeek.ro: could not connect to host
 linuxmint.cz: max-age too low: 0
 linuxmonitoring.net: could not connect to host
-linuxwebservertips.in: could not connect to host
 liquorsanthe.in: could not connect to host
 lisaco.de: could not connect to host
 listafirmelor.com: could not connect to host
 litespeed.io: could not connect to host
 little.pw: did not receive HSTS header
+litz.ca: could not connect to host
+litzenberger.ca: could not connect to host
 livedemo.io: could not connect to host
 livej.am: could not connect to host
 livi.co: did not receive HSTS header
 lixiang.one: could not connect to host
 lkummer.cz: could not connect to host
 loacg.com: could not connect to host
 loadingdeck.com: did not receive HSTS header
 loadso.me: could not connect to host
@@ -2990,16 +3016,18 @@ lognot.net: could not connect to host
 lolidunno.com: could not connect to host
 lolmegafroi.de: could not connect to host
 londonlanguageexchange.com: could not connect to host
 lonerwolf.com: did not receive HSTS header
 look-at-my.site: could not connect to host
 lookasik.eu: did not receive HSTS header
 lookout.com: did not receive HSTS header
 lookzook.com: did not receive HSTS header
+loongsg.xyz: could not connect to host
+lordjevington.co.uk: could not connect to host
 lostg.com: could not connect to host
 lostinsecurity.com: could not connect to host
 lostinweb.eu: could not connect to host
 lothai.re: did not receive HSTS header
 lothuytinhsi.com: could not connect to host
 lotsencafe.de: did not receive HSTS header
 loveable.de: could not connect to host
 lovelifelovelive.com: could not connect to host
@@ -3070,16 +3098,17 @@ mae-berlinistanbul.com: could not connec
 mafamane.com: could not connect to host
 mafiareturns.com: max-age too low: 2592000
 magenx.com: did not receive HSTS header
 mahamed91.pw: could not connect to host
 mail-settings.google.com: did not receive HSTS header (error ignored - included regardless)
 mail.google.com: did not receive HSTS header (error ignored - included regardless)
 maildragon.com: could not connect to host
 mailhost.it: could not connect to host
+maintainerheaven.ch: could not connect to host
 majesnix.org: did not receive HSTS header
 makeitdynamic.com: could not connect to host
 makerstuff.net: did not receive HSTS header
 malena.com.ua: did not receive HSTS header
 malerversand.de: did not receive HSTS header
 malfait.nl: could not connect to host
 maljaars-media.nl: could not connect to host
 malkaso.com.ua: could not connect to host
@@ -3087,16 +3116,17 @@ malmstroms-co.se: could not connect to h
 maltes.website: could not connect to host
 malwaretips.com: did not receive HSTS header
 malwre.io: could not connect to host
 mamaison.io: could not connect to host
 mamaxi.org: did not receive HSTS header
 mammothmail.com: could not connect to host
 mammothmail.net: could not connect to host
 mammothmail.org: could not connect to host
+manaboutahor.se: could not connect to host
 manage.zenpayroll.com: could not connect to host
 managemynetsuite.com: did not receive HSTS header
 maniadeprazer.com.br: could not connect to host
 manifestbin.com: did not receive HSTS header
 manitasicily.com: did not receive HSTS header
 manningbrothers.com: did not receive HSTS header
 mansion-note.com: did not receive HSTS header
 maomaofuli.vip: could not connect to host
@@ -3151,24 +3181,28 @@ matthiassteen.be: max-age too low: 0
 mattressinsider.com: max-age too low: 3153600
 mattsvensson.com: did not receive HSTS header
 matty.digital: max-age too low: 3600
 maultrom.ml: could not connect to host
 maupiknik.com: did not receive HSTS header
 maur.cz: did not receive HSTS header
 mavisang.cf: could not connect to host
 mawe.red: could not connect to host
-maxhoechtl.at: could not connect to host
+maxbruckner.org: could not connect to host
+maxr1998.de: did not receive HSTS header
 maya.mg: could not connect to host
 mazz-tech.com: could not connect to host
+mc81.com: could not connect to host
 mca2017.org: did not receive HSTS header
 mcard.vn: did not receive HSTS header
 mcc.re: could not connect to host
 mcdonalds.ru: did not receive HSTS header
 mcga.media: did not receive HSTS header
+mckinley.school: did not receive HSTS header
+mckinley1.com: did not receive HSTS header
 mclab.su: could not connect to host
 mdfnet.se: did not receive HSTS header
 mdscomp.net: did not receive HSTS header
 mdwftw.com: could not connect to host
 mea.in.ua: could not connect to host
 meamod.com: did not receive HSTS header
 mechanus.io: max-age too low: 2592000
 medallia.io: could not connect to host
@@ -3289,28 +3323,28 @@ miyoshi-kikaku.com: did not receive HSTS
 mizd.at: could not connect to host
 mizi.name: could not connect to host
 mkasu.org: did not receive HSTS header
 mlcdn.co: could not connect to host
 mlpepilepsy.org: could not connect to host
 mmgazhomeloans.com: did not receive HSTS header
 mnemotiv.com: could not connect to host
 mnetworkingsolutions.co.uk: could not connect to host
+mnmt.no: did not receive HSTS header
 mnwt.nl: could not connect to host
 moar.so: could not connect to host
 mobifinans.ru: did not receive HSTS header
 mobilebay.top: could not connect to host
 mobilekey.co: could not connect to host
 mobilemedics.com: did not receive HSTS header
 mobilethreat.net: could not connect to host
 mobilethreatnetwork.net: could not connect to host
 mobilpass.no: could not connect to host
 mobix5.com: did not receive HSTS header
 mocloud.eu: could not connect to host
-mocurio.com: did not receive HSTS header
 moddedark.com: could not connect to host
 model9.io: did not receive HSTS header
 modemagazines.co.uk: could not connect to host
 modernibytovytextil.cz: could not connect to host
 moebel-nagel.de: did not receive HSTS header
 moelord.org: could not connect to host
 moen.io: did not receive HSTS header
 moeyi.xyz: did not receive HSTS header
@@ -3350,17 +3384,16 @@ mortgagecentersmo.com: did not receive H
 mostwuat.com: could not connect to host
 motherbase.io: could not connect to host
 motionfreight.com: could not connect to host
 motionpicturesolutions.com: did not receive HSTS header
 motocyklovedily.cz: did not receive HSTS header
 motoryz.com: max-age too low: 300
 mottvd.com: could not connect to host
 moula.com.au: did not receive HSTS header
-mountainactivitysection.org.uk: max-age too low: 10
 mountainmusicpromotions.com: did not receive HSTS header
 moviesabout.net: could not connect to host
 moy-gorod.od.ua: did not receive HSTS header
 moy.cat: did not receive HSTS header
 mp3juices.is: could not connect to host
 mpintaamalabanna.it: could not connect to host
 mqas.net: could not connect to host
 mrdani.net: could not connect to host
@@ -3409,17 +3442,16 @@ mycoted.com: did not receive HSTS header
 mydeos.com: could not connect to host
 mydigipass.com: did not receive HSTS header
 mydnaresults.com: did not receive HSTS header
 mydnatest.com: did not receive HSTS header
 myepass.de: could not connect to host
 mygate.at: could not connect to host
 mygdut.com: did not receive HSTS header
 mygov.scot: did not receive HSTS header
-myimmitracker.com: did not receive HSTS header
 myiocc.org: could not connect to host
 mykolab.com: did not receive HSTS header
 mykreuzfahrt.de: could not connect to host
 myni.io: could not connect to host
 mypagella.com: could not connect to host
 mypagella.eu: could not connect to host
 mypagella.it: could not connect to host
 mypension.ca: could not connect to host
@@ -3443,16 +3475,17 @@ najedlo.sk: did not receive HSTS header
 nakamastreamingcommunity.com: could not connect to host
 nakliyatsirketi.biz: could not connect to host
 nakuro.de: could not connect to host
 nalifornia.com: did not receive HSTS header
 nallon.com.br: could not connect to host
 namacindia.com: did not receive HSTS header
 named.ga: could not connect to host
 nametaken-cloud.duckdns.org: could not connect to host
+namethatbone.com: could not connect to host
 namorico.me: did not receive HSTS header
 nan.zone: could not connect to host
 nandex.org: could not connect to host
 naniki.co.uk: did not receive HSTS header
 nanogeneinc.com: could not connect to host
 nanogi.ga: could not connect to host
 nanto.eu: could not connect to host
 narada.com.ua: could not connect to host
@@ -3470,16 +3503,17 @@ nauck.org: could not connect to host
 nav.jobs: could not connect to host
 naval.tf: could not connect to host
 navenlle.com: did not receive HSTS header
 navjobs.com: did not receive HSTS header
 nbb.io: could not connect to host
 nbg-ha.de: could not connect to host
 ncc60205.info: could not connect to host
 ncpc.gov: could not connect to host
+ncsccs.com: did not receive HSTS header
 nct.org.uk: did not receive HSTS header
 nctx.co.uk: did not receive HSTS header
 near.st: did not receive HSTS header
 nedzad.me: could not connect to host
 neftaly.com: did not receive HSTS header
 neilgreen.net: did not receive HSTS header
 neko-life.com: did not receive HSTS header
 neko-system.com: did not receive HSTS header
@@ -3489,17 +3523,16 @@ neoani.me: could not connect to host
 neofelhz.space: did not receive HSTS header
 neonisi.com: could not connect to host
 neonnuke.tech: did not receive HSTS header
 neosolution.ca: did not receive HSTS header
 nephos.xyz: did not receive HSTS header
 nepustil.net: did not receive HSTS header
 neris.io: could not connect to host
 nestedquotes.ca: could not connect to host
-neswec.org.uk: max-age too low: 10
 netba.net: could not connect to host
 netbox.cc: could not connect to host
 netherwind.eu: did not receive HSTS header
 netlilo.com: could not connect to host
 netloanusa.com: could not connect to host
 netmagik.com: did not receive HSTS header
 netresourcedesign.com: did not receive HSTS header
 nettefoundation.com: could not connect to host
@@ -3510,16 +3543,20 @@ netztest.at: did not receive HSTS header
 netzvieh.de: could not connect to host
 netzzwerg4u.de: could not connect to host
 neueonlinecasino2016.com: could not connect to host
 neuralgic.net: could not connect to host
 neuro-plus-100.com: could not connect to host
 neuronfactor.com: max-age too low: 1000
 never-afk.de: did not receive HSTS header
 neveta.com: could not connect to host
+new-process.ch: could not connect to host
+new-process.com: could not connect to host
+new-process.de: could not connect to host
+new-process.eu: could not connect to host
 newbieboss.com: did not receive HSTS header
 newcitygas.ca: max-age too low: 0
 newedivideo.it: could not connect to host
 newgenerationplus.org: could not connect to host
 newhdmovies.io: did not receive HSTS header
 newkaliningrad.ru: did not receive HSTS header
 newlooknow.com: did not receive HSTS header
 newmelalife.com: did not receive HSTS header
@@ -3539,16 +3576,17 @@ nginxnudes.com: could not connect to hos
 nglr.org: could not connect to host
 ngt-service.ru: did not receive HSTS header
 ni.search.yahoo.com: did not receive HSTS header
 nibiisclaim.com: could not connect to host
 nicestresser.fr: could not connect to host
 nicky.io: did not receive HSTS header
 nicoborghuis.nl: could not connect to host
 nicolasbettag.me: did not receive HSTS header
+nicolaw.uk: did not receive HSTS header
 niconiconi.xyz: could not connect to host
 niconode.com: could not connect to host
 niduxcomercial.com: could not connect to host
 nien.chat: could not connect to host
 nightwinds.tk: could not connect to host
 niho.jp: did not receive HSTS header
 nikcub.com: could not connect to host
 niklaslindblad.se: did not receive HSTS header
@@ -3583,16 +3621,17 @@ nopex.no: could not connect to host
 nopol.de: could not connect to host
 norandom.com: could not connect to host
 norb.at: could not connect to host
 nosecretshop.com: did not receive HSTS header
 notadd.com: did not receive HSTS header
 notenoughtime.de: could not connect to host
 notesforpebble.com: could not connect to host
 nothing.net.nz: max-age too low: 7776000
+noticia.do: did not receive HSTS header
 notify.moe: could not connect to host
 nottheonion.net: did not receive HSTS header
 nouvelle-vague-saint-cast.fr: did not receive HSTS header
 novacoast.com: did not receive HSTS header
 novascan.net: could not connect to host
 novatrucking.de: could not connect to host
 nowak.ninja: did not receive HSTS header
 noworrywp.com: could not connect to host
@@ -3623,16 +3662,17 @@ numero-di-telefono.it: could not connect
 numista.com: did not receive HSTS header
 nuos.org: could not connect to host
 nurserybook.co: did not receive HSTS header
 nusatrip-api.com: did not receive HSTS header
 nutleyeducationalfoundation.org: did not receive HSTS header
 nutleyef.org: did not receive HSTS header
 nutritionculture.com: could not connect to host
 nutsandboltsmedia.com: did not receive HSTS header
+nuttyveg.com: could not connect to host
 nwa.xyz: could not connect to host
 nweb.co.nz: could not connect to host
 nwerc.party: could not connect to host
 nwgh.org: could not connect to host
 nwork.media: could not connect to host
 nyantec.com: did not receive HSTS header
 nycroth.com: did not receive HSTS header
 nys-hk.com: could not connect to host
@@ -3642,42 +3682,41 @@ nystart.no: did not receive HSTS header
 nz.search.yahoo.com: max-age too low: 172800
 nzb.cat: did not receive HSTS header
 nzbs.io: could not connect to host
 nzquakes.maori.nz: did not receive HSTS header
 o-rickroll-y.pw: could not connect to host
 o0o.one: could not connect to host
 oasis.mobi: did not receive HSTS header
 obermeiers.eu: could not connect to host
-obscur.us: could not connect to host
 obsydian.org: could not connect to host
 ocapic.com: could not connect to host
 occentus.net: did not receive HSTS header
 ochaken.cf: could not connect to host
 octocat.ninja: did not receive HSTS header
 odin.xxx: could not connect to host
 odinoffice.no: did not receive HSTS header
 odysseyandco.com: could not connect to host
 oe8.bet: could not connect to host
 ofcourselanguages.com: could not connect to host
 offenedialoge.de: max-age too low: 2592000
 offshore-firma.org: could not connect to host
 ogogoshop.com: could not connect to host
+ohsocool.org: could not connect to host
 oishioffice.com: did not receive HSTS header
 okane.love: could not connect to host
 okok-rent.com: could not connect to host
 okok.rent: could not connect to host
 okutama.in.th: could not connect to host
 olanderflorist.com: could not connect to host
 olcso-vps-szerver.hu: could not connect to host
 oldchaphome.nl: did not receive HSTS header
 oldoakflorist.com: could not connect to host
 oliverdunk.com: did not receive HSTS header
 ollehbizev.co.kr: could not connect to host
-olygazoo.com: could not connect to host
 omacostudio.com: could not connect to host
 omgaanmetidealen.com: could not connect to host
 ominto.com: max-age too low: 0
 omniti.com: max-age too low: 1
 omquote.gq: could not connect to host
 omskit.ru: did not receive HSTS header
 oneb4nk.com: could not connect to host
 oneclickloan.com: could not connect to host
@@ -3697,16 +3736,17 @@ online-casino.eu: did not receive HSTS h
 online-wetten.de: did not receive HSTS header
 online.swedbank.se: did not receive HSTS header
 onlinebiller.com: did not receive HSTS header
 onlinecompliance.org: did not receive HSTS header
 onlinedeposit.us: could not connect to host
 onlinekasino.de: did not receive HSTS header
 onlinepollsph.com: could not connect to host
 onlinespielothek.com: did not receive HSTS header
+onlinetravelmoney.co.uk: did not receive HSTS header
 onlinewetten.de: could not connect to host
 onlyshopstation.com: did not receive HSTS header
 onlyzero.net: could not connect to host
 ononpay.com: did not receive HSTS header
 onovlena.dn.ua: could not connect to host
 onpatient.com: did not receive HSTS header
 onsitemassageco.com: did not receive HSTS header
 ontimestamp.com: did not receive HSTS header
@@ -3755,16 +3795,17 @@ orthodoxy.lt: did not receive HSTS heade
 osaiyuwu.com: could not connect to host
 osao.org: could not connect to host
 oslfoundation.org: did not receive HSTS header
 oslinux.net: did not receive HSTS header
 osp.cx: could not connect to host
 ossan-kobe-gourmet.com: did not receive HSTS header
 ossbinaries.com: could not connect to host
 osteammate.com: did not receive HSTS header
+osterkraenzchen.de: could not connect to host
 osticketawesome.com: did not receive HSTS header
 otakuworld.de: could not connect to host
 othercode.nl: could not connect to host
 othermedia.cc: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
 otherstuff.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
 otichi.com: did not receive HSTS header
 ottospora.nl: could not connect to host
 ourbank.com: did not receive HSTS header
@@ -3813,32 +3854,34 @@ panoti.com: could not connect to host
 pansu.space: could not connect to host
 pants-off.xyz: could not connect to host
 papalytics.com: could not connect to host
 papeda.net: could not connect to host
 papercard.co.uk: did not receive HSTS header
 paperturn.com: did not receive HSTS header
 papierniak.net: could not connect to host
 papygeek.com: could not connect to host
+parabhairavayoga.com: did not receive HSTS header
 paradiselost.com: max-age too low: 0
 parent5446.us: could not connect to host
 parentmail.co.uk: did not receive HSTS header
 parithy.net: could not connect to host
 parkingplus.co.il: could not connect to host
 parkrocker.com: did not receive HSTS header
 parpaing-paillette.net: could not connect to host
 particonpsplus.it: did not receive HSTS header
 partijtjevoordevrijheid.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
 partirkyoto.jp: did not receive HSTS header
 partou.de: did not receive HSTS header
 partyhaus.ovh: did not receive HSTS header
 partyvan.it: could not connect to host
 partyvan.moe: could not connect to host
 partyvan.nl: could not connect to host
 partyvan.se: could not connect to host
+pasadenapooch.org: did not receive HSTS header
 passumpsicbank.com: did not receive HSTS header
 passwordbox.com: did not receive HSTS header
 passwordrevelator.net: did not receive HSTS header
 passwords.google.com: did not receive HSTS header (error ignored - included regardless)
 pastaf.com: could not connect to host
 pastdream.xyz: could not connect to host
 paste.linode.com: could not connect to host
 pastebin.linode.com: could not connect to host
@@ -3923,18 +3966,18 @@ pickr.co: could not connect to host
 picotronic.biz: could not connect to host
 picscare.co.uk: did not receive HSTS header
 pieperhome.de: could not connect to host
 pieterjangeeroms.me: could not connect to host
 piggott.me.uk: did not receive HSTS header
 pilgermaske.org: did not receive HSTS header
 piligrimname.com: could not connect to host
 pillowandpepper.com: did not receive HSTS header
-pinkhq.com: could not connect to host
 pippen.io: could not connect to host
+piratebit.tech: could not connect to host
 piratedb.com: could not connect to host
 piratedot.com: could not connect to host
 piratelist.online: could not connect to host
 piratenlogin.de: could not connect to host
 pirateproxy.pe: could not connect to host
 pirateproxy.sx: could not connect to host
 pirateproxy.vip: could not connect to host
 pirati.cz: did not receive HSTS header
@@ -3956,21 +3999,20 @@ plaettliaktion.ch: did not receive HSTS 
 planpharmacy.com: could not connect to host
 plass.hamburg: could not connect to host
 platform.lookout.com: could not connect to host
 play.google.com: did not receive HSTS header (error ignored - included regardless)
 playflick.com: did not receive HSTS header
 playmaker.io: could not connect to host
 playmyplay.com: did not receive HSTS header
 playnation.io: could not connect to host
-playsharp.com: could not connect to host
 please-deny.me: did not receive HSTS header
 pleasure.forsale: could not connect to host
 pleier-it.de: did not receive HSTS header
-pleier.it: could not connect to host
+pleier.it: did not receive HSTS header
 plhdb.org: did not receive HSTS header
 plirt.ru: did not receive HSTS header
 plixer.com: did not receive HSTS header
 plogable.co: could not connect to host
 plombirator.kz: did not receive HSTS header
 plothost.com: did not receive HSTS header
 ploup.net: could not connect to host
 pluff.nl: did not receive HSTS header
@@ -4023,16 +4065,17 @@ ppy3.com: did not receive HSTS header
 pr.search.yahoo.com: did not receive HSTS header
 prattpokemon.com: could not connect to host
 prediksisydney.com: did not receive HSTS header
 preezzie.com: could not connect to host
 prefontaine.name: could not connect to host
 prego-shop.de: did not receive HSTS header
 preissler.co.uk: could not connect to host
 prelist.org: did not receive HSTS header
+presidentials2016.com: could not connect to host
 press-anime-nenkan.com: did not receive HSTS header
 pressfreedomfoundation.org: did not receive HSTS header
 pretzlaff.info: did not receive HSTS header
 preworkout.me: did not receive HSTS header
 prezola.com: did not receive HSTS header
 prgslab.net: could not connect to host
 pridoc.se: did not receive HSTS header
 printerest.io: could not connect to host
@@ -4079,51 +4122,49 @@ prxio.site: could not connect to host
 prytkov.com: did not receive HSTS header
 pshostpk.com: could not connect to host
 psw.academy: did not receive HSTS header
 psw.consulting: did not receive HSTS header
 psxtr.com: could not connect to host
 ptn.moscow: could not connect to host
 pubkey.is: could not connect to host
 pugliese.fr: could not connect to host
-puhe.se: could not connect to host
 puiterwijk.org: could not connect to host
 pumpgames.net: could not connect to host
 punchr-kamikazee.rhcloud.com: did not receive HSTS header
 puppydns.com: did not receive HSTS header
 purewebmasters.com: could not connect to host
 purplemoon.mobi: did not receive HSTS header
 purplestar.mobi: did not receive HSTS header
 push.world: did not receive HSTS header
 pushapp.org: did not receive HSTS header
 pwd.ovh: could not connect to host
 pwnies.dk: could not connect to host
 py.search.yahoo.com: did not receive HSTS header
+pycrypto.org: could not connect to host
 pyol.org: could not connect to host
 pypi-status.org: could not connect to host
 pyplo.org: did not receive HSTS header
 pypt.lt: did not receive HSTS header
 q-rickroll-u.pw: could not connect to host
 q2.si: did not receive HSTS header
-qa.stg.fedoraproject.org: could not connect to host
 qccqld.org.au: could not connect to host
 qingpat.com: could not connect to host
 qingxuan.info: max-age too low: 864000
 qinxi1992.com: could not connect to host
 qirinus.com: could not connect to host
 qldconservation.org: could not connect to host
 qonqa.de: did not receive HSTS header
 qop.io: could not connect to host
 qorm.co.uk: did not receive HSTS header
 qqq.gg: could not connect to host
 qrara.net: did not receive HSTS header
 qrlending.com: did not receive HSTS header
-qtxh.net: could not connect to host
 quail.solutions: could not connect to host
-quality1.com.br: did not receive HSTS header
+quality1.com.br: could not connect to host
 quanglepro.com: did not receive HSTS header
 quantacloud.ch: could not connect to host
 quantenteranik.eu: could not connect to host
 quantum-cloud.xyz: could not connect to host
 quantumcourse.org: did not receive HSTS header
 quebecmailbox.com: could not connect to host
 queercoders.com: did not receive HSTS header
 queryplayground.com: could not connect to host
@@ -4148,32 +4189,33 @@ railjob.cn: could not connect to host
 rainbowbarracuda.com: could not connect to host
 ramon-c.nl: could not connect to host
 ramonj.nl: could not connect to host
 randomcage.com: did not receive HSTS header
 randomcloud.net: could not connect to host
 randomhero.cloud: could not connect to host
 rankthespot.com: could not connect to host
 rannseier.org: did not receive HSTS header
-rany.duckdns.org: could not connect to host
-rany.io: could not connect to host
-rany.pw: could not connect to host
+rany.duckdns.org: max-age too low: 0
+rany.io: max-age too low: 0
+rany.pw: max-age too low: 0
 rapenroer.nl: could not connect to host
 rapidresearch.me: could not connect to host
 rapidthunder.io: could not connect to host
 rasing.me: did not receive HSTS header
 rastreador.com.es: did not receive HSTS header
 ratajczak.fr: could not connect to host
 rate-esport.de: could not connect to host
 rathorian.fr: could not connect to host
 ratuseks.com: could not connect to host
 ratuseks.net: could not connect to host
 ratuseks.us: could not connect to host
 rauchenwald.net: did not receive HSTS header
 raulfraile.net: could not connect to host
+ravage.fm: did not receive HSTS header
 raven.lipetsk.ru: could not connect to host
 ravengergaming.ga: could not connect to host
 rawet.se: did not receive HSTS header
 rawoil.com: could not connect to host
 rawstorieslondon.com: could not connect to host
 raydan.space: could not connect to host
 raydobe.me: could not connect to host
 razlaw.name: did not receive HSTS header
@@ -4207,28 +4249,29 @@ redmbk.com: did not receive HSTS header
 redports.org: could not connect to host
 redy.host: did not receive HSTS header
 regaloaks.com: did not receive HSTS header
 regalpalms.com: did not receive HSTS header
 regenbogenwald.de: did not receive HSTS header
 regenerescence.com: did not receive HSTS header
 reggae-cdmx.com: did not receive HSTS header
 reic.me: could not connect to host
-reichl-online.net: could not connect to host
 reinaldudras.ee: did not receive HSTS header
 reisyukaku.org: did not receive HSTS header
 rejo.in: could not connect to host
 rejuvemedspa.com: did not receive HSTS header
+relaxhavefun.com: did not receive HSTS header
 relayawards.com: could not connect to host
 reliable-mail.de: did not receive HSTS header
 relisten.nl: did not receive HSTS header
 rem.pe: could not connect to host
 remedioskaseros.com: did not receive HSTS header
 remitatm.com: did not receive HSTS header
 remodela.com.ve: could not connect to host
+remonttitekniikka.fi: could not connect to host
 rene-schwarz.com: could not connect to host
 renem.net: did not receive HSTS header
 renkhosting.com: did not receive HSTS header
 renlong.org: did not receive HSTS header
 renrenss.com: did not receive HSTS header
 rentacarcluj.xyz: could not connect to host
 rentbrowsertrain.me: could not connect to host
 rentcarassist.com: could not connect to host
@@ -4259,19 +4302,21 @@ rex.st: could not connect to host
 rhapsodhy.hu: could not connect to host
 rhdigital.pro: could not connect to host
 rhering.de: could not connect to host
 richiemail.net: did not receive HSTS header
 richmondsunlight.com: did not receive HSTS header
 richsiciliano.com: could not connect to host
 rid-wan.com: could not connect to host
 rideworks.com: did not receive HSTS header
+ridwan.co: did not receive HSTS header
 riesenweber.id.au: did not receive HSTS header
 right2.org: could not connect to host
 righttoknow.ie: did not receive HSTS header
+rigolitch.fr: could not connect to host
 rijndael.xyz: could not connect to host
 rika.me: could not connect to host
 ring0.xyz: did not receive HSTS header
 ringh.am: could not connect to host
 rippleunion.com: could not connect to host
 riskmgt.com.au: could not connect to host
 rivlo.com: could not connect to host
 rix.ninja: could not connect to host
@@ -4279,20 +4324,19 @@ rizon.me: did not receive HSTS header
 rj.gg: could not connect to host
 rk6.cz: could not connect to host
 rkkhok.hu: did not receive HSTS header
 rkmantpur.org: did not receive HSTS header
 rme.li: did not receive HSTS header
 rngmeme.com: could not connect to host
 roadfeast.com: could not connect to host
 roan24.pl: did not receive HSTS header
-robandjanine.com: could not connect to host
+rob.uk.com: could not connect to host
 robertglastra.com: could not connect to host
 robigalia.org: did not receive HSTS header
-robspc.repair: could not connect to host
 robteix.com: did not receive HSTS header
 robtex.net: did not receive HSTS header
 robtex.org: did not receive HSTS header
 rochman.id: could not connect to host
 rocksberg.net: could not connect to host
 rockstarloan.com: could not connect to host
 rockz.io: could not connect to host
 roddis.net: did not receive HSTS header
@@ -4301,24 +4345,24 @@ rodosto.com: could not connect to host
 roeper.party: could not connect to host
 roesemann.email: could not connect to host
 roguelikecenter.fr: did not receive HSTS header
 rolemaster.net: could not connect to host
 rolroer.co.za: could not connect to host
 romab.com: did not receive HSTS header
 romans-place.me.uk: did not receive HSTS header
 romulusapp.com: could not connect to host
+rondoniatec.com.br: could not connect to host
 ronvandordt.info: could not connect to host
 ronwo.de: max-age too low: 1
 roosterpgplus.nl: could not connect to host
 rootforum.org: did not receive HSTS header
 rootservice.org: did not receive HSTS header
 rootwpn.com: could not connect to host
 rop.io: could not connect to host
-roseitsolutions.co.uk: max-age too low: 10
 rossen.be: did not receive HSTS header
 rosslug.org.uk: could not connect to host
 rough.nu: could not connect to host
 roundtheme.com: did not receive HSTS header
 rous.se: could not connect to host
 rout0r.org: did not receive HSTS header
 rouvray.org: could not connect to host
 royal-forest.org: max-age too low: 0
@@ -4330,17 +4374,16 @@ rsajeey.info: could not connect to host
 rsampaio.info: could not connect to host
 rsf.io: could not connect to host
 rsmaps.org: could not connect to host
 rubbereggs.ca: could not connect to host
 rubberfurs.org: did not receive HSTS header
 rubecodeberg.com: could not connect to host
 rubenschulz.nl: did not receive HSTS header
 ruborr.se: did not receive HSTS header
-rubyquincunx.com: could not connect to host
 rubyshop.nl: max-age too low: 604800
 rudeotter.com: did not receive HSTS header
 rugirlfriend.com: could not connect to host
 ruiming.me: did not receive HSTS header
 runawebinar.nl: could not connect to host
 runementors.com: could not connect to host
 runtondev.com: did not receive HSTS header
 ruqu.nl: could not connect to host
@@ -4388,16 +4431,17 @@ sanguoxiu.com: could not connect to host
 sansdev.com: could not connect to host
 sansemea.com: did not receive HSTS header
 sansonehowell.com: max-age too low: 0
 sarah-beckett-harpist.com: did not receive HSTS header
 sarahsweetlife.com: could not connect to host
 sarahsweger.com: did not receive HSTS header
 sarisonproductions.com: did not receive HSTS header
 saruwebshop.co.za: could not connect to host
+sash.pw: could not connect to host
 satinn.pl: max-age too low: 2592000
 satmep.com: did not receive HSTS header
 satriyowibowo.my.id: did not receive HSTS header
 satsukii.moe: did not receive HSTS header
 saturne.tk: could not connect to host
 saturngames.co.uk: did not receive HSTS header
 saucyfox.net: did not receive HSTS header
 saumon.xyz: could not connect to host
@@ -4443,25 +4487,25 @@ screencaster.io: did not receive HSTS he
 screenresolution.space: could not connect to host
 screensaversplanet.com: did not receive HSTS header
 scribbleserver.com: could not connect to host
 scribe.systems: could not connect to host
 scrion.com: could not connect to host
 script.google.com: did not receive HSTS header (error ignored - included regardless)
 scriptenforcer.net: could not connect to host
 scriptict.nl: could not connect to host
-sculpture.support: did not receive HSTS header
 sdmoscow.ru: could not connect to host
 sdrobs.com: did not receive HSTS header
 sdsl-speedtest.de: could not connect to host
 sealbaker.com: could not connect to host
 search-one.de: did not receive HSTS header
 sebastian-lutsch.de: could not connect to host
 sebster.com: did not receive HSTS header
 secandtech.com: could not connect to host
+seccom.ch: did not receive HSTS header
 secondary-survivor.com: could not connect to host
 secondary-survivor.help: could not connect to host
 secondary-survivor.net: could not connect to host
 secondarysurvivor.help: could not connect to host
 secondarysurvivorportal.com: could not connect to host
 secondarysurvivorportal.help: could not connect to host
 secondbyte.nl: could not connect to host
 secondspace.ca: did not receive HSTS header
@@ -4473,17 +4517,17 @@ secureradio.net: could not connect to ho
 securesuisse.ch: could not connect to host
 security-carpet.com: could not connect to host
 security.google.com: did not receive HSTS header (error ignored - included regardless)
 securitybsides.pl: did not receive HSTS header
 securityinet.biz: did not receive HSTS header
 securityinet.net: did not receive HSTS header
 securityinet.org.il: did not receive HSTS header
 securiviera.ch: did not receive HSTS header
-sedrubal.de: could not connect to host
+sedziapilkarski.pl: did not receive HSTS header
 seedboxers.net: could not connect to host
 seele.ca: could not connect to host
 segulink.com: could not connect to host
 sehenderson.com: did not receive HSTS header
 seiko-dojo.com: could not connect to host
 selecadm.name: could not connect to host
 selectruckscalltrackingreports.com: could not connect to host
 self-evident.org: could not connect to host
@@ -4527,28 +4571,30 @@ sfsltd.com: did not receive HSTS header
 shadoom.com: did not receive HSTS header
 shadowmorph.info: did not receive HSTS header
 shadowsocks.net: could not connect to host
 shanesage.com: could not connect to host
 shareimg.xyz: could not connect to host
 sharepass.pw: could not connect to host
 shauncrowley.co.uk: could not connect to host
 shaunwheelhou.se: could not connect to host
+shav.it: could not connect to host
 sheehyinfinitioftysonsparts.com: could not connect to host
 shellj.me: max-age too low: 86400
 shellsec.pw: did not receive HSTS header
 shereallyheals.com: could not connect to host
 shibe.club: could not connect to host
 shiftins.com: did not receive HSTS header
 shiftplanning.com: did not receive HSTS header
 shiinko.com: could not connect to host
 shindorei.fr: did not receive HSTS header
 shinebijoux.com.br: could not connect to host
 shinju.moe: could not connect to host
 shiona.xyz: did not receive HSTS header
+shipping24h.com: could not connect to host
 shirosaki.org: could not connect to host
 shocksrv.com: did not receive HSTS header
 shooshosha.com: could not connect to host
 shopontarget.com: did not receive HSTS header
 shoprose.ru: could not connect to host
 shops.neonisi.com: could not connect to host
 shota.party: could not connect to host
 showkeeper.tv: did not receive HSTS header
@@ -4561,30 +4607,31 @@ si.to: could not connect to host
 siammedia.co: could not connect to host
 siamsnus.com: did not receive HSTS header
 sichere-kartenakzeptanz.de: did not receive HSTS header
 siciliadigitale.pro: could not connect to host
 siddhant.me: did not receive HSTS header
 siebens.net: could not connect to host
 sifls.com: could not connect to host
 sig6.org: could not connect to host
-sijimi.cn: could not connect to host
+sijimi.cn: did not receive HSTS header
 sijmenschoon.nl: did not receive HSTS header
 silaslova-ekb.ru: could not connect to host
 silentcircle.com: did not receive HSTS header
 silentcircle.org: could not connect to host
 silentexplosion.de: could not connect to host
 silentlink.io: could not connect to host
 silicagelpackets.ca: did not receive HSTS header
 silkebaekken.no: did not receive HSTS header
 silver-drachenkrieger.de: did not receive HSTS header
 silverhome.ninja: could not connect to host
 silverpvp.com: could not connect to host
 simbast.com: could not connect to host
 simbihaiti.com: did not receive HSTS header
+simfri.com: did not receive HSTS header
 simobilklub.si: did not receive HSTS header
 simod.org: could not connect to host
 simon.butcher.name: max-age too low: 2629743
 simongong.net: did not receive HSTS header
 simpan.id: could not connect to host
 simpleai.net: max-age too low: 600
 simplelearner.com: could not connect to host
 simplepractice.com: did not receive HSTS header
@@ -4596,29 +4643,29 @@ singul4rity.com: could not connect to ho
 sinosky.org: did not receive HSTS header
 siriad.com: could not connect to host
 sirius-lee.net: could not connect to host
 sistemy48.ru: did not receive HSTS header
 sitennisclub.com: did not receive HSTS header
 siterip.org: could not connect to host
 sites.google.com: did not receive HSTS header (error ignored - included regardless)
 sitesten.com: did not receive HSTS header
+sitsy.ru: could not connect to host
 sixtwentyten.com: did not receive HSTS header
 skhosting.eu: max-age too low: 0
 ski-insurance.com.au: did not receive HSTS header
 skidstresser.com: did not receive HSTS header
 skile.ru: could not connect to host
 skk.io: could not connect to host
 skoda-clever-lead.de: could not connect to host
-skolem.de: could not connect to host
 skotty.io: did not receive HSTS header
 skullhouse.nyc: did not receive HSTS header
 skyflix.me: could not connect to host
 skyoy.com: did not receive HSTS header
-slash-dev.de: did not receive HSTS header
+slash-dev.de: could not connect to host
 slashand.co: did not receive HSTS header
 slashem.me: did not receive HSTS header
 slattery.co: could not connect to host
 slauber.de: did not receive HSTS header
 sleep10.com: could not connect to host
 slicketl.com: did not receive HSTS header
 slightfuture.click: could not connect to host
 slightfuture.com: did not receive HSTS header
@@ -4676,16 +4723,17 @@ solidfuelappliancespares.co.uk: did not 
 soll-i.ch: did not receive HSTS header
 solsystems.ru: could not connect to host
 someshit.xyz: could not connect to host
 somethingnew.xyz: could not connect to host
 sonic.network: did not receive HSTS header
 sonicrainboom.rocks: could not connect to host
 soobi.org: did not receive HSTS header
 soondy.com: did not receive HSTS header
+sortaweird.net: could not connect to host
 sosaka.ml: could not connect to host
 sotor.de: did not receive HSTS header
 soucorneteiro.com.br: could not connect to host
 soulema.com: could not connect to host
 soulfulglamour.uk: could not connect to host
 sourcelair.com: did not receive HSTS header
 southgale.condos: could not connect to host
 southside-crew.club: could not connect to host
@@ -4743,17 +4791,17 @@ srrr.ca: could not connect to host
 ss.wtf: could not connect to host
 ssl.panoramio.com: did not receive HSTS header
 ssl.rip: could not connect to host
 ssmato.me: could not connect to host
 ssnc.org: max-age too low: 300
 sspanda.com: did not receive HSTS header
 sss3s.com: could not connect to host
 ssworld.ga: could not connect to host
-staack.com: did not receive HSTS header
+staack.com: could not connect to host
 stabletoken.com: could not connect to host
 stadjerspasonline.nl: could not connect to host
 stadtbauwerk.at: did not receive HSTS header
 staffjoy.com: did not receive HSTS header
 staffjoystaging.com: could not connect to host
 stahl.xyz: could not connect to host
 stalkerhispano.com: max-age too low: 0
 stalkthe.net: could not connect to host
@@ -4808,17 +4856,17 @@ storecove.com: did not receive HSTS head
 storeden.com: did not receive HSTS header
 storefrontify.com: did not receive HSTS header
 stormhub.org: could not connect to host
 stqry.com: did not receive HSTS header
 str0.at: did not receive HSTS header
 strasweb.fr: did not receive HSTS header
 strbt.de: could not connect to host
 stream.pub: did not receive HSTS header
-streamingeverywhere.com: did not receive HSTS header
+streamingeverywhere.com: could not connect to host
 streamingmagazin.de: could not connect to host
 streampanel.net: did not receive HSTS header
 streams.dyndns.org: could not connect to host
 strictlysudo.com: could not connect to host
 strivephysmed.com: did not receive HSTS header
 stroeercrm.de: could not connect to host
 strongest-privacy.com: could not connect to host
 stuartbaxter.co: could not connect to host
@@ -4838,23 +4886,23 @@ stylenda.com: could not connect to host
 subbing.work: could not connect to host
 subdimension.org: did not receive HSTS header
 subeesu.com: could not connect to host
 subhacker.net: did not receive HSTS header
 subrosa.io: could not connect to host
 subsys.no: did not receive HSTS header
 subtitle.rip: could not connect to host
 sudo.li: did not receive HSTS header
+sudosu.fr: could not connect to host
 suian.or.jp: max-age too low: 86400
 suite73.org: could not connect to host
 suksit.com: could not connect to host
 sumoatm.com: did not receive HSTS header
 sumoscout.de: did not receive HSTS header
 suncountrymarine.com: did not receive HSTS header
-sunflyer.cn: did not receive HSTS header
 sunnyfruit.ru: did not receive HSTS header
 sunshinepress.org: could not connect to host
 sunyanzi.tk: could not connect to host
 suos.io: could not connect to host
 supcro.com: could not connect to host
 super-erotica.ru: did not receive HSTS header
 super-garciniaslim.com: could not connect to host
 super-radiant-skin.com: could not connect to host
@@ -4883,18 +4931,16 @@ swdatlantico.pt: could not connect to ho
 sweetstreats.ca: could not connect to host
 swimbee.nl: did not receive HSTS header
 swimming.ca: did not receive HSTS header
 swmd5c.org: did not receive HSTS header
 sxbk.pw: could not connect to host
 syam.cc: could not connect to host
 sydgrabber.tk: could not connect to host
 sykl.us: could not connect to host
-sylvan.me: could not connect to host
-sylvangarden.net: could not connect to host
 sylvangarden.org: could not connect to host
 sylvanorder.com: could not connect to host
 symphonos.it: did not receive HSTS header
 synackr.com: could not connect to host
 syncappate.com: could not connect to host
 syncclinicalstudy.com: could not connect to host
 syncer.jp: did not receive HSTS header
 syneic.com: did not receive HSTS header
@@ -4915,17 +4961,17 @@ t-tz.com: could not connect to host
 t4x.org: did not receive HSTS header
 taabe.xyz: could not connect to host
 tacomafia.net: did not receive HSTS header
 tadigitalstore.com: could not connect to host
 tafoma.com: did not receive HSTS header
 tageau.com: could not connect to host
 taglondon.org: did not receive HSTS header
 tailify.com: did not receive HSTS header
-tails.com.ar: could not connect to host
+tails.com.ar: did not receive HSTS header
 tales-of-interia.de: did not receive HSTS header
 talk.google.com: did not receive HSTS header (error ignored - included regardless)
 talktwincities.com: could not connect to host
 tallr.se: could not connect to host
 tallshoe.com: could not connect to host
 tamex.xyz: could not connect to host
 tandarts-haarlem.nl: did not receive HSTS header
 tangel.me: could not connect to host
@@ -4935,17 +4981,16 @@ tanze-jetzt.de: did not receive HSTS hea
 taozj.org: did not receive HSTS header
 tapfinder.ca: could not connect to host
 tapka.cz: did not receive HSTS header
 tappublisher.com: did not receive HSTS header
 taravancil.com: did not receive HSTS header
 tarhauskielto.fi: did not receive HSTS header
 tartaneagle.org.uk: could not connect to host
 tartaros.fi: could not connect to host
-taskotron.stg.fedoraproject.org: could not connect to host
 taskstats.com: could not connect to host
 taskulu.ir: could not connect to host
 tasmansecurity.com: could not connect to host
 tasta.ro: did not receive HSTS header
 tastyyy.co: could not connect to host
 tatt.io: could not connect to host
 tauchkater.de: could not connect to host
 tavopica.lt: did not receive HSTS header
@@ -4958,18 +5003,18 @@ tcao.info: could not connect to host
 tcby45.xyz: could not connect to host
 tcdw.net: did not receive HSTS header
 tcl.ath.cx: did not receive HSTS header
 tcomms.org: max-age too low: 0
 tcp.expert: did not receive HSTS header
 tcptun.com: could not connect to host
 teachforcanada.ca: did not receive HSTS header
 team-teasers.com: could not connect to host
-teambeoplay.co.uk: did not receive HSTS header
 teamblueridge.org: could not connect to host
+teamhood.io: could not connect to host
 teamsocial.co: did not receive HSTS header
 teamzeus.cz: could not connect to host
 tech55i.com: could not connect to host
 techassist.io: did not receive HSTS header
 techelements.co: could not connect to host
 techhipster.net: could not connect to host
 techhub.ml: could not connect to host
 techllage.com: could not connect to host
@@ -4996,19 +5041,19 @@ tempus-aquilae.de: could not connect to 
 tendertool.nl: could not connect to host
 tenni.xyz: could not connect to host
 tensei-slime.com: did not receive HSTS header
 tensionup.com: could not connect to host
 teos.online: could not connect to host
 terra.by: did not receive HSTS header
 terrax.berlin: could not connect to host
 terrax.info: could not connect to host
+terrax.net: could not connect to host
 testandroid.xyz: could not connect to host
 testnode.xyz: could not connect to host
-testosterone-complex.com: did not receive HSTS header
 teulon.eu: could not connect to host
 texte-zur-taufe.de: did not receive HSTS header
 texter-linz.at: did not receive HSTS header
 textoplano.xyz: could not connect to host
 textracer.dk: could not connect to host
 tezcam.tk: could not connect to host
 tf2stadium.com: did not receive HSTS header
 tfcoms-sp-tracker-client.azurewebsites.net: could not connect to host
@@ -5031,16 +5076,17 @@ thecapitalbank.com: did not receive HSTS
 thecharlestonwaldorf.com: did not receive HSTS header
 theclementinebutchers.com: could not connect to host
 theclubjersey.com: did not receive HSTS header
 thecoffeehouse.xyz: could not connect to host
 thecrochetcottage.net: could not connect to host
 thediaryofadam.com: did not receive HSTS header
 theendofzion.com: did not receive HSTS header
 theescapistswiki.com: could not connect to host
+theeyeopener.com: did not receive HSTS header
 thefarbeyond.com: could not connect to host
 theflowerbasketonline.com: could not connect to host
 thefootballanalyst.com: did not receive HSTS header
 thefrozenfire.com: did not receive HSTS header
 thefutureharrills.com: could not connect to host
 thegcccoin.com: did not receive HSTS header
 thego2swatking.com: could not connect to host
 thehiddenbay.eu: could not connect to host
@@ -5079,17 +5125,16 @@ thierryhayoz.ch: could not connect to ho
 thinkcoding.de: could not connect to host
 thinkcoding.org: could not connect to host
 thinlyveiledcontempt.com: could not connect to host
 thirdpartytrade.com: did not receive HSTS header
 thirty5.net: did not receive HSTS header
 thisisacompletetest.ga: could not connect to host
 thisisforager.com: could not connect to host
 thiswebhost.com: did not receive HSTS header
-thomascloud.ddns.net: could not connect to host
 thomaskliszowski.fr: did not receive HSTS header
 thomasschweizer.net: could not connect to host
 thorncreek.net: did not receive HSTS header
 thriveapproach.co.uk: did not receive HSTS header
 thumbtack.com: did not receive HSTS header
 thusoy.com: did not receive HSTS header
 ti.blog.br: could not connect to host
 tickettoaster.de: max-age too low: 0
@@ -5154,17 +5199,16 @@ tollmanz.com: did not receive HSTS heade
 tolud.com: could not connect to host
 tomeara.net: could not connect to host
 tomharris.tech: did not receive HSTS header
 tomlankhorst.nl: did not receive HSTS header
 tomli.me: could not connect to host
 tommsy.com: did not receive HSTS header
 tommyads.com: could not connect to host
 tonyfantjr.com: could not connect to host
-tonyw.xyz: could not connect to host
 toomanypillows.com: could not connect to host
 top-stage.net: could not connect to host
 topdeskdev.net: could not connect to host
 topmarine.se: could not connect to host
 topnewstoday.org: could not connect to host
 topshelfguild.com: could not connect to host
 torahanytime.com: did not receive HSTS header
 torlock.download: could not connect to host
@@ -5242,17 +5286,17 @@ tuxcloud.net: could not connect to host
 tuxz.net: did not receive HSTS header
 tv.search.yahoo.com: could not connect to host
 tvtubeflix.com: did not receive HSTS header
 tvz-materijali.com: could not connect to host
 twarog.cc: could not connect to host
 twillionmas.com: max-age too low: 0
 twinkseason.ca: could not connect to host
 twinkseason.co: could not connect to host
-twinkseason.co.uk: did not receive HSTS header
+twinkseason.co.uk: could not connect to host
 twinkseason.com: did not receive HSTS header
 twinkseason.net: could not connect to host
 twinkseason.org: could not connect to host
 twinkseason.xyz: could not connect to host
 twist.party: could not connect to host
 twodadsgames.com: could not connect to host
 twogo.com: did not receive HSTS header
 twolinepassbrewing.com: could not connect to host
@@ -5268,22 +5312,22 @@ tyroproducts.eu: did not receive HSTS he
 tzappa.net: could not connect to host
 u-blox.com: max-age too low: 0
 ua.search.yahoo.com: did not receive HSTS header
 uadp.pw: could not connect to host
 uber.com.au: did not receive HSTS header
 uberfunction.com: did not receive HSTS header
 ubicloud.de: could not connect to host
 ublox.com: did not receive HSTS header
+ubtce.com: could not connect to host
 ubuntuhot.com: did not receive HSTS header
 uega.net: did not receive HSTS header
 ueu.me: could not connect to host
 ufgaming.com: did not receive HSTS header
 ufotable.uk: could not connect to host
-ugcdn.com: could not connect to host
 ui8.net: max-age too low: 86400
 ukas.com: did not receive HSTS header
 ukdropshipment.co.uk: did not receive HSTS header
 ukdropshipment.com: did not receive HSTS header
 ukk.dk: max-age too low: 0
 ukrgadget.com: could not connect to host
 ulabox.cat: did not receive HSTS header
 ulabox.es: did not receive HSTS header
@@ -5337,21 +5381,21 @@ uonstaffhub.com: could not connect to ho
 uow.ninja: could not connect to host
 up1.ca: could not connect to host
 upaknship.com: did not receive HSTS header
 upldr.pw: could not connect to host
 uprotect.it: could not connect to host
 upstats.eu: could not connect to host
 ur-lauber.de: did not receive HSTS header
 urandom.eu.org: did not receive HSTS header
-urbanstylestaging.com: did not receive HSTS header
 urown.net: could not connect to host
 urphp.com: could not connect to host
 us-immigration.com: did not receive HSTS header
 usaa.com: did not receive HSTS header
+usaab.org: did not receive HSTS header
 usbtypeccompliant.com: could not connect to host
 uscitizenship.info: did not receive HSTS header
 uscntalk.com: could not connect to host
 uscurrency.gov: did not receive HSTS header
 used-in.jp: could not connect to host
 usercare.com: did not receive HSTS header
 userify.com: did not receive HSTS header
 ustr.gov: max-age too low: 86400
@@ -5410,17 +5454,17 @@ veterinaire-cazeres-foucault.fr: could n
 vetmgmt.com: could not connect to host
 veto.fish: could not connect to host
 vfree.org: could not connect to host
 vglimg.com: could not connect to host
 vhost.co.id: could not connect to host
 viadeux.com: could not connect to host
 vicianovi.cz: could not connect to host
 videnskabsklubben.dk: did not receive HSTS header
-videomuz.com: did not receive HSTS header
+videomuz.com: could not connect to host
 videotogel.net: did not receive HSTS header
 vidid.net: did not receive HSTS header
 vidz.ga: could not connect to host
 vieaw.com: did not receive HSTS header
 vietnamphotographytours.com: did not receive HSTS header
 vigilo.cf: could not connect to host
 vigilo.ga: could not connect to host
 vijos.org: did not receive HSTS header
@@ -5455,17 +5499,16 @@ vmrdev.com: could not connect to host
 voceinveste.com: did not receive HSTS header
 vodpay.com: could not connect to host
 vodpay.net: could not connect to host
 vodpay.org: could not connect to host
 voicesuk.co.uk: did not receive HSTS header
 voidpay.com: could not connect to host
 voidpay.net: could not connect to host
 voidpay.org: could not connect to host
-voidptr.eu: could not connect to host
 volcrado.com: could not connect to host
 voliere-info.nl: did not receive HSTS header
 volkden.com: could not connect to host
 vortexhobbies.com: did not receive HSTS header
 vosjesweb.nl: could not connect to host
 vox.vg: did not receive HSTS header
 vpl.me: did not receive HSTS header
 vpn-byen.dk: did not receive HSTS header
@@ -5566,19 +5609,18 @@ wetttipps.com: did not receive HSTS head
 wetttipps.de: did not receive HSTS header
 wevahoo.com: could not connect to host
 wftda.com: did not receive HSTS header
 whatnext.limited: did not receive HSTS header
 whats.io: could not connect to host
 whatsstalk.me: could not connect to host
 whatsyouroffer.co.uk: did not receive HSTS header
 when-release.com: did not receive HSTS header
-wheresben.today: could not connect to host
 whisker.network: could not connect to host
-whitehat.id: did not receive HSTS header
+whitehat.id: could not connect to host
 whiterabbitcakery.com: could not connect to host
 whitestagforge.com: did not receive HSTS header
 whoclicks.net: could not connect to host
 whoisapi.online: could not connect to host
 wholebites.com: did not receive HSTS header
 whoneedstobeprimaried.today: could not connect to host
 whoshotya.de: did not receive HSTS header
 whysuck.com: could not connect to host
@@ -5586,33 +5628,35 @@ whyworldhot.com: could not connect to ho
 wienholding.at: max-age too low: 0
 wieninternational.at: did not receive HSTS header
 wiire.me: could not connect to host
 wikiclash.info: could not connect to host
 wikisports.eu: could not connect to host
 wilf1rst.com: could not connect to host
 willcipriano.com: could not connect to host
 william.si: did not receive HSTS header
+williamsapiens.com: could not connect to host
 willosagiede.com: did not receive HSTS header
 winaes.com: did not receive HSTS header
 winclient.cn: could not connect to host
 windowsphoneblog.it: could not connect to host
 winecodeavocado.com: could not connect to host
 winged.io: could not connect to host
 wingumd.net: could not connect to host
 winpack.cf: could not connect to host
 winpack.eu.org: could not connect to host
 winsec.nl: could not connect to host
 winshiplending.com: did not receive HSTS header
 wipply.com: did not receive HSTS header
 wirc.gr: could not connect to host
 wireshark.org: did not receive HSTS header
+wiretrip.io: did not receive HSTS header
 wiseloan.com: did not receive HSTS header
 wishcert.com: could not connect to host
-witae.com: did not receive HSTS header
+witae.com: could not connect to host
 withgoogle.com: did not receive HSTS header (error ignored - included regardless)
 withmy.beer: could not connect to host
 withustrading.com: could not connect to host
 withyoutube.com: did not receive HSTS header (error ignored - included regardless)
 wittcher.com: could not connect to host
 wittydonut.com: could not connect to host
 witzemaschine.com: max-age too low: 0
 wiz.biz: could not connect to host
@@ -5621,30 +5665,31 @@ wmcuk.net: could not connect to host
 wmfinanz.com: could not connect to host
 wnmm.nl: could not connect to host
 wobblylang.org: could not connect to host
 wodice.com: could not connect to host
 wohnungsbau-ludwigsburg.de: did not receive HSTS header
 woima.fi: max-age too low: 604800
 wolfesden.com: could not connect to host
 wolfeyesusa.com: could not connect to host
-womb.city: could not connect to host
 womosale.de: could not connect to host
 wonderfall.xyz: could not connect to host
 wonderhost.info: could not connect to host
 woodmafia.com.au: max-age too low: 0
 woording.com: could not connect to host
 wootton95.com: could not connect to host
 word-grabber.com: did not receive HSTS header
 woresite.jp: did not receive HSTS header
+work-and-jockel.de: did not receive HSTS header
 workfone.io: did not receive HSTS header
 workpermit.com.vn: did not receive HSTS header
 workwithgo.com: could not connect to host
 worldsbeststory.com: did not receive HSTS header
 worldwhisperer.net: could not connect to host
+worshapp.com: did not receive HSTS header
 wowapi.org: could not connect to host
 wpblog.com.tw: did not receive HSTS header
 wpcarer.pro: did not receive HSTS header
 wpdublin.com: could not connect to host
 wpfortify.com: did not receive HSTS header
 wphostingspot.com: did not receive HSTS header
 wpmetadatastandardsproject.org: did not receive HSTS header
 writeapp.me: did not receive HSTS header
@@ -5699,31 +5744,31 @@ xett.com: could not connect to host
 xf-liam.com: did not receive HSTS header
 xfive.de: did not receive HSTS header
 xiaody.me: could not connect to host
 xiaolvmu.com: could not connect to host
 xiaolvmu.me: could not connect to host
 xiaoxiao.im: could not connect to host
 xichuangke.com: could not connect to host
 ximens.me: did not receive HSTS header
-xinbiji.cn: did not receive HSTS header
 xisa.it: could not connect to host
 xiyu.moe: could not connect to host
 xmonk.org: could not connect to host
 xmppwocky.net: could not connect to host
 xmr.my: could not connect to host
 xn--3lqt7ir4md4tzwa.cn: did not receive HSTS header
 xn--3lqt7ir4md4tzwa.xn--fiqs8s: did not receive HSTS header
 xn--4dbjwf8c.cf: could not connect to host
 xn--4dbjwf8c.ga: could not connect to host
 xn--4dbjwf8c.gq: could not connect to host
 xn--4dbjwf8c.tk: could not connect to host
 xn--79q87uvkclvgd56ahq5a.net: did not receive HSTS header
 xn--7rvz7ku3ppnr.jp: did not receive HSTS header
 xn--80aaihqncaejjobbu6v.xn--p1ai: max-age too low: 10000
+xn--90accgba6bldkcbb7a.xn--p1acf: could not connect to host
 xn--9pr52k0p5a.com: did not receive HSTS header
 xn--d1acj9c.xn--90ais: could not connect to host
 xn--datenrettung-mnchen-jbc.com: did not receive HSTS header
 xn--jobbrse-d1a.de: did not receive HSTS header
 xn--lgb3a8bcpn.cf: could not connect to host
 xn--lgb3a8bcpn.ga: could not connect to host
 xn--lgb3a8bcpn.gq: could not connect to host
 xn--lgb3a8bcpn.ml: could not connect to host
@@ -5733,31 +5778,32 @@ xn--mgbbh2a9fub.xn--ngbc5azd: could not 
 xn--neb-tma3u8u.xyz: could not connect to host
 xn--seelenwchter-mcb.eu: could not connect to host
 xn--werner-schffer-fib.de: could not connect to host
 xn--yoamomisuasbcn-ynb.com: could not connect to host
 xnode.org: did not receive HSTS header
 xobox.me: could not connect to host
 xoffy.com: did not receive HSTS header
 xom.party: could not connect to host
+xperiacodes.com: did not receive HSTS header
 xpi.fr: could not connect to host
 xsmobile.de: could not connect to host
 xtom.email: could not connect to host
 xtream-hosting.com: could not connect to host
 xtream-hosting.de: could not connect to host
 xtream-hosting.eu: could not connect to host
 xtreamhosting.eu: could not connect to host
 xtrim.ru: did not receive HSTS header
 xuri.me: max-age too low: 2592000
 xuwei.de: could not connect to host
 xuyh0120.win: did not receive HSTS header
 xxbase.com: could not connect to host
 xynex.us: could not connect to host
 y-o-w.com: did not receive HSTS header
-y-s.pw: max-age too low: 2592000
+y-s.pw: could not connect to host
 yabrt.cn: did not receive HSTS header
 yagi2.com: could not connect to host
 yalook.com: did not receive HSTS header
 yamamo10.com