Merge m-c to inbound, a=merge
authorWes Kocher <wkocher@mozilla.com>
Fri, 22 Sep 2017 15:06:12 -0700
changeset 382580 bec1b493c91e58f9e26e370905e9c2d8fd1ba992
parent 382579 ddff620ec86abbb80d2e3e46d105e30938729481 (current diff)
parent 382511 3d72fdb0e561ea59d9e5850c3e71367dbb8a7148 (diff)
child 382581 c37cb1a6bdcb78e3044f324546b637591cde8c32
push id32562
push userarchaeopteryx@coole-files.de
push dateSat, 23 Sep 2017 09:38:29 +0000
treeherdermozilla-central@8db0c4ecd94c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone58.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 m-c to inbound, a=merge MozReview-Commit-ID: 7rJ9fpLBazL
taskcluster/docker/firefox-snap/distribution.ini
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/webdriver/tests/sessions/new_session/create.py
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1082,21 +1082,17 @@ pref("security.sandbox.content.level", 3
 // to whitelist more system calls.
 //
 // So the purpose of this setting is to allow nightly users to disable the
 // sandbox while we fix their problems. This way, they won't have to wait for
 // another nightly release which disables seccomp-bpf again.
 //
 // This setting may not be required anymore once we decide to permanently
 // enable the content sandbox.
-#ifdef NIGHTLY_BUILD
 pref("security.sandbox.content.level", 3);
-#else
-pref("security.sandbox.content.level", 2);
-#endif
 pref("security.sandbox.content.write_path_whitelist", "");
 pref("security.sandbox.content.read_path_whitelist", "");
 pref("security.sandbox.content.syscall_whitelist", "");
 #endif
 
 #if defined(XP_MACOSX) || defined(XP_WIN)
 #if defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
 // ID (a UUID when set by gecko) that is used to form the name of a
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1354,17 +1354,17 @@ var gBrowserInit = {
     if (!window.toolbar.visible) {
       // adjust browser UI for popups
       gURLBar.setAttribute("readonly", "true");
       gURLBar.setAttribute("enablehistory", "false");
     }
 
     // Misc. inits.
     TabletModeUpdater.init();
-    CombinedStopReload.init();
+    CombinedStopReload.ensureInitialized();
     gPrivateBrowsingUI.init();
     BrowserPageActions.init();
     gAccessibilityServiceIndicator.init();
 
     if (window.matchMedia("(-moz-os-version: windows-win8)").matches &&
         window.matchMedia("(-moz-windows-default-theme)").matches) {
       let windowFrameColor = new Color(...Cu.import("resource:///modules/Windows8WindowFrameColor.jsm", {})
                                             .Windows8WindowFrameColor.get());
@@ -4919,42 +4919,55 @@ var LinkTargetDisplay = {
   _hide() {
     clearTimeout(this._timer);
 
     XULBrowserWindow.updateStatusField();
   }
 };
 
 var CombinedStopReload = {
-  init() {
+  // Try to initialize. Returns whether initialization was successful, which
+  // may mean we had already initialized.
+  ensureInitialized() {
     if (this._initialized)
-      return;
+      return true;
+    if (this._destroyed)
+      return false;
 
     let reload = document.getElementById("reload-button");
     let stop = document.getElementById("stop-button");
-    if (!stop || !reload || reload.nextSibling != stop)
-      return;
+    // It's possible the stop/reload buttons have been moved to the palette.
+    // They may be reinserted later, so we will retry initialization if/when
+    // we get notified of document loads.
+    if (!stop || !reload)
+      return false;
 
     this._initialized = true;
     if (XULBrowserWindow.stopCommand.getAttribute("disabled") != "true")
       reload.setAttribute("displaystop", "true");
     stop.addEventListener("click", this);
     this.reload = reload;
     this.stop = stop;
     this.stopReloadContainer = this.reload.parentNode;
     this.timeWhenSwitchedToStop = 0;
+
+    if (this._shouldStartPrefMonitoring) {
+      this.startAnimationPrefMonitoring();
+    }
+    return true;
   },
 
   uninit() {
+    this._destroyed = true;
+
     if (!this._initialized)
       return;
 
     Services.prefs.removeObserver("toolkit.cosmeticAnimations.enabled", this);
     this._cancelTransition();
-    this._initialized = false;
     this.stop.removeEventListener("click", this);
     this.stopReloadContainer.removeEventListener("animationend", this);
     this.stopReloadContainer = null;
     this.reload = null;
     this.stop = null;
   },
 
   handleEvent(event) {
@@ -4979,33 +4992,37 @@ var CombinedStopReload = {
   observe(subject, topic, data) {
     if (topic == "nsPref:changed") {
       this.animate = Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled");
     }
   },
 
   startAnimationPrefMonitoring() {
     // CombinedStopReload may have been uninitialized before the idleCallback is executed.
-    if (!this._initialized)
+    if (this._destroyed)
       return;
+    if (!this.ensureInitialized()) {
+      this._shouldStartPrefMonitoring = true;
+      return;
+    }
     this.animate = Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled") &&
                    Services.prefs.getBoolPref("browser.stopReloadAnimation.enabled");
     Services.prefs.addObserver("toolkit.cosmeticAnimations.enabled", this);
     this.stopReloadContainer.addEventListener("animationend", this);
   },
 
   onTabSwitch() {
     // Reset the time in the event of a tabswitch since the stored time
     // would have been associated with the previous tab, so the animation will
     // still run if the page has been loading until long after the tab switch.
     this.timeWhenSwitchedToStop = window.performance.now();
   },
 
   switchToStop(aRequest, aWebProgress) {
-    if (!this._initialized || !this._shouldSwitch(aRequest, aWebProgress)) {
+    if (!this.ensureInitialized() || !this._shouldSwitch(aRequest, aWebProgress)) {
       return;
     }
 
     // Store the time that we switched to the stop button only if a request
     // is active. Requests are null if the switch is related to a tabswitch.
     // This is used to determine if we should show the stop->reload animation.
     if (aRequest instanceof Ci.nsIRequest) {
       this.timeWhenSwitchedToStop = window.performance.now();
@@ -5024,17 +5041,17 @@ var CombinedStopReload = {
       this.stopReloadContainer.setAttribute("animate", "true");
     } else {
       this.stopReloadContainer.removeAttribute("animate");
     }
     this.reload.setAttribute("displaystop", "true");
   },
 
   switchToReload(aRequest, aWebProgress) {
-    if (!this._initialized || !this._shouldSwitch(aRequest, aWebProgress) ||
+    if (!this.ensureInitialized() || !this._shouldSwitch(aRequest, aWebProgress) ||
         !this.reload.hasAttribute("displaystop")) {
       return;
     }
 
     let shouldAnimate = aRequest instanceof Ci.nsIRequest &&
                         aWebProgress.isTopLevel &&
                         !aWebProgress.isLoadingDocument &&
                         !gBrowser.tabAnimationsInProgress &&
--- a/browser/base/content/test/performance/browser_startup_images.js
+++ b/browser/base/content/test/performance/browser_startup_images.js
@@ -29,16 +29,18 @@ const whitelist = [
     file: "chrome://browser/skin/tabbrowser/tab-overflow-indicator.png",
     platforms: ["linux", "win", "macosx"],
   },
 
   {
     file: "chrome://browser/skin/places/toolbarDropMarker.png",
     platforms: ["linux", "win", "macosx"],
   },
+
+  // Bug 1363040
   {
     file: "chrome://browser/skin/tracking-protection-16.svg#enabled",
     platforms: ["linux", "win", "macosx"],
   },
 
   {
     file: "chrome://browser/skin/tabbrowser/tabDragIndicator.png",
     hidpi: "chrome://browser/skin/tabbrowser/tabDragIndicator@2x.png",
@@ -66,16 +68,26 @@ const whitelist = [
     file: "chrome://browser/skin/chevron.svg",
     platforms: ["win", "linux", "macosx"],
   },
 
   {
     file: "chrome://global/skin/icons/resizer.png",
     platforms: ["win"],
   },
+
+  {
+    file: "chrome://browser/skin/window-controls/maximize.svg",
+    platforms: ["win"],
+    // This is to prevent perma-fails in case Windows machines
+    // go back to running tests in non-maximized windows.
+    intermittentShown: ["win"],
+    // This file is not loaded on Windows 7/8.
+    intermittentNotLoaded: ["win"],
+  },
 ];
 
 add_task(async function() {
   if (!AppConstants.DEBUG) {
     ok(false, "You need to run this test on a debug build.");
   }
 
   let startupRecorder = Cc["@mozilla.org/test/startuprecorder;1"].getService().wrappedJSObject;
--- a/browser/base/content/test/performance/hidpi/browser.ini
+++ b/browser/base/content/test/performance/hidpi/browser.ini
@@ -1,6 +1,6 @@
 [DEFAULT]
 prefs =
   layout.css.devPixelsPerPx='2'
 
 [../browser_startup_images.js]
-skip-if = !debug || (os == 'win' && (os_version == '6.1' || os_version == '10.0'))  # hidpi results in the toolbar overflowing on Win 7; fails on Win 10 (bug 1400357)
+skip-if = !debug || (os == 'win' && (os_version == '6.1'))  # hidpi results in the toolbar overflowing on Win 7
--- a/browser/components/places/content/places.xul
+++ b/browser/components/places/content/places.xul
@@ -39,18 +39,21 @@
         onunload="PlacesOrganizer.destroy();"
         width="&places.library.width;" height="&places.library.height;"
         screenX="10" screenY="10"
         toggletoolbar="true"
         persist="width height screenX screenY sizemode">
 
   <script type="application/javascript"
           src="chrome://browser/content/places/places.js"/>
+#ifndef XP_MACOSX
+  <!-- On Mac, this is included via macBrowserOverlay.xul -> browser.js -> defineLazyScriptGetter -->
   <script type="application/javascript"
           src="chrome://browser/content/places/editBookmarkOverlay.js"/>
+#endif
 
   <stringbundleset id="placesStringSet">
     <stringbundle id="brandStrings" src="chrome://branding/locale/brand.properties"/>
   </stringbundleset>
 
 
 #ifdef XP_MACOSX
 #include ../../../base/content/browserMountPoints.inc
--- a/browser/extensions/activity-stream/data/content/activity-stream.css
+++ b/browser/extensions/activity-stream/data/content/activity-stream.css
@@ -200,17 +200,17 @@ main {
   text-transform: uppercase; }
   .section-title span {
     color: #737373;
     fill: #737373;
     vertical-align: middle; }
 
 .body-wrapper {
   opacity: 0;
-  transition: opacity 0.1s ease-in-out; }
+  transition: opacity 75ms ease-in-out 125ms; }
   .body-wrapper.on {
     opacity: 1; }
 
 .top-sites-list {
   list-style: none;
   margin: 0;
   margin-bottom: -18px;
   padding: 0;
--- a/browser/modules/ContentLinkHandler.jsm
+++ b/browser/modules/ContentLinkHandler.jsm
@@ -291,18 +291,21 @@ this.ContentLinkHandler = {
           }
           break;
         case "icon":
           isRichIcon = false;
           // Fall through to rich icon handling
         case "apple-touch-icon":
         case "apple-touch-icon-precomposed":
         case "fluid-icon":
-          if (iconAdded || !Services.prefs.getBoolPref("browser.chrome.site_icons"))
+          if (link.hasAttribute("mask") || // Masked icons are not supported yet.
+              iconAdded ||
+              !Services.prefs.getBoolPref("browser.chrome.site_icons")) {
             break;
+          }
 
           iconAdded = handleFaviconLink(link, isRichIcon, chromeGlobal, faviconLoads);
           break;
         case "search":
           if (!searchAdded && event.type == "DOMLinkAdded") {
             var type = link.type && link.type.toLowerCase();
             type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
 
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -719,18 +719,16 @@ html|span.ac-emphasize-text-url {
 }
 
 #UITourTooltipDescription {
   font-size: 1.05rem;
 }
 
 #UITourTooltipClose {
   margin-inline-end: -4px;
-  height: 16px;
-  width: 16px;
 }
 
 /**
  * Override the --arrowpanel-padding so the background extends
  * to the sides and bottom of the panel.
  */
 #UITourTooltipButtons {
   margin-left: -10px;
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -1261,22 +1261,16 @@ html|*.addon-webext-perm-list {
   line-height: 2rem;
 }
 
 #UITourTooltipClose {
   margin-inline-end: -10px;
   margin-top: -14px;
 }
 
-@media (min-resolution: 2dppx) {
-  #UITourTooltipClose > .toolbarbutton-icon {
-    width: 16px;
-  }
-}
-
 %include ../shared/contextmenu.inc.css
 
 #context-navigation > .menuitem-iconic {
   padding-left: 0;
   padding-right: 0;
 }
 
 .browser-extension-panel > .panel-arrowcontainer > .panel-arrowcontent {
--- a/browser/themes/shared/icons/menu-badged.svg
+++ b/browser/themes/shared/icons/menu-badged.svg
@@ -1,6 +1,6 @@
 <!-- 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/. -->
 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
-  <path fill="context-fill" d="M3,4H7.755A8,8,0,0,1,6.584,2H3A1,1,0,0,0,3,4ZM13,7H3A1,1,0,0,0,3,9H13a1,1,0,0,0,0-2Zm0,5H3a1,1,0,0,0,0,2H13a1,1,0,0,0,0-2Z"/>
+  <path fill="context-fill" fill-opacity="context-fill-opacity" d="M3,4H7.755A8,8,0,0,1,6.584,2H3A1,1,0,0,0,3,4ZM13,7H3A1,1,0,0,0,3,9H13a1,1,0,0,0,0-2Zm0,5H3a1,1,0,0,0,0,2H13a1,1,0,0,0,0-2Z"/>
 </svg>
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -299,16 +299,18 @@ tabbrowser {
 .tab-label {
   margin-inline-end: 0;
   margin-inline-start: 0;
 }
 
 .tab-close-button {
   margin-inline-end: -2px;
   padding: 0;
+  -moz-context-properties: fill, fill-opacity, stroke-opacity;
+  stroke-opacity: var(--toolbarbutton-icon-fill-opacity);
 }
 
 :root[uidensity=touch] .tab-close-button {
   margin-inline-end: -@horizontalTabPadding@;
   padding: 10px calc(@horizontalTabPadding@ - 2px);
 }
 
 .tab-icon-sound {
--- a/browser/themes/windows/compacttheme.css
+++ b/browser/themes/windows/compacttheme.css
@@ -48,37 +48,33 @@
 
   #main-menubar:not(:-moz-window-inactive) {
     background-color: rgba(255,255,255,.5);
     color: black;
     border-radius: 4px;
   }
 }
 
-/* Windows 7 specific tab styles that apply to default, dark and light themes
- * (the default theme counterpart lives in browser.css) */
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-win7),
+       (-moz-os-version: windows-win8) {
   /* Always show full-height tab separators on tabs with borders. */
   .tabbrowser-tab::before {
     border-image: none !important;
   }
 
   /* Show the tabs toolbar background color inside tabs on Win 7. */
   .tab-background:not([selected=true]) {
     background-color: var(--chrome-background-color) !important;
   }
 
   /* Show border on tabs with background colors in Windows 7. */
   .tab-background {
     border-top: 1px solid var(--tabs-border);
   }
-}
 
-@media (-moz-os-version: windows-win7),
-       (-moz-os-version: windows-win8) {
   /* Use default window colors when in non-maximized mode */
   #tabbrowser-tabs,
   #TabsToolbar,
   #browser-panel,
   #titlebar-content {
     background: transparent;
   }
 
--- a/build/sparse-profiles/taskgraph
+++ b/build/sparse-profiles/taskgraph
@@ -5,16 +5,17 @@
 path:browser/locales/all-locales
 
 # Lots of random files in here are read. Just pull in the whole thing.
 path:build/
 
 # TODO remove once bug 1402010 is resolved and test manifests aren't
 # processed in Files() reading mode in moz.build files.
 path:layout/tools/reftest/
+path:testing/web-platform/tests/tools/
 
 # This file is read as part of validating the taskgraph.
 path:mobile/locales/l10n-changesets.json
 
 # The main meat of this profile.
 path:taskcluster/
 
 # Various files in these directories are read by taskgraph. Just pull
--- a/config/check_vanilla_allocations.py
+++ b/config/check_vanilla_allocations.py
@@ -124,19 +124,19 @@ def main():
 
     for line in lines:
         m = re.search(alloc_fns_re, line)
         if m is None:
             continue
 
         filename = m.group(1)
 
-        # mozalloc contains calls to memalign. These are ok, so we whitelist
-        # them.
-        if "mozalloc" in filename:
+        # The memory allocator code contains calls to memalign. These are ok, so
+        # we whitelist them.
+        if "_memory_" in filename:
             continue
 
         fn = m.group(2)
         if filename == 'jsutil.o':
             jsutil_cpp.add(fn)
         else:
             # An allocation is present in a non-special file.  Fail!
             fail("'" + fn + "' present in " + filename)
--- a/devtools/client/shared/components/reps/reps.css
+++ b/devtools/client/shared/components/reps/reps.css
@@ -250,17 +250,17 @@
   -o-user-select: none;
   user-select: none;
 }
 
 .tree button {
   display: block;
 }
 
-.tree .tree-node {
+.tree .tree-node[data-expandable="true"] {
   cursor: pointer;
 }
 
 .tree .tree-node:not(.focused):hover {
   background-color: var(--tree-node-hover-background-color);
 }
 
 .tree .tree-node.focused {
--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -131,18 +131,18 @@ const escapeRegexp = new RegExp("[" +
 // Quote and backslash.
 "\"\\\\" +
 // Controls.
 "\x00-\x1f" +
 // More controls.
 "\x7f-\x9f" +
 // BOM
 "\ufeff" +
-// Replacement characters and non-characters.
-"\ufffc-\uffff" +
+// Specials, except for the replacement character.
+"\ufff0-\ufffc\ufffe\uffff" +
 // Surrogates.
 "\ud800-\udfff" +
 // Mathematical invisibles.
 "\u2061-\u2064" +
 // Line and paragraph separators.
 "\u2028-\u2029" +
 // Private use area.
 "\ue000-\uf8ff" + "]", "g");
@@ -769,29 +769,31 @@ const { a, span } = React.DOM;
 StringRep.propTypes = {
   useQuotes: React.PropTypes.bool,
   escapeWhitespace: React.PropTypes.bool,
   style: React.PropTypes.object,
   object: React.PropTypes.string.isRequired,
   member: React.PropTypes.any,
   cropLimit: React.PropTypes.number,
   openLink: React.PropTypes.func,
-  className: React.PropTypes.string
+  className: React.PropTypes.string,
+  omitLinkHref: React.PropTypes.bool
 };
 
 function StringRep(props) {
   let {
     className,
     cropLimit,
     object: text,
     member,
     style,
     useQuotes = true,
     escapeWhitespace = true,
-    openLink
+    openLink,
+    omitLinkHref = true
   } = props;
 
   const classNames = ["objectBox", "objectBox-string"];
   if (className) {
     classNames.push(className);
   }
   let config = { className: classNames.join(" ") };
   if (style) {
@@ -823,17 +825,17 @@ function StringRep(props) {
     tokenStart = text.indexOf(token, textIndex);
     if (isURL(token)) {
       items.push(text.slice(textIndex, tokenStart));
       textIndex = tokenStart + token.length;
 
       items.push(a({
         className: "url",
         title: token,
-        href: token,
+        href: omitLinkHref === true ? null : token,
         draggable: false,
         onClick: openLink ? e => {
           e.preventDefault();
           openLink(token);
         } : null
       }, token));
     }
   });
@@ -2223,16 +2225,20 @@ function nodeHasAllEntriesInPreview(item
 
   const {
     entries,
     items,
     length,
     size
   } = preview;
 
+  if (!entries && !items) {
+    return false;
+  }
+
   return entries ? entries.length === size : items.length === length;
 }
 
 function nodeNeedsNumericalBuckets(item) {
   return nodeSupportsNumericalBucketing(item) && getNumericalPropertiesCount(item) > MAX_NUMERICAL_PROPERTIES;
 }
 
 function makeNodesForPromiseProperties(item) {
@@ -5136,16 +5142,17 @@ const ArrowExpander = createFactory(crea
     });
   }
 }));
 
 const TreeNode = createFactory(createClass({
   displayName: "TreeNode",
 
   propTypes: {
+    id: PropTypes.any.isRequired,
     index: PropTypes.number.isRequired,
     depth: PropTypes.number.isRequired,
     focused: PropTypes.bool.isRequired,
     expanded: PropTypes.bool.isRequired,
     item: PropTypes.any.isRequired,
     isExpandable: PropTypes.bool.isRequired,
     onClick: PropTypes.func,
     renderItem: PropTypes.func.isRequired
@@ -5153,16 +5160,17 @@ const TreeNode = createFactory(createCla
 
   shouldComponentUpdate(nextProps) {
     return this.props.item !== nextProps.item || this.props.focused !== nextProps.focused || this.props.expanded !== nextProps.expanded;
   },
 
   render() {
     const {
       depth,
+      id,
       item,
       focused,
       expanded,
       renderItem,
       isExpandable
     } = this.props;
 
     const arrow = isExpandable ? ArrowExpander({
@@ -5202,25 +5210,27 @@ const TreeNode = createFactory(createCla
     if (this.props.isExpandable) {
       ariaExpanded = false;
     }
     if (this.props.expanded) {
       ariaExpanded = true;
     }
 
     return dom.div({
+      id,
       className: "tree-node" + (focused ? " focused" : ""),
       style: {
         paddingInlineStart,
         backgroundImage: backgroundBorder
       },
       onClick: this.props.onClick,
       role: "treeitem",
       "aria-level": depth,
-      "aria-expanded": ariaExpanded
+      "aria-expanded": ariaExpanded,
+      "data-expandable": this.props.isExpandable
     }, renderItem(item, depth, focused, arrow, expanded));
   }
 }));
 
 /**
  * Create a function that calls the given function `fn` only once per animation
  * frame.
  *
@@ -5412,20 +5422,16 @@ const Tree = createClass({
     //
     // Type: isExpanded(item: Item) -> Boolean
     //
     // Example:
     //
     //     isExpanded: item => item.expanded,
     isExpanded: PropTypes.func.isRequired,
 
-    // The height of an item in the tree including margin and padding, in
-    // pixels.
-    itemHeight: PropTypes.number.isRequired,
-
     // Optional props
 
     // The currently focused item, if any such item exists.
     focused: PropTypes.any,
 
     // Handle when a new item is focused.
     onFocus: PropTypes.func,
 
@@ -5467,35 +5473,26 @@ const Tree = createClass({
     return {
       autoExpandDepth: AUTO_EXPAND_DEPTH,
       autoExpandAll: true
     };
   },
 
   getInitialState() {
     return {
-      scroll: 0,
-      height: window.innerHeight,
       seen: new Set()
     };
   },
 
   componentDidMount() {
-    window.addEventListener("resize", this._updateHeight);
     this._autoExpand();
-    this._updateHeight();
   },
 
   componentWillReceiveProps(nextProps) {
     this._autoExpand();
-    this._updateHeight();
-  },
-
-  componentWillUnmount() {
-    window.removeEventListener("resize", this._updateHeight);
   },
 
   _autoExpand() {
     if (!this.props.autoExpandDepth) {
       return;
     }
 
     // Automatically expand the first autoExpandDepth levels for new items. Do
@@ -5542,25 +5539,16 @@ const Tree = createClass({
           if (e.nativeEvent.stopPropagation) {
             e.nativeEvent.stopPropagation();
           }
         }
     }
   },
 
   /**
-   * Updates the state's height based on clientHeight.
-   */
-  _updateHeight() {
-    this.setState({
-      height: this.refs.tree.clientHeight
-    });
-  },
-
-  /**
    * Perform a pre-order depth-first search from item.
    */
   _dfs(item, maxDepth = Infinity, traversal = [], _depth = 0) {
     traversal.push({ item, depth: _depth });
 
     if (!this.props.isExpanded(item)) {
       return traversal;
     }
@@ -5632,59 +5620,47 @@ const Tree = createClass({
    * @param {Number} index
    *        The index of the item in a full DFS traversal (ignoring collapsed
    *        nodes). Ignored if `item` is undefined.
    *
    * @param {Object|undefined} item
    *        The item to be focused, or undefined to focus no item.
    */
   _focus(index, item) {
-    if (item !== undefined) {
-      const itemStartPosition = index * this.props.itemHeight;
-      const itemEndPosition = (index + 1) * this.props.itemHeight;
-
-      // Note that if the height of the viewport (this.state.height) is less than
-      // `this.props.itemHeight`, we could accidentally try and scroll both up and
-      // down in a futile attempt to make both the item's start and end positions
-      // visible. Instead, give priority to the start of the item by checking its
-      // position first, and then using an "else if", rather than a separate "if",
-      // for the end position.
-      if (this.state.scroll > itemStartPosition) {
-        this.refs.tree.scrollTop = itemStartPosition;
-      } else if (this.state.scroll + this.state.height < itemEndPosition) {
-        this.refs.tree.scrollTop = itemEndPosition - this.state.height;
-      }
-    }
+    // TODO: Revisit how we should handle focus without having fixed item height.
+    // if (item !== undefined) {
+    //   const itemStartPosition = index * this.props.itemHeight;
+    //   const itemEndPosition = (index + 1) * this.props.itemHeight;
+
+    //   // Note that if the height of the viewport (this.state.height) is less than
+    //   // `this.props.itemHeight`, we could accidentally try and scroll both up and
+    //   // down in a futile attempt to make both the item's start and end positions
+    //   // visible. Instead, give priority to the start of the item by checking its
+    //   // position first, and then using an "else if", rather than a separate "if",
+    //   // for the end position.
+    //   if (this.state.scroll > itemStartPosition) {
+    //     this.refs.tree.scrollTop = itemStartPosition;
+    //   } else if ((this.state.scroll + this.state.height) < itemEndPosition) {
+    //     this.refs.tree.scrollTop = itemEndPosition - this.state.height;
+    //   }
+    // }
 
     if (this.props.onFocus) {
       this.props.onFocus(item);
     }
   },
 
   /**
    * Sets the state to have no focused item.
    */
   _onBlur() {
     this._focus(0, undefined);
   },
 
   /**
-   * Fired on a scroll within the tree's container, updates
-   * the stored position of the view port to handle virtual view rendering.
-   *
-   * @param {Event} e
-   */
-  _onScroll: oncePerAnimationFrame(function (e) {
-    this.setState({
-      scroll: Math.max(this.refs.tree.scrollTop, 0),
-      height: this.refs.tree.clientHeight
-    });
-  }),
-
-  /**
    * Handles key down events in the tree's container.
    *
    * @param {Event} e
    */
   _onKeyDown(e) {
     if (this.props.focused == null) {
       return;
     }
@@ -5805,18 +5781,20 @@ const Tree = createClass({
   render() {
     const traversal = this._dfsFromRoots();
     const {
       focused
     } = this.props;
 
     const nodes = traversal.map((v, i) => {
       const { item, depth } = traversal[i];
+      const key = this.props.getKey(item, i);
       return TreeNode({
-        key: this.props.getKey(item, i),
+        key,
+        id: key,
         index: i,
         item,
         depth,
         renderItem: this.props.renderItem,
         focused: focused === item,
         expanded: this.props.isExpanded(item),
         isExpandable: this._nodeIsExpandable(item),
         onExpand: this._onExpand,
@@ -5840,17 +5818,16 @@ const Tree = createClass({
     return dom.div({
       className: `tree ${this.props.className ? this.props.className : ""}`,
       ref: "tree",
       role: "tree",
       tabIndex: "0",
       onKeyDown: this._onKeyDown,
       onKeyPress: this._preventArrowKeyScrolling,
       onKeyUp: this._preventArrowKeyScrolling,
-      onScroll: this._onScroll,
       onFocus: ({ nativeEvent }) => {
         if (focused || !nativeEvent || !this.refs.tree) {
           return;
         }
 
         let { explicitOriginalTarget } = nativeEvent;
         // Only set default focus to the first tree node if the focus came
         // from outside the tree (e.g. by tabbing to the tree from other
@@ -5957,71 +5934,100 @@ module.exports = __WEBPACK_EXTERNAL_MODU
 /* 50 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 let enumIndexedProperties = (() => {
   var _ref = _asyncToGenerator(function* (objectClient, start, end) {
-    const { iterator } = yield objectClient.enumProperties({ ignoreNonIndexedProperties: true });
-    const response = yield iteratorSlice(iterator, start, end);
-    return response;
+    try {
+      const { iterator } = yield objectClient.enumProperties({ ignoreNonIndexedProperties: true });
+      const response = yield iteratorSlice(iterator, start, end);
+      return response;
+    } catch (e) {
+      console.error("Error in enumIndexedProperties", e);
+      return {};
+    }
   });
 
   return function enumIndexedProperties(_x, _x2, _x3) {
     return _ref.apply(this, arguments);
   };
 })(); /* 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/. */
 
 let enumNonIndexedProperties = (() => {
   var _ref2 = _asyncToGenerator(function* (objectClient, start, end) {
-    const { iterator } = yield objectClient.enumProperties({ ignoreIndexedProperties: true });
-
-    const response = yield iteratorSlice(iterator, start, end);
-    return response;
+    try {
+      const { iterator } = yield objectClient.enumProperties({ ignoreIndexedProperties: true });
+      const response = yield iteratorSlice(iterator, start, end);
+      return response;
+    } catch (e) {
+      console.error("Error in enumNonIndexedProperties", e);
+      return {};
+    }
   });
 
   return function enumNonIndexedProperties(_x4, _x5, _x6) {
     return _ref2.apply(this, arguments);
   };
 })();
 
 let enumEntries = (() => {
   var _ref3 = _asyncToGenerator(function* (objectClient, start, end) {
-    const { iterator } = yield objectClient.enumEntries();
-    const response = yield iteratorSlice(iterator, start, end);
-    return response;
+    try {
+      const { iterator } = yield objectClient.enumEntries();
+      const response = yield iteratorSlice(iterator, start, end);
+      return response;
+    } catch (e) {
+      console.error("Error in enumEntries", e);
+      return {};
+    }
   });
 
   return function enumEntries(_x7, _x8, _x9) {
     return _ref3.apply(this, arguments);
   };
 })();
 
 let enumSymbols = (() => {
   var _ref4 = _asyncToGenerator(function* (objectClient, start, end) {
-    const { iterator } = yield objectClient.enumSymbols();
-    const response = yield iteratorSlice(iterator, start, end);
-    return response;
+    try {
+      const { iterator } = yield objectClient.enumSymbols();
+      const response = yield iteratorSlice(iterator, start, end);
+      return response;
+    } catch (e) {
+      console.error("Error in enumSymbols", e);
+      return {};
+    }
   });
 
   return function enumSymbols(_x10, _x11, _x12) {
     return _ref4.apply(this, arguments);
   };
 })();
 
+let getPrototype = (() => {
+  var _ref5 = _asyncToGenerator(function* (objectClient) {
+    if (typeof objectClient.getPrototype !== "function") {
+      console.error("objectClient.getPrototype is not a function");
+      return Promise.resolve({});
+    }
+    return objectClient.getPrototype();
+  });
+
+  return function getPrototype(_x13) {
+    return _ref5.apply(this, arguments);
+  };
+})();
+
 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
-function getPrototype(objectClient) {
-  return objectClient.getPrototype();
-}
-
 function iteratorSlice(iterator, start, end) {
   start = start || 0;
   const count = end ? end - start + 1 : iterator.count;
   return iterator.slice(start, count);
 }
 
 module.exports = {
   enumEntries,
--- a/dom/media/ChannelMediaResource.cpp
+++ b/dom/media/ChannelMediaResource.cpp
@@ -63,50 +63,60 @@ NS_IMPL_ISUPPORTS(ChannelMediaResource::
                   nsIChannelEventSink,
                   nsIInterfaceRequestor,
                   nsIThreadRetargetableStreamListener)
 
 nsresult
 ChannelMediaResource::Listener::OnStartRequest(nsIRequest* aRequest,
                                                nsISupports* aContext)
 {
+  MOZ_ASSERT(NS_IsMainThread());
   if (!mResource)
     return NS_OK;
   return mResource->OnStartRequest(aRequest, mOffset);
 }
 
 nsresult
 ChannelMediaResource::Listener::OnStopRequest(nsIRequest* aRequest,
                                               nsISupports* aContext,
                                               nsresult aStatus)
 {
+  MOZ_ASSERT(NS_IsMainThread());
   if (!mResource)
     return NS_OK;
   return mResource->OnStopRequest(aRequest, aStatus);
 }
 
 nsresult
 ChannelMediaResource::Listener::OnDataAvailable(nsIRequest* aRequest,
                                                 nsISupports* aContext,
                                                 nsIInputStream* aStream,
                                                 uint64_t aOffset,
                                                 uint32_t aCount)
 {
   // This might happen off the main thread.
-  MOZ_DIAGNOSTIC_ASSERT(mResource);
-  return mResource->OnDataAvailable(mLoadID, aStream, aCount);
+  RefPtr<ChannelMediaResource> res;
+  {
+    MutexAutoLock lock(mMutex);
+    res = mResource;
+  }
+  // Note Rekove() might happen at the same time to reset mResource. We check
+  // the load ID to determine if the data is from an old channel.
+  return res ? res->OnDataAvailable(mLoadID, aStream, aCount) : NS_OK;
 }
 
 nsresult
 ChannelMediaResource::Listener::AsyncOnChannelRedirect(
   nsIChannel* aOld,
   nsIChannel* aNew,
   uint32_t aFlags,
   nsIAsyncVerifyRedirectCallback* cb)
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   nsresult rv = NS_OK;
   if (mResource) {
     rv = mResource->OnChannelRedirect(aOld, aNew, aFlags, mOffset);
   }
 
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -122,16 +132,24 @@ ChannelMediaResource::Listener::CheckLis
 }
 
 nsresult
 ChannelMediaResource::Listener::GetInterface(const nsIID& aIID, void** aResult)
 {
   return QueryInterface(aIID, aResult);
 }
 
+void
+ChannelMediaResource::Listener::Revoke()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MutexAutoLock lock(mMutex);
+  mResource = nullptr;
+}
+
 static bool
 IsPayloadCompressed(nsIHttpChannel* aChannel)
 {
   nsAutoCString encoding;
   Unused << aChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"), encoding);
   return encoding.Length() > 0;
 }
 
@@ -410,23 +428,26 @@ ChannelMediaResource::CopySegmentToCache
 }
 
 nsresult
 ChannelMediaResource::OnDataAvailable(uint32_t aLoadID,
                                       nsIInputStream* aStream,
                                       uint32_t aCount)
 {
   // This might happen off the main thread.
-  // Don't assert |mChannel.get() == aRequest| since reading mChannel here off
-  // the main thread is a data race.
 
   RefPtr<ChannelMediaResource> self = this;
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-    "ChannelMediaResource::OnDataAvailable",
-    [self, aCount]() { self->mChannelStatistics.AddBytes(aCount); });
+    "ChannelMediaResource::OnDataAvailable", [self, aCount, aLoadID]() {
+      if (aLoadID != self->mLoadID) {
+        // Ignore data from the old channel.
+        return;
+      }
+      self->mChannelStatistics.AddBytes(aCount);
+    });
   mCallback->AbstractMainThread()->Dispatch(r.forget());
 
   Closure closure{ aLoadID, this };
   uint32_t count = aCount;
   while (count > 0) {
     uint32_t read;
     nsresult rv =
       aStream->ReadSegments(CopySegmentToCache, &closure, count, &read);
--- a/dom/media/ChannelMediaResource.h
+++ b/dom/media/ChannelMediaResource.h
@@ -111,31 +111,36 @@ public:
     : public nsIStreamListener
     , public nsIInterfaceRequestor
     , public nsIChannelEventSink
     , public nsIThreadRetargetableStreamListener
   {
     ~Listener() {}
   public:
     Listener(ChannelMediaResource* aResource, int64_t aOffset, uint32_t aLoadID)
-      : mResource(aResource)
+      : mMutex("Listener.mMutex")
+      , mResource(aResource)
       , mOffset(aOffset)
       , mLoadID(aLoadID)
     {}
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSICHANNELEVENTSINK
     NS_DECL_NSIINTERFACEREQUESTOR
     NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
 
-    void Revoke() { mResource = nullptr; }
+    void Revoke();
 
   private:
+    Mutex mMutex;
+    // mResource should only be modified on the main thread with the lock.
+    // So it can be read without lock on the main thread or on other threads
+    // with the lock.
     RefPtr<ChannelMediaResource> mResource;
     const int64_t mOffset;
     const uint32_t mLoadID;
   };
   friend class Listener;
 
   nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override;
 
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -457,17 +457,16 @@ MediaCacheStream::MediaCacheStream(Chann
                                    bool aIsPrivateBrowsing)
   : mMediaCache(nullptr)
   , mClient(aClient)
   , mDidNotifyDataEnded(false)
   , mResourceID(0)
   , mIsTransportSeekable(false)
   , mCacheSuspended(false)
   , mChannelEnded(false)
-  , mChannelOffset(0)
   , mStreamLength(-1)
   , mStreamOffset(0)
   , mPlaybackBytesPerSecond(10000)
   , mPinCount(0)
   , mCurrentMode(MODE_PLAYBACK)
   , mMetadataInPartialBlockBuffer(false)
   , mIsPrivateBrowsing(aIsPrivateBrowsing)
 {
@@ -1118,23 +1117,35 @@ MediaCache::PredictNextUseForIncomingDat
   }
   if (bytesAhead <= 0)
     return TimeDuration(0);
   int64_t millisecondsAhead = bytesAhead*1000/aStream->mPlaybackBytesPerSecond;
   return TimeDuration::FromMilliseconds(
       std::min<int64_t>(millisecondsAhead, INT32_MAX));
 }
 
-enum StreamAction { NONE, SEEK, SEEK_AND_RESUME, RESUME, SUSPEND };
-
 void
 MediaCache::Update()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
+  struct StreamAction
+  {
+    enum
+    {
+      NONE,
+      SEEK,
+      RESUME,
+      SUSPEND
+    } mTag = NONE;
+    // Members for 'SEEK' only.
+    bool mResume = false;
+    int64_t mSeekTarget = -1;
+  };
+
   // The action to use for each stream. We store these so we can make
   // decisions while holding the cache lock but implement those decisions
   // without holding the cache lock, since we need to call out to
   // stream, decoder and element code.
   AutoTArray<StreamAction,10> actions;
 
   {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
@@ -1245,17 +1256,17 @@ MediaCache::Update()
         latestNextUse = PredictNextUse(now, reusableBlock);
       }
     }
 
     int32_t resumeThreshold = Preferences::GetInt("media.cache_resume_threshold", 10);
     int32_t readaheadLimit = Preferences::GetInt("media.cache_readahead_limit", 30);
 
     for (uint32_t i = 0; i < mStreams.Length(); ++i) {
-      actions.AppendElement(NONE);
+      actions.AppendElement(StreamAction{});
 
       MediaCacheStream* stream = mStreams[i];
       if (stream->mClosed) {
         LOG("Stream %p closed", stream);
         continue;
       }
 
       // Figure out where we should be reading from. It's the first
@@ -1383,25 +1394,27 @@ MediaCache::Update()
         // We need to seek now.
         NS_ASSERTION(stream->mIsTransportSeekable || desiredOffset == 0,
                      "Trying to seek in a non-seekable stream!");
         // Round seek offset down to the start of the block. This is essential
         // because we don't want to think we have part of a block already
         // in mPartialBlockBuffer.
         stream->mChannelOffset =
           OffsetToBlockIndexUnchecked(desiredOffset) * BLOCK_SIZE;
-        actions[i] = stream->mCacheSuspended ? SEEK_AND_RESUME : SEEK;
+        actions[i].mTag = StreamAction::SEEK;
+        actions[i].mResume = stream->mCacheSuspended;
+        actions[i].mSeekTarget = stream->mChannelOffset;
         // mChannelOffset is updated to a new position. We don't want data from
         // the old channel to be written to the wrong position. 0 is a sentinel
         // value which will not match any ID passed to NotifyDataReceived().
         stream->mLoadID = 0;
       } else if (enableReading && stream->mCacheSuspended) {
-        actions[i] = RESUME;
+        actions[i].mTag = StreamAction::RESUME;
       } else if (!enableReading && !stream->mCacheSuspended) {
-        actions[i] = SUSPEND;
+        actions[i].mTag = StreamAction::SUSPEND;
       }
     }
 #ifdef DEBUG
     mInUpdate = false;
 #endif
   }
 
   // Update the channel state without holding our cache lock. While we're
@@ -1412,57 +1425,57 @@ MediaCache::Update()
   // the action, which can only be written by the main thread (i.e., this
   // thread), so we don't have races here.
 
   // First, update the mCacheSuspended/mCacheEnded flags so that they're all correct
   // when we fire our CacheClient commands below. Those commands can rely on these flags
   // being set correctly for all streams.
   for (uint32_t i = 0; i < mStreams.Length(); ++i) {
     MediaCacheStream* stream = mStreams[i];
-    switch (actions[i]) {
-    case SEEK:
-	case SEEK_AND_RESUME:
-      stream->mCacheSuspended = false;
-      stream->mChannelEnded = false;
-      break;
-    case RESUME:
-      stream->mCacheSuspended = false;
-      break;
-    case SUSPEND:
-      stream->mCacheSuspended = true;
-      break;
-    default:
-      break;
+    switch (actions[i].mTag) {
+      case StreamAction::SEEK:
+        stream->mCacheSuspended = false;
+        stream->mChannelEnded = false;
+        break;
+      case StreamAction::RESUME:
+        stream->mCacheSuspended = false;
+        break;
+      case StreamAction::SUSPEND:
+        stream->mCacheSuspended = true;
+        break;
+      default:
+        break;
     }
   }
 
   for (uint32_t i = 0; i < mStreams.Length(); ++i) {
     MediaCacheStream* stream = mStreams[i];
     nsresult rv;
-    switch (actions[i]) {
-    case SEEK:
-	case SEEK_AND_RESUME:
-      LOG("Stream %p CacheSeek to %" PRId64 " (resume=%d)", stream,
-          stream->mChannelOffset, actions[i] == SEEK_AND_RESUME);
-      rv = stream->mClient->CacheClientSeek(stream->mChannelOffset,
-                                            actions[i] == SEEK_AND_RESUME);
-      break;
-    case RESUME:
-      LOG("Stream %p Resumed", stream);
-      rv = stream->mClient->CacheClientResume();
-      QueueSuspendedStatusUpdate(stream->mResourceID);
-      break;
-    case SUSPEND:
-      LOG("Stream %p Suspended", stream);
-      rv = stream->mClient->CacheClientSuspend();
-      QueueSuspendedStatusUpdate(stream->mResourceID);
-      break;
-    default:
-      rv = NS_OK;
-      break;
+    switch (actions[i].mTag) {
+      case StreamAction::SEEK:
+        LOG("Stream %p CacheSeek to %" PRId64 " (resume=%d)",
+            stream,
+            actions[i].mSeekTarget,
+            actions[i].mResume);
+        rv = stream->mClient->CacheClientSeek(actions[i].mSeekTarget,
+                                              actions[i].mResume);
+        break;
+      case StreamAction::RESUME:
+        LOG("Stream %p Resumed", stream);
+        rv = stream->mClient->CacheClientResume();
+        QueueSuspendedStatusUpdate(stream->mResourceID);
+        break;
+      case StreamAction::SUSPEND:
+        LOG("Stream %p Suspended", stream);
+        rv = stream->mClient->CacheClientSuspend();
+        QueueSuspendedStatusUpdate(stream->mResourceID);
+        break;
+      default:
+        rv = NS_OK;
+        break;
     }
 
     if (NS_FAILED(rv)) {
       // Close the streams that failed due to error. This will cause all
       // client Read and Seek operations on those streams to fail. Blocked
       // Reads will also be woken up.
       stream->mClient->Close();
     }
@@ -2187,17 +2200,17 @@ MediaCacheStream::GetLength()
 {
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   return mStreamLength;
 }
 
 int64_t
 MediaCacheStream::GetOffset() const
 {
-  MOZ_ASSERT(NS_IsMainThread());
+  ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   return mChannelOffset;
 }
 
 int64_t
 MediaCacheStream::GetNextCachedData(int64_t aOffset)
 {
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   return GetNextCachedDataInternal(aOffset);
--- a/dom/media/MediaCache.h
+++ b/dom/media/MediaCache.h
@@ -455,25 +455,25 @@ private:
   // The last reported seekability state for the underlying channel
   bool mIsTransportSeekable;
   // True if the cache has suspended our channel because the cache is
   // full and the priority of the data that would be received is lower
   // than the priority of the data already in the cache
   bool mCacheSuspended;
   // True if the channel ended and we haven't seeked it again.
   bool mChannelEnded;
-  // The offset where the next data from the channel will arrive
-  int64_t      mChannelOffset;
   // The reported or discovered length of the data, or -1 if nothing is
   // known
   int64_t      mStreamLength;
 
   // The following fields are protected by the cache's monitor can can be written
   // by any thread.
 
+  // The offset where the next data from the channel will arrive
+  int64_t mChannelOffset = 0;
   // The offset where the reader is positioned in the stream
   int64_t           mStreamOffset;
   // For each block in the stream data, maps to the cache entry for the
   // block, or -1 if the block is not cached.
   nsTArray<int32_t> mBlocks;
   // The list of read-ahead blocks, ordered by stream offset; the first
   // block is the earliest in the stream (so the last block will be the
   // least valuable).
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -2818,17 +2818,17 @@ MediaFormatReader::AttemptSeek()
     MOZ_CRASH();
   }
 }
 
 void
 MediaFormatReader::OnSeekFailed(TrackType aTrack, const MediaResult& aError)
 {
   MOZ_ASSERT(OnTaskQueue());
-  LOGV("%s failure:%" PRIu32, TrackTypeToStr(aTrack), static_cast<uint32_t>(aError.Code()));
+  LOGV("%s failure:%s" PRIu32, TrackTypeToStr(aTrack), aError.ErrorName().get());
   if (aTrack == TrackType::kVideoTrack) {
     mVideo.mSeekRequest.Complete();
   } else {
     mAudio.mSeekRequest.Complete();
   }
 
   if (aError == NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA) {
     if (HasVideo() &&
--- a/dom/media/MediaResult.h
+++ b/dom/media/MediaResult.h
@@ -37,30 +37,37 @@ public:
   {
   }
   MediaResult(const MediaResult& aOther) = default;
   MediaResult(MediaResult&& aOther) = default;
   MediaResult& operator=(const MediaResult& aOther) = default;
   MediaResult& operator=(MediaResult&& aOther) = default;
 
   nsresult Code() const { return mCode; }
+  nsCString ErrorName() const
+  {
+    nsCString name;
+    GetErrorName(mCode, name);
+    return name;
+  }
+
   const nsCString& Message() const { return mMessage; }
 
   // Interoperations with nsresult.
   bool operator==(nsresult aResult) const { return aResult == mCode; }
   bool operator!=(nsresult aResult) const { return aResult != mCode; }
   operator nsresult () const { return mCode; }
 
   nsCString Description() const
   {
     if (NS_SUCCEEDED(mCode)) {
       return nsCString();
     }
     nsCString name;
-    GetErrorName(mCode, static_cast<nsACString&>(name));
+    GetErrorName(mCode, name);
     return nsPrintfCString("%s (0x%08" PRIx32 ")%s%s",
                            name.get(),
                            static_cast<uint32_t>(mCode),
                            mMessage.IsEmpty() ? "" : " - ",
                            mMessage.get());
   }
 
   void SetGPUCrashTimeStamp(const TimeStamp& aTime) { mGPUCrashTimeStamp = aTime; }
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -206,16 +206,19 @@ TrackBuffersManager::ProcessTasks()
     case Type::Reset:
       CompleteResetParserState();
       break;
     case Type::Detach:
       mCurrentInputBuffer = nullptr;
       mTaskQueue = nullptr;
       MOZ_DIAGNOSTIC_ASSERT(mQueue.Length() == 0,
                             "Detach task must be the last");
+      mVideoTracks.Reset();
+      mAudioTracks.Reset();
+      ShutdownDemuxers();
       return;
     default:
       NS_WARNING("Invalid Task");
   }
   GetTaskQueue()->Dispatch(
     NewRunnableMethod("TrackBuffersManager::ProcessTasks",
                       this,
                       &TrackBuffersManager::ProcessTasks));
--- a/dom/media/mediasource/TrackBuffersManager.h
+++ b/dom/media/mediasource/TrackBuffersManager.h
@@ -371,18 +371,30 @@ private:
     EvictionIndex mEvictionIndex;
 
     void ResetAppendState()
     {
       mLastDecodeTimestamp.reset();
       mLastFrameDuration.reset();
       mHighestEndTimestamp.reset();
       mNeedRandomAccessPoint = true;
+      mNextInsertionIndex.reset();
+    }
 
-      mNextInsertionIndex.reset();
+    void Reset()
+    {
+      ResetAppendState();
+      mEvictionIndex.Reset();
+      for (auto& buffer : mBuffers) {
+        buffer.Clear();
+      }
+      mSizeBuffer = 0;
+      mNextGetSampleIndex.reset();
+      mBufferedRanges.Clear();
+      mSanitizedBufferedRanges.Clear();
     }
 
     void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes) const;
   };
 
   void CheckSequenceDiscontinuity(const media::TimeUnit& aPresentationTime);
   void ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData);
   media::TimeInterval PresentationInterval(const TrackBuffer& aSamples) const;
--- a/dom/media/mediasource/test/mochitest.ini
+++ b/dom/media/mediasource/test/mochitest.ini
@@ -104,16 +104,17 @@ skip-if = toolkit == 'android' # Not sup
 [test_OnEvents.html]
 skip-if = android_version == '22' # bug 1359010
 [test_PlayEvents.html]
 skip-if = toolkit == 'android' # Not supported on android
 [test_PlayEventsAutoPlaying.html]
 skip-if = toolkit == 'android' # Not supported on android
 [test_PlayEventsAutoPlaying2.html]
 skip-if = toolkit == 'android' # Not supported on android
+[test_RemoveSourceBuffer.html]
 [test_ResumeAfterClearing_mp4.html]
 skip-if = toolkit == 'android' # Not supported on android
 [test_SeekableAfterEndOfStream.html]
 [test_SeekableAfterEndOfStream_mp4.html]
 skip-if = toolkit == 'android' # Not supported on android
 [test_SeekableAfterEndOfStreamSplit.html]
 [test_SeekableAfterEndOfStreamSplit_mp4.html]
 skip-if = toolkit == 'android' # Not supported on android
new file mode 100644
--- /dev/null
+++ b/dom/media/mediasource/test/test_RemoveSourceBuffer.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">
+  <title>MSE: check buffered status after removed all source buffer</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="mediasource.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test"><script class="testbody" type="text/javascript">
+
+var videoURL = "seek.webm";
+
+SimpleTest.waitForExplicitFinish();
+
+runWithMSE(async function(ms, el) {
+  info("- wait for sourceopen -");
+  await once(ms, 'sourceopen');
+
+  info("- wait for fetching data -");
+  var arrayBuffer = await fetchWithXHR(videoURL);
+
+  info("- create source buffer and append data -");
+  var sourceBuffer = ms.addSourceBuffer("video/webm");
+  sourceBuffer.appendBuffer(arrayBuffer);
+  await once(sourceBuffer, "updateend");
+  is(ms.sourceBuffers.length, 1,
+     "the length of source buffers list is 1.");
+  is(ms.activeSourceBuffers.length, 1,
+     "the length of active source buffers list is 1.");
+  ok(ms.duration != 0, "duration is not 0.");
+  is(el.buffered.length, 1, "buffered range is 1.");
+
+  info("- remove source buffer from media source -");
+  ms.removeSourceBuffer(sourceBuffer);
+  await once(ms.sourceBuffers, "removesourcebuffer");
+  is(ms.sourceBuffers.length, 0, "source buffers list is empty.");
+  is(ms.activeSourceBuffers.length, 0, "active source buffers list is empty.");
+  ok(ms.duration != 0, "duration is not 0.");
+  is(el.buffered.length, 0,
+     "buffered range is empty since we don't have any source buffer.");
+
+  info("- call endOfStream -");
+  ms.endOfStream();
+  is(ms.duration, 0, "duraton is 0 since we don't have any source buffer.");
+  SimpleTest.finish();
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -67,16 +67,21 @@ struct gfxFontStyle;
 
 struct CGContext;
 typedef struct CGContext *CGContextRef;
 
 namespace mozilla {
 
 class Mutex;
 
+namespace wr {
+struct WrFontInstanceOptions;
+struct FontInstancePlatformOptions;
+}
+
 namespace gfx {
 class UnscaledFont;
 class ScaledFont;
 }
 
 template<>
 struct WeakPtrTraits<gfx::UnscaledFont>
 {
@@ -765,17 +770,19 @@ public:
 
   virtual bool GetFontInstanceData(FontInstanceDataOutput, void *) { return false; }
 
   virtual bool GetFontDescriptor(FontDescriptorOutput, void *) { return false; }
 
   virtual already_AddRefed<ScaledFont>
     CreateScaledFont(Float aGlyphSize,
                      const uint8_t* aInstanceData,
-                     uint32_t aInstanceDataLength)
+                     uint32_t aInstanceDataLength,
+                     const FontVariation* aVariations,
+                     uint32_t aNumVariations)
   {
     return nullptr;
   }
 
 protected:
   UnscaledFont() {}
 
 private:
@@ -815,20 +822,29 @@ public:
    * others.
    */
   virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint = nullptr) = 0;
 
   /* This gets the metrics of a set of glyphs for the current font face.
    */
   virtual void GetGlyphDesignMetrics(const uint16_t* aGlyphIndices, uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics) = 0;
 
-  typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength, void* aBaton);
+  typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength,
+                                         const FontVariation* aVariations, uint32_t aNumVariations,
+                                         void* aBaton);
 
   virtual bool GetFontInstanceData(FontInstanceDataOutput, void *) { return false; }
 
+  virtual bool GetWRFontInstanceOptions(Maybe<wr::WrFontInstanceOptions>* aOutOptions,
+                                        Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
+                                        std::vector<FontVariation>* aOutVariations)
+  {
+    return false;
+  }
+
   virtual bool CanSerialize() { return false; }
 
   void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
     mUserData.Add(key, userData, destroy);
   }
   void *GetUserData(UserDataKey *key) {
     return mUserData.Get(key);
   }
--- a/gfx/2d/RecordedEventImpl.h
+++ b/gfx/2d/RecordedEventImpl.h
@@ -1018,20 +1018,22 @@ private:
 
   template<class S>
   MOZ_IMPLICIT RecordedUnscaledFontDestruction(S &aStream);
 };
 
 class RecordedScaledFontCreation : public RecordedEventDerived<RecordedScaledFontCreation> {
 public:
 
-  static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize, void* aBaton)
+  static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
+                                   const FontVariation* aVariations, uint32_t aNumVariations,
+                                   void* aBaton)
   {
     auto recordedScaledFontCreation = static_cast<RecordedScaledFontCreation*>(aBaton);
-    recordedScaledFontCreation->SetFontInstanceData(aData, aSize);
+    recordedScaledFontCreation->SetFontInstanceData(aData, aSize, aVariations, aNumVariations);
   }
 
   RecordedScaledFontCreation(ScaledFont* aScaledFont,
                              UnscaledFont* aUnscaledFont)
     : RecordedEventDerived(SCALEDFONTCREATION)
     , mRefPtr(aScaledFont)
     , mUnscaledFont(aUnscaledFont)
     , mGlyphSize(aScaledFont->GetSize())
@@ -1042,25 +1044,27 @@ public:
   virtual bool PlayEvent(Translator *aTranslator) const;
 
   template<class S> void Record(S &aStream) const;
   virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
   
   virtual std::string GetName() const { return "ScaledFont Creation"; }
   virtual ReferencePtr GetObjectRef() const { return mRefPtr; }
 
-  void SetFontInstanceData(const uint8_t *aData, uint32_t aSize);
+  void SetFontInstanceData(const uint8_t *aData, uint32_t aSize,
+                           const FontVariation* aVariations, uint32_t aNumVariations);
 
 private:
   friend class RecordedEvent;
 
   ReferencePtr mRefPtr;
   ReferencePtr mUnscaledFont;
   Float mGlyphSize;
   std::vector<uint8_t> mInstanceData;
+  std::vector<FontVariation> mVariations;
 
   template<class S>
   MOZ_IMPLICIT RecordedScaledFontCreation(S &aStream);
 };
 
 class RecordedScaledFontDestruction : public RecordedEventDerived<RecordedScaledFontDestruction> {
 public:
   MOZ_IMPLICIT RecordedScaledFontDestruction(ReferencePtr aRefPtr)
@@ -2890,56 +2894,66 @@ RecordedScaledFontCreation::PlayEvent(Tr
   UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
   if (!unscaledFont) {
     gfxDevCrash(LogReason::UnscaledFontNotFound) <<
       "UnscaledFont lookup failed for key |" << hexa(mUnscaledFont) << "|.";
     return false;
   }
 
   RefPtr<ScaledFont> scaledFont =
-    unscaledFont->CreateScaledFont(mGlyphSize, mInstanceData.data(), mInstanceData.size());
+    unscaledFont->CreateScaledFont(mGlyphSize,
+                                   mInstanceData.data(), mInstanceData.size(),
+                                   mVariations.data(), mVariations.size());
   aTranslator->AddScaledFont(mRefPtr, scaledFont);
   return true;
 }
 
 template<class S>
 void
 RecordedScaledFontCreation::Record(S &aStream) const
 {
   WriteElement(aStream, mRefPtr);
   WriteElement(aStream, mUnscaledFont);
   WriteElement(aStream, mGlyphSize);
   WriteElement(aStream, (size_t)mInstanceData.size());
   aStream.write((char*)mInstanceData.data(), mInstanceData.size());
+  WriteElement(aStream, (size_t)mVariations.size());
+  aStream.write((char*)mVariations.data(), sizeof(FontVariation) * mVariations.size());
 }
 
 inline void
 RecordedScaledFontCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] ScaledFont Created";
 }
 
 inline void
-RecordedScaledFontCreation::SetFontInstanceData(const uint8_t *aData, uint32_t aSize)
+RecordedScaledFontCreation::SetFontInstanceData(const uint8_t *aData, uint32_t aSize,
+                                                const FontVariation* aVariations, uint32_t aNumVariations)
 {
   mInstanceData.assign(aData, aData + aSize);
+  mVariations.assign(aVariations, aVariations + aNumVariations);
 }
 
 template<class S>
 RecordedScaledFontCreation::RecordedScaledFontCreation(S &aStream)
   : RecordedEventDerived(SCALEDFONTCREATION)
 {
   ReadElement(aStream, mRefPtr);
   ReadElement(aStream, mUnscaledFont);
   ReadElement(aStream, mGlyphSize);
 
   size_t size;
   ReadElement(aStream, size);
   mInstanceData.resize(size);
   aStream.read((char*)mInstanceData.data(), size);
+  size_t numVariations;
+  ReadElement(aStream, numVariations);
+  mVariations.resize(numVariations);
+  aStream.read((char*)mVariations.data(), sizeof(FontVariation) * numVariations);
 }
 
 inline bool
 RecordedScaledFontDestruction::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->RemoveScaledFont(mRefPtr);
   return true;
 }
--- a/gfx/2d/ScaledFontDWrite.cpp
+++ b/gfx/2d/ScaledFontDWrite.cpp
@@ -291,24 +291,26 @@ UnscaledFontDWrite::GetFontFileData(Font
 
   return true;
 }
 
 bool
 ScaledFontDWrite::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
 {
   InstanceData instance(this);
-  aCb(reinterpret_cast<uint8_t*>(&instance), sizeof(instance), aBaton);
+  aCb(reinterpret_cast<uint8_t*>(&instance), sizeof(instance), nullptr, 0, aBaton);
   return true;
 }
 
 already_AddRefed<ScaledFont>
 UnscaledFontDWrite::CreateScaledFont(Float aGlyphSize,
                                      const uint8_t* aInstanceData,
-                                     uint32_t aInstanceDataLength)
+                                     uint32_t aInstanceDataLength,
+                                     const FontVariation* aVariations,
+                                     uint32_t aNumVariations)
 {
   if (aInstanceDataLength < sizeof(ScaledFontDWrite::InstanceData)) {
     gfxWarning() << "DWrite scaled font instance data is truncated.";
     return nullptr;
   }
 
   const ScaledFontDWrite::InstanceData *instanceData =
     reinterpret_cast<const ScaledFontDWrite::InstanceData*>(aInstanceData);
--- a/gfx/2d/ScaledFontFontconfig.cpp
+++ b/gfx/2d/ScaledFontFontconfig.cpp
@@ -222,24 +222,26 @@ ScaledFontFontconfig::InstanceData::Setu
   cairo_matrix_init(aFontMatrix, mScale, 0, mSkew, mScale, 0, 0);
 }
 
 bool
 ScaledFontFontconfig::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
 {
   InstanceData instance(GetCairoScaledFont(), mPattern);
 
-  aCb(reinterpret_cast<uint8_t*>(&instance), sizeof(instance), aBaton);
+  aCb(reinterpret_cast<uint8_t*>(&instance), sizeof(instance), nullptr, 0, aBaton);
   return true;
 }
 
 already_AddRefed<ScaledFont>
 UnscaledFontFontconfig::CreateScaledFont(Float aGlyphSize,
                                          const uint8_t* aInstanceData,
-                                         uint32_t aInstanceDataLength)
+                                         uint32_t aInstanceDataLength,
+                                         const FontVariation* aVariations,
+                                         uint32_t aNumVariations)
 {
   if (aInstanceDataLength < sizeof(ScaledFontFontconfig::InstanceData)) {
     gfxWarning() << "Fontconfig scaled font instance data is truncated.";
     return nullptr;
   }
   const ScaledFontFontconfig::InstanceData *instanceData =
     reinterpret_cast<const ScaledFontFontconfig::InstanceData*>(aInstanceData);
   return ScaledFontFontconfig::CreateFromInstanceData(*instanceData, this, aGlyphSize,
--- a/gfx/2d/ScaledFontMac.cpp
+++ b/gfx/2d/ScaledFontMac.cpp
@@ -230,34 +230,16 @@ struct writeBuf
             this->offset++;
         }
     }
 
     unsigned char *data;
     int offset;
 };
 
-static void CollectVariationSetting(const void *key, const void *value, void *context)
-{
-  auto keyPtr = static_cast<const CFTypeRef>(key);
-  auto valuePtr = static_cast<const CFTypeRef>(value);
-  auto vpp = static_cast<FontVariation**>(context);
-  if (CFGetTypeID(keyPtr) == CFNumberGetTypeID() &&
-      CFGetTypeID(valuePtr) == CFNumberGetTypeID()) {
-    uint64_t t;
-    double v;
-    if (CFNumberGetValue(static_cast<CFNumberRef>(keyPtr), kCFNumberSInt64Type, &t) &&
-        CFNumberGetValue(static_cast<CFNumberRef>(valuePtr), kCFNumberDoubleType, &v)) {
-      (*vpp)->mTag = t;
-      (*vpp)->mValue = v;
-      (*vpp)++;
-    }
-  }
-}
-
 bool
 UnscaledFontMac::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
 {
     // We'll reconstruct a TTF font from the tables we can get from the CGFont
     CFArrayRef tags = CGFontCopyTableTags(mFont);
     CFIndex count = CFArrayGetCount(tags);
 
     TableRecord *records = new TableRecord[count];
@@ -322,43 +304,73 @@ UnscaledFontMac::GetFontFileData(FontFil
     memcpy(&buf.data[checkSumAdjustmentOffset], &fontChecksum, sizeof(fontChecksum));
 
     // we always use an index of 0
     aDataCallback(buf.data, buf.offset, 0, aBaton);
 
     return true;
 }
 
+static void
+CollectVariationsFromDictionary(const void* aKey, const void* aValue, void* aContext)
+{
+  auto keyPtr = static_cast<const CFTypeRef>(aKey);
+  auto valuePtr = static_cast<const CFTypeRef>(aValue);
+  auto outVariations = static_cast<std::vector<FontVariation>*>(aContext);
+  if (CFGetTypeID(keyPtr) == CFNumberGetTypeID() &&
+      CFGetTypeID(valuePtr) == CFNumberGetTypeID()) {
+    uint64_t t;
+    double v;
+    if (CFNumberGetValue(static_cast<CFNumberRef>(keyPtr), kCFNumberSInt64Type, &t) &&
+        CFNumberGetValue(static_cast<CFNumberRef>(valuePtr), kCFNumberDoubleType, &v)) {
+      outVariations->push_back(FontVariation{uint32_t(t), float(v)});
+    }
+  }
+}
+
+static bool
+GetVariationsForCTFont(CTFontRef aCTFont, std::vector<FontVariation>* aOutVariations)
+{
+  // Avoid calling potentially buggy variation APIs on pre-Sierra macOS
+  // versions (see bug 1331683)
+  if (!nsCocoaFeatures::OnSierraOrLater()) {
+    return true;
+  }
+  if (!aCTFont) {
+    return true;
+  }
+  AutoRelease<CFDictionaryRef> dict(CTFontCopyVariation(aCTFont));
+  CFIndex count = dict ? CFDictionaryGetCount(dict) : 0;
+  if (count > 0) {
+    aOutVariations->reserve(count);
+    CFDictionaryApplyFunction(dict, CollectVariationsFromDictionary, aOutVariations);
+  }
+  return true;
+}
+
 bool
 ScaledFontMac::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
 {
     // Collect any variation settings that were incorporated into the CTFont.
-    uint32_t variationCount = 0;
-    FontVariation* variations = nullptr;
-    // Avoid calling potentially buggy variation APIs on pre-Sierra macOS
-    // versions (see bug 1331683)
-    if (nsCocoaFeatures::OnSierraOrLater()) {
-      if (mCTFont) {
-        CFDictionaryRef dict = CTFontCopyVariation(mCTFont);
-        if (dict) {
-          CFIndex count = CFDictionaryGetCount(dict);
-          if (count > 0) {
-            variations = new FontVariation[count];
-            FontVariation* vPtr = variations;
-            CFDictionaryApplyFunction(dict, CollectVariationSetting, &vPtr);
-            variationCount = vPtr - variations;
-          }
-          CFRelease(dict);
-        }
-      }
+    std::vector<FontVariation> variations;
+    if (!GetVariationsForCTFont(mCTFont, &variations)) {
+      return false;
     }
+    aCb(nullptr, 0, variations.data(), variations.size(), aBaton);
+    return true;
+}
 
-    aCb(reinterpret_cast<uint8_t*>(variations), variationCount * sizeof(FontVariation), aBaton);
-    delete[] variations;
-
+bool
+ScaledFontMac::GetWRFontInstanceOptions(Maybe<wr::WrFontInstanceOptions>* aOutOptions,
+                                        Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
+                                        std::vector<FontVariation>* aOutVariations)
+{
+    if (!GetVariationsForCTFont(mCTFont, aOutVariations)) {
+      return false;
+    }
     return true;
 }
 
 static CFDictionaryRef
 CreateVariationDictionaryOrNull(CGFontRef aCGFont, uint32_t aVariationCount,
                                 const FontVariation* aVariations)
 {
   // Avoid calling potentially buggy variation APIs on pre-Sierra macOS
@@ -473,27 +485,25 @@ UnscaledFontMac::CreateCGFontWithVariati
   }
 
   return CGFontCreateCopyWithVariations(aFont, varDict);
 }
 
 already_AddRefed<ScaledFont>
 UnscaledFontMac::CreateScaledFont(Float aGlyphSize,
                                   const uint8_t* aInstanceData,
-                                  uint32_t aInstanceDataLength)
+                                  uint32_t aInstanceDataLength,
+                                  const FontVariation* aVariations,
+                                  uint32_t aNumVariations)
+
 {
-  uint32_t variationCount =
-    aInstanceDataLength / sizeof(FontVariation);
-  const FontVariation* variations =
-    reinterpret_cast<const FontVariation*>(aInstanceData);
-
   CGFontRef fontRef = mFont;
-  if (variationCount > 0) {
+  if (aNumVariations > 0) {
     CGFontRef varFont =
-      CreateCGFontWithVariations(mFont, variationCount, variations);
+      CreateCGFontWithVariations(mFont, aNumVariations, aVariations);
     if (varFont) {
       fontRef = varFont;
     }
   }
 
   RefPtr<ScaledFontMac> scaledFont =
     new ScaledFontMac(fontRef, this, aGlyphSize, fontRef != mFont);
 
--- a/gfx/2d/ScaledFontMac.h
+++ b/gfx/2d/ScaledFontMac.h
@@ -47,16 +47,20 @@ public:
   FontType GetType() const override { return FontType::MAC; }
 #ifdef USE_SKIA
   SkTypeface* GetSkTypeface() override;
 #endif
   already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) override;
 
   bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
 
+  bool GetWRFontInstanceOptions(Maybe<wr::WrFontInstanceOptions>* aOutOptions,
+                                Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
+                                std::vector<FontVariation>* aOutVariations) override;
+
   bool CanSerialize() override { return true; }
 
 #ifdef USE_CAIRO_SCALED_FONT
   cairo_font_face_t* GetCairoFontFace() override;
 #endif
 
 private:
   friend class DrawTargetSkia;
--- a/gfx/2d/ScaledFontWin.cpp
+++ b/gfx/2d/ScaledFontWin.cpp
@@ -59,17 +59,17 @@ UnscaledFontGDI::GetFontFileData(FontFil
 
   aDataCallback(fontData.get(), tableSize, 0, aBaton);
   return true;
 }
 
 bool
 ScaledFontWin::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
 {
-  aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), aBaton);
+  aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), nullptr, 0, aBaton);
   return true;
 }
 
 bool
 UnscaledFontGDI::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
 {
   aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), aBaton);
   return true;
@@ -93,17 +93,19 @@ UnscaledFontGDI::CreateFromFontDescripto
   const LOGFONT* logFont = reinterpret_cast<const LOGFONT*>(aData);
   RefPtr<UnscaledFont> unscaledFont = new UnscaledFontGDI(*logFont);
   return unscaledFont.forget();
 }
 
 already_AddRefed<ScaledFont>
 UnscaledFontGDI::CreateScaledFont(Float aGlyphSize,
                                   const uint8_t* aInstanceData,
-                                  uint32_t aInstanceDataLength)
+                                  uint32_t aInstanceDataLength,
+                                  const FontVariation* aVariations,
+                                  uint32_t aNumVariations)
 {
   if (aInstanceDataLength < sizeof(LOGFONT)) {
     gfxWarning() << "GDI unscaled font instance data is truncated.";
     return nullptr;
   }
 
   NativeFont nativeFont;
   nativeFont.mType = NativeFontType::GDI_FONT_FACE;
--- a/gfx/2d/UnscaledFontDWrite.h
+++ b/gfx/2d/UnscaledFontDWrite.h
@@ -31,17 +31,19 @@ public:
   const RefPtr<IDWriteFontFace> GetFontFace() const { return mFontFace; }
   DWRITE_FONT_SIMULATIONS GetSimulations() const { return mSimulations; }
 
   bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) override;
 
   already_AddRefed<ScaledFont>
     CreateScaledFont(Float aGlyphSize,
                      const uint8_t* aInstanceData,
-                     uint32_t aInstanceDataLength) override;
+                     uint32_t aInstanceDataLength,
+                     const FontVariation* aVariations,
+                     uint32_t aNumVariations) override;
 
 private:
   RefPtr<IDWriteFontFace> mFontFace;
   DWRITE_FONT_SIMULATIONS mSimulations;
   bool mNeedsCairo;
 };
 
 } // namespace gfx
--- a/gfx/2d/UnscaledFontFreeType.h
+++ b/gfx/2d/UnscaledFontFreeType.h
@@ -82,17 +82,19 @@ public:
   FontType GetType() const override { return FontType::FONTCONFIG; }
 
   static already_AddRefed<UnscaledFont>
     CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength);
 
   already_AddRefed<ScaledFont>
     CreateScaledFont(Float aGlyphSize,
                      const uint8_t* aInstanceData,
-                     uint32_t aInstanceDataLength) override;
+                     uint32_t aInstanceDataLength,
+                     const FontVariation* aVariations,
+                     uint32_t aNumVariations) override;
 
 private:
   RefPtr<NativeFontResource> mNativeFontResource;
 };
 #endif
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/UnscaledFontGDI.h
+++ b/gfx/2d/UnscaledFontGDI.h
@@ -31,17 +31,19 @@ public:
   bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
 
   static already_AddRefed<UnscaledFont>
     CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength);
 
   already_AddRefed<ScaledFont>
     CreateScaledFont(Float aGlyphSize,
                      const uint8_t* aInstanceData,
-                     uint32_t aInstanceDataLength) override;
+                     uint32_t aInstanceDataLength,
+                     const FontVariation* aVariations,
+                     uint32_t aNumVariations) override;
 
 private:
   LOGFONT mLogFont;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
--- a/gfx/2d/UnscaledFontMac.h
+++ b/gfx/2d/UnscaledFontMac.h
@@ -36,17 +36,19 @@ public:
 
   CGFontRef GetFont() const { return mFont; }
 
   bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) override;
 
   already_AddRefed<ScaledFont>
     CreateScaledFont(Float aGlyphSize,
                      const uint8_t* aInstanceData,
-                     uint32_t aInstanceDataLength) override;
+                     uint32_t aInstanceDataLength,
+                     const FontVariation* aVariations,
+                     uint32_t aNumVariations) override;
 
   static CGFontRef
     CreateCGFontWithVariations(CGFontRef aFont,
                                uint32_t aVariationCount,
                                const FontVariation* aVariations);
 
 private:
   CGFontRef mFont;
--- a/gfx/doc/README.webrender
+++ b/gfx/doc/README.webrender
@@ -74,9 +74,10 @@ there is another crate in m-c called moz
 the same folder to store its rust dependencies. If one of the libraries that is
 required by both mozjs_sys and webrender is updated without updating the other
 project's Cargo.lock file, that results in build bustage.
 This means that any time you do this sort of manual update of packages, you need
 to make sure that mozjs_sys also has its Cargo.lock file updated if needed, hence
 the need to run the cargo update command in js/src as well. Hopefully this will
 be resolved soon.
 
-Latest Commit: 68e2e7cd0e39d216bb6c35dfb353dc0700bb6948
+Latest Commit: 7a5f60aff33010a44d6acbdc67f27f1f63678b5d
+
--- a/gfx/layers/ipc/WebRenderMessages.ipdlh
+++ b/gfx/layers/ipc/WebRenderMessages.ipdlh
@@ -110,17 +110,18 @@ struct OpAddRawFont {
 };
 
 struct OpDeleteFont {
   FontKey key;
 };
 
 struct OpAddFontInstance {
   MaybeFontInstanceOptions options;
-  MaybeFontInstancePlatformOptions platformOptions ;
+  MaybeFontInstancePlatformOptions platformOptions;
+  OffsetRange variations;
   FontInstanceKey instanceKey;
   FontKey fontKey;
   float glyphSize;
 };
 
 struct OpDeleteFontInstance {
   FontInstanceKey key;
 };
--- a/gfx/layers/wr/IpcResourceUpdateQueue.cpp
+++ b/gfx/layers/wr/IpcResourceUpdateQueue.cpp
@@ -277,21 +277,24 @@ IpcResourceUpdateQueue::DeleteFont(wr::F
   mUpdates.AppendElement(layers::OpDeleteFont(aKey));
 }
 
 void
 IpcResourceUpdateQueue::AddFontInstance(wr::FontInstanceKey aKey,
                                         wr::FontKey aFontKey,
                                         float aGlyphSize,
                                         const wr::FontInstanceOptions* aOptions,
-                                        const wr::FontInstancePlatformOptions* aPlatformOptions)
+                                        const wr::FontInstancePlatformOptions* aPlatformOptions,
+                                        Range<const gfx::FontVariation> aVariations)
 {
+  auto bytes = mWriter.WriteAsBytes(aVariations);
   mUpdates.AppendElement(layers::OpAddFontInstance(
     aOptions ? Some(*aOptions) : Nothing(),
     aPlatformOptions ? Some(*aPlatformOptions) : Nothing(),
+    bytes,
     aKey, aFontKey,
     aGlyphSize
   ));
 }
 
 void
 IpcResourceUpdateQueue::DeleteFontInstance(wr::FontInstanceKey aKey)
 {
--- a/gfx/layers/wr/IpcResourceUpdateQueue.h
+++ b/gfx/layers/wr/IpcResourceUpdateQueue.h
@@ -18,16 +18,22 @@ namespace wr {
 /// allocations and creates dedicated shmems for large allocations.
 class ShmSegmentsWriter {
 public:
   ShmSegmentsWriter(ipc::IShmemAllocator* aAllocator, size_t aChunkSize);
   ~ShmSegmentsWriter();
 
   layers::OffsetRange Write(Range<uint8_t> aBytes);
 
+  template<typename T>
+  layers::OffsetRange WriteAsBytes(Range<T> aValues)
+  {
+    return Write(Range<uint8_t>((uint8_t*)aValues.begin().get(), aValues.length() * sizeof(T)));
+  }
+
   void Flush(nsTArray<ipc::Shmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs);
 
   void Clear();
 
 protected:
   void AllocChunk();
   layers::OffsetRange AllocLargeChunk(size_t aSize);
 
@@ -90,17 +96,18 @@ public:
   void AddRawFont(wr::FontKey aKey, Range<uint8_t> aBytes, uint32_t aIndex);
 
   void DeleteFont(wr::FontKey aKey);
 
   void AddFontInstance(wr::FontInstanceKey aKey,
                        wr::FontKey aFontKey,
                        float aGlyphSize,
                        const wr::FontInstanceOptions* aOptions,
-                       const wr::FontInstancePlatformOptions* aPlatformOptions);
+                       const wr::FontInstancePlatformOptions* aPlatformOptions,
+                       Range<const gfx::FontVariation> aVariations);
 
   void DeleteFontInstance(wr::FontInstanceKey aKey);
 
   void Clear();
 
   void Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
              nsTArray<ipc::Shmem>& aSmallAllocs,
              nsTArray<ipc::Shmem>& aLargeAllocs);
--- a/gfx/layers/wr/ScrollingLayersHelper.cpp
+++ b/gfx/layers/wr/ScrollingLayersHelper.cpp
@@ -221,25 +221,27 @@ ScrollingLayersHelper::DefineAndPushChai
   // pushed onto the WR clip stack. Note that the recursion can invalidate the
   // iterator `it`.
   DefineAndPushChain(aChain->mParent, aBuilder, aStackingContext, aAppUnitsPerDevPixel, aCache);
 
   if (!aChain->mClip.HasClip()) {
     // This item in the chain is a no-op, skip over it
     return;
   }
-  if (!clipId) {
+  if (!clipId || aBuilder.HasMaskClip()) {
     // If we don't have a clip id for this chain item yet, define the clip in WR
     // and save the id
     LayoutDeviceRect clip = LayoutDeviceRect::FromAppUnits(
         aChain->mClip.GetClipRect(), aAppUnitsPerDevPixel);
     nsTArray<wr::WrComplexClipRegion> wrRoundedRects;
     aChain->mClip.ToWrComplexClipRegions(aAppUnitsPerDevPixel, aStackingContext, wrRoundedRects);
     clipId = Some(aBuilder.DefineClip(aStackingContext.ToRelativeLayoutRect(clip), &wrRoundedRects));
-    aCache[aChain] = clipId.value();
+    if (!aBuilder.HasMaskClip()) {
+      aCache[aChain] = clipId.value();
+    }
   }
   // Finally, push the clip onto the WR stack
   MOZ_ASSERT(clipId);
   aBuilder.PushClip(clipId.value());
   mPushedClips.push_back(wr::ScrollOrClipId(clipId.value()));
 }
 
 bool
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -308,17 +308,24 @@ WebRenderBridgeChild::GetFontKeyForScale
     resources.AddRawFont(fontKey, data.mFontBuffer.AsSlice(), data.mFontIndex);
 
     mFontKeys.Put(unscaled, fontKey);
   }
 
   instanceKey.mNamespace = GetNamespace();
   instanceKey.mHandle = GetNextResourceId();
 
-  resources.AddFontInstance(instanceKey, fontKey, aScaledFont->GetSize(), nullptr, nullptr);
+  Maybe<wr::FontInstanceOptions> options;
+  Maybe<wr::FontInstancePlatformOptions> platformOptions;
+  std::vector<FontVariation> variations;
+  aScaledFont->GetWRFontInstanceOptions(&options, &platformOptions, &variations);
+
+  resources.AddFontInstance(instanceKey, fontKey, aScaledFont->GetSize(),
+                            options.ptrOr(nullptr), platformOptions.ptrOr(nullptr),
+                            Range<const FontVariation>(variations.data(), variations.size()));
   UpdateResources(resources);
 
   mFontInstanceKeys.Put(aScaledFont, instanceKey);
 
   return instanceKey;
 }
 
 void
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -292,20 +292,25 @@ WebRenderBridgeParent::UpdateResources(c
         if (!reader.Read(op.bytes(), bytes)) {
           return false;
         }
         aUpdates.AddRawFont(op.key(), bytes, op.fontIndex());
         break;
       }
       case OpUpdateResource::TOpAddFontInstance: {
         const auto& op = cmd.get_OpAddFontInstance();
+        wr::Vec_u8 variations;
+        if (!reader.Read(op.variations(), variations)) {
+            return false;
+        }
         aUpdates.AddFontInstance(op.instanceKey(), op.fontKey(),
                                  op.glyphSize(),
                                  op.options().ptrOr(nullptr),
-                                 op.platformOptions().ptrOr(nullptr));
+                                 op.platformOptions().ptrOr(nullptr),
+                                 variations);
         break;
       }
       case OpUpdateResource::TOpDeleteImage: {
         const auto& op = cmd.get_OpDeleteImage();
         aUpdates.DeleteImage(op.key());
         break;
       }
       case OpUpdateResource::TOpDeleteFont: {
--- a/gfx/webrender/Cargo.toml
+++ b/gfx/webrender/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "webrender"
-version = "0.50.0"
+version = "0.52.0"
 authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
 license = "MPL-2.0"
 repository = "https://github.com/servo/webrender"
 build = "build.rs"
 
 [features]
 default = ["freetype-lib"]
 freetype-lib = ["freetype/servo-freetype-sys"]
@@ -31,21 +31,22 @@ plane-split = "0.6"
 ws = { optional = true, version = "0.7.3" }
 serde_json = { optional = true, version = "1.0" }
 serde = { optional = true, version = "1.0" }
 serde_derive = { optional = true, version = "1.0" }
 
 [dev-dependencies]
 angle = {git = "https://github.com/servo/angle", branch = "servo"}
 rand = "0.3"                # for the benchmarks
-servo-glutin = "0.11"     # for the example apps
+servo-glutin = "0.12"     # for the example apps
 
 [target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
 freetype = { version = "0.3", default-features = false }
 
 [target.'cfg(target_os = "windows")'.dependencies]
 dwrote = "0.4"
 gamma-lut = "0.2"
 
 [target.'cfg(target_os = "macos")'.dependencies]
-core-graphics = "0.8.0"
-core-text = { version = "6.1", default-features = false }
+core-foundation = "0.4"
+core-graphics = "0.9"
+core-text = { version = "7.0", default-features = false }
 gamma-lut = "0.2"
--- a/gfx/webrender/examples/basic.rs
+++ b/gfx/webrender/examples/basic.rs
@@ -251,17 +251,17 @@ impl Example for App {
 
         if false {
             // draw text?
             let font_key = api.generate_font_key();
             let font_bytes = load_file("res/FreeSans.ttf");
             resources.add_raw_font(font_key, font_bytes, 0);
 
             let font_instance_key = api.generate_font_instance_key();
-            resources.add_font_instance(font_instance_key, font_key, Au::from_px(32), None, None);
+            resources.add_font_instance(font_instance_key, font_key, Au::from_px(32), None, None, Vec::new());
 
             let text_bounds = (100, 200).by(700, 300);
             let glyphs = vec![
                 GlyphInstance {
                     index: 48,
                     point: LayoutPoint::new(100.0, 100.0),
                 },
                 GlyphInstance {
--- a/gfx/webrender/examples/common/boilerplate.rs
+++ b/gfx/webrender/examples/common/boilerplate.rs
@@ -211,16 +211,38 @@ pub fn main_wrapper(example: &mut Exampl
                 ) => {
                     let mut flags = renderer.get_debug_flags();
                     flags.toggle(webrender::ALPHA_PRIM_DBG);
                     renderer.set_debug_flags(flags);
                 }
                 glutin::Event::KeyboardInput(
                     glutin::ElementState::Pressed,
                     _,
+                    Some(glutin::VirtualKeyCode::Key1),
+                ) => {
+                    api.set_window_parameters(document_id,
+                        size,
+                        DeviceUintRect::new(DeviceUintPoint::zero(), size),
+                        1.0
+                    );
+                }
+                glutin::Event::KeyboardInput(
+                    glutin::ElementState::Pressed,
+                    _,
+                    Some(glutin::VirtualKeyCode::Key2),
+                ) => {
+                    api.set_window_parameters(document_id,
+                        size,
+                        DeviceUintRect::new(DeviceUintPoint::zero(), size),
+                        2.0
+                    );
+                }
+                glutin::Event::KeyboardInput(
+                    glutin::ElementState::Pressed,
+                    _,
                     Some(glutin::VirtualKeyCode::M),
                 ) => {
                     api.notify_memory_pressure();
                 }
                 _ => if example.on_event(event, &api, document_id) {
                     let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
                     let mut resources = ResourceUpdates::new();
 
--- a/gfx/webrender/examples/scrolling.rs
+++ b/gfx/webrender/examples/scrolling.rs
@@ -77,17 +77,17 @@ impl Example for App {
                 LayoutPrimitiveInfo::with_clip_rect((50, 0).to(100, 50), (60, 10).to(110, 60));
             builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
 
             // Below the above rectangles, set up a nested scrollbox. It's still in
             // the same stacking context, so note that the rects passed in need to
             // be relative to the stacking context.
             let nested_clip_id = builder.define_scroll_frame(
                 None,
-                (0, 100).to(300, 400),
+                (0, 100).to(300, 1000),
                 (0, 100).to(200, 300),
                 vec![],
                 None,
                 ScrollSensitivity::ScriptAndInputEvents,
             );
             builder.push_clip_id(nested_clip_id);
 
             // give it a giant gray background just to distinguish it and to easily
@@ -95,41 +95,43 @@ impl Example for App {
             let info = LayoutPrimitiveInfo::new((-1000, -1000).to(5000, 5000));
             builder.push_rect(&info, ColorF::new(0.5, 0.5, 0.5, 1.0));
 
             // add a teal square to visualize the scrolling/clipping behaviour
             // as you scroll the nested scrollbox
             let info = LayoutPrimitiveInfo::new((0, 200).to(50, 250));
             builder.push_rect(&info, ColorF::new(0.0, 1.0, 1.0, 1.0));
 
-            // Add a sticky frame. It will "stick" at a margin of 10px from the top, until
-            // the scrollframe scrolls another 60px, at which point it will "unstick". This lines
-            // it up with the above teal square as it scrolls out of the visible area of the
-            // scrollframe
+            // Add a sticky frame. It will "stick" twice while scrolling, once
+            // at a margin of 10px from the bottom, for 40 pixels of scrolling,
+            // and once at a margin of 10px from the top, for 60 pixels of
+            // scrolling.
             let sticky_id = builder.define_sticky_frame(
                 None,
-                (50, 140).to(100, 190),
+                (50, 350).by(50, 50),
                 StickyFrameInfo::new(
                     Some(StickySideConstraint {
                         margin: 10.0,
                         max_offset: 60.0,
                     }),
                     None,
-                    None,
+                    Some(StickySideConstraint {
+                        margin: 10.0,
+                        max_offset: -40.0,
+                    }),
                     None,
                 ),
             );
             builder.push_clip_id(sticky_id);
-            let info = LayoutPrimitiveInfo::new((50, 140).to(100, 190));
+            let info = LayoutPrimitiveInfo::new((50, 350).by(50, 50));
             builder.push_rect(&info, ColorF::new(0.5, 0.5, 1.0, 1.0));
             builder.pop_clip_id(); // sticky_id
 
-            // just for good measure add another teal square in the bottom-right
-            // corner of the nested scrollframe content, which can be scrolled into
-            // view by the user
+            // just for good measure add another teal square further down and to
+            // the right, which can be scrolled into view by the user
             let info = LayoutPrimitiveInfo::new((250, 350).to(300, 400));
             builder.push_rect(&info, ColorF::new(0.0, 1.0, 1.0, 1.0));
 
             builder.pop_clip_id(); // nested_clip_id
 
             builder.pop_clip_id(); // clip_id
             builder.pop_stacking_context();
         }
--- a/gfx/webrender/res/prim_shared.glsl
+++ b/gfx/webrender/res/prim_shared.glsl
@@ -276,32 +276,34 @@ Glyph fetch_glyph(int specific_prim_addr
                   int glyph_index,
                   int subpx_dir) {
     // Two glyphs are packed in each texel in the GPU cache.
     int glyph_address = specific_prim_address +
                         VECS_PER_TEXT_RUN +
                         glyph_index / 2;
     vec4 data = fetch_from_resource_cache_1(glyph_address);
     // Select XY or ZW based on glyph index.
-    vec2 glyph = mix(data.xy, data.zw, bvec2(glyph_index % 2 == 1));
+    // We use "!= 0" instead of "== 1" here in order to work around a driver
+    // bug with equality comparisons on integers.
+    vec2 glyph = mix(data.xy, data.zw, bvec2(glyph_index % 2 != 0));
 
     // In subpixel mode, the subpixel offset has already been
     // accounted for while rasterizing the glyph.
     switch (subpx_dir) {
         case SUBPX_DIR_NONE:
             break;
         case SUBPX_DIR_HORIZONTAL:
             // Glyphs positioned [-0.125, 0.125] get a
             // subpx position of zero. So include that
             // offset in the glyph position to ensure
-            // we truncate to the correct whole position.
-            glyph.x = trunc(glyph.x + 0.125);
+            // we round to the correct whole position.
+            glyph.x = floor(glyph.x + 0.125);
             break;
         case SUBPX_DIR_VERTICAL:
-            glyph.y = trunc(glyph.y + 0.125);
+            glyph.y = floor(glyph.y + 0.125);
             break;
     }
 
     return Glyph(glyph);
 }
 
 struct PrimitiveInstance {
     int prim_address;
--- a/gfx/webrender/res/ps_angle_gradient.glsl
+++ b/gfx/webrender/res/ps_angle_gradient.glsl
@@ -37,17 +37,17 @@ void main(void) {
     vScaledDir = dir / dot(dir, dir);
 
     vTileSize = gradient.tile_size_repeat.xy;
     vTileRepeat = gradient.tile_size_repeat.zw;
 
     vGradientAddress = prim.specific_prim_address + VECS_PER_GRADIENT;
 
     // Whether to repeat the gradient instead of clamping.
-    vGradientRepeat = float(int(gradient.extend_mode.x) == EXTEND_MODE_REPEAT);
+    vGradientRepeat = float(int(gradient.extend_mode.x) != EXTEND_MODE_CLAMP);
 }
 #endif
 
 #ifdef WR_FRAGMENT_SHADER
 void main(void) {
     vec2 pos = mod(vPos, vTileRepeat);
 
     if (pos.x >= vTileSize.x ||
--- a/gfx/webrender/res/ps_gradient.glsl
+++ b/gfx/webrender/res/ps_gradient.glsl
@@ -103,11 +103,11 @@ void main(void) {
     float alpha = 0.0;
     vec2 local_pos = init_transform_fs(vLocalPos, alpha);
 #else
     float alpha = 1.0;
     vec2 local_pos = vPos;
 #endif
 
     alpha = min(alpha, do_clip());
-    oFragColor = dither(vColor * vec4(1.0, 1.0, 1.0, alpha));
+    oFragColor = dither(vColor * alpha);
 }
 #endif
--- a/gfx/webrender/res/ps_radial_gradient.glsl
+++ b/gfx/webrender/res/ps_radial_gradient.glsl
@@ -47,17 +47,17 @@ void main(void) {
     vStartCenter.y *= ratio_xy;
     vEndCenter.y *= ratio_xy;
     vTileSize.y *= ratio_xy;
     vTileRepeat.y *= ratio_xy;
 
     vGradientAddress = prim.specific_prim_address + VECS_PER_GRADIENT;
 
     // Whether to repeat the gradient instead of clamping.
-    vGradientRepeat = float(int(gradient.start_end_radius_ratio_xy_extend_mode.w) == EXTEND_MODE_REPEAT);
+    vGradientRepeat = float(int(gradient.start_end_radius_ratio_xy_extend_mode.w) != EXTEND_MODE_CLAMP);
 }
 #endif
 
 #ifdef WR_FRAGMENT_SHADER
 void main(void) {
     vec2 pos = mod(vPos, vTileRepeat);
 
     if (pos.x >= vTileSize.x ||
--- a/gfx/webrender/src/border.rs
+++ b/gfx/webrender/src/border.rs
@@ -1,19 +1,19 @@
 /* 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/. */
 
 use api::{BorderSide, BorderStyle, BorderWidths, ClipAndScrollInfo, ColorF, LayerPoint, LayerRect};
-use api::{LayerPrimitiveInfo, LayerSize, NormalBorder};
+use api::{LayerPrimitiveInfo, LayerSize, NormalBorder, RepeatMode};
 use clip::ClipSource;
 use ellipse::Ellipse;
 use frame_builder::FrameBuilder;
 use gpu_cache::GpuDataRequest;
-use prim_store::{BorderPrimitiveCpu, PrimitiveContainer};
+use prim_store::{BorderPrimitiveCpu, PrimitiveContainer, TexelRect};
 use tiling::PrimitiveFlags;
 use util::{lerp, pack_as_float};
 
 #[repr(u8)]
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub enum BorderCornerInstance {
     Single, // Single instance needed - corner styles are same or similar.
     Double, // Different corner styles. Draw two instances, one per style.
@@ -790,8 +790,60 @@ struct DotInfo {
     diameter: f32,
 }
 
 impl DotInfo {
     fn new(arc_pos: f32, diameter: f32) -> DotInfo {
         DotInfo { arc_pos, diameter }
     }
 }
+
+#[derive(Debug, Clone)]
+pub struct ImageBorderSegment {
+    pub geom_rect: LayerRect,
+    pub sub_rect: TexelRect,
+    pub stretch_size: LayerSize,
+    pub tile_spacing: LayerSize,
+}
+
+impl ImageBorderSegment {
+    pub fn new(
+        rect: LayerRect,
+        sub_rect: TexelRect,
+        repeat_horizontal: RepeatMode,
+        repeat_vertical: RepeatMode,
+    ) -> ImageBorderSegment {
+        let tile_spacing = LayerSize::zero();
+
+        debug_assert!(sub_rect.uv1.x >= sub_rect.uv0.x);
+        debug_assert!(sub_rect.uv1.y >= sub_rect.uv0.y);
+
+        let image_size = LayerSize::new(
+            sub_rect.uv1.x - sub_rect.uv0.x,
+            sub_rect.uv1.y - sub_rect.uv0.y,
+        );
+
+        let stretch_size_x = match repeat_horizontal {
+            RepeatMode::Stretch => rect.size.width,
+            RepeatMode::Repeat => image_size.width,
+            RepeatMode::Round | RepeatMode::Space => {
+                error!("Round/Space not supported yet!");
+                rect.size.width
+            }
+        };
+
+        let stretch_size_y = match repeat_vertical {
+            RepeatMode::Stretch => rect.size.height,
+            RepeatMode::Repeat => image_size.height,
+            RepeatMode::Round | RepeatMode::Space => {
+                error!("Round/Space not supported yet!");
+                rect.size.height
+            }
+        };
+
+        ImageBorderSegment {
+            geom_rect: rect,
+            sub_rect,
+            stretch_size: LayerSize::new(stretch_size_x, stretch_size_y),
+            tile_spacing,
+        }
+    }
+}
--- a/gfx/webrender/src/frame.rs
+++ b/gfx/webrender/src/frame.rs
@@ -1,30 +1,30 @@
 /* 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/. */
 
-use api::{BuiltDisplayList, BuiltDisplayListIter, ClipAndScrollInfo, ClipId, ColorF};
+use api::{BuiltDisplayListIter, ClipAndScrollInfo, ClipId, ColorF};
 use api::{ComplexClipRegion, DeviceUintRect, DeviceUintSize, DisplayItemRef, Epoch, FilterOp};
 use api::{ImageDisplayItem, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize,
           LayerToScrollTransform};
-use api::{LayerVector2D, LayoutSize, LayoutTransform, LocalClip, MixBlendMode, PipelineId};
-use api::{PropertyBinding, ScrollClamping, ScrollEventPhase, ScrollLayerState, ScrollLocation};
+use api::{LayerVector2D, LayoutSize, LayoutTransform, LocalClip, PipelineId};
+use api::{ScrollClamping, ScrollEventPhase, ScrollLayerState, ScrollLocation};
 use api::{ScrollPolicy, ScrollSensitivity, SpecificDisplayItem, StackingContext, TileOffset};
 use api::{TransformStyle, WorldPoint};
 use clip::ClipRegion;
 use clip_scroll_tree::{ClipScrollTree, ScrollStates};
 use euclid::rect;
 use frame_builder::{FrameBuilder, FrameBuilderConfig};
 use gpu_cache::GpuCache;
 use internal_types::{FastHashMap, FastHashSet, RendererFrame};
 use profiler::{GpuCacheProfileCounters, TextureCacheProfileCounters};
 use resource_cache::{ResourceCache, TiledImageMap};
-use scene::{Scene, SceneProperties};
-use tiling::{CompositeOps, DisplayListMap, PrimitiveFlags};
+use scene::{Scene, StackingContextHelpers, ScenePipeline};
+use tiling::{CompositeOps, PrimitiveFlags};
 use util::{subtract_rect, ComplexClipRegionHelpers};
 
 #[derive(Copy, Clone, PartialEq, PartialOrd, Debug, Eq, Ord)]
 pub struct FrameId(pub u32);
 
 static DEFAULT_SCROLLBAR_COLOR: ColorF = ColorF {
     r: 0.3,
     g: 0.3,
@@ -179,105 +179,34 @@ impl<'a> FlattenContext<'a> {
         pipeline_id: PipelineId,
         complex_clips: ItemRange<ComplexClipRegion>,
     ) -> Vec<ComplexClipRegion> {
         if complex_clips.is_empty() {
             return vec![];
         }
 
         self.scene
-            .display_lists
+            .pipelines
             .get(&pipeline_id)
             .expect("No display list?")
+            .display_list
             .get(complex_clips)
             .collect()
     }
 }
 
 // TODO: doc
 pub struct Frame {
     pub clip_scroll_tree: ClipScrollTree,
     pub pipeline_epoch_map: FastHashMap<PipelineId, Epoch>,
     id: FrameId,
     frame_builder_config: FrameBuilderConfig,
     pub frame_builder: Option<FrameBuilder>,
 }
 
-trait FilterOpHelpers {
-    fn resolve(self, properties: &SceneProperties) -> FilterOp;
-    fn is_noop(&self) -> bool;
-}
-
-impl FilterOpHelpers for FilterOp {
-    fn resolve(self, properties: &SceneProperties) -> FilterOp {
-        match self {
-            FilterOp::Opacity(ref value) => {
-                let amount = properties.resolve_float(value, 1.0);
-                FilterOp::Opacity(PropertyBinding::Value(amount))
-            }
-            _ => self,
-        }
-    }
-
-    fn is_noop(&self) -> bool {
-        match *self {
-            FilterOp::Blur(length) => length == 0.0,
-            FilterOp::Brightness(amount) => amount == 1.0,
-            FilterOp::Contrast(amount) => amount == 1.0,
-            FilterOp::Grayscale(amount) => amount == 0.0,
-            FilterOp::HueRotate(amount) => amount == 0.0,
-            FilterOp::Invert(amount) => amount == 0.0,
-            FilterOp::Opacity(value) => match value {
-                PropertyBinding::Value(amount) => amount == 1.0,
-                PropertyBinding::Binding(..) => {
-                    panic!("bug: binding value should be resolved");
-                }
-            },
-            FilterOp::Saturate(amount) => amount == 1.0,
-            FilterOp::Sepia(amount) => amount == 0.0,
-        }
-    }
-}
-
-trait StackingContextHelpers {
-    fn mix_blend_mode_for_compositing(&self) -> Option<MixBlendMode>;
-    fn filter_ops_for_compositing(
-        &self,
-        display_list: &BuiltDisplayList,
-        input_filters: ItemRange<FilterOp>,
-        properties: &SceneProperties,
-    ) -> Vec<FilterOp>;
-}
-
-impl StackingContextHelpers for StackingContext {
-    fn mix_blend_mode_for_compositing(&self) -> Option<MixBlendMode> {
-        match self.mix_blend_mode {
-            MixBlendMode::Normal => None,
-            _ => Some(self.mix_blend_mode),
-        }
-    }
-
-    fn filter_ops_for_compositing(
-        &self,
-        display_list: &BuiltDisplayList,
-        input_filters: ItemRange<FilterOp>,
-        properties: &SceneProperties,
-    ) -> Vec<FilterOp> {
-        let mut filters = vec![];
-        for filter in display_list.get(input_filters) {
-            let filter = filter.resolve(properties);
-            if filter.is_noop() {
-                continue;
-            }
-            filters.push(filter);
-        }
-        filters
-    }
-}
-
 impl Frame {
     pub fn new(config: FrameBuilderConfig) -> Frame {
         Frame {
             pipeline_epoch_map: FastHashMap::default(),
             clip_scroll_tree: ClipScrollTree::new(),
             id: FrameId(0),
             frame_builder: None,
             frame_builder_config: config,
@@ -329,26 +258,21 @@ impl Frame {
         inner_rect: DeviceUintRect,
         device_pixel_ratio: f32,
     ) {
         let root_pipeline_id = match scene.root_pipeline_id {
             Some(root_pipeline_id) => root_pipeline_id,
             None => return,
         };
 
-        let root_pipeline = match scene.pipeline_map.get(&root_pipeline_id) {
+        let root_pipeline = match scene.pipelines.get(&root_pipeline_id) {
             Some(root_pipeline) => root_pipeline,
             None => return,
         };
 
-        let display_list = match scene.display_lists.get(&root_pipeline_id) {
-            Some(display_list) => display_list,
-            None => return,
-        };
-
         if window_size.width == 0 || window_size.height == 0 {
             error!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
         }
 
         let old_scrolling_states = self.reset();
 
         self.pipeline_epoch_map
             .insert(root_pipeline_id, root_pipeline.epoch);
@@ -377,17 +301,17 @@ impl Frame {
             context.builder.setup_viewport_offset(
                 window_size,
                 inner_rect,
                 device_pixel_ratio,
                 &mut self.clip_scroll_tree,
             );
 
             self.flatten_root(
-                &mut display_list.iter(),
+                &mut root_pipeline.display_list.iter(),
                 root_pipeline_id,
                 &mut context,
                 &root_pipeline.content_size,
             );
         }
 
         self.frame_builder = Some(frame_builder);
         self.clip_scroll_tree
@@ -459,21 +383,22 @@ impl Frame {
         // Avoid doing unnecessary work for empty stacking contexts.
         if traversal.current_stacking_context_empty() {
             traversal.skip_current_stacking_context();
             return;
         }
 
         let composition_operations = {
             // TODO(optimization?): self.traversal.display_list()
-            let display_list = context
+            let display_list = &context
                 .scene
-                .display_lists
+                .pipelines
                 .get(&pipeline_id)
-                .expect("No display list?!");
+                .expect("No display list?!")
+                .display_list;
             CompositeOps::new(
                 stacking_context.filter_ops_for_compositing(
                     display_list,
                     filters,
                     &context.scene.properties,
                 ),
                 stacking_context.mix_blend_mode_for_compositing(),
             )
@@ -552,26 +477,21 @@ impl Frame {
         &mut self,
         pipeline_id: PipelineId,
         parent_id: ClipId,
         bounds: &LayerRect,
         local_clip: &LocalClip,
         context: &mut FlattenContext,
         reference_frame_relative_offset: LayerVector2D,
     ) {
-        let pipeline = match context.scene.pipeline_map.get(&pipeline_id) {
+        let pipeline = match context.scene.pipelines.get(&pipeline_id) {
             Some(pipeline) => pipeline,
             None => return,
         };
 
-        let display_list = match context.scene.display_lists.get(&pipeline_id) {
-            Some(display_list) => display_list,
-            None => return,
-        };
-
         let mut clip_region = ClipRegion::create_for_clip_node_with_local_clip(local_clip);
         clip_region.origin += reference_frame_relative_offset;
         let parent_pipeline_id = parent_id.pipeline_id();
         let clip_id = self.clip_scroll_tree
             .generate_new_clip_id(parent_pipeline_id);
         context.builder.add_clip_node(
             clip_id,
             parent_id,
@@ -600,17 +520,17 @@ impl Frame {
             pipeline_id,
             &iframe_rect,
             &pipeline.content_size,
             ScrollSensitivity::ScriptAndInputEvents,
             &mut self.clip_scroll_tree,
         );
 
         self.flatten_root(
-            &mut display_list.iter(),
+            &mut pipeline.display_list.iter(),
             pipeline_id,
             context,
             &pipeline.content_size,
         );
 
         context.builder.pop_reference_frame();
     }
 
@@ -679,17 +599,17 @@ impl Frame {
                         );
                     }
                     None => {
                         warn!("Unknown font instance key: {:?}", text_info.font_key);
                     }
                 }
             }
             SpecificDisplayItem::Rectangle(ref info) => {
-                if !self.try_to_add_rectangle_splitting_on_clip(
+                if !try_to_add_rectangle_splitting_on_clip(
                     context,
                     &prim_info,
                     &info.color,
                     &clip_and_scroll,
                 ) {
                     context.builder.add_solid_rectangle(
                         clip_and_scroll,
                         &prim_info,
@@ -875,75 +795,16 @@ impl Frame {
             }
             SpecificDisplayItem::PopTextShadow => {
                 context.builder.pop_text_shadow();
             }
         }
         None
     }
 
-    /// Try to optimize the rendering of a solid rectangle that is clipped by a single
-    /// rounded rectangle, by only masking the parts of the rectangle that intersect
-    /// the rounded parts of the clip. This is pretty simple now, so has a lot of
-    /// potential for further optimizations.
-    fn try_to_add_rectangle_splitting_on_clip(
-        &mut self,
-        context: &mut FlattenContext,
-        info: &LayerPrimitiveInfo,
-        color: &ColorF,
-        clip_and_scroll: &ClipAndScrollInfo,
-    ) -> bool {
-        // If this rectangle is not opaque, splitting the rectangle up
-        // into an inner opaque region just ends up hurting batching and
-        // doing more work than necessary.
-        if color.a != 1.0 {
-            return false;
-        }
-
-        let inner_unclipped_rect = match &info.local_clip {
-            &LocalClip::Rect(_) => return false,
-            &LocalClip::RoundedRect(_, ref region) => region.get_inner_rect_full(),
-        };
-        let inner_unclipped_rect = match inner_unclipped_rect {
-            Some(rect) => rect,
-            None => return false,
-        };
-
-        // The inner rectangle is not clipped by its assigned clipping node, so we can
-        // let it be clipped by the parent of the clipping node, which may result in
-        // less masking some cases.
-        let mut clipped_rects = Vec::new();
-        subtract_rect(&info.rect, &inner_unclipped_rect, &mut clipped_rects);
-
-        let prim_info = LayerPrimitiveInfo {
-            rect: inner_unclipped_rect,
-            local_clip: LocalClip::from(*info.local_clip.clip_rect()),
-            is_backface_visible: info.is_backface_visible,
-        };
-
-        context.builder.add_solid_rectangle(
-            *clip_and_scroll,
-            &prim_info,
-            color,
-            PrimitiveFlags::None,
-        );
-
-        for clipped_rect in &clipped_rects {
-            let mut info = info.clone();
-            info.rect = *clipped_rect;
-            context.builder.add_solid_rectangle(
-                *clip_and_scroll,
-                &info,
-                color,
-                PrimitiveFlags::None,
-            );
-        }
-        true
-    }
-
     fn flatten_root<'a>(
         &mut self,
         traversal: &mut BuiltDisplayListIter<'a>,
         pipeline_id: PipelineId,
         context: &mut FlattenContext,
         content_size: &LayoutSize,
     ) {
         context.builder.push_stacking_context(
@@ -960,17 +821,17 @@ impl Frame {
         // FIXME(mrobinson): Currently only the first one will, which for the moment is
         // sufficient for all our use cases.
         context.builder.notify_waiting_for_root_stacking_context();
 
         // For the root pipeline, there's no need to add a full screen rectangle
         // here, as it's handled by the framebuffer clear.
         let clip_id = ClipId::root_scroll_node(pipeline_id);
         if context.scene.root_pipeline_id != Some(pipeline_id) {
-            if let Some(pipeline) = context.scene.pipeline_map.get(&pipeline_id) {
+            if let Some(pipeline) = context.scene.pipelines.get(&pipeline_id) {
                 if let Some(bg_color) = pipeline.background_color {
                     let root_bounds = LayerRect::new(LayerPoint::zero(), *content_size);
                     let info = LayerPrimitiveInfo::new(root_bounds);
                     context.builder.add_solid_rectangle(
                         ClipAndScrollInfo::simple(clip_id),
                         &info,
                         &bg_color,
                         PrimitiveFlags::None,
@@ -1338,58 +1199,116 @@ impl Frame {
             );
         }
     }
 
     pub fn build(
         &mut self,
         resource_cache: &mut ResourceCache,
         gpu_cache: &mut GpuCache,
-        display_lists: &DisplayListMap,
+        pipelines: &FastHashMap<PipelineId, ScenePipeline>,
         device_pixel_ratio: f32,
         pan: LayerPoint,
         output_pipelines: &FastHashSet<PipelineId>,
         texture_cache_profile: &mut TextureCacheProfileCounters,
         gpu_cache_profile: &mut GpuCacheProfileCounters,
     ) -> RendererFrame {
         self.clip_scroll_tree.update_all_node_transforms(pan);
         let frame = self.build_frame(
             resource_cache,
             gpu_cache,
-            display_lists,
+            pipelines,
             device_pixel_ratio,
             output_pipelines,
             texture_cache_profile,
             gpu_cache_profile,
         );
         frame
     }
 
     fn build_frame(
         &mut self,
         resource_cache: &mut ResourceCache,
         gpu_cache: &mut GpuCache,
-        display_lists: &DisplayListMap,
+        pipelines: &FastHashMap<PipelineId, ScenePipeline>,
         device_pixel_ratio: f32,
         output_pipelines: &FastHashSet<PipelineId>,
         texture_cache_profile: &mut TextureCacheProfileCounters,
         gpu_cache_profile: &mut GpuCacheProfileCounters,
     ) -> RendererFrame {
         let mut frame_builder = self.frame_builder.take();
         let frame = frame_builder.as_mut().map(|builder| {
             builder.build(
                 resource_cache,
                 gpu_cache,
                 self.id,
                 &mut self.clip_scroll_tree,
-                display_lists,
+                pipelines,
                 device_pixel_ratio,
                 output_pipelines,
                 texture_cache_profile,
                 gpu_cache_profile,
             )
         });
         self.frame_builder = frame_builder;
 
         let nodes_bouncing_back = self.clip_scroll_tree.collect_nodes_bouncing_back();
         RendererFrame::new(self.pipeline_epoch_map.clone(), nodes_bouncing_back, frame)
     }
 }
+
+/// Try to optimize the rendering of a solid rectangle that is clipped by a single
+/// rounded rectangle, by only masking the parts of the rectangle that intersect
+/// the rounded parts of the clip. This is pretty simple now, so has a lot of
+/// potential for further optimizations.
+fn try_to_add_rectangle_splitting_on_clip(
+    context: &mut FlattenContext,
+    info: &LayerPrimitiveInfo,
+    color: &ColorF,
+    clip_and_scroll: &ClipAndScrollInfo,
+) -> bool {
+    // If this rectangle is not opaque, splitting the rectangle up
+    // into an inner opaque region just ends up hurting batching and
+    // doing more work than necessary.
+    if color.a != 1.0 {
+        return false;
+    }
+
+    let inner_unclipped_rect = match &info.local_clip {
+        &LocalClip::Rect(_) => return false,
+        &LocalClip::RoundedRect(_, ref region) => region.get_inner_rect_full(),
+    };
+    let inner_unclipped_rect = match inner_unclipped_rect {
+        Some(rect) => rect,
+        None => return false,
+    };
+
+    // The inner rectangle is not clipped by its assigned clipping node, so we can
+    // let it be clipped by the parent of the clipping node, which may result in
+    // less masking some cases.
+    let mut clipped_rects = Vec::new();
+    subtract_rect(&info.rect, &inner_unclipped_rect, &mut clipped_rects);
+
+    let prim_info = LayerPrimitiveInfo {
+        rect: inner_unclipped_rect,
+        local_clip: LocalClip::from(*info.local_clip.clip_rect()),
+        is_backface_visible: info.is_backface_visible,
+    };
+
+    context.builder.add_solid_rectangle(
+        *clip_and_scroll,
+        &prim_info,
+        color,
+        PrimitiveFlags::None,
+    );
+
+    for clipped_rect in &clipped_rects {
+        let mut info = info.clone();
+        info.rect = *clipped_rect;
+        context.builder.add_solid_rectangle(
+            *clip_and_scroll,
+            &info,
+            color,
+            PrimitiveFlags::None,
+        );
+    }
+    true
+}
--- a/gfx/webrender/src/frame_builder.rs
+++ b/gfx/webrender/src/frame_builder.rs
@@ -8,16 +8,17 @@ use api::{DeviceIntPoint, DeviceIntRect,
 use api::{device_length, ExtendMode, FilterOp, FontInstance, FontRenderMode};
 use api::{GlyphInstance, GlyphOptions, GradientStop};
 use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect,
           LayerSize};
 use api::{LayerToScrollTransform, LayerVector2D, LayoutVector2D, LineOrientation, LineStyle};
 use api::{LocalClip, PipelineId, RepeatMode, ScrollSensitivity, SubpixelDirection, TextShadow};
 use api::{TileOffset, TransformStyle, WorldPixel, YuvColorSpace, YuvData};
 use app_units::Au;
+use border::ImageBorderSegment;
 use clip::{ClipMode, ClipRegion, ClipSource, ClipSources, ClipStore};
 use clip_scroll_node::{ClipInfo, ClipScrollNode, NodeType};
 use clip_scroll_tree::ClipScrollTree;
 use euclid::{SideOffsets2D, vec2, vec3};
 use frame::FrameId;
 use gpu_cache::GpuCache;
 use internal_types::{FastHashMap, FastHashSet, HardwareCompositeOp};
 use plane_split::{BspSplitter, Polygon, Splitter};
@@ -25,76 +26,25 @@ use prim_store::{BoxShadowPrimitiveCpu, 
 use prim_store::{GradientPrimitiveCpu, ImagePrimitiveCpu, LinePrimitive, PrimitiveKind};
 use prim_store::{PrimitiveContainer, PrimitiveIndex};
 use prim_store::{PrimitiveStore, RadialGradientPrimitiveCpu, TextRunMode};
 use prim_store::{RectanglePrimitive, TextRunPrimitiveCpu, TextShadowPrimitiveCpu};
 use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
 use render_task::{AlphaRenderItem, ClipWorkItem, RenderTask};
 use render_task::{RenderTaskId, RenderTaskLocation, RenderTaskTree};
 use resource_cache::ResourceCache;
+use scene::ScenePipeline;
 use std::{mem, usize, f32, i32};
-use tiling::{ClipScrollGroup, ClipScrollGroupIndex, CompositeOps, DisplayListMap, Frame};
+use tiling::{ClipScrollGroup, ClipScrollGroupIndex, CompositeOps, Frame};
 use tiling::{ContextIsolation, StackingContextIndex};
 use tiling::{PackedLayer, PackedLayerIndex, PrimitiveFlags, PrimitiveRunCmd, RenderPass};
 use tiling::{RenderTargetContext, ScrollbarPrimitive, StackingContext};
 use util::{self, pack_as_float, recycle_vec, subtract_rect};
 use util::{MatrixHelpers, RectHelpers};
 
-#[derive(Debug, Clone)]
-struct ImageBorderSegment {
-    geom_rect: LayerRect,
-    sub_rect: TexelRect,
-    stretch_size: LayerSize,
-    tile_spacing: LayerSize,
-}
-
-impl ImageBorderSegment {
-    fn new(
-        rect: LayerRect,
-        sub_rect: TexelRect,
-        repeat_horizontal: RepeatMode,
-        repeat_vertical: RepeatMode,
-    ) -> ImageBorderSegment {
-        let tile_spacing = LayerSize::zero();
-
-        debug_assert!(sub_rect.uv1.x >= sub_rect.uv0.x);
-        debug_assert!(sub_rect.uv1.y >= sub_rect.uv0.y);
-
-        let image_size = LayerSize::new(
-            sub_rect.uv1.x - sub_rect.uv0.x,
-            sub_rect.uv1.y - sub_rect.uv0.y,
-        );
-
-        let stretch_size_x = match repeat_horizontal {
-            RepeatMode::Stretch => rect.size.width,
-            RepeatMode::Repeat => image_size.width,
-            RepeatMode::Round | RepeatMode::Space => {
-                error!("Round/Space not supported yet!");
-                rect.size.width
-            }
-        };
-
-        let stretch_size_y = match repeat_vertical {
-            RepeatMode::Stretch => rect.size.height,
-            RepeatMode::Repeat => image_size.height,
-            RepeatMode::Round | RepeatMode::Space => {
-                error!("Round/Space not supported yet!");
-                rect.size.height
-            }
-        };
-
-        ImageBorderSegment {
-            geom_rect: rect,
-            sub_rect,
-            stretch_size: LayerSize::new(stretch_size_x, stretch_size_y),
-            tile_spacing,
-        }
-    }
-}
-
 /// Construct a polygon from stacking context boundaries.
 /// `anchor` here is an index that's going to be preserved in all the
 /// splits of the polygon.
 fn make_polygon(
     stacking_context: &StackingContext,
     node: &ClipScrollNode,
     anchor: usize,
 ) -> Polygon<f32, WorldPixel> {
@@ -1059,16 +1009,18 @@ impl FrameBuilder {
 
         let prim_font = FontInstance::new(
             font.font_key,
             font.size,
             *color,
             normal_render_mode,
             subpx_dir,
             font.platform_options,
+            font.variations.clone(),
+            font.synthetic_italics,
         );
         let prim = TextRunPrimitiveCpu {
             font: prim_font,
             glyph_range,
             glyph_count,
             glyph_gpu_blocks: Vec::new(),
             glyph_keys: Vec::new(),
             shadow_render_mode,
@@ -1086,16 +1038,22 @@ impl FrameBuilder {
         // TODO(gw): Refactor to avoid having to store them in a Vec first.
         let mut fast_text_shadow_prims = Vec::new();
         for shadow_prim_index in &self.shadow_prim_stack {
             let shadow_metadata = &self.prim_store.cpu_metadata[shadow_prim_index.0];
             let shadow_prim = &self.prim_store.cpu_text_shadows[shadow_metadata.cpu_prim_index.0];
             if shadow_prim.shadow.blur_radius == 0.0 {
                 let mut text_prim = prim.clone();
                 text_prim.font.color = shadow_prim.shadow.color.into();
+                // If we have translucent text, we need to ensure it won't go
+                // through the subpixel blend mode, which doesn't work with
+                // traditional alpha blending.
+                if shadow_prim.shadow.color.a != 1.0 {
+                    text_prim.font.render_mode = text_prim.font.render_mode.limit_by(FontRenderMode::Alpha);
+                }
                 text_prim.color = shadow_prim.shadow.color;
                 text_prim.offset += shadow_prim.shadow.offset;
                 fast_text_shadow_prims.push(text_prim);
             }
         }
         for text_prim in fast_text_shadow_prims {
             let rect = info.rect;
             let mut info = info.clone();
@@ -1427,29 +1385,29 @@ impl FrameBuilder {
     }
 
     /// Compute the contribution (bounding rectangles, and resources) of layers and their
     /// primitives in screen space.
     fn build_layer_screen_rects_and_cull_layers(
         &mut self,
         screen_rect: &DeviceIntRect,
         clip_scroll_tree: &mut ClipScrollTree,
-        display_lists: &DisplayListMap,
+        pipelines: &FastHashMap<PipelineId, ScenePipeline>,
         resource_cache: &mut ResourceCache,
         gpu_cache: &mut GpuCache,
         render_tasks: &mut RenderTaskTree,
         profile_counters: &mut FrameProfileCounters,
         device_pixel_ratio: f32,
     ) {
         profile_scope!("cull");
         LayerRectCalculationAndCullingPass::create_and_run(
             self,
             screen_rect,
             clip_scroll_tree,
-            display_lists,
+            pipelines,
             resource_cache,
             gpu_cache,
             render_tasks,
             profile_counters,
             device_pixel_ratio,
         );
     }
 
@@ -1802,17 +1760,17 @@ impl FrameBuilder {
     }
 
     pub fn build(
         &mut self,
         resource_cache: &mut ResourceCache,
         gpu_cache: &mut GpuCache,
         frame_id: FrameId,
         clip_scroll_tree: &mut ClipScrollTree,
-        display_lists: &DisplayListMap,
+        pipelines: &FastHashMap<PipelineId, ScenePipeline>,
         device_pixel_ratio: f32,
         output_pipelines: &FastHashSet<PipelineId>,
         texture_cache_profile: &mut TextureCacheProfileCounters,
         gpu_cache_profile: &mut GpuCacheProfileCounters,
     ) -> Frame {
         profile_scope!("build");
 
         let mut profile_counters = FrameProfileCounters::new();
@@ -1833,17 +1791,17 @@ impl FrameBuilder {
 
         self.update_scroll_bars(clip_scroll_tree, gpu_cache);
 
         let mut render_tasks = RenderTaskTree::new();
 
         self.build_layer_screen_rects_and_cull_layers(
             &screen_rect,
             clip_scroll_tree,
-            display_lists,
+            pipelines,
             resource_cache,
             gpu_cache,
             &mut render_tasks,
             &mut profile_counters,
             device_pixel_ratio,
         );
 
         let main_render_task_id = self.build_render_task(
@@ -1912,27 +1870,21 @@ impl FrameBuilder {
             layer_texture_data: self.packed_layers.clone(),
             render_tasks,
             deferred_resolves,
             gpu_cache_updates: Some(gpu_cache_updates),
         }
     }
 }
 
-#[derive(Debug, Clone, Copy)]
-struct LayerClipBounds {
-    outer: DeviceIntRect,
-    inner: DeviceIntRect,
-}
-
 struct LayerRectCalculationAndCullingPass<'a> {
     frame_builder: &'a mut FrameBuilder,
     screen_rect: &'a DeviceIntRect,
     clip_scroll_tree: &'a mut ClipScrollTree,
-    display_lists: &'a DisplayListMap,
+    pipelines: &'a FastHashMap<PipelineId, ScenePipeline>,
     resource_cache: &'a mut ResourceCache,
     gpu_cache: &'a mut GpuCache,
     profile_counters: &'a mut FrameProfileCounters,
     device_pixel_ratio: f32,
     stacking_context_stack: Vec<StackingContextIndex>,
     render_tasks: &'a mut RenderTaskTree,
 
     /// A cached clip info stack, which should handle the most common situation,
@@ -1945,28 +1897,28 @@ struct LayerRectCalculationAndCullingPas
     current_clip_info: Option<(ClipId, Option<DeviceIntRect>)>,
 }
 
 impl<'a> LayerRectCalculationAndCullingPass<'a> {
     fn create_and_run(
         frame_builder: &'a mut FrameBuilder,
         screen_rect: &'a DeviceIntRect,
         clip_scroll_tree: &'a mut ClipScrollTree,
-        display_lists: &'a DisplayListMap,
+        pipelines: &'a FastHashMap<PipelineId, ScenePipeline>,
         resource_cache: &'a mut ResourceCache,
         gpu_cache: &'a mut GpuCache,
         render_tasks: &'a mut RenderTaskTree,
         profile_counters: &'a mut FrameProfileCounters,
         device_pixel_ratio: f32,
     ) {
         let mut pass = LayerRectCalculationAndCullingPass {
             frame_builder,
             screen_rect,
             clip_scroll_tree,
-            display_lists,
+            pipelines,
             resource_cache,
             gpu_cache,
             profile_counters,
             device_pixel_ratio,
             stacking_context_stack: Vec::new(),
             current_clip_stack: Vec::new(),
             current_clip_info: None,
             render_tasks,
@@ -2181,19 +2133,17 @@ impl<'a> LayerRectCalculationAndCullingP
                     Some(rect) => rect,
                     None => return None,
                 }
             }
 
             //TODO-LCCR: bake a single LCCR instead of all aligned rects?
             self.current_clip_stack.push(ClipWorkItem {
                 layer_index: clip.packed_layer_index,
-                clip_sources: self.frame_builder
-                    .clip_store
-                    .create_weak_handle(&clip.clip_sources),
+                clip_sources: clip.clip_sources.weak(),
                 apply_rectangles: next_node_needs_region_mask,
             });
             next_node_needs_region_mask = false;
         }
 
         self.current_clip_stack.reverse();
         self.current_clip_info = Some((clip_id, Some(bounding_rect)));
         Some(bounding_rect)
@@ -2248,19 +2198,20 @@ impl<'a> LayerRectCalculationAndCullingP
             match self.rebuild_clip_info_stack_if_necessary(clip_and_scroll.clip_node_id()) {
                 Some(rect) => rect,
                 None => return,
             };
 
         let stacking_context =
             &mut self.frame_builder.stacking_context_store[stacking_context_index.0];
         let packed_layer = &self.frame_builder.packed_layers[packed_layer_index.0];
-        let display_list = self.display_lists
+        let display_list = &self.pipelines
             .get(&pipeline_id)
-            .expect("No display list?");
+            .expect("No display list?")
+            .display_list;
         debug!(
             "\tclip_bounds {:?}, layer_local_clip {:?}",
             clip_bounds,
             packed_layer.local_clip_rect
         );
 
         if !stacking_context.is_backface_visible && packed_layer.transform.is_backface_visible() {
             return;
@@ -2312,19 +2263,17 @@ impl<'a> LayerRectCalculationAndCullingP
                         Some(rect) => rect,
                         None => continue,
                     },
                     _ => prim_screen_rect,
                 };
 
                 let extra = ClipWorkItem {
                     layer_index: packed_layer_index,
-                    clip_sources: self.frame_builder
-                        .clip_store
-                        .create_weak_handle(&prim_metadata.clip_sources),
+                    clip_sources: prim_metadata.clip_sources.weak(),
                     apply_rectangles: false,
                 };
 
                 RenderTask::new_mask(
                     None,
                     mask_rect,
                     &self.current_clip_stack,
                     Some(extra),
--- a/gfx/webrender/src/freelist.rs
+++ b/gfx/webrender/src/freelist.rs
@@ -10,19 +10,30 @@ use util::recycle_vec;
 //           retain() style functionality.
 
 #[derive(Debug, Copy, Clone, PartialEq)]
 struct Epoch(u32);
 
 #[derive(Debug)]
 pub struct FreeListHandle<T> {
     index: u32,
+    epoch: Epoch,
     _marker: PhantomData<T>,
 }
 
+impl<T> FreeListHandle<T> {
+    pub fn weak(&self) -> WeakFreeListHandle<T> {
+        WeakFreeListHandle {
+            index: self.index,
+            epoch: self.epoch,
+            _marker: PhantomData,
+        }
+    }
+}
+
 impl<T> Clone for WeakFreeListHandle<T> {
     fn clone(&self) -> WeakFreeListHandle<T> {
         WeakFreeListHandle {
             index: self.index,
             epoch: self.epoch,
             _marker: PhantomData,
         }
     }
@@ -89,25 +100,16 @@ impl<T> FreeList<T> {
         let slot = &mut self.slots[id.index as usize];
         if slot.epoch == id.epoch {
             slot.value.as_mut()
         } else {
             None
         }
     }
 
-    pub fn create_weak_handle(&self, id: &FreeListHandle<T>) -> WeakFreeListHandle<T> {
-        let slot = &self.slots[id.index as usize];
-        WeakFreeListHandle {
-            index: id.index,
-            epoch: slot.epoch,
-            _marker: PhantomData,
-        }
-    }
-
     // Perform a database style UPSERT operation. If the provided
     // handle is a valid entry, update the value and return the
     // previous data. If the provided handle is invalid, then
     // insert the data into a new slot and return the new handle.
     pub fn upsert(&mut self, id: &WeakFreeListHandle<T>, data: T) -> UpsertResult<T> {
         if self.slots[id.index as usize].epoch == id.epoch {
             let slot = &mut self.slots[id.index as usize];
             let result = UpsertResult::Updated(slot.value.take().unwrap());
@@ -125,30 +127,33 @@ impl<T> FreeList<T> {
 
                 // Remove from free list.
                 self.free_list_head = slot.next;
                 slot.next = None;
                 slot.value = Some(item);
 
                 FreeListHandle {
                     index: free_index,
+                    epoch: slot.epoch,
                     _marker: PhantomData,
                 }
             }
             None => {
                 let index = self.slots.len() as u32;
+                let epoch = Epoch(0);
 
                 self.slots.push(Slot {
                     next: None,
-                    epoch: Epoch(0),
+                    epoch,
                     value: Some(item),
                 });
 
                 FreeListHandle {
                     index,
+                    epoch,
                     _marker: PhantomData,
                 }
             }
         }
     }
 
     pub fn free(&mut self, id: FreeListHandle<T>) -> T {
         let slot = &mut self.slots[id.index as usize];
--- a/gfx/webrender/src/glyph_rasterizer.rs
+++ b/gfx/webrender/src/glyph_rasterizer.rs
@@ -405,16 +405,18 @@ fn raterize_200_glyphs() {
 
     let font = FontInstance::new(
         font_key,
         Au::from_px(32),
         ColorF::new(0.0, 0.0, 0.0, 1.0),
         FontRenderMode::Subpixel,
         SubpixelDirection::Horizontal,
         None,
+        Vec::new(),
+        false,
     );
 
     let mut glyph_keys = Vec::with_capacity(200);
     for i in 0 .. 200 {
         glyph_keys.push(GlyphKey::new(
             i,
             LayoutPoint::zero(),
             font.render_mode,
--- a/gfx/webrender/src/lib.rs
+++ b/gfx/webrender/src/lib.rs
@@ -108,16 +108,18 @@ mod platform {
     }
     #[cfg(target_os = "windows")]
     pub mod windows {
         pub mod font;
     }
 }
 
 #[cfg(target_os = "macos")]
+extern crate core_foundation;
+#[cfg(target_os = "macos")]
 extern crate core_graphics;
 #[cfg(target_os = "macos")]
 extern crate core_text;
 
 #[cfg(all(unix, not(target_os = "macos")))]
 extern crate freetype;
 
 #[cfg(target_os = "windows")]
--- a/gfx/webrender/src/platform/macos/font.rs
+++ b/gfx/webrender/src/platform/macos/font.rs
@@ -1,35 +1,40 @@
 /* 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/. */
 
 use api::{ColorU, FontKey, FontRenderMode, GlyphDimensions};
-use api::{FontInstance, NativeFontHandle};
+use api::{FontInstance, FontVariation, NativeFontHandle};
 use api::GlyphKey;
 use app_units::Au;
+use core_foundation::array::{CFArray, CFArrayRef};
+use core_foundation::base::TCFType;
+use core_foundation::dictionary::{CFDictionary, CFDictionaryRef};
+use core_foundation::number::{CFNumber, CFNumberRef};
+use core_foundation::string::{CFString, CFStringRef};
 use core_graphics::base::{kCGImageAlphaNoneSkipFirst, kCGImageAlphaPremultipliedLast};
 use core_graphics::base::kCGBitmapByteOrder32Little;
 use core_graphics::color_space::CGColorSpace;
 use core_graphics::context::{CGContext, CGTextDrawingMode};
 use core_graphics::data_provider::CGDataProvider;
-use core_graphics::font::{CGFont, CGGlyph};
+use core_graphics::font::{CGFont, CGFontRef, CGGlyph};
 use core_graphics::geometry::{CGPoint, CGRect, CGSize};
 use core_text;
-use core_text::font::CTFont;
+use core_text::font::{CTFont, CTFontRef};
 use core_text::font_descriptor::kCTFontDefaultOrientation;
 use gamma_lut::{Color as ColorLut, GammaLut};
 use internal_types::FastHashMap;
 use std::collections::hash_map::Entry;
 use std::ptr;
 use std::sync::Arc;
 
 pub struct FontContext {
     cg_fonts: FastHashMap<FontKey, CGFont>,
-    ct_fonts: FastHashMap<(FontKey, Au), CTFont>,
+    ct_fonts: FastHashMap<(FontKey, Au, Vec<FontVariation>), CTFont>,
     gamma_lut: GammaLut,
 }
 
 // core text is safe to use on multiple threads and non-shareable resources are
 // all hidden inside their font context.
 unsafe impl Send for FontContext {}
 
 pub struct RasterizedGlyph {
@@ -142,16 +147,127 @@ fn get_glyph_metrics(
         rasterized_ascent: top,
         rasterized_descent: -bottom,
         advance: advance as f32,
     };
 
     metrics
 }
 
+#[link(name = "ApplicationServices", kind = "framework")]
+extern {
+    static kCTFontVariationAxisIdentifierKey: CFStringRef;
+    static kCTFontVariationAxisNameKey: CFStringRef;
+    static kCTFontVariationAxisMinimumValueKey: CFStringRef;
+    static kCTFontVariationAxisMaximumValueKey: CFStringRef;
+    static kCTFontVariationAxisDefaultValueKey: CFStringRef;
+
+    fn CTFontCopyVariationAxes(font: CTFontRef) -> CFArrayRef;
+
+    fn CGFontCreateCopyWithVariations(font: CGFontRef, vars: CFDictionaryRef) -> CGFontRef;
+}
+
+fn new_ct_font_with_variations(cg_font: &CGFont, size: Au, variations: &[FontVariation]) -> CTFont {
+    unsafe {
+        let ct_font = core_text::font::new_from_CGFont(cg_font, size.to_f64_px());
+        if variations.is_empty() {
+            return ct_font;
+        }
+        let axes_ref = CTFontCopyVariationAxes(ct_font.as_concrete_TypeRef());
+        if axes_ref.is_null() {
+            return ct_font;
+        }
+        let axes: CFArray = TCFType::wrap_under_create_rule(axes_ref);
+        let mut vals: Vec<(CFString, CFNumber)> = Vec::with_capacity(variations.len() as usize);
+        for axis_ptr in axes.iter() {
+            let axis: CFDictionary = TCFType::wrap_under_get_rule(axis_ptr as CFDictionaryRef);
+            if !axis.instance_of::<CFDictionaryRef, CFDictionary>() {
+                return ct_font;
+            }
+            let tag_val = match axis.find(kCTFontVariationAxisIdentifierKey as *const _) {
+                Some(tag_ptr) => {
+                    let tag: CFNumber = TCFType::wrap_under_get_rule(tag_ptr as CFNumberRef);
+                    if !tag.instance_of::<CFNumberRef, CFNumber>() {
+                        return ct_font;
+                    }
+                    match tag.to_i64() {
+                        Some(val) => val,
+                        None => return ct_font,
+                    }
+                }
+                None => return ct_font,
+            };
+            let mut val = match variations.iter().find(|variation| (variation.tag as i64) == tag_val) {
+                Some(variation) => variation.value as f64,
+                None => continue,
+            };
+
+            let name: CFString = match axis.find(kCTFontVariationAxisNameKey as *const _) {
+                Some(name_ptr) => TCFType::wrap_under_get_rule(name_ptr as CFStringRef),
+                None => return ct_font,
+            };
+            if !name.instance_of::<CFStringRef, CFString>() {
+                return ct_font;
+            }
+
+            let min_val = match axis.find(kCTFontVariationAxisMinimumValueKey as *const _) {
+                Some(min_ptr) => {
+                    let min: CFNumber = TCFType::wrap_under_get_rule(min_ptr as CFNumberRef);
+                    if !min.instance_of::<CFNumberRef, CFNumber>() {
+                        return ct_font;
+                    }
+                    match min.to_f64() {
+                        Some(val) => val,
+                        None => return ct_font,
+                    }
+                }
+                None => return ct_font,
+            };
+            let max_val = match axis.find(kCTFontVariationAxisMaximumValueKey as *const _) {
+                Some(max_ptr) => {
+                    let max: CFNumber = TCFType::wrap_under_get_rule(max_ptr as CFNumberRef);
+                    if !max.instance_of::<CFNumberRef, CFNumber>() {
+                        return ct_font;
+                    }
+                    match max.to_f64() {
+                        Some(val) => val,
+                        None => return ct_font,
+                    }
+                }
+                None => return ct_font,
+            };
+            let def_val = match axis.find(kCTFontVariationAxisDefaultValueKey as *const _) {
+                Some(def_ptr) => {
+                    let def: CFNumber = TCFType::wrap_under_get_rule(def_ptr as CFNumberRef);
+                    if !def.instance_of::<CFNumberRef, CFNumber>() {
+                        return ct_font;
+                    }
+                    match def.to_f64() {
+                        Some(val) => val,
+                        None => return ct_font,
+                    }
+                }
+                None => return ct_font,
+            };
+
+            val = val.max(min_val).min(max_val);
+            if val != def_val {
+                vals.push((name, CFNumber::from_f64(val)));
+            }
+        }
+        if vals.is_empty() {
+            return ct_font;
+        }
+        let vals_dict = CFDictionary::from_CFType_pairs(&vals);
+        let cg_var_font_ref = CGFontCreateCopyWithVariations(cg_font.as_concrete_TypeRef(), vals_dict.as_concrete_TypeRef());
+        let cg_var_font: CGFont = TCFType::wrap_under_create_rule(cg_var_font_ref);
+        core_text::font::new_from_CGFont(&cg_var_font, size.to_f64_px())
+    }
+}
+
 impl FontContext {
     pub fn new() -> FontContext {
         debug!("Test for subpixel AA support: {}", supports_subpixel_aa());
 
         // Force CG to use sRGB color space to gamma correct.
         let contrast = 0.0;
         let gamma = 0.0;
 
@@ -199,53 +315,58 @@ impl FontContext {
                 .cloned()
                 .collect::<Vec<_>>();
             for ct_font_key in ct_font_keys {
                 self.ct_fonts.remove(&ct_font_key);
             }
         }
     }
 
-    fn get_ct_font(&mut self, font_key: FontKey, size: Au) -> Option<CTFont> {
-        match self.ct_fonts.entry(((font_key).clone(), size)) {
+    fn get_ct_font(
+        &mut self,
+        font_key: FontKey,
+        size: Au,
+        variations: &[FontVariation],
+    ) -> Option<CTFont> {
+        match self.ct_fonts.entry((font_key, size, variations.to_vec())) {
             Entry::Occupied(entry) => Some((*entry.get()).clone()),
             Entry::Vacant(entry) => {
                 let cg_font = match self.cg_fonts.get(&font_key) {
                     None => return None,
                     Some(cg_font) => cg_font,
                 };
-                let ct_font = core_text::font::new_from_CGFont(cg_font, size.to_f64_px());
+                let ct_font = new_ct_font_with_variations(cg_font, size, variations);
                 entry.insert(ct_font.clone());
                 Some(ct_font)
             }
         }
     }
 
     pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option<u32> {
         let character = ch as u16;
         let mut glyph = 0;
 
-        self.get_ct_font(font_key, Au(16 * 60))
+        self.get_ct_font(font_key, Au(16 * 60), &[])
             .and_then(|ref ct_font| {
                 let result = ct_font.get_glyphs_for_characters(&character, &mut glyph, 1);
 
                 if result {
                     Some(glyph as u32)
                 } else {
                     None
                 }
             })
     }
 
     pub fn get_glyph_dimensions(
         &mut self,
         font: &FontInstance,
         key: &GlyphKey,
     ) -> Option<GlyphDimensions> {
-        self.get_ct_font(font.font_key, font.size)
+        self.get_ct_font(font.font_key, font.size, &font.variations)
             .and_then(|ref ct_font| {
                 let glyph = key.index as CGGlyph;
                 let (x_offset, y_offset) = font.get_subpx_offset(key);
                 let metrics = get_glyph_metrics(ct_font, glyph, x_offset, y_offset);
                 if metrics.rasterized_width == 0 || metrics.rasterized_height == 0 {
                     None
                 } else {
                     Some(GlyphDimensions {
@@ -301,17 +422,17 @@ impl FontContext {
         }
     }
 
     pub fn rasterize_glyph(
         &mut self,
         font: &FontInstance,
         key: &GlyphKey,
     ) -> Option<RasterizedGlyph> {
-        let ct_font = match self.get_ct_font(font.font_key, font.size) {
+        let ct_font = match self.get_ct_font(font.font_key, font.size, &font.variations) {
             Some(font) => font,
             None => return Some(RasterizedGlyph::blank()),
         };
 
         let glyph = key.index as CGGlyph;
         let (x_offset, y_offset) = font.get_subpx_offset(key);
         let metrics = get_glyph_metrics(&ct_font, glyph, x_offset, y_offset);
         if metrics.rasterized_width == 0 || metrics.rasterized_height == 0 {
--- a/gfx/webrender/src/platform/unix/font.rs
+++ b/gfx/webrender/src/platform/unix/font.rs
@@ -4,19 +4,19 @@
 
 use api::{FontInstance, FontKey, FontRenderMode, GlyphDimensions};
 use api::{NativeFontHandle, SubpixelDirection};
 use api::GlyphKey;
 use freetype::freetype::{FT_BBox, FT_Outline_Translate, FT_Pixel_Mode, FT_Render_Mode};
 use freetype::freetype::{FT_Done_Face, FT_Error, FT_Get_Char_Index, FT_Int32};
 use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter, FT_Pos};
 use freetype::freetype::{FT_F26Dot6, FT_Face, FT_Glyph_Format, FT_Long, FT_UInt};
-use freetype::freetype::{FT_GlyphSlot, FT_LcdFilter, FT_New_Memory_Face};
+use freetype::freetype::{FT_GlyphSlot, FT_LcdFilter, FT_New_Memory_Face, FT_Outline_Transform};
 use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph};
-use freetype::freetype::{FT_Library, FT_Outline_Get_CBox, FT_Set_Char_Size};
+use freetype::freetype::{FT_Library, FT_Matrix, FT_Outline_Get_CBox, FT_Set_Char_Size};
 use internal_types::FastHashMap;
 use std::{mem, ptr, slice};
 use std::sync::Arc;
 
 // This constant is not present in the freetype
 // bindings due to bindgen not handling the way
 // the macro is defined.
 const FT_LOAD_TARGET_LIGHT: FT_Int32 = 1 << 16;
@@ -300,16 +300,30 @@ impl FontContext {
             let outline = &(*slot).outline;
             let mut cbox: FT_BBox = mem::uninitialized();
             FT_Outline_Get_CBox(outline, &mut cbox);
             FT_Outline_Translate(
                 outline,
                 dx - ((cbox.xMin + dx) & !63),
                 dy - ((cbox.yMin + dy) & !63),
             );
+
+            if font.synthetic_italics {
+                // These magic numbers are pre-encoded fixed point
+                // values that apply ~12 degree shear. Borrowed
+                // from the Freetype implementation of the
+                // FT_GlyphSlot_Oblique function.
+                let transform = FT_Matrix {
+                    xx: 0x10000,
+                    yx: 0x00000,
+                    xy: 0x0366A,
+                    yy: 0x10000,
+                };
+                FT_Outline_Transform(outline, &transform);
+            }
         }
 
         let result = unsafe { FT_Render_Glyph(slot, render_mode) };
         if result != SUCCESS {
             error!(
                 "Unable to rasterize {:?} with {:?}, {:?}",
                 key,
                 render_mode,
--- a/gfx/webrender/src/render_backend.rs
+++ b/gfx/webrender/src/render_backend.rs
@@ -30,16 +30,17 @@ use thread_profiler::register_thread_wit
 use time::precise_time_ns;
 
 struct Document {
     scene: Scene,
     frame: Frame,
     window_size: DeviceUintSize,
     inner_rect: DeviceUintRect,
     pan: DeviceIntPoint,
+    device_pixel_ratio: f32,
     page_zoom_factor: f32,
     pinch_zoom_factor: f32,
     // A set of pipelines that the caller has requested be
     // made available as output textures.
     output_pipelines: FastHashSet<PipelineId>,
     // A helper switch to prevent any frames rendering triggered by scrolling
     // messages between `SetDisplayList` and `GenerateFrame`.
     // If we allow them, then a reftest that scrolls a few layers before generating
@@ -48,66 +49,69 @@ struct Document {
     render_on_scroll: Option<bool>,
 }
 
 impl Document {
     pub fn new(
         config: FrameBuilderConfig,
         initial_size: DeviceUintSize,
         enable_render_on_scroll: bool,
+        default_device_pixel_ratio: f32,
     ) -> Self {
         let render_on_scroll = if enable_render_on_scroll {
             Some(false)
         } else {
             None
         };
         Document {
             scene: Scene::new(),
             frame: Frame::new(config),
             window_size: initial_size,
             inner_rect: DeviceUintRect::new(DeviceUintPoint::zero(), initial_size),
             pan: DeviceIntPoint::zero(),
             page_zoom_factor: 1.0,
             pinch_zoom_factor: 1.0,
+            device_pixel_ratio: default_device_pixel_ratio,
             render_on_scroll,
             output_pipelines: FastHashSet::default(),
         }
     }
 
-    fn accumulated_scale_factor(&self, hidpi_factor: f32) -> f32 {
-        hidpi_factor * self.page_zoom_factor * self.pinch_zoom_factor
+    fn accumulated_scale_factor(&self) -> f32 {
+        self.device_pixel_ratio *
+        self.page_zoom_factor *
+        self.pinch_zoom_factor
     }
 
-    fn build_scene(&mut self, resource_cache: &mut ResourceCache, hidpi_factor: f32) {
-        let accumulated_scale_factor = self.accumulated_scale_factor(hidpi_factor);
+    fn build_scene(&mut self, resource_cache: &mut ResourceCache) {
+        let accumulated_scale_factor = self.accumulated_scale_factor();
         self.frame.create(
             &self.scene,
             resource_cache,
             self.window_size,
             self.inner_rect,
             accumulated_scale_factor,
         );
     }
 
     fn render(
         &mut self,
         resource_cache: &mut ResourceCache,
         gpu_cache: &mut GpuCache,
         resource_profile: &mut ResourceProfileCounters,
-        hidpi_factor: f32,
     ) -> RendererFrame {
-        let accumulated_scale_factor = self.accumulated_scale_factor(hidpi_factor);
+        let accumulated_scale_factor = self.accumulated_scale_factor();
         let pan = LayerPoint::new(
             self.pan.x as f32 / accumulated_scale_factor,
             self.pan.y as f32 / accumulated_scale_factor,
         );
         self.frame.build(
             resource_cache,
             gpu_cache,
-            &self.scene.display_lists,
+            &self.scene.pipelines,
             accumulated_scale_factor,
             pan,
             &self.output_pipelines,
             &mut resource_profile.texture_cache,
             &mut resource_profile.gpu_cache,
         )
     }
 }
@@ -124,20 +128,18 @@ enum DocumentOp {
 /// GPU-friendly work which is then submitted to the renderer in the form of a frame::Frame.
 ///
 /// The render backend operates on its own thread.
 pub struct RenderBackend {
     api_rx: MsgReceiver<ApiMsg>,
     payload_rx: PayloadReceiver,
     payload_tx: PayloadSender,
     result_tx: Sender<ResultMsg>,
-
-    // TODO(gw): Consider using strongly typed units here.
-    hidpi_factor: f32,
     next_namespace_id: IdNamespace,
+    default_device_pixel_ratio: f32,
 
     gpu_cache: GpuCache,
     resource_cache: ResourceCache,
 
     frame_config: FrameBuilderConfig,
     documents: FastHashMap<DocumentId, Document>,
 
     notifier: Arc<Mutex<Option<Box<RenderNotifier>>>>,
@@ -147,17 +149,17 @@ pub struct RenderBackend {
 }
 
 impl RenderBackend {
     pub fn new(
         api_rx: MsgReceiver<ApiMsg>,
         payload_rx: PayloadReceiver,
         payload_tx: PayloadSender,
         result_tx: Sender<ResultMsg>,
-        hidpi_factor: f32,
+        default_device_pixel_ratio: f32,
         texture_cache: TextureCache,
         workers: Arc<ThreadPool>,
         notifier: Arc<Mutex<Option<Box<RenderNotifier>>>>,
         frame_config: FrameBuilderConfig,
         recorder: Option<Box<ApiRecordingReceiver>>,
         blob_image_renderer: Option<Box<BlobImageRenderer>>,
         enable_render_on_scroll: bool,
     ) -> RenderBackend {
@@ -165,18 +167,17 @@ impl RenderBackend {
 
         register_thread_with_profiler("Backend".to_string());
 
         RenderBackend {
             api_rx,
             payload_rx,
             payload_tx,
             result_tx,
-            hidpi_factor,
-
+            default_device_pixel_ratio,
             resource_cache,
             gpu_cache: GpuCache::new(),
             frame_config,
             documents: FastHashMap::default(),
             next_namespace_id: IdNamespace(1),
             notifier,
             recorder,
 
@@ -212,19 +213,21 @@ impl RenderBackend {
             }
             DocumentMsg::SetPan(pan) => {
                 doc.pan = pan;
                 DocumentOp::Nop
             }
             DocumentMsg::SetWindowParameters {
                 window_size,
                 inner_rect,
+                device_pixel_ratio,
             } => {
                 doc.window_size = window_size;
                 doc.inner_rect = inner_rect;
+                doc.device_pixel_ratio = device_pixel_ratio;
                 DocumentOp::Nop
             }
             DocumentMsg::SetDisplayList {
                 epoch,
                 pipeline_id,
                 background,
                 viewport_size,
                 content_size,
@@ -266,17 +269,17 @@ impl RenderBackend {
                     doc.scene.set_display_list(
                         pipeline_id,
                         epoch,
                         built_display_list,
                         background,
                         viewport_size,
                         content_size,
                     );
-                    doc.build_scene(&mut self.resource_cache, self.hidpi_factor);
+                    doc.build_scene(&mut self.resource_cache);
                 }
 
                 if let Some(ref mut ros) = doc.render_on_scroll {
                     *ros = false; //wait for `GenerateFrame`
                 }
 
                 // Note: this isn't quite right as auxiliary values will be
                 // pulled out somewhere in the prim_store, but aux values are
@@ -293,19 +296,19 @@ impl RenderBackend {
                 );
 
                 DocumentOp::Built
             }
             DocumentMsg::SetRootPipeline(pipeline_id) => {
                 profile_scope!("SetRootPipeline");
 
                 doc.scene.set_root_pipeline_id(pipeline_id);
-                if doc.scene.display_lists.get(&pipeline_id).is_some() {
+                if doc.scene.pipelines.get(&pipeline_id).is_some() {
                     let _timer = profile_counters.total_time.timer();
-                    doc.build_scene(&mut self.resource_cache, self.hidpi_factor);
+                    doc.build_scene(&mut self.resource_cache);
                     DocumentOp::Built
                 } else {
                     DocumentOp::Nop
                 }
             }
             DocumentMsg::RemovePipeline(pipeline_id) => {
                 profile_scope!("RemovePipeline");
 
@@ -317,50 +320,47 @@ impl RenderBackend {
                 let _timer = profile_counters.total_time.timer();
 
                 if doc.frame.scroll(delta, cursor, move_phase) && doc.render_on_scroll == Some(true)
                 {
                     let frame = doc.render(
                         &mut self.resource_cache,
                         &mut self.gpu_cache,
                         &mut profile_counters.resources,
-                        self.hidpi_factor,
                     );
                     DocumentOp::Scrolled(frame)
                 } else {
                     DocumentOp::ScrolledNop
                 }
             }
             DocumentMsg::ScrollNodeWithId(origin, id, clamp) => {
                 profile_scope!("ScrollNodeWithScrollId");
                 let _timer = profile_counters.total_time.timer();
 
                 if doc.frame.scroll_node(origin, id, clamp) && doc.render_on_scroll == Some(true) {
                     let frame = doc.render(
                         &mut self.resource_cache,
                         &mut self.gpu_cache,
                         &mut profile_counters.resources,
-                        self.hidpi_factor,
                     );
                     DocumentOp::Scrolled(frame)
                 } else {
                     DocumentOp::ScrolledNop
                 }
             }
             DocumentMsg::TickScrollingBounce => {
                 profile_scope!("TickScrollingBounce");
                 let _timer = profile_counters.total_time.timer();
 
                 doc.frame.tick_scrolling_bounce_animations();
                 if doc.render_on_scroll == Some(true) {
                     let frame = doc.render(
                         &mut self.resource_cache,
                         &mut self.gpu_cache,
                         &mut profile_counters.resources,
-                        self.hidpi_factor,
                     );
                     DocumentOp::Scrolled(frame)
                 } else {
                     DocumentOp::ScrolledNop
                 }
             }
             DocumentMsg::GetScrollNodeState(tx) => {
                 profile_scope!("GetScrollNodeState");
@@ -378,29 +378,28 @@ impl RenderBackend {
                 // just rebuilds the frame if there are animated property
                 // bindings present for now.
                 // TODO(gw): Once the scrolling / reference frame changes
                 //           are completed, optimize the internals of
                 //           animated properties to not require a full
                 //           rebuild of the frame!
                 if let Some(property_bindings) = property_bindings {
                     doc.scene.properties.set_properties(property_bindings);
-                    doc.build_scene(&mut self.resource_cache, self.hidpi_factor);
+                    doc.build_scene(&mut self.resource_cache);
                 }
 
                 if let Some(ref mut ros) = doc.render_on_scroll {
                     *ros = true;
                 }
 
                 if doc.scene.root_pipeline_id.is_some() {
                     let frame = doc.render(
                         &mut self.resource_cache,
                         &mut self.gpu_cache,
                         &mut profile_counters.resources,
-                        self.hidpi_factor,
                     );
                     DocumentOp::Rendered(frame)
                 } else {
                     DocumentOp::ScrolledNop
                 }
             }
         }
     }
@@ -451,16 +450,17 @@ impl RenderBackend {
                     self.next_namespace_id = IdNamespace(namespace.0 + 1);
                     sender.send(namespace).unwrap();
                 }
                 ApiMsg::AddDocument(document_id, initial_size) => {
                     let document = Document::new(
                         self.frame_config.clone(),
                         initial_size,
                         self.enable_render_on_scroll,
+                        self.default_device_pixel_ratio,
                     );
                     self.documents.insert(document_id, document);
                 }
                 ApiMsg::UpdateDocument(document_id, doc_msg) => match self.process_document(
                     document_id,
                     doc_msg,
                     frame_counter,
                     &mut profile_counters,
@@ -640,19 +640,19 @@ impl RenderBackend {
 
     #[cfg(feature = "debugger")]
     fn get_docs_for_debugger(&self) -> String {
         let mut docs = debug_server::DocumentList::new();
 
         for (_, doc) in &self.documents {
             let mut debug_doc = debug_server::TreeNode::new("document");
 
-            for (_, display_list) in &doc.scene.display_lists {
+            for (_, pipeline) in &doc.scene.pipelines {
                 let mut debug_dl = debug_server::TreeNode::new("display_list");
-                self.traverse_items(&mut display_list.iter(), &mut debug_dl);
+                self.traverse_items(&mut pipeline.display_list.iter(), &mut debug_dl);
                 debug_doc.add_child(debug_dl);
             }
 
             docs.add(debug_doc);
         }
 
         serde_json::to_string(&docs).unwrap()
     }
--- a/gfx/webrender/src/resource_cache.rs
+++ b/gfx/webrender/src/resource_cache.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use api::{AddFont, BlobImageData, BlobImageResources, ResourceUpdate, ResourceUpdates};
 use api::{BlobImageDescriptor, BlobImageError, BlobImageRenderer, BlobImageRequest};
 use api::{ColorF, FontRenderMode, SubpixelDirection};
 use api::{DevicePoint, DeviceUintRect, DeviceUintSize};
 use api::{Epoch, FontInstance, FontInstanceKey, FontKey, FontTemplate};
 use api::{ExternalImageData, ExternalImageType};
-use api::{FontInstanceOptions, FontInstancePlatformOptions};
+use api::{FontInstanceOptions, FontInstancePlatformOptions, FontVariation};
 use api::{GlyphDimensions, GlyphKey, IdNamespace};
 use api::{ImageData, ImageDescriptor, ImageKey, ImageRendering};
 use api::{TileOffset, TileSize};
 use app_units::Au;
 use device::TextureFilter;
 use frame::FrameId;
 use glyph_cache::GlyphCache;
 use glyph_rasterizer::{GlyphRasterizer, GlyphRequest};
@@ -298,16 +298,17 @@ impl ResourceCache {
                 }
                 ResourceUpdate::AddFontInstance(instance) => {
                     self.add_font_instance(
                         instance.key,
                         instance.font_key,
                         instance.glyph_size,
                         instance.options,
                         instance.platform_options,
+                        instance.variations,
                     );
                 }
                 ResourceUpdate::DeleteFontInstance(instance) => {
                     self.delete_font_instance(instance);
                 }
             }
         }
     }
@@ -329,32 +330,37 @@ impl ResourceCache {
 
     pub fn add_font_instance(
         &mut self,
         instance_key: FontInstanceKey,
         font_key: FontKey,
         glyph_size: Au,
         options: Option<FontInstanceOptions>,
         platform_options: Option<FontInstancePlatformOptions>,
+        variations: Vec<FontVariation>,
     ) {
-        let mut render_mode = FontRenderMode::Subpixel;
+        let mut requested_render_mode = FontRenderMode::Subpixel;
         let mut subpx_dir = SubpixelDirection::Horizontal;
         if let Some(options) = options {
-            render_mode = options.render_mode;
-            if render_mode == FontRenderMode::Mono {
-                subpx_dir = SubpixelDirection::None;
+            if let Some(render_mode) = options.render_mode {
+                requested_render_mode = render_mode;
             }
         }
+        if requested_render_mode == FontRenderMode::Mono {
+            subpx_dir = SubpixelDirection::None;
+        }
         let instance = FontInstance::new(
             font_key,
             glyph_size,
             ColorF::new(0.0, 0.0, 0.0, 1.0),
-            render_mode,
+            requested_render_mode,
             subpx_dir,
             platform_options,
+            variations,
+            options.map_or(false, |opts| opts.synthetic_italics),
         );
         self.resources.font_instances.insert(instance_key, instance);
     }
 
     pub fn delete_font_instance(&mut self, instance_key: FontInstanceKey) {
         self.resources.font_instances.remove(&instance_key);
         if let Some(ref mut r) = self.blob_image_renderer {
             r.delete_font_instance(instance_key);
--- a/gfx/webrender/src/scene.rs
+++ b/gfx/webrender/src/scene.rs
@@ -1,14 +1,15 @@
 /* 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/. */
 
 use api::{BuiltDisplayList, ColorF, DynamicProperties, Epoch, LayerSize, LayoutSize};
-use api::{LayoutTransform, PipelineId, PropertyBinding, PropertyBindingId};
+use api::{FilterOp, LayoutTransform, PipelineId, PropertyBinding, PropertyBindingId};
+use api::{ItemRange, MixBlendMode, StackingContext};
 use internal_types::FastHashMap;
 
 /// Stores a map of the animated property bindings for the current display list. These
 /// can be used to animate the transform and/or opacity of a display list without
 /// re-submitting the display list itself.
 pub struct SceneProperties {
     transform_properties: FastHashMap<PropertyBindingId, LayoutTransform>,
     float_properties: FastHashMap<PropertyBindingId, f32>,
@@ -71,69 +72,137 @@ impl SceneProperties {
                     warn!("Property binding {:?} has an invalid value.", key);
                     default_value
                 }),
         }
     }
 }
 
 /// A representation of the layout within the display port for a given document or iframe.
-#[derive(Debug)]
 pub struct ScenePipeline {
     pub pipeline_id: PipelineId,
     pub epoch: Epoch,
     pub viewport_size: LayerSize,
     pub content_size: LayoutSize,
     pub background_color: Option<ColorF>,
+    pub display_list: BuiltDisplayList,
 }
 
 /// A complete representation of the layout bundling visible pipelines together.
 pub struct Scene {
     pub root_pipeline_id: Option<PipelineId>,
-    pub pipeline_map: FastHashMap<PipelineId, ScenePipeline>,
-    pub display_lists: FastHashMap<PipelineId, BuiltDisplayList>,
+    pub pipelines: FastHashMap<PipelineId, ScenePipeline>,
     pub properties: SceneProperties,
 }
 
 impl Scene {
     pub fn new() -> Scene {
         Scene {
             root_pipeline_id: None,
-            pipeline_map: FastHashMap::default(),
-            display_lists: FastHashMap::default(),
+            pipelines: FastHashMap::default(),
             properties: SceneProperties::new(),
         }
     }
 
     pub fn set_root_pipeline_id(&mut self, pipeline_id: PipelineId) {
         self.root_pipeline_id = Some(pipeline_id);
     }
 
     pub fn set_display_list(
         &mut self,
         pipeline_id: PipelineId,
         epoch: Epoch,
-        built_display_list: BuiltDisplayList,
+        display_list: BuiltDisplayList,
         background_color: Option<ColorF>,
         viewport_size: LayerSize,
         content_size: LayoutSize,
     ) {
-        self.display_lists.insert(pipeline_id, built_display_list);
-
         let new_pipeline = ScenePipeline {
             pipeline_id,
             epoch,
             viewport_size,
             content_size,
             background_color,
+            display_list,
         };
 
-        self.pipeline_map.insert(pipeline_id, new_pipeline);
+        self.pipelines.insert(pipeline_id, new_pipeline);
     }
 
     pub fn remove_pipeline(&mut self, pipeline_id: PipelineId) {
         if self.root_pipeline_id == Some(pipeline_id) {
             self.root_pipeline_id = None;
         }
-        self.display_lists.remove(&pipeline_id);
-        self.pipeline_map.remove(&pipeline_id);
+        self.pipelines.remove(&pipeline_id);
     }
 }
+
+pub trait FilterOpHelpers {
+    fn resolve(self, properties: &SceneProperties) -> FilterOp;
+    fn is_noop(&self) -> bool;
+}
+
+impl FilterOpHelpers for FilterOp {
+    fn resolve(self, properties: &SceneProperties) -> FilterOp {
+        match self {
+            FilterOp::Opacity(ref value) => {
+                let amount = properties.resolve_float(value, 1.0);
+                FilterOp::Opacity(PropertyBinding::Value(amount))
+            }
+            _ => self,
+        }
+    }
+
+    fn is_noop(&self) -> bool {
+        match *self {
+            FilterOp::Blur(length) => length == 0.0,
+            FilterOp::Brightness(amount) => amount == 1.0,
+            FilterOp::Contrast(amount) => amount == 1.0,
+            FilterOp::Grayscale(amount) => amount == 0.0,
+            FilterOp::HueRotate(amount) => amount == 0.0,
+            FilterOp::Invert(amount) => amount == 0.0,
+            FilterOp::Opacity(value) => match value {
+                PropertyBinding::Value(amount) => amount == 1.0,
+                PropertyBinding::Binding(..) => {
+                    panic!("bug: binding value should be resolved");
+                }
+            },
+            FilterOp::Saturate(amount) => amount == 1.0,
+            FilterOp::Sepia(amount) => amount == 0.0,
+        }
+    }
+}
+
+pub trait StackingContextHelpers {
+    fn mix_blend_mode_for_compositing(&self) -> Option<MixBlendMode>;
+    fn filter_ops_for_compositing(
+        &self,
+        display_list: &BuiltDisplayList,
+        input_filters: ItemRange<FilterOp>,
+        properties: &SceneProperties,
+    ) -> Vec<FilterOp>;
+}
+
+impl StackingContextHelpers for StackingContext {
+    fn mix_blend_mode_for_compositing(&self) -> Option<MixBlendMode> {
+        match self.mix_blend_mode {
+            MixBlendMode::Normal => None,
+            _ => Some(self.mix_blend_mode),
+        }
+    }
+
+    fn filter_ops_for_compositing(
+        &self,
+        display_list: &BuiltDisplayList,
+        input_filters: ItemRange<FilterOp>,
+        properties: &SceneProperties,
+    ) -> Vec<FilterOp> {
+        let mut filters = vec![];
+        for filter in display_list.get(input_filters) {
+            let filter = filter.resolve(properties);
+            if filter.is_noop() {
+                continue;
+            }
+            filters.push(filter);
+        }
+        filters
+    }
+}
--- a/gfx/webrender/src/texture_cache.rs
+++ b/gfx/webrender/src/texture_cache.rs
@@ -665,17 +665,17 @@ impl TextureCache {
                 // This handle has never been allocated, so just
                 // insert a new cache entry.
                 Some(self.entries.insert(new_cache_entry))
             }
         };
 
         // If the cache entry is new, update it in the cache handle.
         if let Some(new_entry_handle) = new_entry_handle {
-            handle.entry = Some(self.entries.create_weak_handle(&new_entry_handle));
+            handle.entry = Some(new_entry_handle.weak());
             // Store the strong handle in the list that we scan for
             // cache evictions.
             if allocated_in_shared_cache {
                 self.shared_entry_handles.push(new_entry_handle);
             } else {
                 self.standalone_entry_handles.push(new_entry_handle);
             }
         }
--- a/gfx/webrender/src/tiling.rs
+++ b/gfx/webrender/src/tiling.rs
@@ -1,13 +1,13 @@
 /* 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/. */
 
-use api::{BuiltDisplayList, ClipAndScrollInfo, ClipId, ColorF, DeviceIntPoint, ImageKey};
+use api::{ClipAndScrollInfo, ClipId, ColorF, DeviceIntPoint, ImageKey};
 use api::{DeviceIntRect, DeviceIntSize, DeviceUintPoint, DeviceUintSize};
 use api::{ExternalImageType, FilterOp, FontRenderMode, ImageRendering, LayerRect};
 use api::{LayerToWorldTransform, MixBlendMode, PipelineId, PropertyBinding, TransformStyle};
 use api::{LayerVector2D, TileOffset, WorldToLayerTransform, YuvColorSpace, YuvFormat};
 use border::{BorderCornerInstance, BorderCornerSide};
 use clip::{ClipSource, ClipStore};
 use device::Texture;
 use gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle, GpuCacheUpdateList};
@@ -28,18 +28,16 @@ use std::{cmp, usize, f32, i32};
 use texture_allocator::GuillotineAllocator;
 use util::{TransformedRect, TransformedRectKind};
 
 // Special sentinel value recognized by the shader. It is considered to be
 // a dummy task that doesn't mask out anything.
 const OPAQUE_TASK_ADDRESS: RenderTaskAddress = RenderTaskAddress(i32::MAX as u32);
 const MIN_TARGET_SIZE: u32 = 2048;
 
-pub type DisplayListMap = FastHashMap<PipelineId, BuiltDisplayList>;
-
 trait AlphaBatchHelpers {
     fn get_blend_mode(
         &self,
         metadata: &PrimitiveMetadata,
         transform_kind: TransformedRectKind,
     ) -> BlendMode;
 }
 
--- a/gfx/webrender_api/Cargo.toml
+++ b/gfx/webrender_api/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "webrender_api"
-version = "0.50.0"
+version = "0.52.0"
 authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
 license = "MPL-2.0"
 repository = "https://github.com/servo/webrender"
 
 [features]
 nightly = ["euclid/unstable", "serde/unstable"]
 ipc = ["ipc-channel"]
 
@@ -16,13 +16,13 @@ byteorder = "1.0"
 euclid = "0.15"
 fxhash = "0.2.1"
 heapsize = ">= 0.3.6, < 0.5"
 ipc-channel = {version = "0.8", optional = true}
 serde = { version = "1.0", features = ["rc", "derive"] }
 time = "0.1"
 
 [target.'cfg(target_os = "macos")'.dependencies]
-core-foundation = "0.3"
-core-graphics = "0.8"
+core-foundation = "0.4"
+core-graphics = "0.9"
 
 [target.'cfg(target_os = "windows")'.dependencies]
 dwrote = "0.4"
--- a/gfx/webrender_api/src/api.rs
+++ b/gfx/webrender_api/src/api.rs
@@ -1,15 +1,16 @@
 /* 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/. */
 
 use {BuiltDisplayList, BuiltDisplayListDescriptor, ClipId, ColorF, DeviceIntPoint};
 use {DeviceUintRect, DeviceUintSize, FontInstanceKey, FontKey, GlyphDimensions, GlyphKey};
-use {FontInstance, FontInstanceOptions, FontInstancePlatformOptions, NativeFontHandle, WorldPoint};
+use {FontInstance, FontInstanceOptions, FontInstancePlatformOptions, FontVariation,
+     NativeFontHandle, WorldPoint};
 use {ImageData, ImageDescriptor, ImageKey, LayoutPoint, LayoutSize, LayoutTransform,
      LayoutVector2D};
 use app_units::Au;
 use channel::{self, MsgSender, Payload, PayloadSender, PayloadSenderHelperMethods};
 use std::cell::Cell;
 use std::fmt;
 use std::marker::PhantomData;
 
@@ -89,24 +90,26 @@ impl ResourceUpdates {
 
     pub fn add_font_instance(
         &mut self,
         key: FontInstanceKey,
         font_key: FontKey,
         glyph_size: Au,
         options: Option<FontInstanceOptions>,
         platform_options: Option<FontInstancePlatformOptions>,
+        variations: Vec<FontVariation>,
     ) {
         self.updates
             .push(ResourceUpdate::AddFontInstance(AddFontInstance {
                 key,
                 font_key,
                 glyph_size,
                 options,
                 platform_options,
+                variations,
             }));
     }
 
     pub fn delete_font_instance(&mut self, key: FontInstanceKey) {
         self.updates.push(ResourceUpdate::DeleteFontInstance(key));
     }
 
     pub fn merge(&mut self, mut other: ResourceUpdates) {
@@ -142,16 +145,17 @@ pub enum AddFont {
 
 #[derive(Clone, Deserialize, Serialize)]
 pub struct AddFontInstance {
     pub key: FontInstanceKey,
     pub font_key: FontKey,
     pub glyph_size: Au,
     pub options: Option<FontInstanceOptions>,
     pub platform_options: Option<FontInstancePlatformOptions>,
+    pub variations: Vec<FontVariation>,
 }
 
 #[derive(Clone, Deserialize, Serialize)]
 pub enum DocumentMsg {
     SetDisplayList {
         list_descriptor: BuiltDisplayListDescriptor,
         epoch: Epoch,
         pipeline_id: PipelineId,
@@ -165,16 +169,17 @@ pub enum DocumentMsg {
     SetPinchZoom(ZoomFactor),
     SetPan(DeviceIntPoint),
     SetRootPipeline(PipelineId),
     RemovePipeline(PipelineId),
     EnableFrameOutput(PipelineId, bool),
     SetWindowParameters {
         window_size: DeviceUintSize,
         inner_rect: DeviceUintRect,
+        device_pixel_ratio: f32,
     },
     Scroll(ScrollLocation, WorldPoint, ScrollEventPhase),
     ScrollNodeWithId(LayoutPoint, ClipId, ScrollClamping),
     TickScrollingBounce,
     GetScrollNodeState(MsgSender<Vec<ScrollLayerState>>),
     GenerateFrame(Option<DynamicProperties>),
 }
 
@@ -619,22 +624,24 @@ impl RenderApi {
         self.send(document_id, DocumentMsg::SetPan(pan));
     }
 
     pub fn set_window_parameters(
         &self,
         document_id: DocumentId,
         window_size: DeviceUintSize,
         inner_rect: DeviceUintRect,
+        device_pixel_ratio: f32,
     ) {
         self.send(
             document_id,
             DocumentMsg::SetWindowParameters {
                 window_size,
                 inner_rect,
+                device_pixel_ratio,
             },
         );
     }
 
     pub fn tick_scrolling_bounce_animations(&self, document_id: DocumentId) {
         self.send(document_id, DocumentMsg::TickScrollingBounce);
     }
 
--- a/gfx/webrender_api/src/color.rs
+++ b/gfx/webrender_api/src/color.rs
@@ -55,17 +55,17 @@ impl Hash for ColorF {
         self.r._to_bits().hash(state);
         self.g._to_bits().hash(state);
         self.b._to_bits().hash(state);
         self.a._to_bits().hash(state);
     }
 }
 
 // FIXME: remove this when Rust 1.21 is stable (float_bits_conv)
-trait ToBits {
+pub trait ToBits {
     fn _to_bits(self) -> u32;
 }
 impl ToBits for f32 {
     fn _to_bits(self) -> u32 {
         unsafe { ::std::mem::transmute(self) }
     }
 }
 
--- a/gfx/webrender_api/src/font.rs
+++ b/gfx/webrender_api/src/font.rs
@@ -1,24 +1,26 @@
 /* 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/. */
 
-use {ColorF, ColorU, IdNamespace, LayoutPoint};
+use {ColorF, ColorU, IdNamespace, LayoutPoint, ToBits};
 use app_units::Au;
 #[cfg(target_os = "macos")]
 use core_foundation::string::CFString;
 #[cfg(target_os = "macos")]
 use core_graphics::font::CGFont;
 #[cfg(target_os = "windows")]
 use dwrote::FontDescriptor;
 #[cfg(target_os = "macos")]
 use serde::de::{self, Deserialize, Deserializer};
 #[cfg(target_os = "macos")]
 use serde::ser::{Serialize, Serializer};
+use std::cmp::Ordering;
+use std::hash::{Hash, Hasher};
 use std::sync::Arc;
 
 
 #[cfg(target_os = "macos")]
 #[derive(Clone)]
 pub struct NativeFontHandle(pub CGFont);
 
 #[cfg(target_os = "macos")]
@@ -108,17 +110,17 @@ impl FontRenderMode {
         // Following the conventions of Gecko and Skia, we want
         // to quantize the subpixel position, such that abs(pos) gives:
         // [0.0, 0.125) -> Zero
         // [0.125, 0.375) -> Quarter
         // [0.375, 0.625) -> Half
         // [0.625, 0.875) -> ThreeQuarters,
         // [0.875, 1.0) -> Zero
         // The unit tests below check for this.
-        let apos = (pos.fract() * 8.0).abs() as i32;
+        let apos = ((pos - pos.floor()) * 8.0) as i32;
 
         match apos {
             0 | 7 => SubpixelOffset::Zero,
             1...2 => SubpixelOffset::Quarter,
             3...4 => SubpixelOffset::Half,
             5...6 => SubpixelOffset::ThreeQuarters,
             _ => unreachable!("bug: unexpected quantized result"),
         }
@@ -149,25 +151,56 @@ impl Into<f64> for SubpixelOffset {
             SubpixelOffset::Quarter => 0.25,
             SubpixelOffset::Half => 0.5,
             SubpixelOffset::ThreeQuarters => 0.75,
         }
     }
 }
 
 #[repr(C)]
+#[derive(Clone, Copy, Debug, PartialOrd, Deserialize, Serialize)]
+pub struct FontVariation {
+    pub tag: u32,
+    pub value: f32,
+}
+
+impl Ord for FontVariation {
+    fn cmp(&self, other: &FontVariation) -> Ordering {
+        self.tag.cmp(&other.tag)
+            .then(self.value._to_bits().cmp(&other.value._to_bits()))
+    }
+}
+
+impl PartialEq for FontVariation {
+    fn eq(&self, other: &FontVariation) -> bool {
+        self.tag == other.tag &&
+        self.value._to_bits() == other.value._to_bits()
+    }
+}
+
+impl Eq for FontVariation {}
+
+impl Hash for FontVariation {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.tag.hash(state);
+        self.value._to_bits().hash(state);
+    }
+}
+
+#[repr(C)]
 #[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
 pub struct GlyphOptions {
     pub render_mode: FontRenderMode,
 }
 
 #[repr(C)]
 #[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
 pub struct FontInstanceOptions {
-    pub render_mode: FontRenderMode,
+    pub render_mode: Option<FontRenderMode>,
+    pub synthetic_italics: bool,
 }
 
 #[repr(C)]
 #[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
 pub struct FontInstancePlatformOptions {
     // These are currently only used on windows for dwrite fonts.
     pub use_embedded_bitmap: bool,
     pub force_gdi_rendering: bool,
@@ -181,41 +214,47 @@ pub struct FontInstance {
     // can't store as a f32 due to use of this type as a hash key.
     // TODO(gw): Perhaps consider having LogicalAu and DeviceAu
     //           or something similar to that.
     pub size: Au,
     pub color: ColorU,
     pub render_mode: FontRenderMode,
     pub subpx_dir: SubpixelDirection,
     pub platform_options: Option<FontInstancePlatformOptions>,
+    pub variations: Vec<FontVariation>,
+    pub synthetic_italics: bool,
 }
 
 impl FontInstance {
     pub fn new(
         font_key: FontKey,
         size: Au,
         mut color: ColorF,
         render_mode: FontRenderMode,
         subpx_dir: SubpixelDirection,
         platform_options: Option<FontInstancePlatformOptions>,
+        variations: Vec<FontVariation>,
+        synthetic_italics: bool,
     ) -> FontInstance {
         // In alpha/mono mode, the color of the font is irrelevant.
         // Forcing it to black in those cases saves rasterizing glyphs
         // of different colors when not needed.
         if render_mode != FontRenderMode::Subpixel {
             color = ColorF::new(0.0, 0.0, 0.0, 1.0);
         }
 
         FontInstance {
             font_key,
             size,
             color: color.into(),
             render_mode,
             subpx_dir,
             platform_options,
+            variations,
+            synthetic_italics,
         }
     }
 
     pub fn get_subpx_offset(&self, glyph: &GlyphKey) -> (f64, f64) {
         match self.subpx_dir {
             SubpixelDirection::None => (0.0, 0.0),
             SubpixelDirection::Horizontal => (glyph.subpixel_offset.into(), 0.0),
             SubpixelDirection::Vertical => (0.0, glyph.subpixel_offset.into()),
@@ -307,13 +346,13 @@ mod test {
         assert_eq!(rm.subpixel_quantize_offset(0.89), SubpixelOffset::Zero);
         assert_eq!(rm.subpixel_quantize_offset(0.91), SubpixelOffset::Zero);
         assert_eq!(rm.subpixel_quantize_offset(0.967), SubpixelOffset::Zero);
         assert_eq!(rm.subpixel_quantize_offset(0.999), SubpixelOffset::Zero);
 
         assert_eq!(rm.subpixel_quantize_offset(-1.0), SubpixelOffset::Zero);
         assert_eq!(rm.subpixel_quantize_offset(1.0), SubpixelOffset::Zero);
         assert_eq!(rm.subpixel_quantize_offset(1.5), SubpixelOffset::Half);
-        assert_eq!(rm.subpixel_quantize_offset(-1.625), SubpixelOffset::ThreeQuarters);
-        assert_eq!(rm.subpixel_quantize_offset(-4.33), SubpixelOffset::Quarter);
+        assert_eq!(rm.subpixel_quantize_offset(-1.625), SubpixelOffset::Half);
+        assert_eq!(rm.subpixel_quantize_offset(-4.33), SubpixelOffset::ThreeQuarters);
 
     }
 }
--- a/gfx/webrender_bindings/Cargo.toml
+++ b/gfx/webrender_bindings/Cargo.toml
@@ -1,19 +1,19 @@
 [package]
 name = "webrender_bindings"
 version = "0.1.0"
 authors = ["The Mozilla Project Developers"]
 license = "MPL-2.0"
 
 [dependencies]
-webrender_api = {path = "../webrender_api", version = "0.50.0"}
+webrender_api = {path = "../webrender_api", version = "0.52.0"}
 bincode = "0.8"
 rayon = "0.8"
 thread_profiler = "0.1.1"
 euclid = "0.15"
 app_units = "0.5.6"
 gleam = "0.4"
 
 [dependencies.webrender]
 path = "../webrender"
-version = "0.50.0"
+version = "0.52.0"
 default-features = false
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -563,20 +563,22 @@ ResourceUpdateQueue::DeleteFont(wr::Font
   wr_resource_updates_delete_font(mUpdates, aKey);
 }
 
 void
 ResourceUpdateQueue::AddFontInstance(wr::FontInstanceKey aKey,
                                      wr::FontKey aFontKey,
                                      float aGlyphSize,
                                      const wr::FontInstanceOptions* aOptions,
-                                     const wr::FontInstancePlatformOptions* aPlatformOptions)
+                                     const wr::FontInstancePlatformOptions* aPlatformOptions,
+                                     wr::Vec_u8& aVariations)
 {
   wr_resource_updates_add_font_instance(mUpdates, aKey, aFontKey, aGlyphSize,
-                                        aOptions, aPlatformOptions);
+                                        aOptions, aPlatformOptions,
+                                        &aVariations.inner);
 }
 
 void
 ResourceUpdateQueue::DeleteFontInstance(wr::FontInstanceKey aKey)
 {
   wr_resource_updates_delete_font_instance(mUpdates, aKey);
 }
 
@@ -617,16 +619,17 @@ void
 WebRenderAPI::RunOnRenderThread(UniquePtr<RendererEvent> aEvent)
 {
   auto event = reinterpret_cast<uintptr_t>(aEvent.release());
   wr_api_send_external_event(mDocHandle, event);
 }
 
 DisplayListBuilder::DisplayListBuilder(PipelineId aId,
                                        const wr::LayoutSize& aContentSize)
+  : mMaskClipCount(0)
 {
   MOZ_COUNT_CTOR(DisplayListBuilder);
   mWrState = wr_state_new(aId, aContentSize);
 }
 
 DisplayListBuilder::~DisplayListBuilder()
 {
   MOZ_COUNT_DTOR(DisplayListBuilder);
@@ -702,31 +705,35 @@ DisplayListBuilder::DefineClip(const wr:
   WRDL_LOG("DefineClip id=%" PRIu64 " r=%s m=%p b=%s complex=%zu\n", mWrState,
       clip_id, Stringify(aClipRect).c_str(), aMask,
       aMask ? Stringify(aMask->rect).c_str() : "none",
       aComplex ? aComplex->Length() : 0);
   return wr::WrClipId { clip_id };
 }
 
 void
-DisplayListBuilder::PushClip(const wr::WrClipId& aClipId, bool aRecordInStack)
+DisplayListBuilder::PushClip(const wr::WrClipId& aClipId, bool aMask)
 {
   wr_dp_push_clip(mWrState, aClipId.id);
   WRDL_LOG("PushClip id=%" PRIu64 "\n", mWrState, aClipId.id);
-  if (aRecordInStack) {
+  if (!aMask) {
     mClipIdStack.push_back(aClipId);
+  } else {
+    mMaskClipCount++;
   }
 }
 
 void
-DisplayListBuilder::PopClip(bool aRecordInStack)
+DisplayListBuilder::PopClip(bool aMask)
 {
   WRDL_LOG("PopClip id=%" PRIu64 "\n", mWrState, mClipIdStack.back().id);
-  if (aRecordInStack) {
+  if (!aMask) {
     mClipIdStack.pop_back();
+  } else {
+    mMaskClipCount--;
   }
   wr_dp_pop_clip(mWrState);
 }
 
 wr::WrStickyId
 DisplayListBuilder::DefineStickyFrame(const wr::LayoutRect& aContentRect,
                                       const wr::StickySideConstraint* aTop,
                                       const wr::StickySideConstraint* aRight,
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -96,17 +96,18 @@ public:
   void AddRawFont(wr::FontKey aKey, wr::Vec_u8& aBytes, uint32_t aIndex);
 
   void DeleteFont(wr::FontKey aKey);
 
   void AddFontInstance(wr::FontInstanceKey aKey,
                        wr::FontKey aFontKey,
                        float aGlyphSize,
                        const wr::FontInstanceOptions* aOptions,
-                       const wr::FontInstancePlatformOptions* aPlatformOptions);
+                       const wr::FontInstancePlatformOptions* aPlatformOptions,
+                       wr::Vec_u8& aVariations);
 
   void DeleteFontInstance(wr::FontInstanceKey aKey);
 
   void Clear();
 
   // Try to avoid using this when possible.
   wr::ResourceUpdates* Raw() { return mUpdates; }
 
@@ -221,18 +222,18 @@ public:
                            const wr::MixBlendMode& aMixBlendMode,
                            const nsTArray<wr::WrFilterOp>& aFilters,
                            bool aIsBackfaceVisible);
   void PopStackingContext();
 
   wr::WrClipId DefineClip(const wr::LayoutRect& aClipRect,
                           const nsTArray<wr::WrComplexClipRegion>* aComplex = nullptr,
                           const wr::WrImageMask* aMask = nullptr);
-  void PushClip(const wr::WrClipId& aClipId, bool aRecordInStack = true);
-  void PopClip(bool aRecordInStack = true);
+  void PushClip(const wr::WrClipId& aClipId, bool aMask = false);
+  void PopClip(bool aMask = false);
 
   wr::WrStickyId DefineStickyFrame(const wr::LayoutRect& aContentRect,
                                    const wr::StickySideConstraint* aTop,
                                    const wr::StickySideConstraint* aRight,
                                    const wr::StickySideConstraint* aBottom,
                                    const wr::StickySideConstraint* aLeft);
   void PushStickyFrame(const wr::WrStickyId& aStickyId);
   void PopStickyFrame();
@@ -396,31 +397,38 @@ public:
   layers::FrameMetrics::ViewID TopmostScrollId();
   // Returns the scroll id that was pushed just before the given scroll id. This
   // function returns Nothing() if the given scrollid has not been encountered,
   // or if it is the rootmost scroll id (and therefore has no ancestor).
   Maybe<layers::FrameMetrics::ViewID> ParentScrollIdFor(layers::FrameMetrics::ViewID aScrollId);
 
   // Try to avoid using this when possible.
   wr::WrState* Raw() { return mWrState; }
+
+  // Return true if the current clip stack has any mask type clip.
+  bool HasMaskClip() { return mMaskClipCount > 0; }
+
 protected:
   wr::WrState* mWrState;
 
   // Track the stack of clip ids and scroll layer ids that have been pushed
   // (by PushClip and PushScrollLayer, respectively) and are still active.
   // This is helpful for knowing e.g. what the ancestor scroll id of a particular
   // scroll id is, and doing other "queries" of current state.
   std::vector<wr::WrClipId> mClipIdStack;
   std::vector<layers::FrameMetrics::ViewID> mScrollIdStack;
 
   // Track the parent scroll id of each scroll id that we encountered. A
   // Nothing() value indicates a root scroll id. We also use this structure to
   // ensure that we don't define a particular scroll layer multiple times.
   std::unordered_map<layers::FrameMetrics::ViewID, Maybe<layers::FrameMetrics::ViewID>> mScrollParents;
 
+  // The number of mask clips that are in the stack.
+  uint32_t mMaskClipCount;
+
   friend class WebRenderAPI;
 };
 
 Maybe<wr::ImageFormat>
 SurfaceFormatToImageFormat(gfx::SurfaceFormat aFormat);
 
 } // namespace wr
 } // namespace mozilla
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -23,16 +23,17 @@
 namespace mozilla {
 namespace wr {
 
 typedef wr::WrWindowId WindowId;
 typedef wr::WrPipelineId PipelineId;
 typedef wr::WrImageKey ImageKey;
 typedef wr::WrFontKey FontKey;
 typedef wr::WrFontInstanceKey FontInstanceKey;
+typedef wr::WrFontInstanceOptions FontInstanceOptions;
 typedef wr::WrEpoch Epoch;
 typedef wr::WrExternalImageId ExternalImageId;
 typedef wr::WrDebugFlags DebugFlags;
 
 typedef mozilla::Maybe<mozilla::wr::WrImageMask> MaybeImageMask;
 typedef Maybe<ExternalImageId> MaybeExternalImageId;
 
 typedef Maybe<FontInstanceOptions> MaybeFontInstanceOptions;
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -84,21 +84,32 @@ pub struct WrVecU8 {
 
 impl WrVecU8 {
     fn to_vec(self) -> Vec<u8> {
         unsafe { Vec::from_raw_parts(self.data, self.length, self.capacity) }
     }
 
     // Equivalent to `to_vec` but clears self instead of consuming the value.
     fn flush_into_vec(&mut self) -> Vec<u8> {
-        let vec = unsafe { Vec::from_raw_parts(self.data, self.length, self.capacity) };
+        self.convert_into_vec::<u8>()
+    }
+
+    // Like flush_into_vec, but also does an unsafe conversion to the desired type.
+    fn convert_into_vec<T>(&mut self) -> Vec<T> {
+        let vec = unsafe {
+            Vec::from_raw_parts(
+                self.data as *mut T,
+                self.length / mem::size_of::<T>(),
+                self.capacity / mem::size_of::<T>(),
+            )
+        };
         self.data = ptr::null_mut();
         self.length = 0;
         self.capacity = 0;
-        return vec;
+        vec
     }
 
     fn from_vec(mut v: Vec<u8>) -> WrVecU8 {
         let w = WrVecU8 {
             data: v.as_mut_ptr(),
             length: v.len(),
             capacity: v.capacity(),
         };
@@ -160,16 +171,32 @@ impl MutByteSlice {
 
     pub fn as_mut_slice(&mut self) -> &mut [u8] {
         make_slice_mut(self.buffer, self.len)
     }
 }
 
 #[repr(C)]
 #[derive(Debug, Clone, Copy)]
+pub struct WrFontInstanceOptions {
+    pub render_mode: FontRenderMode,
+    pub synthetic_italics: bool,
+}
+
+impl Into<FontInstanceOptions> for WrFontInstanceOptions {
+    fn into(self) -> FontInstanceOptions {
+        FontInstanceOptions {
+            render_mode: Some(self.render_mode),
+            synthetic_italics: self.synthetic_italics,
+        }
+    }
+}
+
+#[repr(C)]
+#[derive(Debug, Clone, Copy)]
 pub struct WrImageMask {
     image: WrImageKey,
     rect: LayoutRect,
     repeat: bool,
 }
 
 impl Into<ImageMask> for WrImageMask {
     fn into(self) -> ImageMask {
@@ -815,17 +842,18 @@ pub extern "C" fn wr_api_set_root_pipeli
 
 #[no_mangle]
 pub extern "C" fn wr_api_set_window_parameters(dh: &mut DocumentHandle,
                                                width: i32,
                                                height: i32) {
     let size = DeviceUintSize::new(width as u32, height as u32);
     dh.api.set_window_parameters(dh.document_id,
                                  size,
-                                 DeviceUintRect::new(DeviceUintPoint::new(0, 0), size));
+                                 DeviceUintRect::new(DeviceUintPoint::new(0, 0), size),
+                                 1.0);
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn wr_api_set_display_list(
     dh: &mut DocumentHandle,
     color: ColorF,
     epoch: WrEpoch,
     viewport_width: f32,
@@ -956,25 +984,30 @@ pub extern "C" fn wr_resource_updates_de
 }
 
 #[no_mangle]
 pub extern "C" fn wr_resource_updates_add_font_instance(
     resources: &mut ResourceUpdates,
     key: WrFontInstanceKey,
     font_key: WrFontKey,
     glyph_size: f32,
-    options: *const FontInstanceOptions,
-    platform_options: *const FontInstancePlatformOptions
+    options: *const WrFontInstanceOptions,
+    platform_options: *const FontInstancePlatformOptions,
+    variations: &mut WrVecU8,
 ) {
+    let instance_options: Option<FontInstanceOptions> = unsafe {
+        options.as_ref().map(|opts|{ (*opts).into() })
+    };
     resources.add_font_instance(
         key,
         font_key,
         Au::from_f32_px(glyph_size),
-        unsafe { options.as_ref().cloned() },
-        unsafe { platform_options.as_ref().cloned() }
+        instance_options,
+        unsafe { platform_options.as_ref().cloned() },
+        variations.convert_into_vec::<FontVariation>(),
     );
 }
 
 #[no_mangle]
 pub extern "C" fn wr_resource_updates_delete_font_instance(
     resources: &mut ResourceUpdates,
     key: WrFontInstanceKey
 ) {
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -724,21 +724,23 @@ struct FontKey {
   bool operator==(const FontKey& aOther) const {
     return mNamespace == aOther.mNamespace &&
            mHandle == aOther.mHandle;
   }
 };
 
 typedef FontKey WrFontKey;
 
-struct FontInstanceOptions {
+struct WrFontInstanceOptions {
   FontRenderMode render_mode;
+  bool synthetic_italics;
 
-  bool operator==(const FontInstanceOptions& aOther) const {
-    return render_mode == aOther.render_mode;
+  bool operator==(const WrFontInstanceOptions& aOther) const {
+    return render_mode == aOther.render_mode &&
+           synthetic_italics == aOther.synthetic_italics;
   }
 };
 
 struct FontInstancePlatformOptions {
   bool use_embedded_bitmap;
   bool force_gdi_rendering;
 
   bool operator==(const FontInstancePlatformOptions& aOther) const {
@@ -1216,18 +1218,19 @@ void wr_resource_updates_add_external_im
                                             uint8_t aChannelIndex)
 WR_FUNC;
 
 WR_INLINE
 void wr_resource_updates_add_font_instance(ResourceUpdates *aResources,
                                            WrFontInstanceKey aKey,
                                            WrFontKey aFontKey,
                                            float aGlyphSize,
-                                           const FontInstanceOptions *aOptions,
-                                           const FontInstancePlatformOptions *aPlatformOptions)
+                                           const WrFontInstanceOptions *aOptions,
+                                           const FontInstancePlatformOptions *aPlatformOptions,
+                                           WrVecU8 *aVariations)
 WR_FUNC;
 
 WR_INLINE
 void wr_resource_updates_add_image(ResourceUpdates *aResources,
                                    WrImageKey aImageKey,
                                    const WrImageDescriptor *aDescriptor,
                                    WrVecU8 *aBytes)
 WR_FUNC;
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -9030,25 +9030,18 @@ IonBuilder::setElemTryReferenceElemOfTyp
 {
     ReferenceTypeDescr::Type elemType = elemPrediction.referenceType();
     uint32_t elemSize = ReferenceTypeDescr::size(elemType);
 
     LinearSum indexAsByteOffset(alloc());
     if (!checkTypedObjectIndexInBounds(elemSize, obj, index, objPrediction, &indexAsByteOffset))
         return Ok();
 
-    MOZ_TRY_VAR(*emitted, storeReferenceTypedObjectValue(obj, indexAsByteOffset, elemType, value, nullptr));
-    if (!*emitted)
-        return Ok();
-
-    current->push(value);
-
-    trackOptimizationSuccess();
-    *emitted = true;
-    return Ok();
+    return setPropTryReferenceTypedObjectValue(emitted, obj, indexAsByteOffset,
+                                               elemType, value, nullptr);
 }
 
 AbortReasonOr<Ok>
 IonBuilder::setElemTryScalarElemOfTypedObject(bool* emitted,
                                               MDefinition* obj,
                                               MDefinition* index,
                                               TypedObjectPrediction objPrediction,
                                               MDefinition* value,
@@ -9058,24 +9051,17 @@ IonBuilder::setElemTryScalarElemOfTypedO
     // Must always be loading the same scalar type
     ScalarTypeDescr::Type elemType = elemPrediction.scalarType();
     MOZ_ASSERT(elemSize == ScalarTypeDescr::alignment(elemType));
 
     LinearSum indexAsByteOffset(alloc());
     if (!checkTypedObjectIndexInBounds(elemSize, obj, index, objPrediction, &indexAsByteOffset))
         return Ok();
 
-    // Store the element
-    MOZ_TRY(storeScalarTypedObjectValue(obj, indexAsByteOffset, elemType, value));
-
-    current->push(value);
-
-    trackOptimizationSuccess();
-    *emitted = true;
-    return Ok();
+    return setPropTryScalarTypedObjectValue(emitted, obj, indexAsByteOffset, elemType, value);
 }
 
 AbortReasonOr<Ok>
 IonBuilder::setElemTryTypedStatic(bool* emitted, MDefinition* object,
                                   MDefinition* index, MDefinition* value)
 {
     MOZ_ASSERT(*emitted == false);
 
@@ -11751,25 +11737,17 @@ IonBuilder::setPropTryReferencePropOfTyp
     TypeSet::ObjectKey* globalKey = TypeSet::ObjectKey::get(&script()->global());
     if (globalKey->hasFlags(constraints(), OBJECT_FLAG_TYPED_OBJECT_HAS_DETACHED_BUFFER))
         return Ok();
 
     LinearSum byteOffset(alloc());
     if (!byteOffset.add(fieldOffset))
         return abort(AbortReason::Disable, "Overflow of field offset.");
 
-    MOZ_TRY_VAR(*emitted, storeReferenceTypedObjectValue(obj, byteOffset, fieldType, value, name));
-    if (!*emitted)
-        return Ok();
-
-    current->push(value);
-
-    trackOptimizationSuccess();
-    *emitted = true;
-    return Ok();
+    return setPropTryReferenceTypedObjectValue(emitted, obj, byteOffset, fieldType, value, name);
 }
 
 AbortReasonOr<Ok>
 IonBuilder::setPropTryScalarPropOfTypedObject(bool* emitted,
                                               MDefinition* obj,
                                               int32_t fieldOffset,
                                               MDefinition* value,
                                               TypedObjectPrediction fieldPrediction)
@@ -11781,23 +11759,17 @@ IonBuilder::setPropTryScalarPropOfTypedO
     TypeSet::ObjectKey* globalKey = TypeSet::ObjectKey::get(&script()->global());
     if (globalKey->hasFlags(constraints(), OBJECT_FLAG_TYPED_OBJECT_HAS_DETACHED_BUFFER))
         return Ok();
 
     LinearSum byteOffset(alloc());
     if (!byteOffset.add(fieldOffset))
         return abort(AbortReason::Disable, "Overflow of field offet.");
 
-    MOZ_TRY(storeScalarTypedObjectValue(obj, byteOffset, fieldType, value));
-
-    current->push(value);
-
-    trackOptimizationSuccess();
-    *emitted = true;
-    return Ok();
+    return setPropTryScalarTypedObjectValue(emitted, obj, byteOffset, fieldType, value);
 }
 
 AbortReasonOr<Ok>
 IonBuilder::setPropTryDefiniteSlot(bool* emitted, MDefinition* obj,
                                    PropertyName* name, MDefinition* value,
                                    bool barrier, TemporaryTypeSet* objTypes)
 {
     MOZ_ASSERT(*emitted == false);
@@ -13475,21 +13447,24 @@ IonBuilder::typeObjectForFieldFromStruct
 
     MInstruction* unboxFieldType = MUnbox::New(alloc(), fieldType, MIRType::Object, MUnbox::Infallible);
     current->add(unboxFieldType);
 
     return unboxFieldType;
 }
 
 AbortReasonOr<Ok>
-IonBuilder::storeScalarTypedObjectValue(MDefinition* typedObj,
-                                        const LinearSum& byteOffset,
-                                        ScalarTypeDescr::Type type,
-                                        MDefinition* value)
-{
+IonBuilder::setPropTryScalarTypedObjectValue(bool* emitted,
+                                             MDefinition* typedObj,
+                                             const LinearSum& byteOffset,
+                                             ScalarTypeDescr::Type type,
+                                             MDefinition* value)
+{
+    MOZ_ASSERT(!*emitted);
+
     // Find location within the owner object.
     MDefinition* elements;
     MDefinition* scaledOffset;
     int32_t adjustment;
     uint32_t alignment = ScalarTypeDescr::alignment(type);
     MOZ_TRY(loadTypedObjectElements(typedObj, byteOffset, alignment,
                                     &elements, &scaledOffset, &adjustment));
 
@@ -13500,40 +13475,46 @@ IonBuilder::storeScalarTypedObjectValue(
         current->add(toWrite->toInstruction());
     }
 
     MStoreUnboxedScalar* store =
         MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, toWrite,
                                  type, MStoreUnboxedScalar::TruncateInput,
                                  DoesNotRequireMemoryBarrier, adjustment);
     current->add(store);
-
-    return Ok();
-}
-
-AbortReasonOr<bool>
-IonBuilder::storeReferenceTypedObjectValue(MDefinition* typedObj,
-                                           const LinearSum& byteOffset,
-                                           ReferenceTypeDescr::Type type,
-                                           MDefinition* value,
-                                           PropertyName* name)
-{
+    current->push(value);
+
+    trackOptimizationSuccess();
+    *emitted = true;
+    return resumeAfter(store);
+}
+
+AbortReasonOr<Ok>
+IonBuilder::setPropTryReferenceTypedObjectValue(bool* emitted,
+                                                MDefinition* typedObj,
+                                                const LinearSum& byteOffset,
+                                                ReferenceTypeDescr::Type type,
+                                                MDefinition* value,
+                                                PropertyName* name)
+{
+    MOZ_ASSERT(!*emitted);
+
     // Make sure we aren't adding new type information for writes of object and value
     // references.
     if (type != ReferenceTypeDescr::TYPE_STRING) {
         MOZ_ASSERT(type == ReferenceTypeDescr::TYPE_ANY ||
                    type == ReferenceTypeDescr::TYPE_OBJECT);
         MIRType implicitType =
             (type == ReferenceTypeDescr::TYPE_ANY) ? MIRType::Undefined : MIRType::Null;
 
         if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &typedObj, name, &value,
                                           /* canModify = */ true, implicitType))
         {
             trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier);
-            return false;
+            return Ok();
         }
     }
 
     // Find location within the owner object.
     MDefinition* elements;
     MDefinition* scaledOffset;
     int32_t adjustment;
     uint32_t alignment = ReferenceTypeDescr::alignment(type);
@@ -13558,17 +13539,21 @@ IonBuilder::storeReferenceTypedObjectVal
       case ReferenceTypeDescr::TYPE_STRING:
         // Strings are not nursery allocated, so these writes do not need post
         // barriers.
         store = MStoreUnboxedString::New(alloc(), elements, scaledOffset, value, adjustment);
         break;
     }
 
     current->add(store);
-    return true;
+    current->push(value);
+
+    trackOptimizationSuccess();
+    *emitted = true;
+    return resumeAfter(store);
 }
 
 JSObject*
 IonBuilder::checkNurseryObject(JSObject* obj)
 {
     // If we try to use any nursery pointers during compilation, make sure that
     // the active thread will cancel this compilation before performing a minor
     // GC. All constants used during compilation should either go through this
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -278,21 +278,32 @@ class IonBuilder
                                              PropertyName* name, MDefinition* value,
                                              bool barrier, TemporaryTypeSet* objTypes);
     AbortReasonOr<Ok> setPropTryTypedObject(bool* emitted, MDefinition* obj,
                                             PropertyName* name, MDefinition* value);
     AbortReasonOr<Ok> setPropTryReferencePropOfTypedObject(bool* emitted, MDefinition* obj,
                                                            int32_t fieldOffset, MDefinition* value,
                                                            TypedObjectPrediction fieldPrediction,
                                                            PropertyName* name);
+    AbortReasonOr<Ok> setPropTryReferenceTypedObjectValue(bool* emitted,
+                                                          MDefinition* typedObj,
+                                                          const LinearSum& byteOffset,
+                                                          ReferenceTypeDescr::Type type,
+                                                          MDefinition* value,
+                                                          PropertyName* name);
     AbortReasonOr<Ok> setPropTryScalarPropOfTypedObject(bool* emitted,
                                                         MDefinition* obj,
                                                         int32_t fieldOffset,
                                                         MDefinition* value,
                                                         TypedObjectPrediction fieldTypeReprs);
+    AbortReasonOr<Ok> setPropTryScalarTypedObjectValue(bool* emitted,
+                                                       MDefinition* typedObj,
+                                                       const LinearSum& byteOffset,
+                                                       ScalarTypeDescr::Type type,
+                                                       MDefinition* value);
     AbortReasonOr<Ok> setPropTryCache(bool* emitted, MDefinition* obj,
                                       PropertyName* name, MDefinition* value,
                                       bool barrier, TemporaryTypeSet* objTypes);
 
     // jsop_binary_arith helpers.
     MBinaryArithInstruction* binaryArithInstruction(JSOp op, MDefinition* left, MDefinition* right);
     AbortReasonOr<Ok> binaryArithTryConcat(bool* emitted, JSOp op, MDefinition* left,
                                            MDefinition* right);
@@ -353,25 +364,16 @@ class IonBuilder
                                               const LinearSum& byteOffset,
                                               uint32_t scale,
                                               MDefinition** ownerElements,
                                               MDefinition** ownerScaledOffset,
                                               int32_t* ownerByteAdjustment);
     MDefinition* typeObjectForElementFromArrayStructType(MDefinition* typedObj);
     MDefinition* typeObjectForFieldFromStructType(MDefinition* type,
                                                   size_t fieldIndex);
-    AbortReasonOr<bool> storeReferenceTypedObjectValue(MDefinition* typedObj,
-                                                       const LinearSum& byteOffset,
-                                                       ReferenceTypeDescr::Type type,
-                                                       MDefinition* value,
-                                                       PropertyName* name);
-    AbortReasonOr<Ok> storeScalarTypedObjectValue(MDefinition* typedObj,
-                                                  const LinearSum& byteOffset,
-                                                  ScalarTypeDescr::Type type,
-                                                  MDefinition* value);
     bool checkTypedObjectIndexInBounds(uint32_t elemSize,
                                        MDefinition* obj,
                                        MDefinition* index,
                                        TypedObjectPrediction objTypeDescrs,
                                        LinearSum* indexAsByteOffset);
     AbortReasonOr<Ok> pushDerivedTypedObject(bool* emitted,
                                              MDefinition* obj,
                                              const LinearSum& byteOffset,
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/1401709.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <ruby>
+    <rtc style="writing-mode: vertical-rl">
+      <div style="float: left"></div>
+    </rtc>
+  </ruby>
+</body>
+</html>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -653,8 +653,9 @@ load 1304441.html
 load 1308876-1.html
 load 1316649.html
 load 1349650.html
 asserts-if(browserIsRemote,0-5) load 1349816-1.html # bug 1350352
 load 1364361-1.html
 load 1367413-1.html
 load 1368617-1.html
 load 1373586.html
+load 1401709.html
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -76,19 +76,19 @@ nsLineLayout::nsLineLayout(nsPresContext
     mDirtyNextLine(false),
     mLineAtStart(false),
     mHasRuby(false),
     mSuppressLineWrap(nsSVGUtils::IsInSVGTextSubtree(aOuterReflowInput->mFrame))
 {
   MOZ_ASSERT(aOuterReflowInput, "aOuterReflowInput must not be null");
   NS_ASSERTION(aFloatManager || aOuterReflowInput->mFrame->IsLetterFrame(),
                "float manager should be present");
-  MOZ_ASSERT(aOuterReflowInput->mFrame->IsRubyTextContainerFrame() ||
-             !mBaseLineLayout,
-             "Only ruby text container frames may have "
+  MOZ_ASSERT((!!mBaseLineLayout) ==
+              aOuterReflowInput->mFrame->IsRubyTextContainerFrame(),
+             "Only ruby text container frames have "
              "a different base line layout");
   MOZ_COUNT_CTOR(nsLineLayout);
 
   // Stash away some style data that we need
   nsBlockFrame* blockFrame = do_QueryFrame(aOuterReflowInput->mFrame);
   if (blockFrame)
     mStyleText = blockFrame->StyleTextForLineLayout();
   else
@@ -1209,16 +1209,20 @@ nsLineLayout::SyncAnnotationBounds(PerFr
   MOZ_ASSERT(aRubyFrame->mFrame->IsRubyFrame());
   MOZ_ASSERT(aRubyFrame->mSpan);
 
   PerSpanData* span = aRubyFrame->mSpan;
   WritingMode lineWM = mRootSpan->mWritingMode;
   for (PerFrameData* pfd = span->mFirstFrame; pfd; pfd = pfd->mNext) {
     for (PerFrameData* rtc = pfd->mNextAnnotation;
          rtc; rtc = rtc->mNextAnnotation) {
+      if (lineWM.IsOrthogonalTo(rtc->mFrame->GetWritingMode())) {
+        // Inter-character case: don't attempt to sync annotation bounds.
+        continue;
+      }
       // When the annotation container is reflowed, the width of the
       // ruby container is unknown so we use a dummy container size;
       // in the case of RTL block direction, the final position will be
       // fixed up later.
       const nsSize dummyContainerSize;
       LogicalRect rtcBounds(lineWM, rtc->mFrame->GetRect(),
                             dummyContainerSize);
       rtc->mBounds = rtcBounds;
@@ -3012,16 +3016,20 @@ nsLineLayout::ExpandRubyBoxWithAnnotatio
   if (reservedISize) {
     ExpandRubyBox(aFrame, reservedISize, aContainerSize);
   }
 
   WritingMode lineWM = mRootSpan->mWritingMode;
   bool isLevelContainer = aFrame->mFrame->IsRubyBaseContainerFrame();
   for (PerFrameData* annotation = aFrame->mNextAnnotation;
        annotation; annotation = annotation->mNextAnnotation) {
+    if (lineWM.IsOrthogonalTo(annotation->mFrame->GetWritingMode())) {
+      // Inter-character case: don't attempt to expand ruby annotations.
+      continue;
+    }
     if (isLevelContainer) {
       nsIFrame* rtcFrame = annotation->mFrame;
       MOZ_ASSERT(rtcFrame->IsRubyTextContainerFrame());
       // It is necessary to set the rect again because the container
       // width was unknown, and zero was used instead when we reflow
       // them. The corresponding base containers were repositioned in
       // VerticalAlignFrames and PlaceTopBottomFrames.
       MOZ_ASSERT(
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -337,50 +337,46 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
   reflowInputs.SetCapacity(rtcCount);
   lineLayouts.SetCapacity(rtcCount);
 
   // Begin the line layout for each ruby text container in advance.
   bool hasSpan = false;
   for (uint32_t i = 0; i < rtcCount; i++) {
     nsRubyTextContainerFrame* textContainer = textContainers[i];
     WritingMode rtcWM = textContainer->GetWritingMode();
-    nsLineLayout* baseLineLayout =
-        lineWM.IsOrthogonalTo(rtcWM) ? nullptr : aReflowInput.mLineLayout;
-        // Don't attach a base line layout in the inter-character case.
+    WritingMode reflowWM = lineWM.IsOrthogonalTo(rtcWM) ? rtcWM : lineWM;
     if (textContainer->IsSpanContainer()) {
       hasSpan = true;
     }
 
     ReflowInput* reflowInput = new ReflowInput(
       aPresContext, *aReflowInput.mParentReflowInput, textContainer,
       availSize.ConvertTo(textContainer->GetWritingMode(), lineWM));
     reflowInputs.AppendElement(reflowInput);
     nsLineLayout* lineLayout = new nsLineLayout(aPresContext,
                                                 reflowInput->mFloatManager,
                                                 reflowInput, nullptr,
-                                                baseLineLayout);
+                                                aReflowInput.mLineLayout);
     lineLayout->SetSuppressLineWrap(true);
     lineLayouts.AppendElement(lineLayout);
 
     // Line number is useless for ruby text
     // XXX nullptr here may cause problem, see comments for
     //     nsLineLayout::mBlockRI and nsLineLayout::AddFloat
     lineLayout->Init(nullptr, reflowInput->CalcLineHeight(), -1);
     reflowInput->mLineLayout = lineLayout;
 
     // Border and padding are suppressed on ruby text containers.
     // If the writing mode is vertical-rl, the horizontal position of
     // rt frames will be updated when reflowing this text container,
     // hence leave container size 0 here for now.
     lineLayout->BeginLineReflow(0, 0, reflowInput->ComputedISize(),
-                                NS_UNCONSTRAINEDSIZE, false, false,
-                                baseLineLayout ? lineWM : rtcWM, nsSize(0, 0));
-    if (baseLineLayout) {
-      lineLayout->AttachRootFrameToBaseLineLayout();
-    }
+                                NS_UNCONSTRAINEDSIZE,
+                                false, false, reflowWM, nsSize(0, 0));
+    lineLayout->AttachRootFrameToBaseLineLayout();
   }
 
   aReflowInput.mLineLayout->BeginSpan(this, &aReflowInput,
                                       0, aReflowInput.AvailableISize(),
                                       &mBaseline);
 
   bool allowInitialLineBreak, allowLineBreak;
   GetIsLineBreakAllowed(this, aReflowInput.mLineLayout->LineIsBreakable(),
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -9150,23 +9150,23 @@ nsDisplayMask::CreateWebRenderCommands(m
   Maybe<wr::WrImageMask> mask = aManager->BuildWrMaskImage(this, aBuilder, aResources,
                                                            aSc, aDisplayListBuilder, bounds);
   if (mask) {
     wr::WrClipId clipId = aBuilder.DefineClip(
         aSc.ToRelativeLayoutRect(bounds), nullptr, mask.ptr());
     // Don't record this clip push in aBuilder's internal clip stack, because
     // otherwise any nested ScrollingLayersHelper instances that are created
     // will get confused about which clips are pushed.
-    aBuilder.PushClip(clipId, /*aRecordInStack*/ false);
+    aBuilder.PushClip(clipId, /*aMask*/ true);
   }
 
   nsDisplaySVGEffects::CreateWebRenderCommands(aBuilder, aResources, aSc, aManager, aDisplayListBuilder);
 
   if (mask) {
-    aBuilder.PopClip(/*aRecordInStack*/ false);
+    aBuilder.PopClip(/*aMask*/ true);
   }
 
   return true;
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayMask::PrintEffects(nsACString& aTo)
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -635,18 +635,16 @@ struct nsStyleImageLayers {
   explicit nsStyleImageLayers(LayerType aType);
   nsStyleImageLayers(const nsStyleImageLayers &aSource);
   ~nsStyleImageLayers() {
     MOZ_COUNT_DTOR(nsStyleImageLayers);
   }
 
   static bool IsInitialPositionForLayerType(mozilla::Position aPosition, LayerType aType);
 
-  struct Size;
-  friend struct Size;
   struct Size {
     struct Dimension : public nsStyleCoord::CalcValue {
       nscoord ResolveLengthPercentage(nscoord aAvailable) const {
         double d = double(mPercent) * double(aAvailable) + double(mLength);
         if (d < 0.0) {
           return 0;
         }
         return NSToCoordRoundWithClamp(float(d));
@@ -698,18 +696,16 @@ struct nsStyleImageLayers {
     void SetInitialValues();
 
     bool operator==(const Size& aOther) const;
     bool operator!=(const Size& aOther) const {
       return !(*this == aOther);
     }
   };
 
-  struct Repeat;
-  friend struct Repeat;
   struct Repeat {
     mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat;
 
     // Initialize nothing
     Repeat() {}
 
     bool IsInitialValue() const {
       return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat &&
@@ -731,18 +727,16 @@ struct nsStyleImageLayers {
       return mXRepeat == aOther.mXRepeat &&
              mYRepeat == aOther.mYRepeat;
     }
     bool operator!=(const Repeat& aOther) const {
       return !(*this == aOther);
     }
   };
 
-  struct Layer;
-  friend struct Layer;
   struct Layer {
     typedef mozilla::StyleGeometryBox StyleGeometryBox;
 
     nsStyleImage  mImage;         // [reset]
     mozilla::Position mPosition;  // [reset]
     Size          mSize;          // [reset]
     StyleGeometryBox  mClip;      // [reset] See nsStyleConsts.h
     MOZ_INIT_OUTSIDE_CTOR
@@ -896,21 +890,16 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   inline bool HasLocalBackground() const;
 
   const nsStyleImageLayers::Layer& BottomLayer() const { return mImage.BottomLayer(); }
 
   nsStyleImageLayers mImage;
   mozilla::StyleComplexColor mBackgroundColor;       // [reset]
 };
 
-#define NS_SPACING_MARGIN   0
-#define NS_SPACING_PADDING  1
-#define NS_SPACING_BORDER   2
-
-
 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin
 {
   explicit nsStyleMargin(const nsPresContext* aContext);
   nsStyleMargin(const nsStyleMargin& aMargin);
   ~nsStyleMargin() {
     MOZ_COUNT_DTOR(nsStyleMargin);
   }
   void FinishStyle(nsPresContext* aPresContext) {}
new file mode 100644
--- /dev/null
+++ b/memory/build/fallback.cpp
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozmemory.h"
+#include "mozjemalloc.h"
+
+struct SystemMalloc {
+#define MALLOC_DECL(name, return_type, ...) \
+  static inline return_type \
+  name(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
+  { \
+    return ::name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
+  }
+#define MALLOC_FUNCS MALLOC_FUNCS_MALLOC_BASE
+#include "malloc_decls.h"
+};
+
+#define MALLOC_DECL(name, return_type, ...) \
+  MOZ_JEMALLOC_API return_type \
+  name(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
+  { \
+    return DummyArenaAllocator<SystemMalloc>::name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
+  }
+#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
+#include "malloc_decls.h"
--- a/memory/build/malloc_decls.h
+++ b/memory/build/malloc_decls.h
@@ -10,44 +10,55 @@
  *   - argument types
  */
 
 #ifndef malloc_decls_h
 #  define malloc_decls_h
 
 #  include "mozjemalloc_types.h"
 
-#  define MALLOC_FUNCS_MALLOC 1
-#  define MALLOC_FUNCS_JEMALLOC 2
-#  define MALLOC_FUNCS_INIT 4
-#  define MALLOC_FUNCS_BRIDGE 8
+#  define MALLOC_FUNCS_MALLOC_BASE 1
+#  define MALLOC_FUNCS_MALLOC_EXTRA 2
+#  define MALLOC_FUNCS_MALLOC (MALLOC_FUNCS_MALLOC_BASE | \
+                               MALLOC_FUNCS_MALLOC_EXTRA)
+#  define MALLOC_FUNCS_JEMALLOC 4
+#  define MALLOC_FUNCS_INIT 8
+#  define MALLOC_FUNCS_BRIDGE 16
+#  define MALLOC_FUNCS_ARENA_BASE 32
+#  define MALLOC_FUNCS_ARENA_ALLOC 64
+#  define MALLOC_FUNCS_ARENA (MALLOC_FUNCS_ARENA_BASE | \
+                              MALLOC_FUNCS_ARENA_ALLOC)
 #  define MALLOC_FUNCS_ALL (MALLOC_FUNCS_INIT | MALLOC_FUNCS_BRIDGE | \
-                            MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC)
+                            MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC | \
+                            MALLOC_FUNCS_ARENA)
 
 #endif /* malloc_decls_h */
 
 #ifndef MALLOC_FUNCS
-#  define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC)
+#  define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC | \
+                        MALLOC_FUNCS_ARENA)
 #endif
 
 #ifdef MALLOC_DECL
 #  if MALLOC_FUNCS & MALLOC_FUNCS_INIT
 MALLOC_DECL(init, void, const malloc_table_t *)
 #  endif
 #  if MALLOC_FUNCS & MALLOC_FUNCS_BRIDGE
 MALLOC_DECL(get_bridge, struct ReplaceMallocBridge*)
 #  endif
-#  if MALLOC_FUNCS & MALLOC_FUNCS_MALLOC
+#  if MALLOC_FUNCS & MALLOC_FUNCS_MALLOC_BASE
 MALLOC_DECL(malloc, void *, size_t)
-MALLOC_DECL(posix_memalign, int, void **, size_t, size_t)
-MALLOC_DECL(aligned_alloc, void *, size_t, size_t)
 MALLOC_DECL(calloc, void *, size_t, size_t)
 MALLOC_DECL(realloc, void *, void *, size_t)
 MALLOC_DECL(free, void, void *)
 MALLOC_DECL(memalign, void *, size_t, size_t)
+#  endif
+#  if MALLOC_FUNCS & MALLOC_FUNCS_MALLOC_EXTRA
+MALLOC_DECL(posix_memalign, int, void **, size_t, size_t)
+MALLOC_DECL(aligned_alloc, void *, size_t, size_t)
 MALLOC_DECL(valloc, void *, size_t)
 MALLOC_DECL(malloc_usable_size, size_t, usable_ptr_t)
 MALLOC_DECL(malloc_good_size, size_t, size_t)
 #  endif
 #  if MALLOC_FUNCS & MALLOC_FUNCS_JEMALLOC
 MALLOC_DECL(jemalloc_stats, void, jemalloc_stats_t *)
 /*
  * On some operating systems (Mac), we use madvise(MADV_FREE) to hand pages
@@ -91,12 +102,43 @@ MALLOC_DECL(jemalloc_free_dirty_pages, v
 MALLOC_DECL(jemalloc_thread_local_arena, void, bool)
 
 /*
  * Provide information about any allocation enclosing the given address.
  */
 MALLOC_DECL(jemalloc_ptr_info, void, const void*, jemalloc_ptr_info_t*)
 #  endif
 
+#  if MALLOC_FUNCS & MALLOC_FUNCS_ARENA_BASE
+/*
+ * Creates a separate arena, and returns its id, valid to use with moz_arena_*
+ * functions.
+ */
+MALLOC_DECL(moz_create_arena, arena_id_t)
+
+/*
+ * Dispose of the given arena. Subsequent uses of the arena will fail.
+ */
+MALLOC_DECL(moz_dispose_arena, void, arena_id_t)
+#  endif
+
+#  if MALLOC_FUNCS & MALLOC_FUNCS_ARENA_ALLOC
+/*
+ * Same as the functions without the moz_arena_ prefix, but using arenas
+ * created with moz_create_arena.
+ * The contract, even if not enforced at runtime in some configurations,
+ * is that moz_arena_realloc and moz_arena_free will crash if the wrong
+ * arena id is given. All functions will crash if the arena id is invalid.
+ * Although discouraged, plain realloc and free can still be used on
+ * pointers allocated with these functions. Realloc will properly keep
+ * new pointers in the same arena as the original.
+ */
+MALLOC_DECL(moz_arena_malloc, void*, arena_id_t, size_t)
+MALLOC_DECL(moz_arena_calloc, void*, arena_id_t, size_t, size_t)
+MALLOC_DECL(moz_arena_realloc, void*, arena_id_t, void*, size_t)
+MALLOC_DECL(moz_arena_free, void, arena_id_t, void*)
+MALLOC_DECL(moz_arena_memalign, void*, arena_id_t, size_t, size_t)
+#  endif
+
 #endif /* MALLOC_DECL */
 
 #undef MALLOC_DECL
 #undef MALLOC_FUNCS
--- a/memory/build/moz.build
+++ b/memory/build/moz.build
@@ -15,20 +15,25 @@ LIBRARY_DEFINES['MOZ_HAS_MOZGLUE'] = Tru
 DEFINES['MOZ_MEMORY_IMPL'] = True
 
 if CONFIG['MOZ_REPLACE_MALLOC']:
     EXPORTS += [
         'replace_malloc.h',
         'replace_malloc_bridge.h',
     ]
 
-UNIFIED_SOURCES += [
-    'mozjemalloc.cpp',
-    'mozmemory_wrap.cpp',
-]
+if CONFIG['MOZ_MEMORY']:
+    UNIFIED_SOURCES += [
+        'mozjemalloc.cpp',
+        'mozmemory_wrap.cpp',
+    ]
+else:
+    UNIFIED_SOURCES += [
+        'fallback.cpp',
+    ]
 
 if CONFIG['OS_TARGET'] == 'Darwin' and (CONFIG['MOZ_REPLACE_MALLOC'] or
         CONFIG['MOZ_MEMORY']):
     SOURCES += [
         'zone.c',
     ]
 
 Library('memory')
--- a/memory/build/mozjemalloc.cpp
+++ b/memory/build/mozjemalloc.cpp
@@ -106,17 +106,16 @@
  *
  *******************************************************************************
  */
 
 #include "mozmemory_wrap.h"
 #include "mozjemalloc.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Likely.h"
-#include "mozilla/MacroArgs.h"
 #include "mozilla/DoublyLinkedList.h"
 
 #ifdef ANDROID
 #define NO_TLS
 #endif
 
 /*
  * On Linux, we use madvise(MADV_DONTNEED) to release memory back to the
@@ -5127,16 +5126,25 @@ MozJemalloc::jemalloc_free_dirty_pages(v
       malloc_spin_lock(&arena->mLock);
       arena->Purge(true);
       malloc_spin_unlock(&arena->mLock);
     }
   }
   malloc_spin_unlock(&arenas_lock);
 }
 
+#define MALLOC_DECL(name, return_type, ...) \
+  template<> inline return_type \
+  MozJemalloc::name(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
+  { \
+    return DummyArenaAllocator<MozJemalloc>::name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
+  }
+#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
+#include "malloc_decls.h"
+
 /*
  * End non-standard functions.
  */
 /******************************************************************************/
 /*
  * Begin library-private functions, used by threading libraries for protection
  * of malloc during fork().  These functions are only called if the program is
  * running in threaded mode, so there is no need to check whether the program
@@ -5205,36 +5213,16 @@ void
 	}
 	malloc_spin_init(&arenas_lock);
 }
 
 /*
  * End library-private functions.
  */
 /******************************************************************************/
-/* Macro helpers */
-
-#define MACRO_CALL(a, b) a b
-/* Can't use macros recursively, so we need another one doing the same as above. */
-#define MACRO_CALL2(a, b) a b
-
-#define ARGS_HELPER(name, ...) MACRO_CALL2( \
-  MOZ_PASTE_PREFIX_AND_ARG_COUNT(name, ##__VA_ARGS__), \
-  (__VA_ARGS__))
-#define TYPED_ARGS0()
-#define TYPED_ARGS1(t1) t1 arg1
-#define TYPED_ARGS2(t1, t2) TYPED_ARGS1(t1), t2 arg2
-#define TYPED_ARGS3(t1, t2, t3) TYPED_ARGS2(t1, t2), t3 arg3
-
-#define ARGS0()
-#define ARGS1(t1) arg1
-#define ARGS2(t1, t2) ARGS1(t1), arg2
-#define ARGS3(t1, t2, t3) ARGS2(t1, t2), arg3
-
-/******************************************************************************/
 #ifdef MOZ_REPLACE_MALLOC
 
 /*
  * Windows doesn't come with weak imports as they are possible with
  * LD_PRELOAD or DYLD_INSERT_LIBRARIES on Linux/OSX. On this platform,
  * the replacement functions are defined as variable pointers to the
  * function resolved with GetProcAddress() instead of weak definitions
  * of functions. On Android, the same needs to happen as well, because
@@ -5343,17 +5331,16 @@ init()
   template<> inline return_type \
   ReplaceMalloc::name(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
   { \
     if (MOZ_UNLIKELY(!replace_malloc_initialized)) { \
       init(); \
     } \
     return replace_malloc_table.name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
   }
-#define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC)
 #include "malloc_decls.h"
 
 MOZ_JEMALLOC_API struct ReplaceMallocBridge*
 get_bridge(void)
 {
   if (MOZ_UNLIKELY(!replace_malloc_initialized))
     init();
   if (MOZ_LIKELY(!replace_get_bridge))
@@ -5390,16 +5377,23 @@ replace_malloc_init_funcs()
     replace_malloc_table.posix_memalign = AlignedAllocator<ReplaceMalloc::memalign>::posix_memalign;
   }
   if (!replace_malloc_table.aligned_alloc && replace_malloc_table.memalign) {
     replace_malloc_table.aligned_alloc = AlignedAllocator<ReplaceMalloc::memalign>::aligned_alloc;
   }
   if (!replace_malloc_table.valloc && replace_malloc_table.memalign) {
     replace_malloc_table.valloc = AlignedAllocator<ReplaceMalloc::memalign>::valloc;
   }
+  if (!replace_malloc_table.moz_create_arena && replace_malloc_table.malloc) {
+#define MALLOC_DECL(name, ...) \
+    replace_malloc_table.name = DummyArenaAllocator<ReplaceMalloc>::name;
+#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
+#include "malloc_decls.h"
+  }
+
 #define MALLOC_DECL(name, ...) \
   if (!replace_malloc_table.name) { \
     replace_malloc_table.name = MozJemalloc::name; \
   }
 #include "malloc_decls.h"
 }
 
 #endif /* MOZ_REPLACE_MALLOC */
@@ -5419,17 +5413,17 @@ replace_malloc_init_funcs()
 #define MALLOC_FUNCS MALLOC_FUNCS_MALLOC
 #include "malloc_decls.h"
 
 #undef GENERIC_MALLOC_DECL
 #define GENERIC_MALLOC_DECL(name, return_type, ...) \
   GENERIC_MALLOC_DECL2(name, name, return_type, ##__VA_ARGS__)
 
 #define MALLOC_DECL(...) MOZ_JEMALLOC_API MACRO_CALL(GENERIC_MALLOC_DECL, (__VA_ARGS__))
-#define MALLOC_FUNCS MALLOC_FUNCS_JEMALLOC
+#define MALLOC_FUNCS (MALLOC_FUNCS_JEMALLOC | MALLOC_FUNCS_ARENA)
 #include "malloc_decls.h"
 /******************************************************************************/
 
 #ifdef HAVE_DLOPEN
 #  include <dlfcn.h>
 #endif
 
 #if defined(__GLIBC__) && !defined(__UCLIBC__)
--- a/memory/build/mozjemalloc.h
+++ b/memory/build/mozjemalloc.h
@@ -1,23 +1,44 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozjemalloc_types.h"
+#include "mozilla/MacroArgs.h"
+
+/* Macro helpers */
+
+#define MACRO_CALL(a, b) a b
+/* Can't use macros recursively, so we need another one doing the same as above. */
+#define MACRO_CALL2(a, b) a b
+
+#define ARGS_HELPER(name, ...) MACRO_CALL2( \
+  MOZ_PASTE_PREFIX_AND_ARG_COUNT(name, ##__VA_ARGS__), \
+  (__VA_ARGS__))
+#define TYPED_ARGS0()
+#define TYPED_ARGS1(t1) t1 arg1
+#define TYPED_ARGS2(t1, t2) TYPED_ARGS1(t1), t2 arg2
+#define TYPED_ARGS3(t1, t2, t3) TYPED_ARGS2(t1, t2), t3 arg3
+
+#define ARGS0()
+#define ARGS1(t1) arg1
+#define ARGS2(t1, t2) ARGS1(t1), arg2
+#define ARGS3(t1, t2, t3) ARGS2(t1, t2), arg3
+
+#ifdef MOZ_MEMORY
 
 /* Generic interface exposing the whole public allocator API
  * This facilitates the implementation of things like replace-malloc.
  * Note: compilers are expected to be able to optimize out `this`.
  */
 template <typename T>
 struct Allocator: public T {
-#define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC)
 #define MALLOC_DECL(name, return_type, ...) \
   static return_type name(__VA_ARGS__);
 #include "malloc_decls.h"
 };
 
 /* The MozJemalloc allocator */
 struct MozJemallocBase {};
 typedef Allocator<MozJemallocBase> MozJemalloc;
@@ -26,8 +47,28 @@ typedef Allocator<MozJemallocBase> MozJe
 /* The replace-malloc allocator */
 struct ReplaceMallocBase {};
 typedef Allocator<ReplaceMallocBase> ReplaceMalloc;
 
 typedef ReplaceMalloc DefaultMalloc;
 #else
 typedef MozJemalloc DefaultMalloc;
 #endif
+
+#endif /* MOZ_MEMORY */
+
+/* Dummy implementation of the moz_arena_* API, falling back to a given
+ * implementation of the base allocator. */
+template <typename T>
+struct DummyArenaAllocator {
+  static arena_id_t moz_create_arena(void) { return 0; }
+
+  static void moz_dispose_arena(arena_id_t) { }
+
+#define MALLOC_DECL(name, return_type, ...) \
+  static return_type \
+  moz_arena_ ## name(arena_id_t, ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
+  { \
+    return T::name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
+  }
+#define MALLOC_FUNCS MALLOC_FUNCS_MALLOC_BASE
+#include "malloc_decls.h"
+};
--- a/memory/build/mozjemalloc_types.h
+++ b/memory/build/mozjemalloc_types.h
@@ -45,16 +45,18 @@ extern "C" {
 #endif
 
 #ifndef MALLOC_USABLE_SIZE_CONST_PTR
 #define MALLOC_USABLE_SIZE_CONST_PTR const
 #endif
 
 typedef MALLOC_USABLE_SIZE_CONST_PTR void* usable_ptr_t;
 
+typedef size_t arena_id_t;
+
 /*
  * jemalloc_stats() is not a stable interface.  When using jemalloc_stats_t, be
  * sure that the compiled results of jemalloc.c are in sync with this header
  * file.
  */
 typedef struct {
 	/*
 	 * Run-time configuration settings.
--- a/memory/build/mozmemory.h
+++ b/memory/build/mozmemory.h
@@ -11,32 +11,30 @@
  *   - malloc_good_size (used to be called je_malloc_usable_in_advance)
  *   - jemalloc_stats
  *   - jemalloc_purge_freed_pages
  *   - jemalloc_free_dirty_pages
  *   - jemalloc_thread_local_arena
  *   - jemalloc_ptr_info
  */
 
-#ifndef MOZ_MEMORY
-#  error Should not include mozmemory.h when MOZ_MEMORY is not set
+#ifdef MALLOC_H
+#include MALLOC_H
 #endif
-
 #include "mozmemory_wrap.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Types.h"
 #include "mozjemalloc_types.h"
 
+#ifdef MOZ_MEMORY
 /*
  * On OSX, malloc/malloc.h contains the declaration for malloc_good_size,
  * which will call back in jemalloc, through the zone allocator so just use it.
  */
-#ifdef XP_DARWIN
-#  include <malloc/malloc.h>
-#else
+#ifndef XP_DARWIN
 MOZ_MEMORY_API size_t malloc_good_size_impl(size_t size);
 
 /* Note: the MOZ_GLUE_IN_PROGRAM ifdef below is there to avoid -Werror turning
  * the protective if into errors. MOZ_GLUE_IN_PROGRAM is what triggers MFBT_API
  * to use weak imports. */
 
 static inline size_t _malloc_good_size(size_t size) {
 #  if defined(MOZ_GLUE_IN_PROGRAM) && !defined(IMPL_MFBT)
@@ -49,9 +47,16 @@ static inline size_t _malloc_good_size(s
 #  define malloc_good_size _malloc_good_size
 #endif
 
 #define MALLOC_DECL(name, return_type, ...) \
   MOZ_JEMALLOC_API return_type name(__VA_ARGS__);
 #define MALLOC_FUNCS MALLOC_FUNCS_JEMALLOC
 #include "malloc_decls.h"
 
+#endif
+
+#define MALLOC_DECL(name, return_type, ...) \
+  MOZ_JEMALLOC_API return_type name(__VA_ARGS__);
+#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
+#include "malloc_decls.h"
+
 #endif /* mozmemory_h */
--- a/memory/build/mozmemory_wrap.h
+++ b/memory/build/mozmemory_wrap.h
@@ -83,20 +83,16 @@
  *
  * Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions
  * should be suffixed with "_impl" both for declarations and use.
  * That is, the implementation declaration for e.g. strdup would look like:
  *   char* strdup_impl(const char *)
  * That implementation would call malloc by using "malloc_impl".
  */
 
-#ifndef MOZ_MEMORY
-#  error Should only include mozmemory_wrap.h when MOZ_MEMORY is set.
-#endif
-
 #if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT)
 #  ifdef MFBT_API /* mozilla/Types.h was already included */
 #    error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not.
 #  endif
 #  define IMPL_MFBT
 #endif
 
 #include "mozilla/Types.h"
--- a/memory/moz.build
+++ b/memory/moz.build
@@ -3,24 +3,21 @@
 # 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/.
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "Memory Allocator")
 
 DIRS += [
+    'build',
     'mozalloc',
     'fallible',
 ]
 
 if not CONFIG['JS_STANDALONE']:
     DIRS += ['volatile']
 
-if CONFIG['MOZ_MEMORY']:
-    # NB: gtest dir is included in toolkit/toolkit.build due to its dependency
-    # on libxul.
-    DIRS += [
-        'build',
-    ]
+# NB: gtest dir is included in toolkit/toolkit.build due to its dependency
+# on libxul.
 
-    if CONFIG['MOZ_REPLACE_MALLOC']:
-        DIRS += ['replace']
+if CONFIG['MOZ_REPLACE_MALLOC']:
+    DIRS += ['replace']
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamPanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamPanel.java
@@ -49,40 +49,41 @@ public class ActivityStreamPanel extends
      * Number of highlights that should be returned (max).
      */
     private static final int HIGHLIGHTS_LIMIT = 10;
 
     public static final String PREF_POCKET_ENABLED = "pref_activitystream_pocket_enabled";
     public static final String PREF_VISITED_ENABLED = "pref_activitystream_visited_enabled";
     public static final String PREF_BOOKMARKS_ENABLED = "pref_activitystream_recentbookmarks_enabled";
 
+    private final RecyclerView contentRecyclerView;
+
     private int desiredTileWidth;
     private int tileMargin;
     private final SharedPreferences sharedPreferences;
 
     public ActivityStreamPanel(Context context, AttributeSet attrs) {
         super(context, attrs);
 
         setBackgroundColor(ContextCompat.getColor(context, R.color.photon_browser_toolbar_bg));
 
         inflate(context, R.layout.as_content, this);
 
         adapter = new StreamRecyclerAdapter();
         sharedPreferences = GeckoSharedPrefs.forProfile(context);
 
-        final RecyclerView rv = (RecyclerView) findViewById(R.id.activity_stream_main_recyclerview);
+        contentRecyclerView = (RecyclerView) findViewById(R.id.activity_stream_main_recyclerview);
+        contentRecyclerView.setAdapter(adapter);
+        contentRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+        contentRecyclerView.setHasFixedSize(true);
+        // Override item animations to avoid horrible topsites refreshing
+        contentRecyclerView.setItemAnimator(new StreamItemAnimator());
+        contentRecyclerView.addItemDecoration(new HighlightsDividerItemDecoration(context));
 
-        rv.setAdapter(adapter);
-        rv.setLayoutManager(new LinearLayoutManager(getContext()));
-        rv.setHasFixedSize(true);
-        // Override item animations to avoid horrible topsites refreshing
-        rv.setItemAnimator(new StreamItemAnimator());
-        rv.addItemDecoration(new HighlightsDividerItemDecoration(context));
-
-        RecyclerViewClickSupport.addTo(rv)
+        RecyclerViewClickSupport.addTo(contentRecyclerView)
                 .setOnItemClickListener(adapter)
                 .setOnItemLongClickListener(adapter);
 
         final Resources resources = getResources();
         desiredTileWidth = resources.getDimensionPixelSize(R.dimen.activity_stream_desired_tile_width);
         tileMargin = resources.getDimensionPixelSize(R.dimen.activity_stream_base_margin);
 
         ActivityStreamTelemetry.Extras.setGlobal(
@@ -145,27 +146,27 @@ public class ActivityStreamPanel extends
 
         // Calculate how many tiles fit into the available horizontal space if we are using our
         // desired tile width.
         int fittingTiles = (w - tileMargin) / (desiredTileWidth + tileMargin);
 
         if (fittingTiles <= TopSitesPage.NUM_COLUMNS) {
             // We can't fit all tiles (or they fit exactly) if we are using the desired tiles width.
             // We will still show all tiles but they might be smaller than what we would like them to be.
-            setPadding(0, 0, 0, 0);
+            contentRecyclerView.setPadding(0, 0, 0, 0);
         } else if (fittingTiles > TopSitesPage.NUM_COLUMNS) {
             // We can fit more tiles than we want to display. Calculate how much space we need and
             // use the remaining space as padding on the left and right.
             int needed = TopSitesPage.NUM_COLUMNS * (desiredTileWidth + tileMargin) + tileMargin;
             int padding = (w - needed) / 2;
 
             // With the padding applied we have less space available for the tiles
             w = needed;
 
-            setPadding(padding, 0, padding, 0);
+            contentRecyclerView.setPadding(padding, 0, padding, 0);
         }
 
         // Now calculate how large an individual tile is
         final int tilesSize = (w - (TopSitesPage.NUM_COLUMNS * tileMargin) - tileMargin) / TopSitesPage.NUM_COLUMNS;
 
         adapter.setTileSize(tilesSize);
     }
 
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1135,9 +1135,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(1514482982353000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1514568659038000);
--- a/security/manager/ssl/nsSTSPreloadList.errors
+++ b/security/manager/ssl/nsSTSPreloadList.errors
@@ -1,15 +1,14 @@
 0005.com: could not connect to host
 0005aa.com: could not connect to host
 007sascha.de: 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 119"  data: no]
 0222aa.com: did not receive HSTS header
 048.ag: could not connect to host
-0day.su: did not receive HSTS header
 0f.io: did not receive HSTS header
 0g.org.uk: could not connect to host
 0o0.ooo: could not connect to host
 0p.no: did not receive HSTS header
 0w0.vc: could not connect to host
 0x0a.net: could not connect to host
 0x1337.eu: could not connect to host
 0x44.net: did not receive HSTS header
@@ -31,16 +30,17 @@ 123.gg: could not connect to host
 123share.org: could not connect to host
 123test.de: did not receive HSTS header
 123test.es: did not receive HSTS header
 123test.fr: did not receive HSTS header
 126ium.moe: could not connect to host
 127011-networks.ch: could not connect to host
 12vpn.org: could not connect to host
 12vpnchina.com: could not connect to host
+1396.net: could not connect to host
 1536.cf: could not connect to host
 163pwd.com: could not connect to host
 166166.com: could not connect to host
 16deza.com: did not receive HSTS header
 16packets.com: could not connect to host
 188betwarriors.co.uk: could not connect to host
 188trafalgar.ca: did not receive HSTS header
 1921958389.rsc.cdn77.org: did not receive HSTS header
@@ -102,17 +102,17 @@ 404404.info: could not connect to host
 420dongstorm.com: could not connect to host
 42ms.org: could not connect to host
 441jj.com: could not connect to host
 44448522.com: could not connect to host
 4448522.com: could not connect to host
 4455software.com: did not receive HSTS header
 44957.com: could not connect to host
 4679.space: could not connect to host
-4azino777.ru: could not connect to host
+4azino777.ru: did not receive HSTS header
 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: did not receive HSTS header
 4sqsu.eu: could not connect to host
 4w-performers.link: could not connect to host
 50millionablaze.org: could not connect to host
@@ -171,17 +171,16 @@ 911911.pw: could not connect to host
 915ers.com: max-age too low: 7776000
 922.be: could not connect to host
 960news.ca: could not connect to host
 9651678.ru: could not connect to host
 98laba.com: could not connect to host
 98laba.net: could not connect to host
 99511.fi: did not receive HSTS header
 99998522.com: could not connect to host
-99buffets.com: did not receive HSTS header
 9point6.com: could not connect to host
 9tolife.be: did not receive HSTS header
 a-intel.com: could not connect to host
 a-plus.space: could not connect to host
 a-rickroll-n.pw: could not connect to host
 a-theme.com: could not connect to host
 a.ai: did not receive HSTS header
 a1-autopartsglasgow.com: did not receive HSTS header
@@ -195,18 +194,18 @@ aaoo.net: could not connect to host
 aapp.space: could not connect to host
 aaron-gustafson.com: did not receive HSTS header
 aaronkimmig.de: could not connect to host
 aati.info: did not receive HSTS header
 abareplace.com: did not receive HSTS header
 abcheck.se: could not connect to host
 abearofsoap.com: could not connect to host
 abecodes.net: did not receive HSTS header
-aberdeenalmeras.com: could not connect to host
 abilitylist.org: did not receive HSTS header
+abilitynet.org.uk: could not connect to host
 abioniere.de: could not connect to host
 ablogagency.net: could not connect to host
 abmahnhelfer.de: did not receive HSTS header
 abnarnro.com: could not connect to host
 abona24.pl: max-age too low: 0
 about.ge: did not receive HSTS header
 abouthrm.nl: did not receive HSTS header
 aboutict.nl: did not receive HSTS header
@@ -281,16 +280,17 @@ advancedstudio.ro: did not receive HSTS 
 adver.top: did not receive HSTS header
 adviespuntklokkenluiders.nl: could not connect to host
 adzuna.co.uk: did not receive HSTS header
 aebian.org: could not connect to host
 aemoria.com: could not connect to host
 aerialmediapro.net: could not connect to host
 aes256.ru: could not connect to host
 aether.pw: could not connect to host
+aevpn.net: could not connect to host
 aeyoun.com: did not receive HSTS header
 af-fotografie.net: did not receive HSTS header
 afdkompakt.de: max-age too low: 86400
 aficotroceni.ro: did not receive HSTS header
 afiru.net: could not connect to host
 afp548.tk: could not connect to host
 after.im: did not receive HSTS header
 afvallendoeje.nu: could not connect to host
@@ -396,16 +396,17 @@ alphabit-secure.com: could not connect t
 alphabuild.io: could not connect to host
 alphagamers.net: did not receive HSTS header
 alphalabs.xyz: could not connect to host
 alphasall.com: could not connect to host
 als-hardware.co.za: did not receive HSTS header
 alt33c3.org: could not connect to host
 altamarea.se: could not connect to host
 alteqnia.com: could not connect to host
+alterbaum.net: could not connect to host
 altfire.ca: could not connect to host
 altmv.com: max-age too low: 7776000
 aluminium-scaffolding.co.uk: could not connect to host
 alusta.co: could not connect to host
 alza.at: did not receive HSTS header
 alza.co.uk: did not receive HSTS header
 alza.cz: did not receive HSTS header
 alza.de: did not receive HSTS header
@@ -471,16 +472,17 @@ andyclark.io: could not connect to host
 andymartin.cc: could not connect to host
 anfsanchezo.co: could not connect to host
 anfsanchezo.me: could not connect to host
 anghami.com: did not receive HSTS header
 anglictinatabor.cz: could not connect to host
 angryroute.com: could not connect to host
 animal-nature-human.com: did not receive HSTS header
 anime1.moe: could not connect to host
+anime1video.tk: could not connect to host
 animeday.ml: could not connect to host
 animesfusion.com.br: could not connect to host
 animesharp.com: could not connect to host
 animurecs.com: did not receive HSTS header
 aniplus.cf: could not connect to host
 aniplus.gq: could not connect to host
 aniplus.ml: could not connect to host
 anitklib.ml: could not connect to host
@@ -498,16 +500,17 @@ anonymousstatecollegelulzsec.com: could 
 anook.com: max-age too low: 0
 another.ch: could not connect to host
 ansdell.info: could not connect to host
 ansibeast.net: could not connect to host
 anstoncs.com.au: max-age too low: 86400
 ant.land: could not connect to host
 anthenor.co.uk: could not connect to host
 anthonyavon.com: could not connect to host
+anthropoid.ca: could not connect to host
 antimine.kr: could not connect to host
 antocom.com: did not receive HSTS header
 antoine-roux.fr: could not connect to host
 antoinedeschenes.com: could not connect to host
 antoinemary.io: 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
@@ -604,16 +607,17 @@ arzaroth.com: did not receive HSTS heade
 as.se: could not connect to host
 as9178.net: could not connect to host
 asahikoji.net: could not connect to host
 asasuou.pw: could not connect to host
 asc16.com: could not connect to host
 ascamso.com: could not connect to host
 aschaefer.net: could not connect to host
 asdpress.cn: could not connect to host
+asdyx.de: could not connect to host
 ashlane-cottages.com: could not connect to host
 asianodor.com: could not connect to host
 ask.pe: did not receive HSTS header
 askfit.cz: did not receive HSTS header
 asm-x.com: could not connect to host
 asmui.ga: could not connect to host
 asmui.ml: could not connect to host
 ass.org.au: did not receive HSTS header
@@ -633,23 +637,23 @@ atbeckett.com: did not receive HSTS head
 atcreform.gov: did not receive HSTS header
 atelier-rk.com: did not receive HSTS header
 athaliasoft.com: could not connect to host
 athenelive.com: could not connect to host
 athensbusinessresources.us: could not connect to host
 athul.xyz: could not connect to host
 atlex.nl: did not receive HSTS header
 atlseccon.com: did not receive HSTS header
-atom-china.org: could not connect to host
 atomic.menu: could not connect to host
 atomik.pro: could not connect to host
 atop.io: could not connect to host
 attic118.com: could not connect to host
 attimidesigns.com: did not receive HSTS header
 attogproductions.com: could not connect to host
+atulhost.com: did not receive HSTS header
 au-pair24.de: did not receive HSTS header
 au.search.yahoo.com: max-age too low: 172800
 au2pb.net: could not connect to host
 aubiosales.com: could not connect to host
 aucubin.moe: could not connect to host
 audiovisualdevices.com.au: did not receive HSTS header
 auditmatrix.com: did not receive HSTS header
 augias.org: could not connect to host
@@ -722,17 +726,16 @@ badcronjob.com: could not connect to hos
 badenhard.eu: could not connect to host
 badkamergigant.com: could not connect to host
 badlink.org: could not connect to host
 baff.lu: did not receive HSTS header
 bagiobella.com: max-age too low: 0
 baiduaccount.com: could not connect to host
 bailbondsaffordable.com: did not receive HSTS header
 bair.io: could not connect to host
-baiyangliu.com: could not connect to host
 bakhansen.com: did not receive HSTS header
 bakingstone.com: could not connect to host
 bakkerdesignandbuild.com: did not receive HSTS header
 balcan-underground.net: could not connect to host
 baldur.cc: could not connect to host
 baldwinkoo.com: could not connect to host
 baleares.party: could not connect to host
 balloonphp.com: could not connect to host
@@ -751,26 +754,26 @@ barrelhead.org: could not connect to hos
 barshout.co.uk: could not connect to host
 barss.io: could not connect to host
 barunisystems.com: could not connect to host
 bashc.at: could not connect to host
 bashcode.ninja: could not connect to host
 basicsolutionsus.com: did not receive HSTS header
 basilisk.io: could not connect to host
 bassh.net: did not receive HSTS header
+batfoundry.com: could not connect to host
 baud.ninja: could not connect to host
 baum.ga: could not connect to host
 baumstark.ca: could not connect to host
 baysse.eu: could not connect to host
 bazarstupava.sk: could not connect to host
 bazisszoftver.hu: did not receive HSTS header
 bb-shiokaze.jp: did not receive HSTS header
-bblove.me: could not connect to host
 bblovess.cn: could not connect to host
-bbrinck.eu: did not receive HSTS header
+bbrinck.eu: could not connect to host
 bbwdom.xyz: could not connect to host
 bbwfacesitting.xyz: could not connect to host
 bbwfight.xyz: could not connect to host
 bcbsmagentprofile.com: could not connect to host
 bcchack.com: could not connect to host
 bccx.com: could not connect to host
 bcheng.cf: did not receive HSTS header
 bchep.com: could not connect to host
@@ -1010,16 +1013,18 @@ bootjp.me: did not receive HSTS header
 borchers-media.de: could not connect to host
 borderlinegroup.com: could not connect to host
 boringsecurity.net: could not connect to host
 boris.one: did not receive HSTS header
 borscheid-wenig.com: did not receive HSTS header
 boschee.net: could not connect to host
 botox.bz: did not receive HSTS header
 botserver.de: could not connect to host
+bouncecoffee.com: did not receive HSTS header
+bouncourseplanner.net: could not connect to host
 bouwbedrijfpurmerend.nl: could not connect to host
 bowlroll.net: max-age too low: 0
 boxcryptor.com: did not receive HSTS header
 boxintense.com: did not receive HSTS header
 bp-wahl.at: did not receive HSTS header
 bqtoolbox.com: could not connect to host
 bragasoft.com.br: did not receive HSTS header
 braineet.com: did not receive HSTS header
@@ -1035,24 +1040,25 @@ brandon.so: could not connect to host
 brandred.net: could not connect to host
 brandspray.com: could not connect to host
 brasilmorar.com: did not receive HSTS header
 bratteng.xyz: could not connect to host
 brava.bg: did not receive HSTS header
 bravz.de: could not connect to host
 bregnedalsystems.dk: did not receive HSTS header
 bremensaki.com: max-age too low: 2592000
+brentnewbury.com: could not connect to host
 brettabel.com: could not connect to host
+bretz-hufer.de: could not connect to host
 brfvh24.se: could not connect to host
 brickoo.com: could not connect to host
 brickyardbuffalo.com: did not receive HSTS header
 bridholm.se: could not connect to host
 brightstarkids.com.au: did not receive HSTS header
 brilliantbuilders.co.uk: did not receive HSTS header
-britishsciencefestival.org: could not connect to host
 britzer-toner.de: did not receive HSTS header
 brks.xyz: could not connect to host
 broken-oak.com: could not connect to host
 brookechase.com: did not receive HSTS header
 browserid.org: could not connect to host
 brrd.io: could not connect to host
 brunix.net: could not connect to host
 brunohenc.from.hr: did not receive HSTS header
@@ -1061,17 +1067,16 @@ brunoramos.com: could not connect to hos
 brunoramos.org: could not connect to host
 brunosouza.org: could not connect to host
 bryn.xyz: could not connect to host
 bsagan.fr: could not connect to host
 bsdtips.com: could not connect to host
 bsociabl.com: could not connect to host
 btc-e.com: did not receive HSTS header
 btcdlc.com: could not connect to host
-buben.tech: could not connect to host
 bubulazi.com: did not receive HSTS header
 bubulazy.com: did not receive HSTS header
 buch-cuber.de: max-age too low: 0
 buchheld.at: did not receive HSTS header
 bucket.tk: could not connect to host
 budgetthostels.nl: did not receive HSTS header
 budskap.eu: could not connect to host
 buenosairesestetica.com.ar: could not connect to host
@@ -1194,16 +1199,17 @@ camjackson.net: did not receive HSTS hea
 cammarkets.com: could not connect to host
 camolist.com: could not connect to host
 campaignelves.com: did not receive HSTS header
 campbellsoftware.co.uk: could not connect to host
 campfire.co.il: did not receive HSTS header
 campusdrugprevention.gov: did not receive HSTS header
 camsanalytics.com: could not connect to host
 canadiangamblingchoice.com: did not receive HSTS header
+canarymod.net: could not connect to host
 cancelmyprofile.com: did not receive HSTS header
 candicontrols.com: did not receive HSTS header
 candratech.com: could not connect to host
 candygirl.shop: could not connect to host
 cannyfoxx.me: 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
@@ -1219,17 +1225,16 @@ carano-service.de: did not receive HSTS 
 caraudio69.cz: could not connect to host
 card-toka.jp: 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
 careerstuds.com: could not connect to host
 cargobay.net: could not connect to host
 caringladies.org: could not connect to host
-carlgo11.com: did not receive HSTS header
 carlo.mx: did not receive HSTS header
 carlolly.co.uk: could not connect to host
 carlosalves.info: could not connect to host
 carpliyz.com: could not connect to host
 carroarmato0.be: did not receive HSTS header
 carsforbackpackers.com: could not connect to host
 carwashvapeur.be: could not connect to host
 casc.cz: did not receive HSTS header
@@ -1243,16 +1248,17 @@ casinostest.com: did not receive HSTS he
 casioshop.eu: did not receive HSTS header
 casovi.cf: could not connect to host
 castagnonavocats.com: did not receive HSTS header
 cata.ga: could not connect to host
 catalin.pw: could not connect to host
 catarsisvr.com: could not connect to host
 catinmay.com: did not receive HSTS header
 catnapstudios.com: could not connect to host
+cattivo.nl: could not connect to host
 cavaleria.ro: did not receive HSTS header
 caveclan.org: did not receive HSTS header
 cavedevs.de: could not connect to host
 cavedroid.xyz: could not connect to host
 cbengineeringinc.com: did not receive HSTS header
 cbhq.net: could not connect to host
 ccblog.de: did not receive HSTS header
 ccsys.com: could not connect to host
@@ -1395,16 +1401,17 @@ clcleaningco.com: could not connect to h
 cleanexperts.co.uk: could not connect to host
 cleaningsquad.ca: did not receive HSTS header
 cleanmta.com: could not connect to host
 clearc.tk: could not connect to host
 clearsky.me: did not receive HSTS header
 clerkendweller.uk: did not receive HSTS header
 clickandgo.com: did not receive HSTS header
 clickandshoot.nl: did not receive HSTS header
+clickclickphish.com: did not receive HSTS header
 clickgram.biz: could not connect to host
 clicn.bio: could not connect to host
 clicnbio.com: did not receive HSTS header
 cliftons.com: did not receive HSTS header
 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
@@ -1438,16 +1445,17 @@ cmc-versand.de: did not receive HSTS hea
 cmci.dk: did not receive HSTS header
 cmsbattle.com: could not connect to host
 cmscafe.ru: did not receive HSTS header
 cmso-cal.com: could not connect to host
 cn.search.yahoo.com: did not receive HSTS header
 cncn.us: did not receive HSTS header
 cnwarn.com: could not connect to host
 co-driversphoto.se: could not connect to host
+co50.com: did not receive HSTS header
 coach-sportif.paris: could not connect to host
 cobrax.net: could not connect to host
 cocaine.ninja: could not connect to host
 cocktailfuture.fr: could not connect to host
 cocolovesdaddy.com: could not connect to host
 codabix.com: did not receive HSTS header
 codabix.de: could not connect to host
 codabix.net: could not connect to host
@@ -1582,32 +1590,33 @@ craftbeerbarn.co.uk: could not connect t
 craftedge.xyz: could not connect to host
 craftmain.eu: could not connect to host
 cranems.com.ua: did not receive HSTS header
 cranioschule.com: 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: could not connect to host
+crazycen.com: did not receive HSTS header
 crazycraftland.de: did not receive HSTS header
 crazycraftland.net: could not connect to host
 crazyhotseeds.com: did not receive HSTS header
 crbug.com: did not receive HSTS header (error ignored - included regardless)
 creaescola.com: did not receive HSTS header
 create-test-publish.co.uk: could not connect to host
 creativephysics.ml: could not connect to host
 creativeplayuk.com: did not receive HSTS header
 crecket.me: could not connect to host
 crendontech.com: could not connect to host
 crestoncottage.com: could not connect to host
 crimewatch.net.za: could not connect to host
 crisissurvivalspecialists.com: could not connect to host
 cristiandeluxe.com: did not receive HSTS header
 crizk.com: could not connect to host
+crmdemo.website: did not receive HSTS header
 crockett.io: did not receive HSTS header
 croome.no-ip.org: could not connect to host
 crosbug.com: did not receive HSTS header (error ignored - included regardless)
 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
 crownruler.com: did not receive HSTS header
@@ -1619,17 +1628,17 @@ crufad.org: did not receive HSTS header
 cruikshank.com.au: could not connect to host
 cruzr.xyz: 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
 cryptodash.net: could not connect to host
 cryptojar.io: did not receive HSTS header
-cryptolab.pro: 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
 cryptopartyatx.org: could not connect to host
 cryptophobia.nl: did not receive HSTS header
 cryptopush.com: did not receive HSTS header
 crysadm.com: max-age too low: 1
 crystalclassics.co.uk: did not receive HSTS header
 crystalmate.eu: did not receive HSTS header
@@ -1780,17 +1789,16 @@ dccode.gov: could not connect to host
 dccraft.net: could not connect to host
 dcl.re: did not receive HSTS header
 dctxf.com: could not connect to host
 dcuofriends.net: could not connect to host
 dcurt.is: did not receive HSTS header
 dcw.io: did not receive HSTS header
 ddatsh.com: could not connect to host
 ddepot.us: did not receive HSTS header
-deadsoul.net: 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
@@ -1935,26 +1943,26 @@ dl.google.com: did not receive HSTS head
 dlc.viasinc.com: could not connect to host
 dlemper.de: did not receive HSTS header
 dlscomputers.com.au: did not receive HSTS header
 dmcibulldog.com: did not receive HSTS header
 dmix.ca: could not connect to host
 dmtry.me: did not receive HSTS header
 dmwall.cn: could not connect to host
 dmz.ninja: could not connect to host
-dndtools.net: could not connect to host
 dns.google.com: did not receive HSTS header (error ignored - included regardless)
 dnsbird.net: could not connect to host
 dnsbird.org: could not connect to host
 dnsknowledge.com: did not receive HSTS header
 do-do.tk: could not connect to host
 do.search.yahoo.com: did not receive HSTS header
 dobet.in: could not connect to host
 docid.io: could not connect to host
 docket.news: could not connect to host
+doclot.io: did not receive HSTS header
 docset.io: could not connect to host
 docufiel.com: could not connect to host
 docxtemplater.com: did not receive HSTS header
 doesmycodehavebugs.today: could not connect to host
 doeswindowssuckforeveryoneorjustme.com: could not connect to host
 dogbox.se: did not receive HSTS header
 dogespeed.ga: could not connect to host
 doggieholic.net: could not connect to host
@@ -2002,17 +2010,16 @@ dougferris.id.au: could not connect to h
 doujin.nagoya: could not connect to host
 dovecotadmin.org: could not connect to host
 doveholesband.co.uk: did not receive HSTS header
 dovetailnow.com: could not connect to host
 download.jitsi.org: did not receive HSTS header
 downsouthweddings.com.au: could not connect to host
 doxcelerate.com: max-age too low: 69
 doyoucheck.com: did not receive HSTS header
-dracon.es: could not connect to host
 dragonisles.net: could not connect to host
 dragons-of-highlands.cz: could not connect to host
 dragonsmoke.cloud: could not connect to host
 dragonstower.net: could not connect to host
 dragonteam.ninja: could not connect to host
 drakefortreasurer.sexy: could not connect to host
 draw.uy: could not connect to host
 drdevil.ru: could not connect to host
@@ -2021,16 +2028,17 @@ dreamcatcherblog.de: could not connect t
 dreamlighteyeserum.com: could not connect to host
 dreamsforabetterworld.com.au: did not receive HSTS header
 drewgle.net: could not connect to host
 drhopeson.com: could not connect to host
 drinknaturespower.com: could not connect to host
 drinkvabeer.com: could not connect to host
 drishti.guru: could not connect to host
 drivercopilot.com: could not connect to host
+drlazarina.net: could not connect to host
 droidboss.com: did not receive HSTS header
 droncentrum.pl: could not connect to host
 droomhuis-in-brielle-kopen.nl: could not connect to host
 droomhuis-in-de-friese-meren-kopen.nl: could not connect to host
 droomhuis-in-delfzijl-kopen.nl: could not connect to host
 droomhuis-in-friesland-kopen.nl: could not connect to host
 droomhuis-in-laren-kopen.nl: could not connect to host
 droomhuis-in-pekela-kopen.nl: could not connect to host
@@ -2046,20 +2054,21 @@ drtti.io: could not connect to host
 drumbandesperanto.nl: did not receive HSTS header
 drupal123.com: did not receive HSTS header
 drycreekapiary.com: could not connect to host
 ds-christiansen.de: could not connect to host
 dshiv.io: could not connect to host
 dtub.co: could not connect to host
 dualias.xyz: could not connect to host
 dubik.su: did not receive HSTS header
+duelysthub.com: could not connect to host
 duerls.de: did not receive HSTS header
 duesee.org: could not connect to host
 dukec.me: could not connect to host
-dullsir.com: could not connect to host
+dullsir.com: did not receive HSTS header
 dungi.org: could not connect to host
 duongpho.com: did not receive HSTS header
 duskopy.top: could not connect to host
 dutchessuganda.com: did not receive HSTS header
 dutchrank.com: did not receive HSTS header
 duuu.ch: could not connect to host
 dycontrol.de: could not connect to host
 dylanscott.com.au: did not receive HSTS header
@@ -2173,17 +2182,16 @@ 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: could not connect to host
 elanguest.ru: could not connect to host
 elastic7.uk: could not connect to host
 elbetech.net: could not connect to host
 elblein.de: did not receive HSTS header
-electr0sheep.com: did not receive HSTS header
 electricant.com: did not receive HSTS header
 electricant.nl: did not receive HSTS header
 electricianforum.co.uk: did not receive HSTS header
 electricoperaduo.com: could not connect to host
 electromc.com: could not connect to host
 elektronring.com: could not connect to host
 elemenx.com: did not receive HSTS header
 elemprendedor.com.ve: did not receive HSTS header
@@ -2203,17 +2211,16 @@ elsemanario.com: did not receive HSTS he
 elsitar.com: could not connect to host
 elsword.moe: max-age too low: 2592000
 email.lookout.com: could not connect to host
 email2rss.net: could not connect to host
 emanatepixels.com: could not connect to host
 emanga.su: did not receive HSTS header
 embroidered-stuff.com: could not connect to host
 emeldi-commerce.com: max-age too low: 0
-emergentvisiontec.com: did not receive HSTS header
 emiele.com.br: did not receive HSTS header
 emilong.com: could not connect to host
 emilyhorsman.com: could not connect to host
 eminovic.me: could not connect to host
 emjainteractive.com: did not receive HSTS header
 emjimadhu.com: could not connect to host
 emmable.com: could not connect to host
 emmaliddell.com: could not connect to host
@@ -2267,16 +2274,17 @@ epicmc.games: could not connect to host
 epicpages.com: could not connect to host
 epoxate.com: could not connect to host
 eq8.net.au: could not connect to host
 eqim.me: could not connect to host
 equate.net.au: did not receive HSTS header
 equatetechnologies.com.au: did not receive HSTS header
 equilibre-yoga-jennifer-will.com: could not connect to host
 equitee.co: did not receive HSTS header
+equityflows.com: did not receive HSTS header
 erawanarifnugroho.com: did not receive HSTS header
 eressea.xyz: could not connect to host
 ergorium.com: did not receive HSTS header
 ergorium.eu: did not receive HSTS header
 ericbond.net: could not connect to host
 erichalv.com: did not receive HSTS header
 ericyl.com: could not connect to host
 eridanus.uk: could not connect to host
@@ -2346,16 +2354,17 @@ eurospecautowerks.com: did not receive H
 eurotime.ua: did not receive HSTS header
 evafojtova.cz: did not receive HSTS header
 evanhandgraaf.nl: did not receive HSTS header
 evdenevenakliyatankara.pw: did not receive HSTS header
 events12.com: did not receive HSTS header
 everybooks.com: could not connect to host
 everylab.org: could not connect to host
 everything.place: did not receive HSTS header
+eveseat.net: could not connect to host
 evi.be: did not receive HSTS header
 evilsay.com: 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
 evowl.com: could not connect to host
 ewallet-optimizer.com: did not receive HSTS header
@@ -2415,17 +2424,16 @@ fallenangelspirits.uk: could not connect
 fam-weyer.de: did not receive HSTS header
 fame-agency.net: could not connect to host
 familie-sprink.de: could not connect to host
 familie-zimmermann.at: could not connect to host
 famio.cn: could not connect to host
 fantasyfootballpundit.com: did not receive HSTS header
 fanyl.cn: could not connect to host
 farces.com: did not receive HSTS header
-farhadexchange.com: did not receive HSTS header
 farmacia.pt: could not connect to host
 fashion.net: did not receive HSTS header
 fashioncare.cz: did not receive HSTS header
 fashionholic.my: did not receive HSTS header
 fasset.jp: could not connect to host
 fastcomcorp.com: did not receive HSTS header
 fastcomcorp.net: did not receive HSTS header
 fastconfirm.com: could not connect to host
@@ -2436,26 +2444,26 @@ fatgeekflix.net: could not connect to ho
 fatherhood.gov: did not receive HSTS header
 fatlossguide.xyz: could not connect to host
 fatwin.pw: could not connect to host
 fatzebra.com.au: max-age too low: 0
 fayolle.info: did not receive HSTS header
 fbox.li: could not connect to host
 fdj.im: could not connect to host
 fdt.name: did not receive HSTS header
+feaden.me: could not connect to host
 feard.space: could not connect to host
 feastr.de: did not receive HSTS header
 fed51.com: could not connect to host
 fedn.it: could not connect to host
 fedo.moe: could not connect to host
 feedthebot.com: did not receive HSTS header
 feezmodo.com: did not receive HSTS header
 fefore.com: could not connect to host
 feirlane.org: could not connect to host
-feitobrasilcosmeticos.com.br: did not receive HSTS header
 felisslovakia.sk: [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 119"  data: no]
 feliwyn.fr: did not receive HSTS header
 felixrr.pro: could not connect to host
 femaledom.xyz: could not connect to host
 feminists.co: could not connect to host
 fenno.net: could not connect to host
 fenteo.com: could not connect to host
 feriahuamantla.com: could not connect to host
@@ -2464,28 +2472,28 @@ ferrolatino.com: could not connect to ho
 festember.com: did not receive HSTS header
 festrip.com: could not connect to host
 fetclips.se: could not connect to host
 fettbrot.tk: did not receive HSTS header
 fexmen.com: could not connect to host
 ff-getzersdorf.at: did not receive HSTS header
 ffmradio.de: did not receive HSTS header
 ffxiv.cc: could not connect to host
+ficlab.com: could not connect to host
 fics-twosigma.com: could not connect to host
 fideleslaici.com: did not receive HSTS header
 fiendishmasterplan.com: did not receive HSTS header
 fiftyshadesofluca.ml: could not connect to host
 fig.co: did not receive HSTS header
 fightr.co: could not connect to host
 fiksel.info: did not receive HSTS header
 fikt.space: could not connect to host
 filebox.moe: could not connect to host
 filemeal.com: did not receive HSTS header
 filey.co.uk: did not receive HSTS header
-filme-online.eu.com: could not connect to host
 filmesubtitrate2017.online: did not receive HSTS header
 finalgear.com: did not receive HSTS header
 finalvpn.com: could not connect to host
 financieringsportaal.nl: did not receive HSTS header
 finanzkontor.net: could not connect to host
 findigo.fish: could not connect to host
 findingmyname.com: did not receive HSTS header
 findtutorsnearme.com: did not receive HSTS header
@@ -2523,16 +2531,17 @@ fjruiz.es: did not receive HSTS header
 fkcovering.be: could not connect to host
 flags.ninja: could not connect to host
 flairbros.at: could not connect to host
 flamewall.net: could not connect to host
 flamingkeys.com.au: could not connect to host
 flareon.net: could not connect to host
 flatbellyreview.com: max-age too low: 2592000
 flawcheck.com: could not connect to host
+fleximus.org: could not connect to host
 fliexer.com: could not connect to host
 flipkey.com: did not receive HSTS header
 flirchi.com: did not receive HSTS header
 flixtor.net: could not connect to host
 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
@@ -2550,16 +2559,17 @@ flurrybridge.com: did not receive HSTS h
 flushstudios.com: did not receive HSTS header
 flyaces.com: could not connect to host
 fm83.nl: could not connect to host
 fmi.gov: did not receive HSTS header
 fnvsecurity.com: could not connect to host
 fojtova.cz: did not receive HSTS header
 fojtovi.cz: did not receive HSTS header
 fonetiq.io: could not connect to host
+foo: could not connect to host
 food4health.guide: could not connect to host
 foodbuddy.ch: could not connect to host
 foodiebox.no: did not receive HSTS header
 foodies.my: did not receive HSTS header
 foodievenues.com: could not connect to host
 foodsafetyworkinggroup.gov: could not connect to host
 footballmapped.com: could not connect to host
 footlegende.fr: did not receive HSTS header
@@ -2613,17 +2623,17 @@ freshfind.xyz: could not connect to host
 freshlymind.com: did not receive HSTS header
 frezbo.com: could not connect to host
 frforms.com: did not receive HSTS header
 friendica.ch: could not connect to host
 friendlyfiregameshow.com: could not connect to host
 friendlysiberia.com: could not connect to host
 frimons.com: could not connect to host
 froggstack.de: could not connect to host
-frontisme.nl: could not connect to host
+frontisme.nl: did not receive HSTS header
 frontmin.com: did not receive HSTS header
 frost-ci.xyz: could not connect to host
 froxlor.support: max-age too low: 0
 frsis2017.com: could not connect to host
 frugro.be: did not receive HSTS header
 fruitusers.com: could not connect to host
 frumious.fyi: could not connect to host
 frusky.net: could not connect to host
@@ -2645,16 +2655,17 @@ funnyang.com: could not connect to host
 funrun.com: did not receive HSTS header
 fuorifuocogenova.it: could not connect to host
 furiffic.com: did not receive HSTS header
 furnation.com: could not connect to host
 furry.be: did not receive HSTS header
 fusedrops.com: could not connect to host
 fusionmate.com: could not connect to host
 futbol11.com: did not receive HSTS header
+futbolvivo.tv: could not connect to host
 futos.de: could not connect to host
 futurestarsusa.org: did not receive HSTS header
 futuretechnologi.es: could not connect to host
 futureyouhealth.com: did not receive HSTS header
 fuvpn.com: did not receive HSTS header
 fuwafuwa.moe: could not connect to host
 fuxwerk.de: could not connect to host
 fwest.ovh: did not receive HSTS header
@@ -2664,26 +2675,25 @@ fx-rk.com: did not receive HSTS header
 fysiohaenraets.nl: did not receive HSTS header
 fzn.io: could not connect to host
 fzslm.me: could not connect to host
 g-i-s.vn: could not connect to host
 g-rickroll-o.pw: could not connect to host
 g01.in.ua: could not connect to host
 g2a.co: did not receive HSTS header
 g2g.com: did not receive HSTS header
-g4w.co: did not receive HSTS header (error ignored - included regardless)
+g4w.co: could not connect to host (error ignored - included regardless)
 g5led.nl: could not connect to host
 gabber.scot: could not connect to host
 gabi.com.es: could not connect to host
 gabi.soy: did not receive HSTS header
 gabi.uno: could not connect to host
 gablaxian.com: max-age too low: 2592000
 gabriele-kluge.de: could not connect to host
 gaelleetarnaud.com: did not receive HSTS header
-gafachi.com: did not receive HSTS header
 gainesvillegoneaustin.org: did not receive HSTS header
 gaite.me: 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
 galena.io: could not connect to host
@@ -2725,29 +2735,27 @@ gardencarezone.com: could not connect to
 garedtech.com: did not receive HSTS header
 garfieldairlines.net: did not receive HSTS header
 gatapro.net: could not connect to host
 gatorsa.es: did not receive HSTS header
 gaussorgues.me: could not connect to host
 gbc-radio.nl: did not receive HSTS header
 gc.net: could not connect to host
 gdegem.org: did not receive HSTS header
-gdz.tv: did not receive HSTS header
 gebn.co.uk: did not receive HSTS header
 gebn.uk: could not connect to host
 gedankenbude.info: could not connect to host
 geekcast.co.uk: did not receive HSTS header
 geeks.lgbt: did not receive HSTS header
 geeky.software: could not connect to host
 geemo.top: could not connect to host
 geeq.ch: could not connect to host
 geli-graphics.com: did not receive HSTS header
 gemsoftheworld.org: could not connect to host
 genesischangelog.com: did not receive HSTS header
-genia-life.de: could not connect to host
 genshiken.org: 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
 geoffdev.com: could not connect to host
 geopals.net: did not receive HSTS header
 george-brighton.co.uk: could not connect to host
@@ -2803,17 +2811,18 @@ giftservices.nl: could not connect to ho
 gigacloud.org: max-age too low: 0
 gigacog.com: could not connect to host
 gigawattz.com: could not connect to host
 gilcloud.com: could not connect to host
 gilgaz.com: did not receive HSTS header
 gillet-cros.fr: could not connect to host
 gilly.berlin: did not receive HSTS header
 gingali.de: did not receive HSTS header
-gintenreiter-photography.com: could not connect to host
+ginijony.com: did not receive HSTS header
+gintenreiter-photography.com: did not receive HSTS header
 giogadesign.com: did not receive HSTS header
 gipsamsfashion.com: could not connect to host
 gipsic.com: did not receive HSTS header
 gis3m.org: did not receive HSTS header
 gistfy.com: could not connect to host
 git-stuff.tk: could not connect to host
 github.party: did not receive HSTS header
 givemyanswer.com: could not connect to host
@@ -3017,17 +3026,16 @@ hackerforever.com: did not receive HSTS 
 hackerone-ext-adroll.com: could not connect to host
 hackerpoints.com: did not receive HSTS header
 hackerspace-ntnu.no: did not receive HSTS header
 hackest.org: did not receive HSTS header
 hackit.im: could not connect to host
 hackroyale.xyz: could not connect to host
 hacksnack.io: could not connect to host
 hadaf.pro: could not connect to host
-hadouk.in: could not connect to host
 hadzic.co: could not connect to host
 haeckdesign.com: did not receive HSTS header
 haeckl.eu: did not receive HSTS header
 haf.gr: could not connect to host
 hahayidu.org: could not connect to host
 hainoni.com: did not receive HSTS header
 haitschi.com: could not connect to host
 haitschi.de: did not receive HSTS header
@@ -3187,17 +3195,16 @@ hoast.xyz: could not connect to host
 hobaugh.social: could not connect to host
 hodne.io: could not connect to host
 hoekwoningverkopen.nl: 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
 hoiku-map.tokyo: could not connect to host
 hoikuen-now.top: could not connect to host
-holebedeljek.hu: did not receive HSTS header
 holgerlehner.com: could not connect to host
 holifestival-freyung.de: could not connect to host
 holymoly.lu: could not connect to host
 homa.website: could not connect to host
 homads.com: did not receive HSTS header
 homeandyarddetailing.com: could not connect to host
 homeclouding.de: could not connect to host
 homedna.com: did not receive HSTS header
@@ -3259,17 +3266,16 @@ http418.xyz: could not connect to host
 httphacker.com: could not connect to host
 https.ps: could not connect to host
 httpstatuscode418.xyz: could not connect to host
 hu.search.yahoo.com: did not receive HSTS header
 huangh.com: could not connect to host
 huarongdao.com: could not connect to host
 hubert.systems: did not receive HSTS header
 hugocollignon.fr: could not connect to host
-huirongis.me: could not connect to host
 humanesources.com: [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 119"  data: no]
 humankode.com: did not receive HSTS header
 humblefinances.com: did not receive HSTS header
 humeurs.net: could not connect to host
 humortuga.pt: could not connect to host
 humpi.at: could not connect to host
 humpteedumptee.in: did not receive HSTS header
 hunger.im: could not connect to host
@@ -3302,16 +3308,17 @@ iamveto.com: could not connect to host
 iapws.com: could not connect to host
 iban.is: could not connect to host
 ibarf.nl: did not receive HSTS header
 ibnuwebhost.com: could not connect to host
 icabanken.se: did not receive HSTS header
 icaforsakring.se: did not receive HSTS header
 ice.yt: could not connect to host
 icepink.com.br: did not receive HSTS header
+icewoman.net: did not receive HSTS header
 icfl.com.br: could not connect to host
 ich-find-den-g.net: could not connect to host
 ich-mach-druck.eu: did not receive HSTS header
 ichnichtskaufmann.de: could not connect to host
 ichoosebtec.com: did not receive HSTS header
 icity.ly: did not receive HSTS header
 icloud.net: could not connect to host
 icntorrent.download: could not connect to host
@@ -3477,16 +3484,17 @@ interlun.com: could not connect to host
 internaldh.com: could not connect to host
 internect.co.za: did not receive HSTS header
 internet-pornografie.de: did not receive HSTS header
 internetcasinos.de: could not connect to host
 internetcensus.org: could not connect to host
 internetdentalalliance.com: did not receive HSTS header
 interserved.com: did not receive HSTS header
 intervisteperstrada.com: did not receive HSTS header
+interways.de: did not receive HSTS header
 intim-uslugi-kazan.net: could not connect to host
 intimateperrierjouet.com: could not connect to host
 intimici.com.br: 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
 intune.life: did not receive HSTS header
 inverselink-user-content.com: could not connect to host
@@ -3588,17 +3596,17 @@ izdiwho.com: could not connect to host
 izolight.ch: could not connect to host
 izoox.com: did not receive HSTS header
 izzzorgconcerten.nl: could not connect to host
 j-lsolutions.com: could not connect to host
 j-rickroll-a.pw: could not connect to host
 ja-publications.com: did not receive HSTS header
 jabbari.io: did not receive HSTS header
 jackalworks.com: could not connect to host
-jackdoan.com: could not connect to host
+jackdoan.com: did not receive HSTS header
 jackfahnestock.com: could not connect to host
 jacobdevans.com: could not connect to host
 jacobparry.ca: did not receive HSTS header
 jagido.de: did not receive HSTS header
 jahliveradio.com: could not connect to host
 jaksi.io: could not connect to host
 jamanji.com.ng: could not connect to host
 james.je: could not connect to host
@@ -3772,17 +3780,16 @@ jumping-duck.com: could not connect to h
 junaos.com: did not receive HSTS header
 junaos.xyz: did not receive HSTS header
 jundimax.com.br: did not receive HSTS header
 junge-selbsthilfe.info: could not connect to host
 junglegoat.xyz: did not receive HSTS header
 junjung.me: max-age too low: 0
 junqtion.com: could not connect to host
 jupp0r.de: did not receive HSTS header
-juristas.com.br: did not receive HSTS header
 justiceforfathers.com: could not connect to host
 justinlemay.com: could not connect to host
 justlikethat.hosting: did not receive HSTS header
 justnaw.co.uk: could not connect to host
 justudin.com: did not receive HSTS header
 justwood.cz: did not receive HSTS header
 jutella.de: did not receive HSTS header
 juvenex.co: could not connect to host
@@ -3792,16 +3799,17 @@ jwilsson.me: could not connect to host
 jxm.in: could not connect to host
 jznet.org: could not connect to host
 k-dev.de: could not connect to host
 k-rickroll-g.pw: could not connect to host
 k1cp.com: could not connect to host
 ka-clan.com: could not connect to host
 kabinapp.com: could not connect to host
 kabuabc.com: could not connect to host
+kabus.org: could not connect to host
 kachlikova2.cz: could not connect to host
 kackscharf.de: could not connect to host
 kadioglumakina.com.tr: did not receive HSTS header
 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
@@ -3834,16 +3842,17 @@ katproxy.tech: could not connect to host
 katproxy.top: did not receive HSTS header
 katyl.info: could not connect to host
 kaufkraftkiel.de: could not connect to host
 kausch.at: could not connect to host
 kavinvin.me: could not connect to host
 kawaiiku.com: could not connect to host
 kawaiiku.de: could not connect to host
 kayscs.com: could not connect to host
+kbfl.org: could not connect to host
 kcluster.io: could not connect to host
 kcolford.com: did not receive HSTS header
 kd-plus.pp.ua: could not connect to host
 kdata.it: did not receive HSTS header
 kdm-online.de: did not receive HSTS header
 keeley.gq: could not connect to host
 keeley.ml: could not connect to host
 keeleysam.me: could not connect to host
@@ -3854,30 +3863,30 @@ kefaloniatoday.com: did not receive HSTS
 kenvix.com: could not connect to host
 kerangalam.com: did not receive HSTS header
 kerksanders.nl: did not receive HSTS header
 kermadec.blog: could not connect to host
 kermadec.com: max-age too low: 43200
 kermadec.net: could not connect to host
 kernl.us: did not receive HSTS header
 keskeces.com: did not receive HSTS header
+kevinmeijer.nl: could not connect to host
 keymaster.lookout.com: did not receive HSTS header
 kfbrussels.be: could not connect to host
 kg-rating.com: could not connect to host
 kgxtech.com: max-age too low: 2592000
 khaganat.net: did not receive HSTS header
 ki-on.net: did not receive HSTS header
 kialo.com: did not receive HSTS header
 kickass-proxies.org: could not connect to host
 kickass.al: could not connect to host
 kickasstorrents.gq: could not connect to host
 kid-dachau.de: did not receive HSTS header
 kidkat.cn: could not connect to host
 kiel-media.de: did not receive HSTS header
-kilerd.me: did not receive HSTS header
 killerit.in: could not connect to host
 kimana.pe: 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
 kindlyfire.com: could not connect to host
 kindof.ninja: could not connect to host
@@ -3912,43 +3921,43 @@ kiyo.space: could not connect to host
 kizil.net: could not connect to host
 kjaermaxi.me: did not receive HSTS header
 kjg-bachrain.de: could not connect to host
 klauwd.com: did not receive HSTS header
 klaxn.org: could not connect to host
 klean-ritekc.com: did not receive HSTS header
 kleertjesvoordelig.nl: could not connect to host
 kleinerarchitekturfuehrer.de: could not connect to host
+kleinreich.de: could not connect to host
 kleppe.co: could not connect to host
 kletterkater.com: did not receive HSTS header
 klicktojob.de: could not connect to host
 klunkergarten.org: could not connect to host
 knapen.io: max-age too low: 604800
 knccloud.com: could not connect to host
 kngk-transavto.ru: could not connect to host
 knight-industries.org: could not connect to host
 knightsbridgegroup.org: could not connect to host
-knightsweep.com: did not receive HSTS header
 knowdebt.org: did not receive HSTS header
 knowledgesnap.com: could not connect to host
 knowledgesnapsites.com: could not connect to host
 koddsson.com: could not connect to host
 kode-it.de: 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
 koelbli.ch: did not receive HSTS header
 koen.io: did not receive HSTS header
 koenrouwhorst.nl: did not receive HSTS header
 koenvdheuvel.me: did not receive HSTS header
 koerperimpuls.ch: did not receive HSTS header
 koik.io: could not connect to host
 kojima-life.co.jp: max-age too low: 0
 kokenmetaanbiedingen.nl: did not receive HSTS header
-kola-entertainments.de: did not receive HSTS header
+kola-entertainments.de: could not connect to host
 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
 konata.us: could not connect to host
 kontaxis.network: could not connect to host
 kontorhaus-schlachte.de: could not connect to host
 koopjesnel.nl: could not connect to host
@@ -4169,17 +4178,17 @@ lifeinitsownway.com: could not connect t
 lifeskillsdirect.com: did not receive HSTS header
 lifetimemoneymachine.com: did not receive HSTS header
 lightarmory.com: could not connect to host
 lightning-ashe.com: did not receive HSTS header
 lightpaste.com: could not connect to host
 lightworx.io: did not receive HSTS header
 lila.pink: did not receive HSTS header
 lillepuu.com: did not receive HSTS header
-lillpopp.eu: did not receive HSTS header
+lillpopp.eu: max-age too low: 10
 lilpwny.com: could not connect to host
 lilycms.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: did not receive HSTS header
 limodo-shop.de: did not receive HSTS header
 limpido.it: could not connect to host
@@ -4187,17 +4196,16 @@ lincolnwayflorist.com: could not connect
 lindberg.io: did not receive HSTS header
 lingerie.net.br: 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
 linkage.ph: did not receive HSTS header
-linkmauve.fr: could not connect to host
 linmi.cc: could not connect to host
 linno.me: could not connect to host
 linorman1997.me: could not connect to host
 linux-mint.cz: could not connect to host
 linuxandstuff.de: 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
@@ -4271,16 +4279,17 @@ lothai.re: did not receive HSTS header
 lothuytinhsi.com: could not connect to host
 lotsencafe.de: did not receive HSTS header
 lotuscloud.de: could not connect to host
 lotuscloud.org: could not connect to host
 louiewatch.com: could not connect to host
 loveable.de: could not connect to host
 lovelifelovelive.com: could not connect to host
 lovelive.us: could not connect to host
+lovelivewiki.com: did not receive HSTS header
 lovelyblogacademy.com: did not receive HSTS header
 lovelycorral.com: did not receive HSTS header
 loveto.at: could not connect to host
 lovingearth.net: max-age too low: 0
 lowhangingfruitgrabber.com: could not connect to host
 loxis.be: did not receive HSTS header
 lpak.nl: could not connect to host
 lpgram.ga: could not connect to host
@@ -4501,19 +4510,19 @@ maur.cz: did not receive HSTS header
 maurus-automation.de: did not receive HSTS header
 mavisang.cf: could not connect to host
 mawe.red: could not connect to host
 maximov.space: could not connect to host
 maxr1998.de: did not receive HSTS header
 maxserver.com: did not receive HSTS header
 maya.mg: could not connect to host
 mazz-tech.com: could not connect to host
+mbconsultancy.nu: did not receive HSTS header
 mc81.com: could not connect to host
 mca2017.org: did not receive HSTS header
-mcadmin.net: could not connect to host
 mcard.vn: did not receive HSTS header
 mcc.re: could not connect to host
 mcdonalds.ru: did not receive HSTS header
 mcga.media: could not connect to host
 mclab.su: could not connect to host
 mclist.it: could not connect to host
 mcooperlaw.com: did not receive HSTS header
 mdfnet.se: did not receive HSTS header
@@ -4566,28 +4575,29 @@ memorytrace.space: could not connect to 
 menkyo-blog.com: did not receive HSTS header
 mensmaximus.de: did not receive HSTS header
 menthix.net: could not connect to host
 menudrivetest.com: could not connect to host
 meow.cloud: could not connect to host
 meozcraft.com: could not connect to host
 mercedes-benz-usedcars.be: could not connect to host
 mereckas.com: could not connect to host
-meredithkm.info: could not connect to host
+meredithkm.info: did not receive HSTS header
 meritz.rocks: could not connect to host
 mersinunivercity.com: did not receive HSTS header
 merson.me: could not connect to host
 meshlab.co: could not connect to host
 mesmoque.com: could not connect to host
 metagrader.com: could not connect to host
 metasyntactic.xyz: could not connect to host
 metebalci.com: did not receive HSTS header
 meteosherbrooke.com: could not connect to host
 meteosky.net: could not connect to host
 meter.md: could not connect to host
+meterhost.com: could not connect to host
 metin2blog.de: did not receive HSTS header
 metis.pw: could not connect to host
 metrans-spedition.de: could not connect to host
 metricaid.com: did not receive HSTS header
 metzgerei-birkenhof.de: could not connect to host
 meuemail.pro: could not connect to host
 mexbt.com: could not connect to host
 mexicanbusinessweb.mx: did not receive HSTS header
@@ -4601,16 +4611,17 @@ mgknet.com: could not connect to host
 mh-bloemen.co.jp: could not connect to host
 mhdsyarif.com: did not receive HSTS header
 mhealthdemocamp.com: could not connect to host
 mhertel.com: did not receive HSTS header
 mhict.nl: could not connect to host
 mht-travel.com: could not connect to host
 mhx.pw: could not connect to host
 mi80.com: could not connect to host
+mia.to: could not connect to host
 mianfei-vpn.com: did not receive HSTS header
 michaeldemuth.com: could not connect to host
 michaelfitzpatrickruth.com: could not connect to host
 michaelmorpurgo.com: did not receive HSTS header
 michaeln.net: did not receive HSTS header
 michaelscrivo.com: did not receive HSTS header
 michaelwaite.org: could not connect to host
 michal-kral.cz: could not connect to host
@@ -4743,17 +4754,17 @@ modx.by: max-age too low: 31536
 modydev.club: could not connect to host
 moe4sale.in: did not receive HSTS header
 moebel-nagel.de: did not receive HSTS header
 moellers.it: could not connect to host
 moelord.org: could not connect to host
 moen.io: did not receive HSTS header
 mogry.net: could not connect to host
 moho.kr: could not connect to host
-mohs.es: could not connect to host
+mohs.es: did not receive HSTS header
 moitur.com: could not connect to host
 mokhtarmial.com: did not receive HSTS header
 mols.me: could not connect to host
 molun.net: did not receive HSTS header
 mommel.com: could not connect to host
 mommelonline.de: could not connect to host
 momoka.moe: could not connect to host
 mon-a-lisa.com: did not receive HSTS header
@@ -4833,17 +4844,17 @@ mtamaki.com: could not connect to host
 mtdn.jp: could not connect to host
 mtg-esport.de: did not receive HSTS header
 mu.search.yahoo.com: did not receive HSTS header
 muahahahaha.co.uk: could not connect to host
 mudcrab.us: did not receive HSTS header
 mujadin.se: did not receive HSTS header
 mundodapoesia.com: did not receive HSTS header
 munich-rage.de: could not connect to host
-munirajiwa.com: could not connect to host
+munirajiwa.com: did not receive HSTS header
 munkiepus.com: did not receive HSTS header
 munuc.org: did not receive HSTS header
 munzee.com: did not receive HSTS header
 muonium.ch: could not connect to host
 muriburi.land: could not connect to host
 muriburiland.com: could not connect to host
 murodese.org: could not connect to host
 murrayrun.com: did not receive HSTS header
@@ -5020,16 +5031,17 @@ newkaliningrad.ru: did not receive HSTS 
 newlooknow.com: did not receive HSTS header
 newmelalife.com: did not receive HSTS header
 newparadigmventures.net: did not receive HSTS header
 newportpropertygroup.com: could not connect to host
 newstarnootropics.com: max-age too low: 7776000
 newtonwarp.com: could not connect to host
 nexgeneration-solutions.com: could not connect to host
 next176.sk: did not receive HSTS header
+next47.com: did not receive HSTS header
 nextcloud.org: could not connect to host
 nexth.de: could not connect to host
 nexth.net: could not connect to host
 nexth.us: could not connect to host
 nextpages.de: could not connect to host
 nextproject.us: could not connect to host
 nexusbyte.de: did not receive HSTS header
 nfo.so: could not connect to host
@@ -5107,16 +5119,17 @@ nothing.net.nz: max-age too low: 7776000
 notjustbitchy.com: did not receive HSTS header
 nottheonion.net: did not receive HSTS header
 nou.si: could not connect to host
 nouvelle-vague-saint-cast.fr: did not receive HSTS header
 nova-elearning.com: did not receive HSTS header
 novaco.in: max-age too low: 3600
 novacoast.com: did not receive HSTS header
 novacraft.me: did not receive HSTS header
+novascan.net: could not connect to host
 novatrucking.de: could not connect to host
 novavoidhowl.com: did not receive HSTS header
 novelabs.de: could not connect to host
 novelabs.eu: did not receive HSTS header
 novurania.com: did not receive HSTS header
 nowak.ninja: did not receive HSTS header
 noworrywp.com: could not connect to host
 nozoe.jp: could not connect to host
@@ -5157,27 +5170,27 @@ nurserybook.co: did not receive HSTS hea
 nusatrip-api.com: did not receive HSTS header
 nutricuerpo.com: 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
 nwork.media: could not connect to host
+nwwc.dk: could not connect to host
 nycroth.com: could not connect to host
 nyesider.org: could not connect to host
 nyored.com: did not receive HSTS header
 nyphox.net: could not connect to host
 nys-hk.com: could not connect to host
 nysepho.pw: could not connect to host
 nysifclaimcentral.com: did not receive HSTS header
 nystart.no: did not receive HSTS header
 nz.search.yahoo.com: max-age too low: 172800
 nzbs.io: could not connect to host
-nzmk.cz: did not receive HSTS header
 nzquakes.maori.nz: could not connect to host
 o-rickroll-y.pw: could not connect to host
 o0o.one: could not connect to host
 oasis.mobi: did not receive HSTS header
 oblast45.ru: did not receive HSTS header
 obscuredfiles.com: could not connect to host
 obsydian.org: could not connect to host
 occentus.net: did not receive HSTS header
@@ -5311,16 +5324,17 @@ originpc.com: did not receive HSTS heade
 orion-universe.com: did not receive HSTS header
 orioncustompcs.com: could not connect to host
 orionfcu.com: did not receive HSTS header
 orionrebellion.com: could not connect to host
 orleika.ml: could not connect to host
 oroweatorganic.com: could not connect to host
 orthodoxy.lt: did not receive HSTS header
 osaiyuwu.com: could not connect to host
+osborneinn.com: did not receive HSTS header
 oscloud.com: could not connect to host
 oscloud.com.ua: could not connect to host
 oscreen.me: could not connect to host
 oscreen.org: could not connect to host
 osdls.gov: could not connect to host
 oshell.me: could not connect to host
 oslfoundation.org: could not connect to host
 osp.cx: could not connect to host
@@ -5388,16 +5402,17 @@ panni.me: could not connect to host
 panoranordic.net: could not connect to host
 pansu.space: could not connect to host
 pants-off.xyz: could not connect to host
 pantsu.cat: did not receive HSTS header
 papalytics.com: could not connect to host
 papeda.net: could not connect to host
 papercard.co.uk: did not receive HSTS header
 papercrunch.io: could not connect to host
+papersmart.net: did not receive HSTS header
 papierniak.net: could not connect to host
 papygeek.com: could not connect to host
 parabhairavayoga.com: max-age too low: 0
 paradiselost.com: max-age too low: 0
 parent5446.us: could not connect to host
 parentmail.co.uk: did not receive HSTS header
 parisvox.info: did not receive HSTS header
 parithy.net: could not connect to host
@@ -5430,17 +5445,16 @@ patfs.com: did not receive HSTS header
 pathwaytofaith.com: could not connect to host
 patientinsight.net: did not receive HSTS header
 patt.us: could not connect to host
 patterson.mp: could not connect to host
 paul-kerebel.pro: could not connect to host
 pauladamsmith.com: could not connect to host
 paulbunyanmls.com: did not receive HSTS header
 paulproell.at: could not connect to host
-paulshir.com: could not connect to host
 paulyang.cn: did not receive HSTS header
 pavelfojt.cz: did not receive HSTS header
 paxwinkel.nl: did not receive HSTS header
 pay.gigahost.dk: did not receive HSTS header
 paybro.eu: did not receive HSTS header
 payfreez.com: could not connect to host
 payments-reference.org: could not connect to host
 payments.google.com: did not receive HSTS header (error ignored - included regardless)
@@ -5468,23 +5482,23 @@ pekkapikkarainen.fi: did not receive HST
 pekkapleppanen.fi: could not connect to host
 pekkarik.ru: could not connect to host
 peliculasaudiolatinoonline.com: could not connect to host
 peliseries24.com: did not receive HSTS header
 pemberton.at: did not receive HSTS header
 pengui.uk: could not connect to host
 penguinclientsystem.com: did not receive HSTS header
 pentagram.me: max-age too low: 2592000
-pentandra.com: could not connect to host
 pentano.net: could not connect to host
 people-mozilla.org: could not connect to host
 peperiot.com: did not receive HSTS header
 pepperhead.com: did not receive HSTS header
 pepperworldhotshop.de: did not receive HSTS header
 pepsicoemployeepreferencesurvey.com: did not receive HSTS header
+percy.io: did not receive HSTS header
 perfect-radiant-wrinkles.com: could not connect to host
 perfectionis.me: could not connect to host
 performaterm.ro: could not connect to host
 performous.org: could not connect to host
 perfumista.vn: did not receive HSTS header
 periscopeliveweb.com: could not connect to host
 perlwork.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 119"  data: no]
 pernatie.ru: could not connect to host
@@ -5515,17 +5529,16 @@ pfgshop.com.br: did not receive HSTS hea
 pflegedienst-gratia.de: max-age too low: 300
 pgcpbc.com: could not connect to host
 pgpm.io: could not connect to host
 pgtb.be: did not receive HSTS header
 phalconist.com: did not receive HSTS header
 pharmgkb.org: could not connect to host
 phdsupply.com: did not receive HSTS header
 phelx.de: could not connect to host
-phil.tw: could not connect to host
 phillipgoldfarb.com: could not connect to host
 phillmoore.com: did not receive HSTS header
 phillprice.com: could not connect to host
 philpropertygroup.com: could not connect to host
 phoebe.co.nz: did not receive HSTS header
 phoenixlogan.com: could not connect to host
 phonenumberinfo.co.uk: could not connect to host
 phongmay24h.com: could not connect to host
@@ -5538,17 +5551,16 @@ physicaltherapist.com: did not receive H
 pianetaottica.net: could not connect to host
 pianetaottica.org: could not connect to host
 picardiascr.com: did not receive HSTS header
 pickersurvey.org: could not connect to host
 pickr.co: did not receive HSTS header
 picone.com.au: could not connect to host
 picotronic.biz: could not connect to host
 picscare.co.uk: did not receive HSTS header
-pieterbos.nl: 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
 pimpmymac.ru: did not receive HSTS header
 pims.global: did not receive HSTS header
 pin.net.au: did not receive HSTS header
@@ -5589,17 +5601,16 @@ placefade.com: could not connect to host
 placollection.org: could not connect to host
 plaettliaktion.ch: did not receive HSTS header
 planpharmacy.com: could not connect to host
 plant.ml: did not receive HSTS header
 plass.hamburg: could not connect to host
 plataformadeinformacion.es: max-age too low: 300
 platform.lookout.com: could not connect to host
 platomania.eu: did not receive HSTS header
-plattner.club: could not connect to host
 play.google.com: did not receive HSTS header (error ignored - included regardless)
 playerhunter.com: did not receive HSTS header
 playflick.com: could not connect to host
 playmaker.io: could not connect to host
 playnation.io: could not connect to host
 playsharp.com: could not connect to host
 pleasure.forsale: could not connect to host
 pleier-it.de: did not receive HSTS header
@@ -5634,17 +5645,16 @@ pol.in.th: could not connect to host
 polarityschule.com: did not receive HSTS header
 pole.net.nz: could not connect to host
 policeiwitness.sg: could not connect to host
 polimat.org: could not connect to host
 politically-incorrect.xyz: could not connect to host
 politologos.org: did not receive HSTS header
 polycoise.com: could not connect to host
 polycrypt.us: could not connect to host
-polymathematician.com: did not receive HSTS header
 polypho.nyc: could not connect to host
 pompefunebrilariviera.it: could not connect to host
 pompompoes.com: could not connect to host
 pontokay.com.br: could not connect to host
 pontualcomp.com: could not connect to host
 pony.today: did not receive HSTS header
 ponythread.com: did not receive HSTS header
 poolsandstuff.com: did not receive HSTS header
@@ -5850,17 +5860,17 @@ quickpayservice.com: could not connect t
 quizionic.com: did not receive HSTS header
 quizmemes.org: could not connect to host
 quli.nl: did not receive HSTS header
 quotehex.com: could not connect to host
 quotemaster.co.za: could not connect to host
 quranserver.net: could not connect to host
 qvi.st: did not receive HSTS header
 qwaser.fr: could not connect to host
-qwilink.me: did not receive HSTS header
+qwilink.me: could not connect to host
 r-core.ru: could not connect to host
 r-rickroll-u.pw: could not connect to host
 r10n.com: did not receive HSTS header
 r15.me: did not receive HSTS header
 r3bl.me: did not receive HSTS header
 r40.us: could not connect to host
 ra-schaal.de: could not connect to host
 raajheshkannaa.com: could not connect to host
@@ -5996,16 +6006,17 @@ renlong.org: did not receive HSTS header
 renrenss.com: could not connect to host
 rentacarcluj.xyz: did not receive HSTS header
 rentbrowsertrain.me: could not connect to host
 rentcarassist.com: could not connect to host
 renteater.com: could not connect to host
 renyiyou.com: could not connect to host
 replacemychina.com: could not connect to host
 reprolife.co.uk: could not connect to host
+reqrut.net: could not connect to host
 res-rheingau.de: did not receive HSTS header
 res42.com: could not connect to host
 reserve-online.net: did not receive HSTS header
 residentsinsurance.co.uk: did not receive HSTS header
 resl20.servehttp.com: could not connect to host
 respice.xyz: could not connect to host
 respostas.com.br: did not receive HSTS header
 restaurace-klokocka.cz: did not receive HSTS header
@@ -6048,17 +6059,16 @@ rigolitch.fr: did not receive HSTS heade
 riiconnect24.net: max-age too low: 0
 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
 rionewyork.com.br: did not receive HSTS header
 ripa.io: did not receive HSTS header
 rippleunion.com: could not connect to host
-risiinfo.com: did not receive HSTS header
 riskmgt.com.au: could not connect to host
 rithm.ch: did not receive HSTS header
 rivaforum.de: did not receive HSTS header
 rivastation.de: did not receive HSTS header
 rivlo.com: could not connect to host
 rix.ninja: could not connect to host
 rizon.me: could not connect to host
 rj.gg: could not connect to host
@@ -6111,16 +6121,17 @@ roundtheme.com: did not receive HSTS hea
 rous.se: could not connect to host
 rouvray.org: could not connect to host
 royal-forest.org: max-age too low: 0
 royalhop.co: could not connect to host
 royalpub.net: did not receive HSTS header
 royalsignaturecruise.com: did not receive HSTS header
 roychan.org: max-age too low: 0
 rozeapp.nl: could not connect to host
+rprimas.duckdns.org: could not connect to host
 rr.in.th: could not connect to host
 rrke.cc: did not receive HSTS header
 rsajeey.info: could not connect to host
 rsampaio.info: could not connect to host
 rsauget.fr: could not connect to host
 rsblake.net: could not connect to host
 rsf.io: could not connect to host
 rsmaps.org: could not connect to host
@@ -6182,17 +6193,16 @@ sakurabuff.com: could not connect to hos
 salserocafe.com: did not receive HSTS header
 salserototal.com: could not connect to host
 saltedskies.com: could not connect to host
 saltra.online: did not receive HSTS header
 samegoal.org: did not receive HSTS header
 sametovymesic.cz: could not connect to host
 samfunnet.no: max-age too low: 0
 saml2.com: could not connect to host
-samm.com.au: did not receive HSTS header
 sampcup.com: could not connect to host
 sampoznay.ru: did not receive HSTS header
 samraskauskas.com: could not connect to host
 samsen.club: did not receive HSTS header
 samui-samui.de: did not receive HSTS header
 sanasalud.org: could not connect to host
 sanatfilan.com: did not receive HSTS header
 sandviks.com: did not receive HSTS header
@@ -6287,17 +6297,16 @@ sdrobs.com: did not receive HSTS header
 sdsl-speedtest.de: could not connect to host
 seans.cc: did not receive HSTS header
 search-one.de: did not receive HSTS header
 seavancouver.com: could not connect to host
 sebastian-bair.de: could not connect to host
 sebastianhampl.de: could not connect to host
 sebster.com: did not receive HSTS header
 secandtech.com: could not connect to host
-secboom.com: did not receive HSTS header
 seccom.ch: did not receive HSTS header
 secnet.ga: could not connect to host
 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
@@ -6307,16 +6316,18 @@ secondspace.ca: could not connect to hos
 secretpanties.com: could not connect to host
 section508.gov: did not receive HSTS header
 sectun.com: did not receive HSTS header
 secumail.nl: did not receive HSTS header
 secur3.us: did not receive HSTS header
 secure-games.us: could not connect to host
 secure.link: did not receive HSTS header
 securechat4.me: could not connect to host
+securedevelop.net: could not connect to host
+securefuture.nl: could not connect to host
 secureobscure.com: could not connect to host
 secureradio.net: could not connect to host
 securesuisse.ch: could not connect to host
 security-carpet.com: could not connect to host
 security-thoughts.org: could not connect to host
 security201.com: could not connect to host
 securitybsides.pl: did not receive HSTS header
 securityglance.com: could not connect to host
@@ -6386,16 +6397,17 @@ sethcaplan.com: could not connect to hos
 setphaserstostun.org: could not connect to host
 setuid.de: could not connect to host
 setuid.io: did not receive HSTS header
 seyahatsagliksigortalari.com: could not connect to host
 sfashion.si: did not receive HSTS header
 sfhobbies.com.br: could not connect to host
 sfsltd.com: did not receive HSTS header
 sgtsnookums.net: could not connect to host
+sh11.pp.ua: max-age too low: 2592000
 shadoom.com: did not receive HSTS header
 shadow-socks.net: did not receive HSTS header
 shadow-socks.org: did not receive HSTS header
 shadowguardian507-irl.tk: did not receive HSTS header
 shadowguardian507.tk: did not receive HSTS header
 shadowmorph.info: did not receive HSTS header
 shadowshocks.net: did not receive HSTS header
 shadowsocks.gift: did not receive HSTS header
@@ -6483,23 +6495,23 @@ simbihaiti.com: did not receive HSTS hea
 simccorp.com: did not receive HSTS header
 simeon.us: max-age too low: 2592000
 simfri.com: did not receive HSTS header
 simobilklub.si: could not connect to host
 simod.org: could not connect to host
 simon-pokorny.com: did not receive HSTS header
 simon.butcher.name: max-age too low: 2629743
 simongong.net: did not receive HSTS header
+simonsaxon.com: did not receive HSTS header
 simpan.id: did not receive HSTS header
 simpleai.net: max-age too low: 600
 simplelearner.com: could not connect to host
 simplepractice.com: did not receive HSTS header
 simplixos.org: could not connect to host
 simply-premium.com: did not receive HSTS header
-simplyfixit.co.uk: did not receive HSTS header
 sin30.net: could not connect to host
 sincai666.com: could not connect to host
 sincron.org: could not connect to host
 sinful.pw: could not connect to host
 singul4rity.com: could not connect to host
 sinneserweiterung.de: could not connect to host
 sinosky.org: did not receive HSTS header
 siriad.com: could not connect to host
@@ -6577,16 +6589,17 @@ snailing.org: could not connect to host
 snakehosting.dk: did not receive HSTS header
 snapappts.com: could not connect to host
 snapworks.net: did not receive HSTS header
 sneeuwhoogtes.eu: could not connect to host
 snekchat.moe: could not connect to host
 snel4u.nl: could not connect to host
 snelwerk.be: could not connect to host
 sng.my: could not connect to host
+snille.com: could not connect to host
 snip.host: could not connect to host
 snippet.host: could not connect to host
 snoozedds.com: max-age too low: 600
 snoqualmiefiber.org: could not connect to host
 sobabox.ru: could not connect to host
 sobinski.pl: did not receive HSTS header
 sobotkama.eu: did not receive HSTS header
 soccergif.com: could not connect to host
@@ -6598,16 +6611,17 @@ socialgrowing.cl: did not receive HSTS h
 socialhead.io: could not connect to host
 socialhub.com: did not receive HSTS header
 socializam.com: did not receive HSTS header
 socialprize.com: could not connect to host
 socialspirit.com.br: did not receive HSTS header
 sockeye.cc: could not connect to host
 socomponents.co.uk: could not connect to host
 sodacore.com: could not connect to host
+soe-server.com: could not connect to host
 softballsavings.com: did not receive HSTS header
 softcreatr.de: did not receive HSTS header
 software.rocks: could not connect to host
 sogeek.me: could not connect to host
 sokolka.tv: did not receive HSTS header
 sol-3.de: did not receive HSTS header
 solanum-games.com: could not connect to host
 solentes.com.br: did not receive HSTS header
@@ -6638,17 +6652,17 @@ southernjamusa.com: did not receive HSTS
 southgale.condos: could not connect to host
 southside-crew.club: could not connect to host
 southworcestershiregpservices.co.uk: could not connect to host
 souyar.de: could not connect to host
 souyar.net: could not connect to host
 souyar.us: could not connect to host
 sovereignshare.com: could not connect to host
 sown.dyndns.org: could not connect to host
-soz6.com: did not receive HSTS header
+soz6.com: could not connect to host
 spacedust.xyz: could not connect to host
 spacefish.biz: could not connect to host
 spacehq.org: could not connect to host
 spaggel.nl: could not connect to host
 spamloco.net: did not receive HSTS header
 sparelib.com: max-age too low: 3650
 spark.team: could not connect to host
 sparklingsparklers.com: did not receive HSTS header
@@ -6684,16 +6698,17 @@ spot-events.com: could not connect to ho
 spotifyripper.tk: could not connect to host
 spotlightsrule.ddns.net: could not connect to host
 spr.id.au: did not receive HSTS header
 spreadsheets.google.com: did not receive HSTS header (error ignored - included regardless)
 spresso.me: did not receive HSTS header
 sprk.fitness: did not receive HSTS header
 sproutconnections.com: did not receive HSTS header
 sprutech.de: did not receive HSTS header
+sputnik1net.org: could not connect to host
 spyroszarzonis.com: did not receive HSTS header
 square.gs: could not connect to host
 squatldf.org: did not receive HSTS header
 sqzryang.com: did not receive HSTS header
 srcc.fr: could not connect to host
 srevilak.net: did not receive HSTS header
 srmaximo.com: could not connect to host
 srna.sk: could not connect to host
@@ -6795,19 +6810,19 @@ streamingeverywhere.com: could not conne
 streamingmagazin.de: could not connect to host
 streams.dyndns.org: could not connect to host
 strictlysudo.com: could not connect to host
 strife.tk: could not connect to host
 strila.me: did not receive HSTS header
 strivephysmed.com: did not receive HSTS header
 stroeercrm.de: could not connect to host
 strongest-privacy.com: could not connect to host
+strozik.de: could not connect to host
 stuartbaxter.co: could not connect to host
 student-scientist.org: did not receive HSTS header
-student.andover.edu: did not receive HSTS header
 studentrdh.com: did not receive HSTS header
 studentresearcher.org: did not receive HSTS header
 studentskydenik.cz: could not connect to host
 studenttravel.cz: did not receive HSTS header
 studinf.xyz: could not connect to host
 studio-panic.com: did not receive HSTS header
 studiozelden.com: did not receive HSTS header
 studybay.com: did not receive HSTS header
@@ -6892,16 +6907,17 @@ sylvangarden.org: could not connect to h
 sylvanorder.com: could not connect to host
 symphonos.it: did not receive HSTS header
 synackr.com: could not connect to host
 synapticconsulting.co.uk: 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
 synchrocube.com: could not connect to host
+synchtu.be: could not connect to host
 syncserve.net: did not receive HSTS header
 syneic.com: did not receive HSTS header
 syno.gq: could not connect to host
 syntaxoff.com: could not connect to host
 syntheticmotoroil.org: did not receive HSTS header
 syrocon.ch: could not connect to host
 sysadminstory.com: could not connect to host
 sysgeek.cn: could not connect to host
@@ -7000,19 +7016,18 @@ techhipster.net: could not connect to ho
 techhub.ml: could not connect to host
 techllage.com: could not connect to host
 techloaner.com: could not connect to host
 techmasters.andover.edu: could not connect to host
 techmatehq.com: could not connect to host
 technogroup.cz: did not receive HSTS header
 technosavvyport.com: did not receive HSTS header
 technotonic.com.au: did not receive HSTS header
-techold.ru: did not receive HSTS header
 techpointed.com: could not connect to host
-techproud.com: could not connect to host
+techproud.com: did not receive HSTS header
 techreview.link: could not connect to host
 techtoy.store: did not receive HSTS header
 techtraveller.com.au: did not receive HSTS header
 tecnimotos.com: did not receive HSTS header
 tecnogaming.com: did not receive HSTS header
 tecture.de: did not receive HSTS header
 tedovo.com: did not receive HSTS header
 tedxkmitl.com: could not connect to host
@@ -7031,17 +7046,17 @@ telescam.com: could not connect to host
 teletra.ru: could not connect to host
 tellingua.com: did not receive HSTS header
 temehu.com: did not receive HSTS header
 tempcraft.net: could not connect to host
 tempus-aquilae.de: could not connect to host
 tendertool.nl: could not connect to host
 tenerife-villas.com: did not receive HSTS header
 tengroup.com: did not receive HSTS header
-tenmm.com: [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 119"  data: no]
+tenmm.com: 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
 tentins.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
@@ -7103,16 +7118,17 @@ thehiddenbay.net: could not connect to h
 thehighersideclothing.com: did not receive HSTS header
 thehistory.me: could not connect to host
 thehonorguard.org: did not receive HSTS header
 thehoopsarchive.com: could not connect to host
 thehotfix.net: could not connect to host
 theinvisibletrailer.com: could not connect to host
 thejserver.de: could not connect to host
 thelapine.ca: did not receive HSTS header
+thelinuxtree.net: could not connect to host
 themadmechanic.net: could not connect to host
 themanufacturingmarketingagency.com: could not connect to host
 themarble.co: could not connect to host
 themathbehindthe.science: could not connect to host
 themathematician.uk: did not receive HSTS header
 themicrocapital.com: could not connect to host
 themillerslive.com: could not connect to host
 themimitoof.fr: did not receive HSTS header
@@ -7160,32 +7176,31 @@ thomasharvey.me: did not receive HSTS he
 thomaskliszowski.fr: did not receive HSTS header
 thomasmeester.nl: did not receive HSTS header
 thomasnet.fr: could not connect to host
 thomasschweizer.net: could not connect to host
 thorbis.com: could not connect to host
 thorgames.nl: did not receive HSTS header
 thorncreek.net: did not receive HSTS header
 thriveapproach.co.uk: did not receive HSTS header
-thrivewellnesshub.co.za: did not receive HSTS header
 throughthelookingglasslens.co.uk: could not connect to host
 thumbtack.com: did not receive HSTS header
 thundercampaign.com: could not connect to host
 ti.blog.br: could not connect to host
 tianxing.pro: did not receive HSTS header
 tianxingvpn.pro: could not connect to host
 tibbitshall.ca: did not receive HSTS header
 tickopa.co.uk: could not connect to host
 tickreport.com: did not receive HSTS header
 ticktock.today: did not receive HSTS header
 tictactux.de: could not connect to host
 tidmore.us: could not connect to host
-tie-online.org: did not receive HSTS header
 tiendschuurstraat.nl: could not connect to host
 tiensnet.com: did not receive HSTS header
+tierarztpraxis-bogenhausen.de: did not receive HSTS header
 tiernanx.com: could not connect to host
 tierrarp.com: could not connect to host
 tightlineproductions.com: did not receive HSTS header
 tikutiku.pl: could not connect to host
 tildebot.com: could not connect to host
 tiliaze.be: could not connect to host
 tiliaze.biz: could not connect to host
 tiliaze.eu: did not receive HSTS header
@@ -7261,16 +7276,17 @@ todobazar.es: could not connect to host
 tofu.im: could not connect to host
 togelonlinecommunity.com: did not receive HSTS header
 tokenloan.com: could not connect to host
 tokobungadijambi.com: did not receive HSTS header
 tokoone.com: did not receive HSTS header
 tokotamz.net: could not connect to host
 tokoyo.biz: could not connect to host
 tollmanz.com: did not receive HSTS header
+tollsjekk.no: could not connect to host
 tolud.com: could not connect to host
 tom.horse: did not receive HSTS header
 tomatenaufdenaugen.de: could not connect to host
 tomeara.net: could not connect to host
 tomevans.io: did not receive HSTS header
 tomharris.tech: did not receive HSTS header
 tomlankhorst.nl: did not receive HSTS header
 tomli.me: could not connect to host
@@ -7428,17 +7444,17 @@ tx041cap.org: did not receive HSTS heade
 txclimbers.com: could not connect to host
 txf.pw: could not connect to host
 ty2u.com: did not receive HSTS header
 tyler.rs: could not connect to host
 tyleromeara.com: could not connect to host
 tylian.net: max-age too low: 0
 typeofweb.com: did not receive HSTS header
 typingrevolution.com: did not receive HSTS header
-tyrelius.com: did not receive HSTS header
+tyrelius.com: could not connect to host
 tyroproducts.eu: did not receive HSTS header
 tyroremotes.no: did not receive HSTS header
 tzappa.net: could not connect to host
 u-blox.com: max-age too low: 0
 u.nu: could not connect to host
 ua.search.yahoo.com: did not receive HSTS header
 uadp.pw: did not receive HSTS header
 uber.com.au: did not receive HSTS header
@@ -7528,17 +7544,16 @@ upboard.jp: could not connect to host
 upldr.pw: could not connect to host
 uporoops.com: 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
 urban-garden.lt: could not connect to host
 urban-garden.lv: could not connect to host
-urbanstylestaging.com: did not receive HSTS header
 urbpic.com: could not connect to host
 urlchomp.com: did not receive HSTS header
 urphp.com: could not connect to host
 us-immigration.com: did not receive HSTS header
 usaab.org: did not receive HSTS header
 usafuelservice.com: did not receive HSTS header
 usbirthcertificate.com: did not receive HSTS header
 usbtypeccompliant.com: could not connect to host
@@ -7565,27 +7580,28 @@ uxux.pl: could not connect to host
 uy.search.yahoo.com: did not receive HSTS header
 uyym.com: could not connect to host
 uz.search.yahoo.com: did not receive HSTS header
 uzmandroid.com: did not receive HSTS header
 uzmandroid.net: could not connect to host
 uzmandroid.top: could not connect to host
 v0rtex.xyz: could not connect to host
 v0tti.com: could not connect to host
+v1sit0r.ru: could not connect to host
 v2.pw: did not receive HSTS header
 v2ex.us: did not receive HSTS header
 v4veedu.com: could not connect to host
 v7.cl: could not connect to host
 v789xl.com: did not receive HSTS header
 vaalmarketplace.co.za: did not receive HSTS header
 vacationality.com: could not connect to host
 vackerbetong.se: could not connect to host
 vaddder.com: could not connect to host
 valenscaelum.com: could not connect to host
-valentin-sundermann.de: did not receive HSTS header
+valentin-sundermann.de: could not connect to host
 valethound.com: could not connect to host
 valhalla-agency.com: did not receive HSTS header
 valhallacostarica.com: could not connect to host
 valhallamovement.com: did not receive HSTS header
 valitron.se: did not receive HSTS header
 valkyrja.xyz: could not connect to host
 valleyridgepta.org: could not connect to host
 vallis.net: did not receive HSTS header
@@ -7639,17 +7655,16 @@ 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
 vh.net: could not connect to host
 vhost.co.id: could not connect to host
 viadeux.com: could not connect to host
 viasinc.com: did not receive HSTS header
-vician.cz: did not receive HSTS header
 vicianovi.cz: could not connect to host
 victorenxovais.com.br: did not receive HSTS header
 victoriapemberton.com: did not receive HSTS header
 vidbuchanan.co.uk: did not receive HSTS header
 viddiaz.com: did not receive HSTS header
 videnskabsklubben.dk: did not receive HSTS header
 videomuz.com: did not receive HSTS header
 videotogel.net: did not receive HSTS header
@@ -7700,26 +7715,25 @@ vizional.com: max-age too low: 0
 vjeff.com: could not connect to host
 vlastimilburian.cz: did not receive HSTS header
 vlora.city: could not connect to host
 vlvvl.com: did not receive HSTS header
 vm0.eu: did not receive HSTS header
 vmgirls.com: could not connect to host
 vmrdev.com: could not connect to host
 voceinveste.com: did not receive HSTS header
+vogler.name: did not receive HSTS header
 voicesuk.co.uk: did not receive HSTS header
-vokativy.cz: did not receive HSTS header
 volcrado.com: did not receive HSTS header
 voliere-info.nl: did not receive HSTS header
 volkden.com: could not connect to host
 vonavy-cukor.sk: could not connect to host
 vonavycukor.sk: could not connect to host
 vooreenveiligthuis.nl: did not receive HSTS header
 vorangerie.com: could not connect to host
-vorodevops.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
 vpip.net: could not connect to host
 vpn-byen.dk: did not receive HSTS header
 vpn.black: could not connect to host
 vpn.pics: did not receive HSTS header
 vpnhot.com: could not connect to host
@@ -7748,17 +7762,16 @@ vyncke.org: max-age too low: 2678400
 vyvybean.cf: could not connect to host
 vzk.io: could not connect to host
 w4.no: could not connect to host
 w4a.fr: did not receive HSTS header
 w4xzr.top: could not connect to host
 w4xzr.xyz: could not connect to host
 waaw.tv: did not receive HSTS header
 wachtwoordencheck.nl: could not connect to host
-wafairhaven.com.au: did not receive HSTS header
 wahhoi.net: did not receive HSTS header
 wait.moe: could not connect to host
 waixingrenfuli7.vip: could not connect to host
 wakapp.de: could not connect to host
 wakened.net: did not receive HSTS header
 walkeryoung.ca: could not connect to host
 wallabag.it: did not receive HSTS header
 wallabag.org: did not receive HSTS header
@@ -7827,17 +7840,16 @@ webmaniabr.com: did not receive HSTS hea
 webmarketingfestival.it: did not receive HSTS header
 webninja.work: could not connect to host
 webnosql.com: could not connect to host
 webperformance.ru: could not connect to host
 webproshosting.tk: could not connect to host
 webpublica.pt: could not connect to host
 webrebels.org: could not connect to host
 webreslist.com: could not connect to host
-websiteadvice.com.au: did not receive HSTS header
 webstationservice.fr: could not connect to host
 webstellung.com: could not connect to host
 webstory.xyz: did not receive HSTS header
 webswitch.io: could not connect to host
 webtechgadgetry.com: did not receive HSTS header
 webtiles.co.uk: could not connect to host
 webtobesocial.de: could not connect to host
 webuni.hu: did not receive HSTS header
@@ -7932,16 +7944,17 @@ wiz.biz: could not connect to host
 wk-cpm.com: could not connect to host
 wlzhiyin.cn: could not connect to host
 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
 wochenentwicklung.com: did not receive HSTS header
 wodice.com: could not connect to host
+woelkchen.me: 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
 wolfie.ovh: could not connect to host
 womosale.de: could not connect to host
 wonderfall.xyz: could not connect to host
 wondy.com: could not connect to host
 woodlandschurch.net: max-age too low: 43200
@@ -7949,17 +7962,16 @@ woodmafia.com.au: max-age too low: 0
 woomu.me: could not connect to host
 woording.com: could not connect to host
 wootton95.com: could not connect to host
 wooviet.com: could not connect to host
 word-grabber.com: did not receive HSTS header
 work-and-jockel.de: did not receive HSTS header
 workfone.io: did not receive HSTS header
 workpermit.com.vn: could not connect to host
-worldfree4.org: could not connect to host
 worldlist.org: could not connect to host
 worldsbeststory.com: did not receive HSTS header
 worldwhisperer.net: could not connect to host
 worshapp.com: could not connect to host
 wow-travel.eu: could not connect to host
 wowapi.org: could not connect to host
 wowinvasion.com: did not receive HSTS header
 wp-rescue.com.au: did not receive HSTS header
@@ -8045,16 +8057,17 @@ xdd.io: could not connect to host
 xecure.zone: did not receive HSTS header
 xehoivn.vn: did not receive HSTS header
 xellos.ga: could not connect to host
 xellos.ml: could not connect to host
 xenesisziarovky.sk: could not connect to host
 xerhost.de: could not connect to host
 xett.com: did not receive HSTS header
 xf-liam.com: did not receive HSTS header
+xfd3.de: did not receive HSTS header
 xfive.de: could not connect to host
 xgusto.com: 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
 xiazhanjian.com: could not connect to host
 xiliant.com: could not connect to host
@@ -8152,17 +8165,16 @@ yellowcar.website: could not connect to 
 yenniferallulli.com: could not connect to host
 yenniferallulli.de: could not connect to host
 yenniferallulli.es: did not receive HSTS header
 yenniferallulli.moda: could not connect to host
 yenniferallulli.nl: could not connect to host
 yesdevnull.net: did not receive HSTS header
 yestees.com: did not receive HSTS header
 yetcore.io: could not connect to host
-yetii.net: could not connect to host
 yhong.me: did not receive HSTS header
 yhrd.org: did not receive HSTS header
 yikzu.cn: could not connect to host
 yin.roma.it: did not receive HSTS header
 yingsuo.ltd: could not connect to host
 yingyj.com: did not receive HSTS header
 yinhe12.net: did not receive HSTS header
 yippie.nl: could not connect to host
@@ -8186,28 +8198,29 @@ youcontrol.ru: could not connect to host
 youfencun.com: did not receive HSTS header
 youlog.net: could not connect to host
 youngandunited.nl: did not receive HSTS header
 youon.tokyo: could not connect to host
 yourbapp.ch: could not connect to host
 yourcomputer.expert: did not receive HSTS header
 yoursecondphone.co: could not connect to host
 yourstrongbox.com: could not connect to host
-youwatchporn.com: did not receive HSTS header
 ypiresia.fr: could not connect to host
 ys-shop.biz: did not receive HSTS header
 ytcuber.xyz: could not connect to host
 ytvwld.de: did not receive HSTS header
 yu7.jp: did not receive HSTS header
 yuan.ga: did not receive HSTS header
 yugege.cf: could not connect to host
 yuhen.ru: could not connect to host
 yukiminami.net: could not connect to host
 yuko.moe: could not connect to host
 yummyfamilyrecipes.com: could not connect to host
+yuna.love: could not connect to host
+yuna.tg: could not connect to host
 yunpan.blue: did not receive HSTS header
 yuntama.xyz: did not receive HSTS header
 yunzhan.io: could not connect to host
 yunzhu.li: did not receive HSTS header
 yunzhu.org: could not connect to host
 yuriykuzmin.com: did not receive HSTS header
 yutabon.com: could not connect to host
 yuushou.com: could not connect to host
--- a/security/manager/ssl/nsSTSPreloadList.inc
+++ b/security/manager/ssl/nsSTSPreloadList.inc
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*****************************************************************************/
 /* This is an automatically generated file. If you're not                    */
 /* nsSiteSecurityService.cpp, you shouldn't be #including it.     */
 /*****************************************************************************/
 
 #include <stdint.h>
-const PRTime gPreloadListExpirationTime = INT64_C(1516902173110000);
+const PRTime gPreloadListExpirationTime = INT64_C(1516987849151000);
 %%
 0-1.party, 1
 0.me.uk, 1
 00001.am, 1
 00002.am, 1
 0005pay.com, 1
 0010100.net, 1
 00220022.net, 1
@@ -39,16 +39,17 @@ 050media.nl, 1
 0513c.com, 1
 0573wk.com, 1
 07733.win, 1
 0au.de, 1
 0c.eu, 1
 0c3.de, 1
 0cdn.ga, 1
 0day.agency, 1
+0day.su, 1
 0fl.com, 1
 0i0.nl, 1
 0ik.de, 1
 0knowledge.de, 1
 0paste.com, 1
 0wx.cat, 1
 0wx.es, 1
 0wx.eu, 1
@@ -114,17 +115,16 @@ 12vpn.net, 1
 130.ua, 1
 132kv.ch, 1
 13318522.com, 1
 1359826938.rsc.cdn77.org, 1
 13826145000.com, 1
 1391kj.com, 1
 1395kj.com, 1
 1396.cc, 1
-1396.net, 1
 1453914078.rsc.cdn77.org, 1
 1464424382.rsc.cdn77.org, 1
 14it.de, 1
 14x3.de, 1
 15-10.com, 1
 1511774230.rsc.cdn77.org, 1
 1600esplanade.com, 1
 16164f.com, 1
@@ -328,17 +328,17 @@ 4winds.pt, 1
 4x.fi, 1
 4x4.lk, 1
 4xlabs.co, 1
 500k.nl, 1
 500p.xyz, 1
 50plusnet.nl, 1
 513vpn.net, 1
 517vpn.cn, 1
-518maicai.com, 1
+518maicai.com, 0
 525.info, 1
 52neptune.com, 1
 5432.cc, 1
 54below.com, 1
 5533445.com, 1
 555fl.com, 1
 555xl.com, 1
 55scc.com, 1
@@ -396,17 +396,17 @@ 87577.com, 1
 8833445.com, 1
 8887999.com, 0
 888azino.com, 1
 888msc.vip, 1
 888sport.dk, 1
 888sport.it, 1
 88laohu.cc, 1
 88laohu.com, 1
-899699.com, 1
+899699.com, 0
 8ack.de, 1
 8ackprotect.com, 1
 8azino777.ru, 1
 8mpay.com, 1
 8ox.ru, 0
 8pecxstudios.com, 1
 8svn.com, 1
 8t8.eu, 1
@@ -419,16 +419,17 @@ 91tianmi.com, 0
 92bmh.com, 1
 92url.com, 1
 9449-27a1-22a1-e0d9-4237-dd99-e75e-ac85-2f47-9d34.de, 1
 987987.com, 1
 9906753.net, 1
 9933445.com, 1
 99599.fi, 1
 99599.net, 1
+99buffets.com, 1
 99rst.org, 1
 9jadirect.com, 1
 9ss6.com, 1
 9uelle.jp, 1
 9vx.org, 1
 9yw.me, 1
 a-1indianawaterproofing.com, 1
 a-allard.be, 1
@@ -466,25 +467,25 @@ abc-rz.de, 1
 abc.li, 1
 abcdef.be, 1
 abdullah.pw, 1
 abe-elektro.de, 1
 abe.cloud, 0
 abeestrada.com, 0
 abenteuer-ahnenforschung.de, 1
 abeontech.com, 1
+aberdeenalmeras.com, 1
 aberdeenjudo.co.uk, 1
 abeus.com, 1
 abhisharma.me, 1
 abi-2017.tk, 1
 abi-fvs.de, 1
 abiapp.net, 1
 abigisp.com, 1
 abilitycaresoftware.com, 1
-abilitynet.org.uk, 1
 abilma.com, 1
 abilymp06.net, 1
 abimelec.com, 1
 abiturma.de, 1
 ablak-nyilaszaro.info, 1
 abloop.com, 1
 abmc.gov, 1
 abmgood.com, 0
@@ -785,17 +786,16 @@ aerolog.co, 1
 aerotheque.fr, 1
 aertel.ie, 1
 aessencia.com.br, 1
 aestheticdr.org, 1
 aesthetics-blog.com, 1
 aestore.by, 1
 aesym.de, 1
 aetherc0r3.eu, 1
-aevpn.net, 1
 aevpn.org, 1
 aextron.com, 1
 aextron.de, 1
 aextron.org, 1
 af-internet.nl, 1
 afavre.io, 1
 afb24.de, 1
 afbeelding.im, 1
@@ -1172,17 +1172,16 @@ alstroemeria.org, 1
 alt-three.com, 1
 alt.org, 1
 altahrim.net, 1
 altaide.com, 1
 altailife.ru, 1
 altbinaries.com, 1
 altedirect.com, 1
 alter-news.fr, 1
-alterbaum.net, 1
 altercpa.ru, 1
 alternador.com.br, 1
 alternative.bike, 1
 alternativedev.ca, 1
 alternativet.party, 1
 alterspalter.de, 1
 altesses.eu, 1
 altestore.com, 1
@@ -1402,17 +1401,16 @@ animaemundi.be, 1
 animal-liberation.com, 1
 animal-rights.com, 1
 animalnet.de, 0
 animalstropic.com, 1
 animationsmusicales.ch, 1
 anime.my, 0
 anime1.me, 1
 anime1.top, 1
-anime1video.tk, 1
 animeai.com, 1
 animefluxxx.com, 1
 animorphsfanforum.com, 1
 anipassion.com, 1
 anisekai.com, 1
 anita-mukorom.hu, 1
 anitaalbersen.nl, 1
 anitube-nocookie.ch, 1
@@ -1478,17 +1476,16 @@ answers-online.ru, 1
 antama.nl, 1
 antarcti.co, 1
 antcas.com, 1
 antenasmundosat.com.br, 1
 anthony-rouanet.com, 1
 anthonyaires.com, 1
 anthonycarbonaro.com, 1
 anthonygaidot.fr, 1
-anthropoid.ca, 1
 anti-bible.com, 1
 anti-radar.org, 1
 anticapitalist.party, 0
 anticopyright.com, 1
 antikvariat.ru, 1
 antiled.by, 1
 antimatiere.space, 1
 antimine.me, 1
@@ -1839,17 +1836,16 @@ asandu.eu, 1
 asanger.biz, 1
 asato-jewelry.com, 1
 asbito.de, 1
 ascension.run, 1
 ascgathering.com, 1
 ascii.moe, 1
 asciitable.tips, 1
 asd.gov.au, 1
-asdyx.de, 1
 asec01.net, 1
 asepms.com, 1
 aserver.co, 1
 asge-handel.de, 1
 ashleakunowski.com, 1
 ashleyadum.com, 1
 ashleyfoley.photography, 1
 ashleymedway.com, 1
@@ -1970,16 +1966,17 @@ atlas.co, 1
 atlaschiropractic.org, 1
 atlascultural.com, 1
 atlassian.io, 1
 atlassian.net, 1
 atletika.hu, 1
 atnis.com, 1
 ato4sound.com, 1
 atolm.net, 1
+atom-china.org, 1
 atom.solutions, 1
 atom86.net, 1
 atombase.org, 1
 atomism.com, 1
 atorcidabrasileira.com.br, 1
 atplonline.co, 1
 atracaosexshop.com.br, 1
 atraining.ru, 1
@@ -1988,17 +1985,16 @@ atrinik.org, 1
 atte.fi, 1
 attendantdesign.com, 1
 attilagyorffy.com, 1
 attilavandervelde.nl, 1
 attitudes-bureaux.fr, 1
 attogtech.com, 1
 attorney.org.il, 1
 attwood.org, 1
-atulhost.com, 1
 atviras.lt, 0
 atwonline.org, 1
 atypicom.es, 1
 atypicom.fr, 1
 atypicom.it, 1
 atypicom.pt, 1
 atzenchefin.de, 1
 au-be.net, 1
@@ -2270,16 +2266,17 @@ baglu.com, 1
 bagspecialist.nl, 1
 bah.im, 0
 bahnbonus-praemienwelt.de, 1
 baifubao.com, 1
 baiker.info, 1
 bailakomigo.com.br, 1
 baileebee.com, 1
 baitulongbaycruises.com, 1
+baiyangliu.com, 1
 bajic.ch, 1
 baka.network, 1
 bakabt.info, 1
 bakaproxy.moe, 1
 bakaweb.fr, 1
 bakersafari.co, 1
 bakim.li, 1
 bakkerinjebuurt.be, 1
@@ -2404,17 +2401,16 @@ basnoslovno.com.ua, 1
 basnoslovno.ru, 1
 bass-pro.ru, 1
 bassblog.net, 1
 bastelzauberwelt.de, 1
 bastianstalder.ch, 1
 bastiv.com, 1
 basyspro.net, 1
 bat909.com, 1
-batfoundry.com, 1
 bati-alu.fr, 1
 batipresta.ch, 1
 batistareisfloresonline.com.br, 1
 batlab.ch, 1
 batolis.com, 1
 batonger.com, 1
 batook.org, 1
 batschu.de, 1
@@ -2448,16 +2444,17 @@ bazos.cz, 1
 bazos.sk, 1
 bazziergraphik.com, 1
 bbb1991.me, 1
 bbdos.ru, 1
 bbgeschenke.ch, 1
 bbimarketing.com, 1
 bbka.org.uk, 1
 bbkworldwide.jp, 1
+bblove.me, 1
 bbnx.net, 1
 bbuio.com, 1
 bbw-wrestling.com, 1
 bbw.dating, 1
 bbwcs.co.uk, 1
 bbwf.de, 1
 bbwfacesitting.us, 1
 bbwteens.org, 1
@@ -3334,18 +3331,16 @@ bouchard-mathieux.com, 1
 bouchonville-knifemaker.com, 1
 bouckaert-usedcars.be, 1
 boudah.pl, 1
 boueki.jp, 1
 boueki.org, 1
 bougeret.fr, 1
 boukoubengo.com, 1
 bounceboxspc.com, 1
-bouncecoffee.com, 1
-bouncourseplanner.net, 1
 bouncyball.eu, 0
 bouncyballs.org, 1
 bountyfactory.io, 1
 bourasse.fr, 1
 bourdon.fr.eu.org, 1
 bourqu.in, 1
 bourse-aux-jouets.org, 0
 bourse-aux-vetements.org, 0
@@ -3470,23 +3465,21 @@ breeswish.org, 1
 breeyn.com, 1
 brefy.com, 1
 brege.org, 1
 breitbild-beamer.de, 1
 brejoc.com, 1
 brendanscherer.com, 1
 brenden.net.au, 1
 brentacampbell.com, 1
-brentnewbury.com, 1
 bress.cloud, 1
 bressier.fr, 1
 bretcarmichael.com, 1
 brettcornwall.com, 1
 brettelliff.com, 1
-bretz-hufer.de, 1
 bretzner.fr, 1
 brevboxar.se, 1
 brewsouth.com, 1
 brewtrackr.com, 1
 brgins.com, 1
 brianalaway.com, 1
 brianalawayconsulting.com, 1
 brianfoshee.com, 1
@@ -3517,16 +3510,17 @@ brinquedoseducativos.art.br, 1
 brio-shop.ch, 1
 brisbanelogistics.com.au, 1
 bristebein.com, 1
 britelocate.com, 1
 britishbeef.com, 1
 britishbookmakers.co.uk, 1
 britishgroupsg.com, 1
 britishmeat.com, 1
+britishsciencefestival.org, 1
 britishscienceweek.org, 1
 britneyclause.com, 1
 britton-photography.com, 1
 brivadois.ovh, 1
 brix.ninja, 1
 brmsalescommunity.com, 1
 brn.by, 1
 bro.hk, 1
@@ -3596,16 +3590,17 @@ btorrent.xyz, 1
 btrb.ml, 1
 btserv.de, 1
 btsoft.eu, 1
 btsow.com, 1
 btxiaobai.com, 1
 bubba.cc, 1
 bubblegumblog.com, 1
 bubblespetspa.com, 1
+buben.tech, 1
 bubhub.io, 1
 buch-angucken.de, 1
 buck.com, 1
 buckmulligans.com, 1
 buckypaper.com, 1
 budaev-shop.ru, 1
 buddhistische-weisheiten.org, 1
 buddlycrafts.com, 1
@@ -3906,17 +3901,16 @@ canadabread.com, 1
 canadalife.de, 1
 canadasmotorcycle.ca, 1
 canadian.dating, 1
 canadianchristianity.com, 0
 canadiantouristboard.com, 1
 canalsidehouse.be, 1
 canalsidehouse.com, 1
 canarianlegalalliance.com, 1
-canarymod.net, 0
 cancerdata.nhs.uk, 1
 cancreate.nl, 1
 candicecity.com, 1
 candidasa.com, 1
 cando.eu, 1
 candy-it.de, 1
 candylion.rocks, 1
 candyout.com, 1
@@ -4013,16 +4007,17 @@ caribbeanarthritisfoundation.org, 1
 caribbeanexams.com, 1
 carif-idf.net, 1
 carif-idf.org, 1
 carigami.fr, 1
 carinsurance.es, 1
 cariocacooking.com, 1
 carisenda.com, 1
 carlandfaith.com, 1
+carlgo11.com, 1
 carlife-at.jp, 1
 carlingfordapartments.com.au, 1
 carlmjohnson.net, 1
 carloshmm.stream, 1
 carlosjeurissen.com, 1
 carlovanwyk.com, 1
 carnaticalifornia.com, 1
 carnet-du-voyageur.com, 1
@@ -4096,17 +4091,16 @@ catharisme.net, 1
 catharisme.org, 1
 catholics.dating, 1
 cathosa.nl, 1
 cativa.net, 1
 catmoose.ca, 1
 catnet.dk, 0
 catnmeow.com, 1
 catsmagic.pp.ua, 1
-cattivo.nl, 0
 caughtredhanded.co.nz, 1
 caulfieldeastapartments.com.au, 1
 caulfieldracecourseapartments.com.au, 1
 caulong-ao.net, 1
 causae-fincas.es, 1
 cav.ac, 1
 cavac.at, 1
 cavalierkingcharlesspaniel.com.br, 1
@@ -4704,17 +4698,16 @@ cles.jp, 1
 clevelandokla.com, 1
 clevertarget.ru, 1
 cleververmarkten.com, 1
 cleververmarkten.de, 1
 clevisto.com, 1
 cleysense.com, 1
 clic-music.com, 1
 click-licht.de, 1
-clickclickphish.com, 1
 clickclock.cc, 1
 clickenergy.com.au, 1
 clickforclever.com, 1
 clickphish.com, 1
 clicks.co.za, 1
 clicktenisdemesa.com.br, 1
 client.coach, 1
 clientboss.com, 1
@@ -4839,17 +4832,16 @@ cncfraises.fr, 1
 cncrans.ch, 1
 cnetw.xyz, 1
 cni-certing.it, 1
 cnlic.com, 1
 cnwage.com, 1
 co-factor.ro, 1
 co-yutaka.com, 1
 co.search.yahoo.com, 0
-co50.com, 1
 coachezmoi.ch, 1
 coaching-impulse.ch, 1
 coachingconsultancy.com, 1
 coalitionministries.org, 1
 coalpointcottage.com, 1
 coam.co, 1
 coastline.net.au, 1
 coatl-industries.com, 1
@@ -5438,17 +5430,16 @@ cristarta.com, 1
 cristianhares.com, 1
 critcola.com, 1
 critical.today, 0
 criticalaim.com, 1
 criticalsurveys.co.uk, 1
 crizin.io, 1
 crl-autos.com, 1
 crm.onlime.ch, 0
-crmdemo.website, 1
 croco.vision, 1
 croixblanche-haguenau.fr, 1
 cronix.cc, 1
 cronometer.com, 1
 crop-alert.com, 1
 croquette.net, 1
 crosbug.com, 1
 cross-led-sign.com, 1
@@ -6053,16 +6044,17 @@ de-mail.info, 1
 de-medici.nl, 1
 de-rwa.de, 1
 de-servers.de, 1
 de-spil.be, 1
 de.search.yahoo.com, 0
 deadbeef.ninja, 1
 deadc0de.re, 1
 deadmann.com, 1
+deadsoul.net, 1
 deaf.dating, 1
 deaf.eu.org, 1
 deaktualisierung.org, 0
 dealbanana.at, 1
 dealbanana.be, 1
 dealbanana.co.uk, 1
 dealbanana.com, 1
 dealbanana.de, 1
@@ -6567,17 +6559,17 @@ discha.net, 1
 disciples.io, 1
 discipul.nl, 1
 disclosure.io, 1
 disco-crazy-world.de, 1
 discofitta.com, 1
 disconformity.net, 1
 discord-chan.net, 1
 discordapp.com, 1
-discotek.club, 1
+discotek.club, 0
 discountmetaux.fr, 1
 discover-mercure.com, 1
 discoverhealthage.com, 0
 discoverrsv.com, 1
 discoverwellness.center, 1
 discoveryballoon.org, 1
 discoveryrom.org, 1
 discreet-condooms.nl, 1
@@ -6663,16 +6655,17 @@ dmfd.net, 1
 dmi.es, 1
 dmlogic.com, 1
 dmxledlights.com, 1
 dn3s.me, 1
 dn42.eu, 0
 dn42.us, 1
 dna.li, 1
 dnc.org.nz, 1
+dndtools.net, 1
 dne.lu, 1
 dnmaze.com, 1
 dnmlab.it, 1
 dnplegal.com, 1
 dns-control.eu, 1
 dns-manager.info, 1
 dns.google.com, 1
 dns8.online, 1
@@ -6697,17 +6690,16 @@ doc.to, 1
 doc8643.com, 1
 docabo.ch, 1
 docbox.ch, 1
 docemeldoces.com, 1
 dochitaceahlau.ro, 1
 doclassworks.com, 1
 docline.gov, 1
 docloh.de, 1
-doclot.io, 1
 docloudu.info, 1
 docplexus.in, 1
 docs.google.com, 0
 docs.python.org, 1
 docs.re, 1
 doctor-locks.co.uk, 1
 doctor.dating, 1
 doctorfox.co.uk, 1
@@ -6890,16 +6882,17 @@ dpsg-roden.de, 0
 dr-becarelli-philippe.chirurgiens-dentistes.fr, 1
 dr-www.de, 1
 dr2dr.ca, 1
 drabben.be, 1
 drabbin.com, 1
 drabim.org, 1
 drach.xyz, 1
 dracisvet.cz, 1
+dracon.es, 1
 dracox.com, 1
 drafton.com, 1
 drageeparadise.fr, 1
 dragfiles.com, 1
 dragon-aspect.com, 1
 dragon-chem.eu, 1
 dragon-hearts.co.uk, 1
 dragoncityhack.tips, 1
@@ -6966,17 +6959,16 @@ drivinghorror.com, 1
 drivingtestpro.com, 1
 drivya.com, 1
 drjacquesmalan.com, 1
 drjoe.ca, 1
 drjuanitacollier.com, 1
 drkhsh.at, 1
 drkmtrx.xyz, 1
 drlangsdon.com, 1
-drlazarina.net, 1
 drms.us, 1
 drobniuch.pl, 0
 drogoz.moe, 1
 drogueriaelbarco.com, 1
 droidapp.nl, 1
 droidgyan.com, 1
 droidhere.com, 1
 droidim.com, 1
@@ -7038,17 +7030,16 @@ ducalendars.com, 1
 duch.cloud, 1
 duckasylum.com, 1
 duckbase.com, 1
 duckduckstart.com, 1
 duckinc.net, 1
 ducohosting.com, 1
 dudesunderwear.com.br, 1
 duelsow.eu, 1
-duelysthub.com, 1
 duernberg.at, 1
 dugnet.com, 1
 dugnet.io, 1
 dugnet.net, 1
 dugnet.org, 1
 dugnet.tech, 1
 dugunedavet.com, 1
 duh.se, 1
@@ -7462,16 +7453,17 @@ eladgames.com, 1
 elaon.de, 1
 elars.de, 1
 elaxy-online.de, 1
 eldertons.co.uk, 1
 eldinhadzic.com, 1
 eldritchfiction.net, 1
 elearningpilot.com, 1
 electionsdatabase.com, 1
+electr0sheep.com, 1
 electragirl.com, 1
 electricalcontrolpanels.co.uk, 1
 electricgatemotorgermiston.co.za, 1
 electronic-ignition-system.com, 1
 electronicfasteners.com, 1
 eled.io, 1
 elefantevoador.com, 1
 eleicoes2014.com.br, 1
@@ -7596,16 +7588,17 @@ embox.net, 1
 embraceni.org, 1
 embracethedarkness.co.uk, 1
 embroideryexpress.co.uk, 1
 emcspotlight.com, 1
 emeliefalk.se, 1
 emeraldcoastrideshare.com, 1
 emeraldonion.org, 1
 emergencyessay.com, 1
+emergentvisiontec.com, 1
 emergenzalavoro.com, 1
 emero.de, 1
 emesolutions.net, 1
 emi-air-comprime.com, 1
 emi.im, 1
 emielraaijmakers.nl, 1
 emil.click, 1
 emilstahl.dk, 1
@@ -7795,17 +7788,16 @@ eqorg.com, 1
 equalcloud.com, 1
 equalparts.eu, 1
 equidam.com, 1
 equinecoaching.ca, 1
 equinox.io, 1
 equipedefrance.tv, 1
 equipeferramentas.com.br, 1
 equipsupply.com, 1
-equityflows.com, 1
 er-music.com, 1
 er.tl, 1
 erad.fr, 1
 erasmusplusrooms.com, 1
 erath.fr, 1
 erdethamburgeronsdag.no, 1
 erepublik-deutschland.de, 1
 erethon.com, 1
@@ -8090,17 +8082,16 @@ evertonarentwe.com, 1
 everwaking.com, 0
 everyarti.st, 1
 everyday.eu.org, 1
 everydaytherich.com, 1
 everyex.com, 1
 everygayporn.com, 1
 everymove.org, 1
 everywhere.cloud, 1
-eveseat.net, 1
 eveshaiwu.com, 1
 eveshamglass.co.uk, 1
 evexia.xyz, 1
 evidence-based.review, 1
 evidencebased.net, 1
 evidenceusa.com.br, 1
 evilarmy.com, 1
 evileden.com, 1
@@ -8371,16 +8362,17 @@ faq.ie, 1
 faq.lookout.com, 0
 fara.gov, 1
 faraslot8.com, 1
 faraslot8.net, 1
 faretravel.co.uk, 1
 farfallapets.com.br, 1
 farfetchos.com, 1
 fargtorget.se, 1
+farhadexchange.com, 1
 farhood.org, 1
 farkas.bz, 1
 farm24.co.uk, 1
 farmaciaformula.com.br, 1
 farmacialaboratorio.it, 1
 farmer.dating, 1
 farmkazuto.com, 1
 faroes.net, 1
@@ -8443,17 +8435,16 @@ fcapartsdb.com, 1
 fcburk.de, 1
 fcforum.net, 1
 fckd.net, 1
 fcprovadia.com, 1
 fcsic.gov, 1
 fdlibre.eu, 1
 fdsys.gov, 0
 feac.us, 1
-feaden.me, 1
 fearghus.org, 1
 fearsomegaming.com, 1
 feastr.io, 1
 featherweightlabs.com, 1
 fecik.sk, 1
 federalinvestments.gov, 1
 federaljobs.gov, 1
 federalregister.gov, 0
@@ -8479,16 +8470,17 @@ fegans.org.uk, 1
 fehngarten.de, 1
 fehnladen.de, 1
 feigling.net, 1
 feilen.de, 1
 feisbed.com, 1
 feisim.com, 1
 feisim.org, 1
 feistyduck.com, 1
+feitobrasilcosmeticos.com.br, 1
 feld.design, 1
 feld.saarland, 1
 feldhousen.com, 1
 felicifia.org, 1
 felistirnavia.sk, 1
 felixbarta.de, 1
 felixhefner.de, 1
 felixkauer.de, 1
@@ -8509,19 +8501,19 @@ feras-alhajjaji.com, 1
 ferdies.co.za, 1
 fergusoncastle.com, 1
 ferien-netzwerk.de, 1
 ferienhaus-polchow-ruegen.de, 0
 ferienwohnungen-lastminute.de, 1
 fermabel.com.br, 1
 fermanacuratampaparts.com, 1
 fernandes.org, 1
-fernandob.com, 0
+fernandob.com, 1
 fernandobarata.pt, 1
-fernandobarillas.com, 0
+fernandobarillas.com, 1
 fernandomiguel.net, 1
 fernangp.com, 1
 ferreteriaxerez.com, 1
 ferrolatino.ch, 1
 ferticare.pt, 1
 fertila.de, 1
 feschiyan.com, 1
 festival.house, 1
@@ -8556,17 +8548,16 @@ fhg90.com, 1
 fhsseniormens.club, 1
 fi-sanki.co.jp, 1
 fi.google.com, 1
 fi.search.yahoo.com, 0
 fiam.me, 1
 fiareapp.red, 1
 ficklenote.net, 1
 fickweiler.nl, 1
-ficlab.com, 1
 ficus.io, 1
 fid-elite.ch, 1
 fid.to, 1
 fidanza.eu, 1
 fidel.uk, 1
 fidelapp.com, 1
 fidelis-it.ch, 1
 fidelis-it.net, 1
@@ -8608,16 +8599,17 @@ filippo.io, 1
 filleritemsindia.com, 1
 fillitupchallenge.eu, 1
 fillmysuitca.se, 1
 fillo.sk, 1
 film-tutorial.com, 1
 film.photography, 1
 film.photos, 1
 filmatiporno.xxx, 1
+filme-online.eu.com, 1
 filme-onlines.com, 1
 filmreviewonline.com, 1
 filmserver.de, 1
 filo.xyz, 1
 filoitoupediou.gr, 1
 filoo.de, 1
 filterlists.com, 1
 finalx.nl, 1
@@ -8762,17 +8754,16 @@ flc999.com, 1
 fleep.io, 1
 fleetssl.com, 1
 fleisch.club, 1
 flemingtonaudiparts.com, 1
 fletchto99.com, 1
 fleurette.me, 1
 fleursdesoleil.fr, 1
 flexapplications.se, 1
-fleximus.org, 0
 flexinvesting.fi, 1
 flexport.com, 1
 flexstart.me, 1
 flextrack.dk, 1
 flightdeckfriend.com, 1
 flightschoolbooking.com, 1
 flightschoolcandidates.gov, 1
 fliino.com, 1
@@ -9316,17 +9307,16 @@ furnitureconcept.co.uk, 1
 furry.dk, 1
 furtivelook.com, 1
 fusa-miyamoto.jp, 1
 fuseos.net, 1
 fushee.com, 1
 fuskator.com, 1
 fussball-xxl.de, 1
 fussell.io, 1
-futbolvivo.tv, 1
 futrou.com, 1
 futurefundapp.com, 1
 futurenda.com, 1
 futureoceans.org, 1
 futuresonline.com, 1
 futurezone.at, 1
 futuristarchitecture.com, 1
 futurope.com, 1
@@ -9375,16 +9365,17 @@ g4w.co, 1
 g77.ca, 1
 gaasuper6.com, 1
 gabemack.com, 1
 gabriel.to, 1
 gachter.name, 1
 gadabit.pl, 1
 gadgethacks.com, 1
 gaestehaus-monika.com, 1
+gafachi.com, 1
 gaflooring.com, 1
 gafunds.com, 1
 gagne.tk, 1
 gagnerplusdargent.info, 1
 gagniard.org, 1
 gagor.pl, 1
 gagygnole.ch, 1
 gaichanh.com, 1
@@ -9512,16 +9503,17 @@ gdb-tutorial.net, 1
 gdevpenze.ru, 1
 gdgrzeszow.pl, 1
 gdiary.net, 1
 gdoce.es, 1
 gdutnic.com, 1
 gdv.me, 1
 gdz-otvety.com, 1
 gdz-spishy.com, 1
+gdz.tv, 1
 ge1.me, 0
 ge3k.net, 0
 gear-acquisition-syndrome.community, 1
 gearev.net, 1
 gearset.com, 1
 geaskb.nl, 1
 geass.xyz, 1
 geblitzt.de, 1
@@ -9600,16 +9592,17 @@ generationnext.pl, 1
 generic.cx, 1
 genesiseureka.com, 1
 genesismachina.ca, 1
 genetargetsolutions.com.au, 1
 genetidyne.com, 1
 geneve-naturisme.ch, 1
 geneve.guide, 1
 genfaerd.dk, 1
+genia-life.de, 1
 genie-seiner-generation.de, 1
 geniuszone.biz, 1
 genomequestlive.com, 1
 genoog.com, 1
 genosse-einhorn.de, 1
 genossen.ru, 1
 genshiken-itb.org, 1
 genslerapps.com, 1
@@ -9775,17 +9768,16 @@ gikovatelojavirtual.com.br, 1
 gileadpac.com, 1
 gillesmorelle.com, 1
 gillmanandsoame.co.uk, 1
 gilmoreid.com.au, 1
 gilnet.be, 1
 gilroywestwood.org, 1
 gina-architektur.design, 1
 gincher.net, 1
-ginijony.com, 1
 ginionusedcars.be, 1
 ginja.co.th, 1
 ginkel.com, 1
 ginnegappen.nl, 1
 ginniemae.gov, 1
 ginzadelunch.jp, 1
 giochi-online.ws, 1
 gioielleriamolena.com, 1
@@ -10390,16 +10382,17 @@ hackingand.coffee, 1
 hackingdh.com, 1
 hackmd.io, 1
 hackmeplz.com, 1
 hackthissite.org, 1
 hacktivis.me, 1
 hackyourfaceoff.com, 1
 hadaly.fr, 1
 hadleighswimmingclub.co.uk, 1
+hadouk.in, 1
 hadrons.org, 1
 haefligermedia.ch, 1
 haehnlein.at, 1
 haemmerle.net, 1
 haens.li, 1
 hafniatimes.com, 1
 haiboxu.com, 1
 hail2u.net, 1
@@ -10971,16 +10964,17 @@ hohm.in, 1
 hohnet.com, 1
 hoiku-navi.com, 1
 hoken-wakaru.jp, 1
 hokieprivacy.org, 1
 hokify.at, 1
 hokify.ch, 1
 hokify.de, 1
 holboxwhalesharktours.com, 1
+holebedeljek.hu, 1
 holidayincotswolds.co.uk, 1
 holistichealer.in, 1
 holisticon.de, 1
 hollandguns.com, 1
 hollermann.eu, 1
 hollo.me, 1
 hollowrap.com, 1
 hollyforrest.ca, 1
@@ -11220,16 +11214,17 @@ huersch.com, 1
 huffduffer.com, 1
 hughtodd.ink, 1
 hugi.is, 1
 hugofs.com, 1
 hugolynx.fr, 1
 huguesblanchard.paris, 1
 huguesditciles.com, 1
 huihui.moe, 1
+huirongis.me, 1
 huiser.nl, 1
 huitaodang.com, 1
 hukaloh.com, 1
 hukkatavara.com, 1
 hulldevs.net, 1
 hulpbijmarketing.nl, 1
 hulsoft.co.uk, 1
 human-clone.com, 1
@@ -11375,17 +11370,16 @@ icasnetwork.com, 1
 icbemp.gov, 1
 iccpublisher.com, 1
 icebat.dyndns.org, 1
 iceberg.academy, 1
 icebound.cc, 1
 icebound.win, 1
 icecars.net, 1
 iceloch.com, 1
-icewoman.net, 1
 ich-tanke.de, 1
 ichasco.com, 1
 ichbinkeinreh.de, 1
 ichronos.net, 1
 icij.org, 0
 iclinic.ua, 1
 icmhd.ch, 1
 icmp2018.org, 1
@@ -11895,17 +11889,16 @@ internshipandwork.com, 1
 internshipandwork.ru, 1
 interociter-enterprises.com, 1
 interracial.dating, 1
 intersectraven.net, 1
 interseller.io, 1
 intertime.services, 1
 interview-suite.com, 1
 interviewpipeline.co.uk, 1
-interways.de, 1
 intexplore.org, 1
 intheater.de, 1
 inthepicture.com, 1
 inthouse.cloud, 1
 intimastoreatacado.com.br, 1
 intl-webs.com, 1
 intmissioncenter.org, 1
 into.technology, 1
@@ -12853,16 +12846,17 @@ jungleculture.co.za, 1
 jungleducks.ca, 1
 junglist.org, 1
 juni.io, 1
 juniwalk.cz, 1
 junkdrome.org, 1
 jurassicbarkharrogate.co.uk, 1
 jurassicgolf.nl, 1
 juridoc.com.br, 1
+juristas.com.br, 1
 juristeo.com, 1
 jurko.cz, 1
 jurriaan.ninja, 1
 just-a-clanpage.de, 1
 just-pools.co.za, 1
 justanothercompany.name, 1
 justboom.co, 1
 justchunks.net, 1
@@ -12914,17 +12908,16 @@ kaangenc.me, 1
 kaasbijwijn.nl, 1
 kaashosting.nl, 1
 kab-s.de, 1
 kabashop.com.br, 1
 kabat-fans.cz, 1
 kabeuchi.com, 1
 kaboom.pw, 1
 kabu-abc.com, 1
-kabus.org, 1
 kack.website, 1
 kadmec.com, 1
 kaffeekrone.de, 1
 kafoom.de, 1
 kaheim.de, 0
 kai-ratzeburg.de, 1
 kaigojj.com, 1
 kaika-facilitymanagement.de, 1
@@ -13098,17 +13091,16 @@ kazandaemon.ru, 1
 kazenojiyu.fr, 1
 kazuhirohigashi.com, 1
 kazumi.ro, 1
 kazy111.info, 1
 kb3.net, 1
 kba-online.de, 1
 kbb-ev.de, 1
 kbcequitas.hu, 1
-kbfl.org, 1
 kbit.dk, 1
 kbjorklu.com, 1
 kc-holzfaeller.de, 1
 kc5mpk.com, 1
 kcptun.com, 1
 kcsordparticipation.org, 1
 kd.net.nz, 1
 kdbx.online, 1
@@ -13204,17 +13196,16 @@ ketty-voyance.com, 1
 kevinapease.com, 1
 kevinbowers.me, 1
 kevinbusse.de, 1
 kevincox.ca, 0
 kevindekoninck.com, 0
 kevinhill.nl, 1
 kevinkla.es, 1
 kevinlocke.name, 1
-kevinmeijer.nl, 1
 kevinmorssink.nl, 1
 kevinpirnie.com, 1
 kevinratcliff.com, 1
 kevinroebert.de, 1
 kevyn.lu, 1
 kewego.co.uk, 1
 keybase.io, 1
 keybored.me, 1
@@ -13277,16 +13268,17 @@ kienlen.org, 1
 kieranjones.uk, 1
 kieranweightman.me, 1
 kiesuwkerstkaart.nl, 1
 kiffmarks.com, 1
 kigmbh.com, 1
 kikbb.com, 1
 kiku.pw, 1
 kikuzuki.org, 1
+kilerd.me, 1
 kilianvalkhof.com, 1
 killaraapartments.com.au, 1
 killerrobots.com, 1
 kilobyte22.de, 1
 kilogram.nl, 1
 kilometertje.nl, 1
 kimiris.com, 1
 kimmel.com, 1
@@ -13415,17 +13407,16 @@ kleberstoff.xyz, 1
 klebetape.de, 1
 kledingrekken.nl, 1
 kleidertauschpartys.de, 1
 kleinblogje.nl, 0
 kleine-dingen.nl, 1
 kleineanfragen.de, 1
 kleinfein.co, 1
 kleinholding.com, 1
-kleinreich.de, 1
 kleinserienproduktion.com, 1
 kleinsys.com, 1
 klempnershop.eu, 1
 kleteckova.cz, 1
 klickstdu.com, 1
 kliemann.me, 1
 klif1.nl, 1
 klimapartner.de, 1
@@ -13461,16 +13452,17 @@ knep.me, 1
 kngk-azs.ru, 1
 kngk-group.ru, 1
 kngk.org, 1
 kngkng.com, 1
 kniga.market, 1
 knigadel.com, 1
 knightsblog.de, 1
 knightsbridge.net, 1
+knightsweep.com, 1
 knip.ch, 1
 knot-store.com, 1
 knowledgehook.com, 1
 knowlevillagecc.co.uk, 1
 knthost.com, 1
 knutur.is, 1
 knygos.lt, 1
 ko-sys.com, 1
@@ -14403,16 +14395,17 @@ linguamilla.com, 1
 linguatrip.com, 0
 lingvo-svoboda.ru, 1
 link-sanitizer.com, 1
 linkages.org, 1
 linkedinbackground.com, 1
 linkenheil.org, 1
 linklocker.co, 1
 linkmaker.co.uk, 1
+linkmauve.fr, 1
 linkonaut.net, 1
 linksanitizer.com, 1
 linky.tk, 1
 linkycat.com, 1
 linley.de, 1
 linode.com, 0
 linost.com, 1
 linpx.com, 1
@@ -14733,17 +14726,16 @@ loveismore.it, 0
 loveismore.org, 0
 loveismore.pl, 0
 loveismore.ru, 0
 loveismore.sk, 0
 loveisourweapon.com, 1
 lovelens.ch, 1
 lovelens.li, 1
 lovelive-anime.tk, 1
-lovelivewiki.com, 1
 lovelyfriends.org, 1
 lovelytimes.net, 1
 lovemomiji.com, 1
 lovemysafetynet.com, 1
 loveph.one, 1
 lover-bg.com, 1
 loverepublic.ru, 1
 lovesmagical.com, 1
@@ -15478,32 +15470,32 @@ mazda626.net, 1
 maze.fr, 1
 mazternet.ru, 1
 mazurlabs.tk, 1
 mb-is.info, 1
 mbaestlein.de, 1
 mbardot.com, 1
 mbasic.facebook.com, 0
 mbcars.be, 1
-mbconsultancy.nu, 1
 mbdrogenbos-usedcars.be, 1
 mbeo.ch, 1
 mbilker.us, 1
 mbinf.de, 0
 mbinformatik.de, 0
 mblankhorst.nl, 1
 mbp.banking.co.at, 0
 mbr-net.de, 1
 mbrooks.info, 1
 mbs-journey.com, 1
 mbsec.net, 1
 mbweir.com, 1
 mbwemmel-usedcars.be, 1
 mc-team.org, 1
 mc-venture.net, 0
+mcadmin.net, 1
 mcatnnlo.org, 1
 mcb-bank.com, 1
 mccarty.io, 1
 mccordworks.com, 1
 mccrackon.com, 1
 mcdanieldevelopmentservices.com, 1
 mcdona1d.me, 1
 mcdonalds.be, 1
@@ -15774,17 +15766,16 @@ meteobox.cz, 1
 meteobox.de, 1
 meteobox.es, 1
 meteobox.fr, 1
 meteobox.mx, 1
 meteobox.pl, 1
 meteobox.sk, 1
 meteorapp.space, 1
 meteosmit.it, 1
-meterhost.com, 1
 methamphetamine.co.uk, 1
 methylone.com, 1
 metin2sepeti.com, 1
 metrix-money-ptc.com, 1
 metroairvirtual.com, 1
 metrobriefs.com, 1
 metronaut.de, 1
 metropop.ch, 1
@@ -15813,17 +15804,16 @@ mgsisk.com, 1
 mhalfter.de, 1
 mhatlaw.com, 1
 mheistermann.de, 1
 mhermans.nl, 1
 mhjuma.com, 1
 mhmfoundationrepair.com, 1
 mi-beratung.de, 1
 mi-so-ji.com, 1
-mia.to, 1
 miagexport.com, 1
 miamicityballet.org, 1
 miaoubox.com, 1
 miaowo.org, 1
 miasarafina.de, 1
 miboulot.com, 1
 micasamgmt.com, 1
 micbase.com, 1
@@ -17268,17 +17258,16 @@ newtnote.com, 1
 newtonhaus.com, 1
 newtrackon.com, 1
 nex.sx, 1
 nexicafiles.com, 1
 nexlab.org, 1
 next-log.ru, 0
 next-taxi.ru, 1
 next24.io, 1
-next47.com, 1
 nextads.ch, 1
 nextcairn.com, 1
 nextcloud.com, 1
 nextcloud.li, 1
 nextend.net, 1
 nextend.org, 1
 nextgen.sk, 1
 nextgencel.com, 1
@@ -17612,17 +17601,16 @@ nottres.com, 1
 notypiesni.sk, 0
 noudjalink.nl, 1
 nova-dess.ch, 1
 nova-wd.org.uk, 1
 nova.live, 1
 novabench.com, 1
 novafreixo.pt, 1
 novaopcaofestas.com.br, 1
-novascan.net, 1
 novawave.ca, 1
 novelfeed.com, 1
 novelinglife.net, 1
 novelshouse.com, 1
 novelvyretraite.fr, 1
 novfishing.ru, 1
 novilaw.com, 1
 novoresume.com, 1
@@ -17723,17 +17711,16 @@ nuvechtdal.nl, 1
 nuvini.com, 1
 nuxer.fr, 1
 nvlop.xyz, 1
 nvr.bz, 1
 nwerc.party, 1
 nwgh.org, 0
 nwk1.com, 1
 nwra.com, 1
-nwwc.dk, 1
 nwwnetwork.net, 1
 nxinfo.ch, 1
 nyan.it, 1
 nyanpasu.tv, 1
 nyantec.com, 1
 nyazeeland.guide, 1
 nycoyote.org, 1
 nyffo.com, 1
@@ -17745,16 +17732,17 @@ nylonfeetporn.com, 1
 nymphetomania.net, 1
 nynex.net, 1
 nyphox.ovh, 1
 nyronet.de, 0
 nystudio107.com, 1
 nyxi.eu, 1
 nyyu.tk, 1
 nzb.cat, 0
+nzmk.cz, 0
 nzstudy.ac.nz, 1
 o-sp.com, 1
 o2careers.co.uk, 1
 o3.wf, 1
 o3wallet.com, 1
 o6asan.com, 1
 oaic.gov.au, 1
 oakington.info, 1
@@ -18185,17 +18173,16 @@ ortlepp.eu, 1
 orwell1984.today, 1
 orz.uno, 1
 os-chrome.ru, 1
 os-s.net, 1
 osacrypt.studio, 1
 osakeannit.fi, 1
 osao.org, 1
 osbi.pl, 1
-osborneinn.com, 1
 osburn.com, 1
 oscamp.eu, 1
 oscarvk.ch, 1
 oscsdp.cz, 0
 osereso.tn, 1
 oses.mobi, 1
 osha-kimi.com, 1
 oshanko.de, 1
@@ -18421,17 +18408,16 @@ papadopoulos.me, 1
 papakatsu-life.com, 1
 papatest24.de, 1
 papayame.com, 1
 papayapythons.com, 1
 papelariadante.com.br, 1
 paper-republic.org, 1
 paperhaven.com.au, 1
 papermasters.com, 1
-papersmart.net, 1
 papertracker.net, 1
 paperturn.com, 1
 paperwork.co.za, 1
 paperwritinghelp.net, 1
 paraborsa.net, 1
 parachute70.com, 1
 paradiesgirls.ch, 1
 paradigi.com.br, 1
@@ -18581,16 +18567,17 @@ paulinewesterman.nl, 1
 paulomonteiro.pt, 1
 paulov.com, 1
 paulov.info, 1
 paulov.ru, 1
 paulrobertlloyd.com, 1
 paulrotter.de, 1
 paulschreiber.com, 1
 paulscustomauto.com, 1
+paulshir.com, 1
 paulswartz.net, 1
 paultibbetts.uk, 1
 paulus-foto.pl, 1
 paulwatabe.com, 1
 pauspam.net, 1
 pautadiaria.com, 1
 pavando.com, 1
 paveljanda.com, 1
@@ -18727,32 +18714,32 @@ pennylane.me.uk, 1
 pennyparkerpaper.com, 1
 penrithapartments.com.au, 1
 pensacolawinterfest.org, 1
 pensador.com, 1
 pensador.info, 1
 pensioenfonds-ey.nl, 1
 pension-waldesruh.de, 1
 pensiunealido.ro, 1
+pentandra.com, 1
 pentest.blog, 1
 pentest.nl, 1
 pentesterlab.com, 1
 penticton.photography, 1
 penz.media, 1
 peoplelikemeapp.com, 1
 peoplesbankal.com, 1
 pepemodelismo.com.br, 1
 peplog.nl, 1
 pepwaterproofing.com, 1
 per-pedes.at, 1
 pera.gs, 1
 peraparker.cz, 1
 percolate.com, 1
 percraft.com, 1
-percy.io, 1
 perd.re, 1
 perdel.cn, 0
 perecraft.com, 1
 pereuda.com, 1
 perezdecastro.org, 1
 perfect.in.th, 1
 perfectcloud.org, 1
 perfectseourl.com, 1
@@ -18867,16 +18854,17 @@ phdwuda.com, 1
 phenomeno-porto.com, 1
 phenomeno.nl, 1
 phenomenoporto.com, 1
 phenomenoporto.nl, 1
 phget.com, 1
 phi-works.com, 1
 phialo.de, 1
 phil-phillies.com, 1
+phil.tw, 1
 philadelphia.com.mx, 1
 philadelphiacandies.com, 1
 philadelphiadancefoundation.org, 1
 philia-sa.com, 1
 philipdb.com, 1
 philipkohn.com, 1
 philipmordue.co.uk, 1
 philipp-trulson.de, 0
@@ -18987,16 +18975,17 @@ pieq.eu.org, 1
 pier28.com, 1
 piercraft.com, 1
 pierre-denoblens.net, 1
 pierre-schmitz.com, 1
 pierrefv.com, 1
 pierrejeansuau.fr, 1
 pietawittermans.nl, 1
 pietechsf.com, 1
+pieterbos.nl, 1
 pieterhordijk.com, 1
 pietz.uk, 1
 pigritia.de, 1
 pijuice.com, 1
 pik.bzh, 1
 pikeitservices.com.au, 1
 pikmy.com, 1
 pileofgarbage.net, 1
@@ -19141,16 +19130,17 @@ plasti-pac.ch, 1
 plasticsurgeryartist.com, 1
 plasvilledescartaveis.com.br, 1
 platformadmin.com, 1
 platinumpeek.com, 1
 platomania.nl, 1
 platschi.net, 1
 platten-nach-mass.de, 1
 platterlauncher.com, 1
+plattner.club, 1
 play.cash, 1
 play.google.com, 1
 playanka.com, 1
 playdreamcraft.com.br, 1
 playerscout.net, 1
 playform.cloud, 1
 playhappywheelsunblocked.com, 1
 playkh.com, 1
@@ -19284,16 +19274,17 @@ polkam.go.id, 1
 pollet-ghijs.be, 1
 pollet-ghys.be, 1
 polletmera.com, 1
 pollingplace.uk, 1
 pollpodium.nl, 1
 polsport.live, 1
 polyfill.io, 1
 polymake.org, 1
+polymathematician.com, 1
 polynomapp.com, 1
 polypet.com.sg, 1
 polytarian.com, 1
 polytechecosystem.vc, 1
 pomar.club, 0
 pomardaserra.com, 1
 pomfe.co, 1
 pommedepain.fr, 1
@@ -20435,17 +20426,16 @@ repsomelt.com, 1
 reptrax.com, 1
 republic.gr, 1
 republique.org, 1
 repugnant-conclusion.com, 1
 repugnantconclusion.com, 1
 repustate.com, 1
 reputationweaver.com, 1
 reqognize.com, 1
-reqrut.net, 1
 request-trent.com, 1
 resama.eu, 1
 resc.la, 1
 rescms-secure.com, 1
 research.facebook.com, 0
 research.md, 1
 researchgate.net, 1
 reservar-un-hotel.com, 1
@@ -20610,16 +20600,17 @@ rip-sport.cz, 1
 ripmixmake.org, 1
 ripple.com, 1
 risaphuketproperty.com, 1
 riscascape.net, 1
 rischard.org, 1
 rise-technologies.com, 1
 riseup.net, 1
 rishikeshyoga.in, 1
+risiinfo.com, 1
 risingsun.red, 1
 riskmitigation.ch, 1
 rissato.com.br, 1
 ristioja.ee, 1
 ristoarea.it, 1
 ristorantefattoamano.eu, 1
 ristorantefattoamano.it, 1
 rivalsa.cn, 1
@@ -20867,17 +20858,16 @@ royzez.com, 1
 rozalisbengal.ro, 1
 rozalynne-dawn.ga, 1
 rozhodce.cz, 1
 rpadovani.com, 1
 rpasafrica.com, 1
 rpgmaker.es, 1
 rpherbig.com, 1
 rpine.net, 1
-rprimas.duckdns.org, 1
 rpy.xyz, 1
 rq-labo.jp, 1
 rr105.de, 1
 rrdesignsuisse.com, 1
 rrg-partner.ch, 1
 rring.me, 1
 rro.rs, 1
 rrom.me, 1
@@ -21158,17 +21148,18 @@ samel.de, 1
 samenwerkingsportaal.nl, 1
 samenwerkingsportaal.tk, 1
 samgrayson.me, 1
 samifar.in, 1
 samirnassar.com, 1
 samizdat.cz, 1
 samkelleher.com, 1
 saml-gateway.org, 1
-sammyjohnson.com, 1
+samm.com.au, 1
+sammyjohnson.com, 0
 sammyservers.com, 1
 samp.im, 1
 samsungmobile.it, 1
 samsungxoa.com, 1
 samuelkeeley.com, 1
 samuellaulhau.fr, 1
 samuirehabcenter.com, 1
 samwilberforce.com, 1
@@ -21567,16 +21558,17 @@ sebastianboegl.de, 1
 sebastiensenechal.com, 1
 sebi.org, 1
 sec-mails.de, 1
 sec-wiki.com, 1
 sec.ec, 1
 sec.gd, 1
 sec3ure.co.uk, 1
 secanje.nl, 1
+secboom.com, 1
 seccomp.ru, 1
 secctexasgiving.org, 0
 secgui.de, 1
 sech.me, 1
 secitem.at, 1
 secitem.de, 1
 secnews.gr, 1
 secomo.org, 1
@@ -21600,20 +21592,18 @@ securai.de, 1
 secure-automotive-cloud.com, 1
 secure-automotive-cloud.org, 1
 secure-graphic.de, 1
 secure-server-hosting.com, 1
 secure.advancepayroll.com.au, 1
 secure.chat, 1
 secure.co.hu, 1
 secure.facebook.com, 0
-securedevelop.net, 1
 securedrop.org, 1
 secureesolutions.com, 1
-securefuture.nl, 1
 secureheaders.com, 1
 secureideas.com, 0
 securejabber.me, 1
 secureonline.co, 1
 securethe.news, 1
 securetheorem.com, 1
 securetronic.ch, 1
 securify.nl, 1
@@ -21860,17 +21850,16 @@ sg.search.yahoo.com, 0
 sgcaccounts.co.uk, 1
 sgroup-hitoduma.com, 1
 sgroup-rec.com, 1
 sgtcodfish.com, 1
 sgthotshot.com, 1
 sgtt.ch, 1
 sh-heppelmann.de, 1
 sh-network.de, 0
-sh11.pp.ua, 1
 sh4y.com, 1
 sha2017.org, 1
 shaaaaaaaaaaaaa.com, 1
 shadesofgrayadr.com, 1
 shadesofgraylaw.com, 1
 shadex.net, 1
 shadigee.org, 1
 shadiku.com, 1
@@ -22212,17 +22201,16 @@ simon.lc, 1
 simoncommunity.org.uk, 1
 simoncook.org, 1
 simonhirscher.de, 1
 simonkjellberg.com, 1
 simonkjellberg.se, 1
 simonlyabonnement.nl, 1
 simonpaarlberg.com, 1
 simonreich.de, 1
-simonsaxon.com, 1
 simonschmitt.ch, 1
 simonsmh.cc, 1
 simonspeich.ch, 1
 simonsreich.de, 1
 simonwessel.net, 1
 simonwoodside.com, 1
 simpbx.net, 1
 simpel.be, 1
@@ -22238,16 +22226,17 @@ simpletax.ca, 1
 simplexgame.net, 1
 simplexsupport.com, 0
 simplia.cz, 1
 simplicitypvp.net, 1
 simplidesigns.nl, 1
 simplycharlottemason.com, 1
 simplycloud.de, 1
 simplyenak.com, 0
+simplyfixit.co.uk, 1
 simplyhelen.de, 1
 simplymozzo.se, 1
 simplystudio.com, 1
 simpte.com, 1
 simpul.nl, 1
 sims4hub.ga, 1
 simsnieuws.nl, 1
 simtin-net.de, 1
@@ -22577,17 +22566,16 @@ snelbv.nl, 1
 snelshops.nl, 1
 snelwebshop.nl, 1
 snelxboxlivegold.nl, 1
 snerith.com, 1
 snfdata.com, 0
 sniderman.eu.org, 1
 sniep.net, 1
 snight.co, 1
-snille.com, 1
 snl.no, 0
 snod.land, 1
 snoupon.com, 1
 snovey.com, 1
 snow-online.com, 1
 snow-online.de, 1
 snow.dog, 1
 snowalerts.eu, 1
@@ -22632,17 +22620,16 @@ sociobiology.com, 1
 sociopathy.org, 1
 socketize.com, 1
 sockeye.io, 1
 sockscap64.com, 1
 socoastal.com, 1
 sodafilm.de, 1
 sodi.nl, 1
 sodiao.cc, 1
-soe-server.com, 1
 sofa-rockers.org, 1
 sofabedshop.de, 1
 sofort.com, 1
 sofortueberweisung.de, 1
 softanka.com, 1
 softballrampage.com, 1
 softclean.pt, 1
 softprayog.in, 1
@@ -22948,17 +22935,16 @@ spron.in, 1
 sprueche-zum-valentinstag.de, 1
 sprueche-zur-geburt.info, 1
 sprueche-zur-hochzeit.de, 1
 sprueche-zur-konfirmation.de, 1
 sps-lehrgang.de, 1
 sptk.org, 1
 spuffin.com, 1
 spur.com.br, 1
-sputnik1net.org, 1
 spydar007.com, 1
 spydar007.net, 1
 spydersec.com, 1
 spykedigital.com, 1
 spyprofit.ru, 1
 sqetsa.com, 1
 sql-und-xml.de, 1
 sqlapius.net, 1
@@ -23326,28 +23312,28 @@ stringtoolbox.com, 1
 stringvox.com, 1
 stripe.com, 1
 strobeltobias.de, 1
 strobeto.de, 1
 strobotti.com, 1
 stroginohelp.ru, 1
 strom.family, 1
 strongrandom.com, 1
-strozik.de, 1
 structurally.net, 1
 strugee.net, 1
 strutta.me, 1
 struxureon.com, 1
 strydom.me.uk, 1
 stt.wiki, 1
 stuartbell.co.uk, 1
 stuco.co, 1
 studenckiemetody.pl, 1
 student-eshop.cz, 1
 student-eshop.sk, 1
+student.andover.edu, 1
 studentforums.biz, 1
 studentite.bg, 0
 studentloans.gov, 1
 studentrightsadvocate.org, 1
 studentshare.net, 1
 studenttenant.com, 1
 studer.su, 1
 studienportal.eu, 1
@@ -23623,17 +23609,16 @@ symbiose-immobilier.ch, 1
 symbiose.com, 1
 symbiosecom.ch, 1
 symeda.de, 1
 synabi.com, 1
 synaptickz.me, 1
 synatra.co, 1
 sync-it.no, 1
 syncaddict.net, 1
-synchtu.be, 0
 syncmylife.net, 0
 syncrise.co.jp, 1
 syndic-discount.fr, 0
 syneart.com, 1
 synergyworkingdogclub.com, 1
 synfin.org, 1
 synony.me, 1
 synotna.eu, 1
@@ -23949,16 +23934,17 @@ technifocal.com, 1
 technikrom.org, 1
 technologie-innovation.fr, 1
 technologyand.me, 1
 technologysi.com, 1
 technoparcepsilon.fr, 1
 technoscoots.com, 1
 technosorcery.net, 1
 technotonic.co.uk, 1
+techold.ru, 1
 techorbiter.com, 1
 techosmarcelo.com.ar, 1
 techpivot.net, 1
 techpro.net.br, 1
 techshift.eu, 1
 techshift.nl, 1
 techshift.se, 1
 techtalks.no, 1
@@ -24267,17 +24253,16 @@ thejobauction.com, 1
 thekeymusic.com, 1
 thekingofhate.com, 1
 thekrewserver.com, 1
 thelaimlife.com, 1
 thelanscape.com, 1
 thelastsurprise.com, 1
 thelefthand.org, 1
 thelinuxspace.com, 1
-thelinuxtree.net, 1
 thelittlecraft.com, 1
 thelocals.ru, 1
 thelostyankee.com, 1
 themacoaching.nl, 1
 themarshallproject.org, 1
 themeaudit.com, 1
 themecraft.studio, 1
 themerchandiser.net, 1
@@ -24463,16 +24448,17 @@ threatcentral.io, 1
 threebrothersbrewing.com, 1
 threecrownsllp.com, 1
 threedpro.me, 1
 threefours.net, 1
 threelions.ch, 1
 threv.net, 1
 thrivesummit.com, 1
 thriveta.com, 1
+thrivewellnesshub.co.za, 1
 throttlerz.in, 1
 throughtheglass.photo, 1
 throwaway.link, 1
 throwpass.com, 1
 thrx.net, 1
 thues.eu, 1
 thuisverpleging-meerdael.be, 1
 thunderfield-boat.co.uk, 1
@@ -24506,21 +24492,21 @@ ticketmates.com.au, 1
 ticketoplichting.nl, 1
 ticketslover.com, 1
 ticketsource.co.uk, 1
 ticketsource.eu, 1
 ticketsource.us, 1
 ticketsourcebeta.co.uk, 1
 tid.jp, 1
 tidycustoms.net, 1
+tie-online.org, 1
 tiendafetichista.com, 1
 tiendavertigo.com, 1
 tiens-ib.cz, 1
 tier-1-entrepreneur.com, 1
-tierarztpraxis-bogenhausen.de, 1
 tierarztpraxis-weinert.de, 1
 tiew.pl, 1
 tifan.net, 1
 tiffnix.com, 1
 tigerchef.com, 1
 tigerdile.com, 1
 tijden.nu, 1
 tiki-god.co.uk, 1
@@ -24712,17 +24698,16 @@ tokototech.com, 1
 tokumei.co, 1
 tokyo-powerstation.com, 1
 tokyo.dating, 1
 tokyomakino.com, 1
 tokyovipper.com, 1
 tolboe.com, 1
 toleressea.fr, 1
 toles-sur-mesure.fr, 1
-tollsjekk.no, 1
 tom-geiger.de, 1
 tom-kunze.de, 1
 tom-maxwell.com, 1
 tom.run, 1
 tomabrafix.de, 1
 tomandshirley.com, 1
 tomasjacik.cz, 1
 tomaskavalek.cz, 1
@@ -25609,16 +25594,17 @@ urban-culture.fr, 1
 urban.melbourne, 1
 urbanesecurity.com, 1
 urbanfi.sh, 1
 urbanguerillas.de, 1
 urbanietz-immobilien.de, 1
 urbanmelbourne.info, 1
 urbannewsservice.com, 1
 urbansparrow.in, 1
+urbanstylestaging.com, 1
 urbanwildlifealliance.org, 1
 urbexdk.nl, 1
 urcentral.com, 1
 urcentral.org, 1
 ureka.org, 1
 urgences-valais.ch, 1
 uripura.de, 1
 urist1011.ru, 1
@@ -25691,17 +25677,16 @@ utugnn.ru, 1
 utw.me, 1
 uvocorp.com, 1
 uwesander.de, 1
 uwfreelanceopticien.nl, 1
 uwimonacs.org.jm, 1
 uygindir.ml, 1
 v-u-z.ru, 1
 v12.co.uk, 1
-v1sit0r.ru, 1
 v2bv.win, 1
 v2ex.com, 1
 v4s.ro, 1
 va-reitartikel.com, 1
 vaaddress.co, 1
 vacationscostarica.com, 1
 vaccines.gov, 1
 vaclavambroz.cz, 1
@@ -25936,16 +25921,17 @@ viaggio-in-cina.it, 1
 viaje-a-china.com, 1
 vialibido.com.br, 1
 vialorran.com, 1
 viaprinto.de, 1
 vibrant-america.com, 1
 vibrashop.com.br, 1
 vicenage.com, 1
 viceversa.xyz, 1
+vician.cz, 0
 viciousviscosity.xyz, 1
 viclab.se, 1
 victorcanera.com, 1
 victordiaz.me, 1
 victoreriksson.se, 1
 victoriaville.ca, 1
 victorjacobs.com, 1
 victornet.de, 1
@@ -26139,30 +26125,30 @@ vnfs-team.com, 1
 vnvisa.center, 1
 vnvisa.ru, 1
 vocab.guru, 1
 vocaloid.my, 1
 vocalviews.com, 1
 vodpay.com, 1
 vodpay.net, 1
 vodpay.org, 1
-vogler.name, 1
 vogt.tech, 1
 voice-of-design.com, 1
 voicu.ch, 1
 void-it.nl, 1
 void-zero.com, 1
 voidi.ca, 1
 voidpay.com, 1
 voidpay.net, 1
 voidpay.org, 1
 voidptr.eu, 1
 voidserv.net, 1
 voidshift.com, 1
 voipsun.com, 1
+vokativy.cz, 0
 vokeapp.com, 1
 volcain.io, 1
 volcanconcretos.com, 1
 volga.us, 1
 volgavibes.ru, 1
 volker-gropp.de, 1
 volkergropp.de, 1
 volkswurst.de, 1
@@ -26179,16 +26165,17 @@ vonterra.us, 1
 voodoochile.at, 1
 voorjou.com, 1
 vop.li, 1
 vorderklier.de, 1
 vorkbaard.nl, 1
 vorlicek.de, 1
 vorlif.org, 1
 vorm2.com, 1
+vorodevops.com, 1
 vos-fleurs.ch, 1
 vos-fleurs.com, 1
 voshod.org, 0
 vosky.fr, 1
 vostronet.com, 1
 voter-info.uk, 1
 voterstartingpoint.uk, 1
 votocek.cz, 1
@@ -26276,16 +26263,17 @@ wabatam.com, 1
 wabifoggynuts.com, 1
 wachter.biz, 1
 wadidi.com, 1
 wadsworth.gallery, 1
 wadvisor.com, 1
 waelisch.de, 1
 waelti.xxx, 1
 wafa4hw.com, 1
+wafairhaven.com.au, 1
 waffle.at, 1
 wafni.com, 1
 wahidhasan.com, 1
 wahlman.org, 1
 wahrnehmungswelt.de, 1
 wahrnehmungswelten.de, 1
 wai-in.com, 1
 waigel.org, 1
@@ -26487,16 +26475,17 @@ webrentcars.com, 1
 webreport.fr, 1
 webs4all.ro, 0
 websectools.com, 1
 websecurity.is, 1
 webseitendesigner.com, 0
 webseitenserver.com, 1
 websenat.de, 1
 websharks.org, 1
+websiteadvice.com.au, 1
 websitedesign.bg, 1
 websiteforlease.ca, 1
 websitesdallas.com, 1
 websiteservice.pro, 1
 webslake.com, 1
 webspiral.jp, 1
 webspotter.nl, 1
 webstore.be, 0
@@ -26912,17 +26901,16 @@ wnnc.co.uk, 1
 wnu.com, 1
 wo-ist-elvira.net, 1
 wo2forum.nl, 0
 wobble.ninja, 1
 wod-stavby.cz, 1
 wodboss.com, 1
 wodinaz.com, 1
 wodka-division.de, 1
-woelkchen.me, 1
 wofford-ecs.org, 1
 woffs.de, 1
 woheni.de, 1
 wohlgemuth.rocks, 1
 wohnbegleitung.ch, 1
 wohnsitz-ausland.com, 1
 woi.vision, 1
 wokeai.net, 1
@@ -26986,16 +26974,17 @@ works-ginan.jp, 1
 workwithgo.com, 1
 world-education-association.org, 1
 world-in-my-eyes.com, 1
 worldcigars.com.br, 1
 worldcrafts.org, 1
 worldcubeassociation.org, 1
 worldessays.com, 1
 worldeventscalendars.com, 1
+worldfree4.org, 1
 worldofbelia.de, 1
 worldofterra.net, 1
 worldofvnc.net, 1
 worldpovertysolutions.org, 1
 worldsgreatestazuredemo.com, 1
 worldsoccerclips.com, 1
 worldstone777.com, 1
 wormdisk.net, 1
@@ -27231,17 +27220,16 @@ xega.org, 1
 xehost.com, 1
 xenophile.name, 1
 xenosphere.tk, 1
 xenoworld.de, 1
 xeonlab.com, 1
 xeonlab.de, 1
 xerblade.com, 1
 xetown.com, 1
-xfd3.de, 1
 xferion.com, 1
 xfix.pw, 1
 xfrag-networks.com, 0
 xg3n1us.de, 0
 xgame.com.tr, 1
 xgclan.com, 1
 xgn.es, 1
 xhadius.de, 1
@@ -27544,16 +27532,17 @@ yemalu.com, 1
 yemekbaz.az, 1
 yep-pro.ch, 1
 yepbitcoin.com, 1
 yesfone.com.br, 1
 yesiammaisey.me, 1
 yesonline.asia, 0
 yesonline.me, 0
 yeswehack.com, 1
+yetii.net, 1
 yetzt.me, 0
 yeu.io, 1
 yfengs.moe, 1
 yffengshi.ml, 1
 yggdar.ga, 1
 yhaupenthal.org, 1
 yhb.io, 1
 yhori.xyz, 1
@@ -27650,16 +27639,17 @@ yoursbookstore.jp, 1
 yourself.today, 1
 yourticketbooking.com, 1
 youruseragent.info, 1
 yourznc.com, 1
 youss.cc, 0
 yout.com, 1
 youtous.me, 1
 youtubedownloader.com, 1
+youwatchporn.com, 1
 youyoulemon.com, 1
 yoxall.me.uk, 1
 yoyoost.duckdns.org, 1
 ypart.eu, 1
 ypcs.fi, 1
 ypid.de, 1
 yplanapp.com, 1
 yr166166.com, 1
@@ -27719,18 +27709,16 @@ yuhuo.org, 1
 yuka.one, 1
 yuki.xyz, 1
 yukonconnector.com, 1
 yukonlip.com, 1
 yukonrefugees.com, 1
 yukontec.com, 1
 yum.beer, 1
 yumeconcert.com, 1
-yuna.love, 1
-yuna.tg, 1
 yunity.org, 1
 yunjishou.pro, 1
 yuricarlenzoli.it, 1
 yurikirin.me, 1
 yurimoens.be, 1
 yusa.me, 1
 yutangyun.com, 1
 yuwei.org, 1
--- a/servo/components/layout/generated_content.rs
+++ b/servo/components/layout/generated_content.rs
@@ -132,28 +132,28 @@ impl<'a> InorderFlowTraversal for Resolv
     #[inline]
     fn should_process_subtree(&mut self, flow: &mut Flow) -> bool {
         flow::base(flow).restyle_damage.intersects(RESOLVE_GENERATED_CONTENT) ||
             flow::base(flow).flags.intersects(AFFECTS_COUNTERS | HAS_COUNTER_AFFECTING_CHILDREN)
     }
 }
 
 /// The object that mutates the generated content fragments.
-struct ResolveGeneratedContentFragmentMutator<'a,'b:'a> {
+struct ResolveGeneratedContentFragmentMutator<'a, 'b: 'a> {
     /// The traversal.
     traversal: &'a mut ResolveGeneratedContent<'b>,
     /// The level we're at in the flow tree.
     level: u32,
     /// Whether this flow is a block flow.
     is_block: bool,
     /// Whether we've incremented the counter yet.
     incremented: bool,
 }
 
-impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
+impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
     fn mutate_fragment(&mut self, fragment: &mut Fragment) {
         // We only reset and/or increment counters once per flow. This avoids double-incrementing
         // counters on list items (once for the main fragment and once for the marker).
         if !self.incremented {
             self.reset_and_increment_counters_as_necessary(fragment);
         }
 
         let mut list_style_type = fragment.style().get_list().list_style_type;
--- a/servo/components/layout/persistent_list.rs
+++ b/servo/components/layout/persistent_list.rs
@@ -64,17 +64,17 @@ impl<T> Clone for PersistentList<T> wher
         // its head.
         PersistentList {
             head: self.head.clone(),
             length: self.length,
         }
     }
 }
 
-pub struct PersistentListIterator<'a,T> where T: 'a + Send + Sync {
+pub struct PersistentListIterator<'a, T> where T: 'a + Send + Sync {
     entry: Option<&'a PersistentListEntry<T>>,
 }
 
 impl<'a, T> Iterator for PersistentListIterator<'a, T> where T: Send + Sync + 'static {
     type Item = &'a T;
 
     #[inline]
     fn next(&mut self) -> Option<&'a T> {
--- a/servo/components/script/body.rs
+++ b/servo/components/script/body.rs
@@ -39,18 +39,19 @@ pub enum FetchedData {
 
 // https://fetch.spec.whatwg.org/#concept-body-consume-body
 #[allow(unrooted_must_root)]
 pub fn consume_body<T: BodyOperations + DomObject>(object: &T, body_type: BodyType) -> Rc<Promise> {
     let promise = Promise::new(&object.global());
 
     // Step 1
     if object.get_body_used() || object.is_locked() {
-        promise.reject_error(promise.global().get_cx(), Error::Type(
-            "The response's stream is disturbed or locked".to_string()));
+        promise.reject_error(Error::Type(
+            "The response's stream is disturbed or locked".to_string(),
+        ));
         return promise;
     }
 
     object.set_body_promise(&promise, body_type);
 
     // Steps 2-4
     // TODO: Body does not yet have a stream.
 
@@ -70,27 +71,26 @@ pub fn consume_body_with_promise<T: Body
         None => return,
     };
 
     let pkg_data_results = run_package_data_algorithm(object,
                                                       body,
                                                       body_type,
                                                       object.get_mime_type());
 
-    let cx = promise.global().get_cx();
     match pkg_data_results {
         Ok(results) => {
             match results {
-                FetchedData::Text(s) => promise.resolve_native(cx, &USVString(s)),
-                FetchedData::Json(j) => promise.resolve_native(cx, &j),
-                FetchedData::BlobData(b) => promise.resolve_native(cx, &b),
-                FetchedData::FormData(f) => promise.resolve_native(cx, &f),
+                FetchedData::Text(s) => promise.resolve_native(&USVString(s)),
+                FetchedData::Json(j) => promise.resolve_native(&j),
+                FetchedData::BlobData(b) => promise.resolve_native(&b),
+                FetchedData::FormData(f) => promise.resolve_native(&f),
             };
         },
-        Err(err) => promise.reject_error(cx, err),
+        Err(err) => promise.reject_error(err),
     }
 }
 
 // https://fetch.spec.whatwg.org/#concept-body-package-data
 #[allow(unsafe_code)]
 fn run_package_data_algorithm<T: BodyOperations + DomObject>(object: &T,
                                                              bytes: Vec<u8>,
                                                              body_type: BodyType,
--- a/servo/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/servo/components/script/dom/bindings/codegen/CodegenRust.py
@@ -783,17 +783,17 @@ def getJSToNativeConversionInfo(type, de
 
                 rooted!(in(cx) let globalObj = CurrentGlobalOrNull(cx));
                 let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get());
 
                 rooted!(in(cx) let mut valueToResolve = $${val}.get());
                 if !JS_WrapValue(cx, valueToResolve.handle_mut()) {
                 $*{exceptionCode}
                 }
-                match Promise::Resolve(&promiseGlobal, cx, valueToResolve.handle()) {
+                match Promise::new_resolved(&promiseGlobal, cx, valueToResolve.handle()) {
                     Ok(value) => value,
                     Err(error) => {
                     throw_dom_exception(cx, &promiseGlobal, error);
                     $*{exceptionCode}
                     }
                 }
             }
             """,
--- a/servo/components/script/dom/bindings/refcounted.rs
+++ b/servo/components/script/dom/bindings/refcounted.rs
@@ -24,17 +24,16 @@
 
 use core::nonzero::NonZero;
 use dom::bindings::conversions::ToJSValConvertible;
 use dom::bindings::error::Error;
 use dom::bindings::js::Root;
 use dom::bindings::reflector::{DomObject, Reflector};
 use dom::bindings::trace::trace_reflector;
 use dom::promise::Promise;
-use js::jsapi::JSAutoCompartment;
 use js::jsapi::JSTracer;
 use libc;
 use std::cell::RefCell;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::collections::hash_map::HashMap;
 use std::hash::Hash;
 use std::marker::PhantomData;
 use std::os;
@@ -121,36 +120,30 @@ impl TrustedPromise {
     }
 
     /// A task which will reject the promise.
     #[allow(unrooted_must_root)]
     pub fn reject_task(self, error: Error) -> impl TaskOnce {
         let this = self;
         task!(reject_promise: move || {
             debug!("Rejecting promise.");
-            let this = this.root();
-            let cx = this.global().get_cx();
-            let _ac = JSAutoCompartment::new(cx, this.reflector().get_jsobject().get());
-            this.reject_error(cx, error);
+            this.root().reject_error(error);
         })
     }
 
     /// A task which will resolve the promise.
     #[allow(unrooted_must_root)]
     pub fn resolve_task<T>(self, value: T) -> impl TaskOnce
     where
         T: ToJSValConvertible + Send,
     {
         let this = self;
         task!(resolve_promise: move || {
             debug!("Resolving promise.");
-            let this = this.root();
-            let cx = this.global().get_cx();
-            let _ac = JSAutoCompartment::new(cx, this.reflector().get_jsobject().get());
-            this.resolve_native(cx, &value);
+            this.root().resolve_native(&value);
         })
     }
 }
 
 /// A safe wrapper around a raw pointer to a DOM object that can be
 /// shared among threads for use in asynchronous operations. The underlying
 /// DOM object is guaranteed to live at least as long as the last outstanding
 /// `Trusted<T>` instance.
--- a/servo/components/script/dom/bluetooth.rs
+++ b/servo/components/script/dom/bluetooth.rs
@@ -28,17 +28,17 @@ use dom::bluetoothuuid::{BluetoothServic
 use dom::eventtarget::EventTarget;
 use dom::globalscope::GlobalScope;
 use dom::permissions::{get_descriptor_permission_state, PermissionAlgorithm};
 use dom::promise::Promise;
 use dom_struct::dom_struct;
 use ipc_channel::ipc::{self, IpcSender};
 use ipc_channel::router::ROUTER;
 use js::conversions::ConversionResult;
-use js::jsapi::{JSAutoCompartment, JSContext, JSObject};
+use js::jsapi::{JSContext, JSObject};
 use js::jsval::{ObjectValue, UndefinedValue};
 use std::cell::Ref;
 use std::collections::HashMap;
 use std::rc::Rc;
 use std::str::FromStr;
 use std::sync::{Arc, Mutex};
 use task::TaskOnce;
 
@@ -89,33 +89,34 @@ impl BluetoothExtraPermissionData {
 }
 
 struct BluetoothContext<T: AsyncBluetoothListener + DomObject> {
     promise: Option<TrustedPromise>,
     receiver: Trusted<T>,
 }
 
 pub trait AsyncBluetoothListener {
-    fn handle_response(&self, result: BluetoothResponse, cx: *mut JSContext, promise: &Rc<Promise>);
+    fn handle_response(&self, result: BluetoothResponse, promise: &Rc<Promise>);
 }
 
-impl<T: AsyncBluetoothListener + DomObject> BluetoothContext<T> {
+impl<T> BluetoothContext<T>
+where
+    T: AsyncBluetoothListener + DomObject,
+{
     #[allow(unrooted_must_root)]
     fn response(&mut self, response: BluetoothResponseResult) {
         let promise = self.promise.take().expect("bt promise is missing").root();
-        let promise_cx = promise.global().get_cx();
 
         // JSAutoCompartment needs to be manually made.
         // Otherwise, Servo will crash.
-        let _ac = JSAutoCompartment::new(promise_cx, promise.reflector().get_jsobject().get());
         match response {
-            Ok(response) => self.receiver.root().handle_response(response, promise_cx, &promise),
+            Ok(response) => self.receiver.root().handle_response(response, &promise),
             // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
             // Step 3 - 4.
-            Err(error) => promise.reject_error(promise_cx, Error::from(error)),
+            Err(error) => promise.reject_error(Error::from(error)),
         }
     }
 }
 
 // https://webbluetoothcg.github.io/web-bluetooth/#bluetooth
 #[dom_struct]
 pub struct Bluetooth {
     eventtarget: EventTarget,
@@ -153,45 +154,45 @@ impl Bluetooth {
         // TODO: Step 1: Triggered by user activation.
 
         // Step 2.2: There are no requiredServiceUUIDS, we scan for all devices.
         let mut uuid_filters = vec!();
 
         if let &Some(ref filters) = filters {
             // Step 2.1.
             if filters.is_empty()  {
-                p.reject_error(p.global().get_cx(), Type(FILTER_EMPTY_ERROR.to_owned()));
+                p.reject_error(Type(FILTER_EMPTY_ERROR.to_owned()));
                 return;
             }
 
             // Step 2.3: There are no requiredServiceUUIDS, we scan for all devices.
 
             // Step 2.4.
             for filter in filters {
                 // Step 2.4.1.
                 match canonicalize_filter(&filter) {
                     // Step 2.4.2.
                     Ok(f) => uuid_filters.push(f),
                     Err(e) => {
-                        p.reject_error(p.global().get_cx(), e);
+                        p.reject_error(e);
                         return;
                     },
                 }
                 // Step 2.4.3: There are no requiredServiceUUIDS, we scan for all devices.
             }
         }
 
         let mut optional_services_uuids = vec!();
         if let &Some(ref opt_services) = optional_services {
             for opt_service in opt_services {
                 // Step 2.5 - 2.6.
                 let uuid = match BluetoothUUID::service(opt_service.clone()) {
                     Ok(u) => u.to_string(),
                     Err(e) => {
-                        p.reject_error(p.global().get_cx(), e);
+                        p.reject_error(e);
                         return;
                     },
                 };
 
                 // Step 2.7.
                 // Note: What we are doing here, is adding the not blocklisted UUIDs to the result vector,
                 // instead of removing them from an already filled vector.
                 if !uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
@@ -200,17 +201,17 @@ impl Bluetooth {
             }
         }
 
         let option = RequestDeviceoptions::new(BluetoothScanfilterSequence::new(uuid_filters),
                                                ServiceUUIDSequence::new(optional_services_uuids));
 
         // Step 4 - 5.
         if let PermissionState::Denied = get_descriptor_permission_state(PermissionName::Bluetooth, None) {
-            return p.reject_error(p.global().get_cx(), Error::NotFound);
+            return p.reject_error(Error::NotFound);
         }
 
         // Note: Step 3, 6 - 8 are implemented in
         // components/net/bluetooth_thread.rs in request_device function.
         self.get_bluetooth_thread().send(BluetoothRequest::RequestDevice(option, sender)).unwrap();
     }
 }
 
@@ -261,40 +262,39 @@ pub fn get_gatt_children<T, F> (
         uuid: Option<StringOrUnsignedLong>,
         instance_id: String,
         connected: bool,
         child_type: GATTType)
         -> Rc<Promise>
         where T: AsyncBluetoothListener + DomObject + 'static,
               F: FnOnce(StringOrUnsignedLong) -> Fallible<UUID> {
     let p = Promise::new(&attribute.global());
-    let p_cx = p.global().get_cx();
 
     let result_uuid = if let Some(u) = uuid {
         // Step 1.
         let canonicalized = match uuid_canonicalizer(u) {
             Ok(canonicalized_uuid) => canonicalized_uuid.to_string(),
             Err(e) => {
-                p.reject_error(p_cx, e);
+                p.reject_error(e);
                 return p;
             }
         };
         // Step 2.
         if uuid_is_blocklisted(canonicalized.as_ref(), Blocklist::All) {
-            p.reject_error(p_cx, Security);
+            p.reject_error(Security);
             return p;
         }
         Some(canonicalized)
     } else {
         None
     };
 
     // Step 3 - 4.
     if !connected {
-        p.reject_error(p_cx, Network);
+        p.reject_error(Network);
         return p;
     }
 
     // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice.
 
     // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptor function
     // and in handle_response function.
     let sender = response_async(&p, attribute);
@@ -474,17 +474,17 @@ impl From<BluetoothError> for Error {
 impl BluetoothMethods for Bluetooth {
     #[allow(unrooted_must_root)]
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
     fn RequestDevice(&self, option: &RequestDeviceOptions) -> Rc<Promise> {
         let p = Promise::new(&self.global());
         // Step 1.
         if (option.filters.is_some() && option.acceptAllDevices) ||
            (option.filters.is_none() && !option.acceptAllDevices) {
-            p.reject_error(p.global().get_cx(), Error::Type(OPTIONS_ERROR.to_owned()));
+            p.reject_error(Error::Type(OPTIONS_ERROR.to_owned()));
             return p;
         }
 
         // Step 2.
         let sender = response_async(&p, self);
         self.request_bluetooth_devices(&p, &option.filters, &option.optionalServices, sender);
         //Note: Step 3 - 4. in response function, Step 5. in handle_response function.
         return p;
@@ -502,47 +502,47 @@ impl BluetoothMethods for Bluetooth {
         p
     }
 
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-onavailabilitychanged
     event_handler!(availabilitychanged, GetOnavailabilitychanged, SetOnavailabilitychanged);
 }
 
 impl AsyncBluetoothListener for Bluetooth {
-    fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
+    fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>) {
         match response {
             // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
             // Step 11, 13 - 14.
             BluetoothResponse::RequestDevice(device) => {
                 let mut device_instance_map = self.device_instance_map.borrow_mut();
                 if let Some(existing_device) = device_instance_map.get(&device.id.clone()) {
-                    return promise.resolve_native(promise_cx, &**existing_device);
+                    return promise.resolve_native(&**existing_device);
                 }
                 let bt_device = BluetoothDevice::new(&self.global(),
                                                      DOMString::from(device.id.clone()),
                                                      device.name.map(DOMString::from),
                                                      &self);
                 device_instance_map.insert(device.id.clone(), JS::from_ref(&bt_device));
 
                 self.global().as_window().bluetooth_extra_permission_data().add_new_allowed_device(
                     AllowedBluetoothDevice {
                         deviceId: DOMString::from(device.id),
                         mayUseGATT: true,
                     }
                 );
                 // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
                 // Step 5.
-                promise.resolve_native(promise_cx, &bt_device);
+                promise.resolve_native(&bt_device);
             },
             // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability
             // Step 2 - 3.
             BluetoothResponse::GetAvailability(is_available) => {
-                promise.resolve_native(promise_cx, &is_available);
+                promise.resolve_native(&is_available);
             }
-            _ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
+            _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
         }
     }
 }
 
 impl PermissionAlgorithm for Bluetooth {
     type Descriptor = BluetoothPermissionDescriptor;
     type Status = BluetoothPermissionResult;
 
@@ -557,28 +557,31 @@ impl PermissionAlgorithm for Bluetooth {
                 Ok(ConversionResult::Success(descriptor)) => Ok(descriptor),
                 Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())),
                 Err(_) => Err(Error::Type(String::from(BT_DESC_CONVERSION_ERROR))),
             }
         }
     }
 
     // https://webbluetoothcg.github.io/web-bluetooth/#query-the-bluetooth-permission
-    fn permission_query(cx: *mut JSContext, promise: &Rc<Promise>,
-                        descriptor: &BluetoothPermissionDescriptor,
-                        status: &BluetoothPermissionResult) {
+    fn permission_query(
+        _cx: *mut JSContext,
+        promise: &Rc<Promise>,
+        descriptor: &BluetoothPermissionDescriptor,
+        status: &BluetoothPermissionResult,
+    ) {
         // Step 1: We are not using the `global` variable.
 
         // Step 2.
         status.set_state(get_descriptor_permission_state(status.get_query(), None));
 
         // Step 3.
         if let PermissionState::Denied = status.get_state() {
             status.set_devices(Vec::new());
-            return promise.resolve_native(cx, status);
+            return promise.resolve_native(status);
         }
 
         // Step 4.
         rooted_vec!(let mut matching_devices);
 
         // Step 5.
         let global = status.global();
         let allowed_devices = global.as_window().bluetooth_extra_permission_data().get_allowed_devices();
@@ -599,59 +602,62 @@ impl PermissionAlgorithm for Bluetooth {
             // Step 6.2.
             if let Some(ref filters) = descriptor.filters {
                 let mut scan_filters: Vec<BluetoothScanfilter> = Vec::new();
 
                 // Step 6.2.1.
                 for filter in filters {
                     match canonicalize_filter(&filter) {
                         Ok(f) => scan_filters.push(f),
-                        Err(error) => return promise.reject_error(cx, error),
+                        Err(error) => return promise.reject_error(error),
                     }
                 }
 
                 // Step 6.2.2.
                 // Instead of creating an internal slot we send an ipc message to the Bluetooth thread
                 // to check if one of the filters matches.
                 let (sender, receiver) = ipc::channel().unwrap();
                 status.get_bluetooth_thread()
                       .send(BluetoothRequest::MatchesFilter(device_id.clone(),
                                                             BluetoothScanfilterSequence::new(scan_filters),
                                                             sender)).unwrap();
 
                 match receiver.recv().unwrap() {
                     Ok(true) => (),
                     Ok(false) => continue,
-                    Err(error) => return promise.reject_error(cx, Error::from(error)),
+                    Err(error) => return promise.reject_error(Error::from(error)),
                 };
             }
 
             // Step 6.3.
             // TODO: Implement this correctly, not just using device ids here.
             // https://webbluetoothcg.github.io/web-bluetooth/#get-the-bluetoothdevice-representing
             if let Some(device) = device_map.get(&device_id) {
                 matching_devices.push(JS::from_ref(&**device));
             }
         }
 
         // Step 7.
         status.set_devices(matching_devices.drain(..).collect());
 
         // https://w3c.github.io/permissions/#dom-permissions-query
         // Step 7.
-        promise.resolve_native(cx, status);
+        promise.resolve_native(status);
     }
 
     // https://webbluetoothcg.github.io/web-bluetooth/#request-the-bluetooth-permission
-    fn permission_request(cx: *mut JSContext, promise: &Rc<Promise>,
-                          descriptor: &BluetoothPermissionDescriptor,