Merge mozilla-inbound to mozilla-central. a=merge
authorDorel Luca <dluca@mozilla.com>
Sat, 15 Sep 2018 12:46:59 +0300
changeset 492259 73a2f427e2fd
parent 492146 87ae93caad9b (current diff)
parent 492258 6807afe94107 (diff)
child 492260 e088bb62f286
child 492263 b03a3a18a407
child 492283 b747e4382671
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly mac
73a2f427e2fd / 64.0a1 / 20180915101434 / files
nightly linux32
nightly linux64
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly mac
Merge mozilla-inbound to mozilla-central. a=merge
build/moz.configure/toolchain.configure
devtools/client/webconsole/test/mochitest/browser_webconsole_closure_inspection.js
dom/base/nsDocument.cpp
dom/base/nsIDocument.h
gfx/thebes/gfxPlatform.cpp
mobile/android/branding/beta/res/mipmap-anydpi-v26/ic_launcher_round.xml
mobile/android/branding/beta/res/mipmap-hdpi/ic_launcher_round.png
mobile/android/branding/beta/res/mipmap-mdpi/ic_launcher.png
mobile/android/branding/beta/res/mipmap-mdpi/ic_launcher_round.png
mobile/android/branding/beta/res/mipmap-xhdpi/ic_launcher_round.png
mobile/android/branding/beta/res/mipmap-xxhdpi/ic_launcher_round.png
mobile/android/branding/beta/res/mipmap-xxxhdpi/ic_launcher_round.png
mobile/android/branding/nightly/res/mipmap-anydpi-v26/ic_launcher_round.xml
mobile/android/branding/nightly/res/mipmap-hdpi/ic_launcher_round.png
mobile/android/branding/nightly/res/mipmap-mdpi/ic_launcher.png
mobile/android/branding/nightly/res/mipmap-mdpi/ic_launcher_round.png
mobile/android/branding/nightly/res/mipmap-xhdpi/ic_launcher_round.png
mobile/android/branding/nightly/res/mipmap-xxhdpi/ic_launcher_round.png
mobile/android/branding/nightly/res/mipmap-xxxhdpi/ic_launcher_round.png
mobile/android/branding/official/res/mipmap-anydpi-v26/ic_launcher_round.xml
mobile/android/branding/official/res/mipmap-hdpi/ic_launcher_round.png
mobile/android/branding/official/res/mipmap-mdpi/ic_launcher.png
mobile/android/branding/official/res/mipmap-mdpi/ic_launcher_round.png
mobile/android/branding/official/res/mipmap-xhdpi/ic_launcher_round.png
mobile/android/branding/official/res/mipmap-xxhdpi/ic_launcher_round.png
mobile/android/branding/official/res/mipmap-xxxhdpi/ic_launcher_round.png
mobile/android/branding/unofficial/res/mipmap-anydpi-v26/ic_launcher_round.xml
mobile/android/branding/unofficial/res/mipmap-hdpi/ic_launcher_round.png
mobile/android/branding/unofficial/res/mipmap-mdpi/ic_launcher.png
mobile/android/branding/unofficial/res/mipmap-mdpi/ic_launcher_round.png
mobile/android/branding/unofficial/res/mipmap-xhdpi/ic_launcher_round.png
mobile/android/branding/unofficial/res/mipmap-xxhdpi/ic_launcher_round.png
mobile/android/branding/unofficial/res/mipmap-xxxhdpi/ic_launcher.png
mobile/android/branding/unofficial/res/mipmap-xxxhdpi/ic_launcher_round.png
python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
testing/web-platform/meta/css/css-contain/contain-layout-cell-001.html.ini
testing/web-platform/meta/css/css-contain/contain-layout-cell-002.html.ini
testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-layout-formatting-context-margin-001.html.ini
testing/web-platform/meta/feature-policy/experimental-features/intrinsicSize-with-responsive-images.tentative.https.sub.html.ini
testing/web-platform/meta/feature-policy/experimental-features/intrinsicSize-without-unsized-media.tentative.https.sub.html.ini
testing/web-platform/meta/feature-policy/experimental-features/unsized-image.tentative.https.sub.html.ini
testing/web-platform/meta/fullscreen/idlharness.window.js.ini
testing/web-platform/meta/web-locks/interfaces-serviceworker.tentative.https.html.ini
testing/web-platform/meta/web-locks/interfaces.tentative.https.any.js.ini
testing/web-platform/tests/css/css-contain/contain-layout-015.html
testing/web-platform/tests/css/css-contain/support/blue50wBy23h.png
testing/web-platform/tests/feature-policy/experimental-features/intrinsicSize-with-responsive-images.tentative.https.sub.html
testing/web-platform/tests/feature-policy/experimental-features/intrinsicSize-without-unsized-media.tentative.https.sub.html
testing/web-platform/tests/feature-policy/experimental-features/intrinsicsize-without-unsized-media.tentative.https.sub.html.headers
testing/web-platform/tests/feature-policy/experimental-features/unsized-image.tentative.https.sub.html
testing/web-platform/tests/feature-policy/experimental-features/unsized-image.tentative.https.sub.html.headers
testing/web-platform/tests/payment-request/MerchantValidationEvent/complete-method-manual.https.html
testing/web-platform/tests/tools/ci/ci_taskcluster.sh
testing/web-platform/tests/web-locks/interfaces-serviceworker.tentative.https.html
testing/web-platform/tests/web-locks/interfaces.idl
testing/web-platform/tests/web-locks/interfaces.tentative.https.any.js
testing/web-platform/tests/web-locks/resources/interfaces-serviceworker.js
toolkit/themes/windows/global/icons/Warning.png
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -275,28 +275,28 @@
       </method>
 
       <method name="_setPositionalAttributes">
         <body><![CDATA[
           let visibleTabs = this._getVisibleTabs();
           if (!visibleTabs.length) {
             return;
           }
-          let selectedIndex = visibleTabs.indexOf(this.selectedItem);
-
+          let selectedTab = this.selectedItem;
+          let selectedIndex = visibleTabs.indexOf(selectedTab);
           if (this._beforeSelectedTab) {
             this._beforeSelectedTab.removeAttribute("beforeselected-visible");
           }
 
-          if (this.selectedItem.closing || selectedIndex <= 0) {
+          if (selectedTab.closing || selectedIndex <= 0) {
             this._beforeSelectedTab = null;
           } else {
             let beforeSelectedTab = visibleTabs[selectedIndex - 1];
             let separatedByScrollButton = this.getAttribute("overflow") == "true" &&
-              beforeSelectedTab.pinned && !this.selectedItem.pinned;
+              beforeSelectedTab.pinned && !selectedTab.pinned;
             if (!separatedByScrollButton) {
               this._beforeSelectedTab = beforeSelectedTab;
               this._beforeSelectedTab.setAttribute("beforeselected-visible",
                                                    "true");
             }
           }
 
           if (this._firstTab)
--- a/browser/components/downloads/DownloadsViewUI.jsm
+++ b/browser/components/downloads/DownloadsViewUI.jsm
@@ -20,16 +20,58 @@ XPCOMUtils.defineLazyModuleGetters(this,
   Downloads: "resource://gre/modules/Downloads.jsm",
   DownloadUtils: "resource://gre/modules/DownloadUtils.jsm",
   DownloadsCommon: "resource:///modules/DownloadsCommon.jsm",
   FileUtils: "resource://gre/modules/FileUtils.jsm",
   OS: "resource://gre/modules/osfile.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
 });
 
+var gDownloadElementButtons = {
+  cancel: {
+    commandName: "downloadsCmd_cancel",
+    l10nId: "download-cancel",
+    descriptionL10nId: "download-cancel-description",
+    iconClass: "downloadIconCancel",
+  },
+  retry: {
+    commandName: "downloadsCmd_retry",
+    l10nId: "download-retry",
+    descriptionL10nId: "download-retry-description",
+    iconClass: "downloadIconRetry",
+  },
+  show: {
+    commandName: "downloadsCmd_show",
+    l10nId: "download-show",
+    descriptionL10nId: "download-show-description",
+    iconClass: "downloadIconShow",
+  },
+  subviewOpenOrRemoveFile: {
+    commandName: "downloadsCmd_showBlockedInfo",
+    l10nId: "download-open-or-remove-file",
+    descriptionL10nId: "download-show-more-information-description",
+    iconClass: "downloadIconSubviewArrow",
+  },
+  askOpenOrRemoveFile: {
+    commandName: "downloadsCmd_chooseOpen",
+    l10nId: "download-open-or-remove-file",
+    iconClass: "downloadIconShow",
+  },
+  askRemoveFileOrAllow: {
+    commandName: "downloadsCmd_chooseUnblock",
+    l10nId: "download-remove-file-or-allow",
+    iconClass: "downloadIconShow",
+  },
+  removeFile: {
+    commandName: "downloadsCmd_confirmBlock",
+    l10nId: "download-remove-file",
+    iconClass: "downloadIconCancel",
+  },
+};
+
 var DownloadsViewUI = {
   /**
    * Returns true if the given string is the name of a command that can be
    * handled by the Downloads user interface, including standard commands.
    */
   isCommandName(name) {
     return name.startsWith("cmd_") || name.startsWith("downloadsCmd_");
   },
@@ -69,16 +111,27 @@ this.DownloadsViewUI.DownloadElementShel
 
 this.DownloadsViewUI.DownloadElementShell.prototype = {
   /**
    * The richlistitem for the download, initialized by the derived object.
    */
   element: null,
 
   /**
+   * Returns a string from the downloads stringbundleset, which contains legacy
+   * strings that are loaded from DTD files instead of properties files. This
+   * won't be necessary once localization is converted to Fluent (bug 1452637).
+   */
+  string(l10nId) {
+    // These strings are not used often enough to require caching.
+    return this.element.ownerDocument.getElementById("downloadsStrings")
+                                     .getAttribute("string-" + l10nId);
+  },
+
+  /**
    * URI string for the file type icon displayed in the download element.
    */
   get image() {
     if (!this.download.target.path) {
       // Old history downloads may not have a target path.
       return "moz-icon://.unknown?size=32";
     }
 
@@ -140,27 +193,72 @@ this.DownloadsViewUI.DownloadElementShel
       this.__progressElement =
            this.element.ownerDocument.getAnonymousElementByAttribute(
                                          this.element, "anonid",
                                          "progressmeter");
     }
     return this.__progressElement;
   },
 
+  showButton(type) {
+    let { commandName, l10nId, descriptionL10nId,
+          iconClass } = gDownloadElementButtons[type];
+
+    this.buttonCommandName = commandName;
+    let labelAttribute = this.isPanel ? "buttonarialabel" : "buttontooltiptext";
+    this.element.setAttribute(labelAttribute, this.string(l10nId));
+    if (this.isPanel && descriptionL10nId) {
+      this.element.setAttribute("buttonHoverStatus",
+                                this.string(descriptionL10nId));
+    }
+    this.element.setAttribute("buttonclass", "downloadButton " + iconClass);
+    this.element.removeAttribute("buttonhidden");
+  },
+
+  hideButton() {
+    this.element.setAttribute("buttonhidden", "true");
+  },
+
   /**
    * Processes a major state change in the user interface, then proceeds with
    * the normal progress update. This function is not called for every progress
    * update in order to improve performance.
    */
   _updateState() {
     this.element.setAttribute("displayName", this.displayName);
     this.element.setAttribute("image", this.image);
     this.element.setAttribute("state",
                               DownloadsCommon.stateOfDownload(this.download));
 
+    // We have to check for download state properties in the specific order used
+    // here, which is the same used by stateOfDownload.
+    if (!this.download.stopped) {
+      this.showButton("cancel");
+    } else if (this.download.succeeded) {
+      // The button is updated in _updateProgress, since its presence also
+      // depends on state that doesn't trigger _updateState when it changes.
+    } else if (this.download.error) {
+      if (this.download.error.becauseBlockedByParentalControls) {
+        this.hideButton();
+      } else if (this.download.error.becauseBlockedByReputationCheck) {
+        // The button is updated in _updateProgress, since its presence also
+        // depends on state that doesn't trigger _updateState when it changes.
+      } else {
+        this.showButton("retry");
+      }
+    } else if (this.download.canceled) {
+      if (this.download.hasPartialData) {
+        this.showButton("cancel");
+      } else {
+        this.showButton("retry");
+      }
+    } else {
+      this.showButton("cancel");
+    }
+
     if (!this.download.succeeded && this.download.error &&
         this.download.error.becauseBlockedByReputationCheck) {
       this.element.setAttribute("verdict",
                                 this.download.error.reputationCheckVerdict);
     } else {
       this.element.removeAttribute("verdict");
     }
 
@@ -170,22 +268,44 @@ this.DownloadsViewUI.DownloadElementShel
     this._updateProgress();
   },
 
   /**
    * Updates the elements that change regularly for in-progress downloads,
    * namely the progress bar and the status line.
    */
   _updateProgress() {
+    // Handle major state changes that don't trigger _updateState. These states
+    // don't occur for in-progress downloads, thus performance is not affected.
     if (this.download.succeeded) {
-      // We only need to add or remove this attribute for succeeded downloads.
       if (this.download.target.exists) {
         this.element.setAttribute("exists", "true");
+        this.showButton("show");
       } else {
         this.element.removeAttribute("exists");
+        this.hideButton();
+      }
+    } else if (this.download.error &&
+               this.download.error.becauseBlockedByReputationCheck) {
+      if (!this.download.hasBlockedData) {
+        this.hideButton();
+      } else if (this.isPanel) {
+        this.showButton("subviewOpenOrRemoveFile");
+      } else {
+        switch (this.download.error.reputationCheckVerdict) {
+          case Downloads.Error.BLOCK_VERDICT_UNCOMMON:
+            this.showButton("askOpenOrRemoveFile");
+            break;
+          case Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED:
+            this.showButton("askRemoveFileOrAllow");
+            break;
+          default: // Assume Downloads.Error.BLOCK_VERDICT_MALWARE
+            this.showButton("removeFile");
+            break;
+        }
       }
     }
 
     // When a block is confirmed, the removal of blocked data will not trigger a
     // state change for the download, so this class must be updated here.
     this.element.classList.toggle("temporary-block",
                                   !!this.download.hasBlockedData);
 
@@ -207,19 +327,23 @@ this.DownloadsViewUI.DownloadElementShel
     // Dispatch the ValueChange event for accessibility, if possible.
     if (this._progressElement) {
       let event = this.element.ownerDocument.createEvent("Events");
       event.initEvent("ValueChange", true, true);
       this._progressElement.dispatchEvent(event);
     }
 
     let labels = this.statusLabels;
-    this.element.setAttribute("status", labels.status);
-    this.element.setAttribute("hoverStatus", labels.hoverStatus);
-    this.element.setAttribute("fullStatus", labels.fullStatus);
+    if (this.isPanel) {
+      this.element.setAttribute("status", labels.status);
+      this.element.setAttribute("hoverStatus", labels.hoverStatus);
+    } else {
+      this.element.setAttribute("status", labels.fullStatus);
+      this.element.setAttribute("fullStatus", labels.fullStatus);
+    }
   },
 
   lastEstimatedSecondsLeft: Infinity,
 
   /**
    * Returns the labels for the status of normal, full, and hovering cases. These
    * are returned by a single property because they are computed together.
    */
@@ -261,23 +385,27 @@ this.DownloadsViewUI.DownloadElementShel
       if (this.download.succeeded && !this.download.target.exists) {
         stateLabel = s.fileMovedOrMissing;
         hoverStatus = stateLabel;
       } else if (this.download.succeeded) {
         // For completed downloads, show the file size
         let sizeStrings = this.sizeStrings;
         stateLabel = sizeStrings.stateLabel;
         status = sizeStrings.status;
-        hoverStatus = status;
+        hoverStatus = this.string("download-open-file-description");
       } else if (this.download.canceled) {
         stateLabel = s.stateCanceled;
       } else if (this.download.error.becauseBlockedByParentalControls) {
         stateLabel = s.stateBlockedParentalControls;
       } else if (this.download.error.becauseBlockedByReputationCheck) {
         stateLabel = this.rawBlockedTitleAndDetails[0];
+        if (this.download.hasBlockedData) {
+          hoverStatus = this.string(
+            "download-show-more-information-description");
+        }
       } else {
         stateLabel = s.stateFailed;
       }
 
       let referrer = this.download.source.referrer || this.download.source.url;
       let [displayHost /* ,fullHost */] = DownloadUtils.getURIHost(referrer);
 
       let date = new Date(this.download.endTime);
@@ -424,16 +552,20 @@ this.DownloadsViewUI.DownloadElementShel
   },
 
   doCommand(aCommand) {
     if (DownloadsViewUI.isCommandName(aCommand)) {
       this[aCommand]();
     }
   },
 
+  onButton() {
+    this.doCommand(this.buttonCommandName);
+  },
+
   downloadsCmd_cancel() {
     // This is the correct way to avoid race conditions when cancelling.
     this.download.cancel().catch(() => {});
     this.download.removePartialData().catch(Cu.reportError);
   },
 
   downloadsCmd_confirmBlock() {
     this.download.confirmBlock().catch(Cu.reportError);
--- a/browser/components/downloads/content/allDownloadsView.js
+++ b/browser/components/downloads/content/allDownloadsView.js
@@ -177,18 +177,18 @@ HistoryDownloadElementShell.prototype = 
     }
   },
 };
 
 /**
  * Relays commands from the download.xml binding to the selected items.
  */
 const DownloadsView = {
-  onDownloadCommand(event, command) {
-    goDoCommand(command);
+  onDownloadButton(event) {
+    event.target.closest("richlistitem")._shell.onButton();
   },
 
   onDownloadClick() {},
 };
 
 /**
  * A Downloads Places View is a places view designed to show a places query
  * for history downloads alongside the session downloads.
--- a/browser/components/downloads/content/contentAreaDownloadsView.xul
+++ b/browser/components/downloads/content/contentAreaDownloadsView.xul
@@ -42,10 +42,11 @@
 
   <stack flex="1">
 #include downloadsRichListBox.inc.xul
     <description id="downloadsListEmptyDescription"
                  value="&downloadsListEmpty.label;"
                  mousethrough="always"/>
   </stack>
 #include downloadsCommands.inc.xul
+#include downloadsStrings.inc.xul
 #include downloadsContextMenu.inc.xul
 </window>
--- a/browser/components/downloads/content/download.xml
+++ b/browser/components/downloads/content/download.xml
@@ -43,75 +43,29 @@
                            xbl:inherits="value=displayName,tooltiptext=displayName"/>
           <xul:progressmeter anonid="progressmeter"
                              class="downloadProgress"
                              min="0"
                              max="100"
                              xbl:inherits="mode=progressmode,value=progress,paused=progresspaused"/>
           <xul:description class="downloadDetails downloadDetailsNormal"
                            crop="end"
-                           xbl:inherits="value=status"/>
+                           xbl:inherits="value=status,tooltiptext=fullStatus"/>
           <xul:description class="downloadDetails downloadDetailsHover"
                            crop="end"
                            xbl:inherits="value=hoverStatus"/>
-          <xul:description class="downloadDetails downloadDetailsFull"
-                           crop="end"
-                           xbl:inherits="value=fullStatus,tooltiptext=fullStatus"/>
-          <xul:description class="downloadDetails downloadOpenFile"
-                           crop="end"
-                           value="&openFile.label;"/>
-          <xul:description class="downloadDetails downloadShowMoreInfo"
+          <xul:description class="downloadDetails downloadDetailsButtonHover"
                            crop="end"
-                           value="&showMoreInformation.label;"/>
-          <xul:stack class="downloadButtonLabels">
-            <xul:description class="downloadDetails downloadShow"
-                             crop="end"
-#ifdef XP_MACOSX
-                             value="&cmd.showMac.label;"
-#else
-                             value="&cmd.show.label;"
-#endif
-                             />
-            <xul:description class="downloadDetails downloadCancel"
-                             crop="end"
-                             value="&cancelDownload.label;"/>
-            <xul:description class="downloadDetails downloadRetry"
-                             crop="end"
-                             value="&retryDownload.label;"/>
-          </xul:stack>
+                           xbl:inherits="value=buttonHoverStatus"/>
         </xul:vbox>
       </xul:hbox>
       <xul:toolbarseparator />
-      <xul:stack class="downloadButtonArea">
-        <xul:button class="downloadButton downloadCancel downloadIconCancel"
-                    tooltiptext="&cmd.cancel.label;"
-                    oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_cancel');"/>
-        <xul:button class="downloadButton downloadRetry downloadIconRetry"
-                    tooltiptext="&cmd.retry.label;"
-                    oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_retry');"/>
-        <xul:button class="downloadButton downloadShow downloadIconShow"
-#ifdef XP_MACOSX
-                    tooltiptext="&cmd.showMac.label;"
-#else
-                    tooltiptext="&cmd.show.label;"
-#endif
-                    oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_show');"/>
-        <xul:button class="downloadButton downloadConfirmBlock downloadIconCancel"
-                    tooltiptext="&cmd.removeFile.label;"
-                    oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_confirmBlock');"/>
-        <xul:button class="downloadButton downloadChooseUnblock downloadIconShow"
-                    tooltiptext="&cmd.chooseUnblock.label;"
-                    oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_chooseUnblock');"/>
-        <xul:button class="downloadButton downloadChooseOpen downloadIconShow"
-                    tooltiptext="&cmd.chooseOpen.label;"
-                    oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_chooseOpen');"/>
-        <xul:button class="downloadButton downloadShowBlockedInfo"
-                    tooltiptext="&cmd.chooseUnblock.label;"
-                    oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_showBlockedInfo');"/>
-      </xul:stack>
+      <xul:button class="downloadButton"
+                  xbl:inherits="class=buttonclass,aria-label=buttonarialabel,tooltiptext=buttontooltiptext"
+                  oncommand="DownloadsView.onDownloadButton(event);"/>
     </content>
   </binding>
 
   <binding id="download-subview-toolbarbutton"
            extends="chrome://global/content/bindings/button.xml#button-base">
     <content>
       <xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label,consumeanchor"/>
       <xul:vbox class="toolbarbutton-text" flex="1">
--- a/browser/components/downloads/content/downloads.css
+++ b/browser/components/downloads/content/downloads.css
@@ -8,21 +8,16 @@
   -moz-binding: url('chrome://browser/content/downloads/download.xml#download');
 }
 
 #downloadsListBox > richlistitem:not([selected]) button {
   /* Only focus buttons in the selected item. */
   -moz-user-focus: none;
 }
 
-#downloadsListBox > richlistitem.download-state[state="1"]:not([exists]) > .downloadButtonArea,
-#downloadsListBox > richlistitem.download-state[state="1"]:not([exists]) > toolbarseparator {
-  display: none;
-}
-
 #downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryProgress,
 #downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryDetails,
 #downloadsFooter:not([showingsummary]) #downloadsSummary {
   display: none;
 }
 
 #downloadsFooter[showingsummary] > stack:hover > #downloadsSummary,
 #downloadsFooter[showingsummary] > stack:not(:hover) > #downloadsFooterButtons {
@@ -60,16 +55,22 @@
 #downloadsRichListBox > richlistitem button {
   /* These buttons should never get focus, as that would "disable"
      the downloads view controller (it's only used when the richlistbox
      is focused). */
   -moz-user-focus: none;
 }
 
 /*** Visibility of controls inside download items ***/
+
+.download-state[buttonhidden] > toolbarseparator,
+.download-state[buttonhidden] > .downloadButton {
+  display: none;
+}
+
 .download-state:not(:-moz-any([state="6"], /* Blocked (parental) */
                               [state="8"], /* Blocked (dirty)    */
                               [state="9"]) /* Blocked (policy)   */)
                                            .downloadBlockedBadge,
 
 .download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
                               [state="5"], /* Starting (queued)  */
                               [state="0"], /* Downloading        */
@@ -118,100 +119,50 @@
                                            .downloadCommandsSeparator,
 .download-state[state="8"]:not(.temporary-block)
                                            .downloadCommandsSeparator
 
 {
   display: none;
 }
 
-/*** Visibility of download buttons ***/
+/*** Visibility of download button labels ***/
 
 .download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
                               [state="5"], /* Starting (queued)  */
                               [state="0"], /* Downloading        */
                               [state="4"]) /* Paused             */)
                                            .downloadCancel,
 
-/* Blocked (dirty) downloads that have not been confirmed and
-   have temporary data, for the Malware case. */
-.download-state:not(          [state="8"]  /* Blocked (dirty)    */)
-                                           .downloadConfirmBlock,
-.download-state[state="8"]:not(.temporary-block)
-                                           .downloadConfirmBlock,
-.download-state[state="8"].temporary-block:not([verdict="Malware"])
-                                           .downloadConfirmBlock,
-
-/* Blocked (dirty) downloads that have not been confirmed and
-   have temporary data, for the Potentially Unwanted case. */
-.download-state:not(          [state="8"]  /* Blocked (dirty)    */)
-                                           .downloadChooseUnblock,
-.download-state[state="8"]:not(.temporary-block)
-                                           .downloadChooseUnblock,
-.download-state[state="8"].temporary-block:not([verdict="PotentiallyUnwanted"])
-                                           .downloadChooseUnblock,
-
-/* Blocked (dirty) downloads that have not been confirmed and
-   have temporary data, for the Uncommon case. */
-.download-state:not(          [state="8"]  /* Blocked (dirty)    */)
-                                           .downloadChooseOpen,
-.download-state[state="8"]:not(.temporary-block)
-                                           .downloadChooseOpen,
-.download-state[state="8"].temporary-block:not([verdict="Uncommon"])
-                                           .downloadChooseOpen,
-
 .download-state:not(:-moz-any([state="2"], /* Failed             */
                               [state="3"]) /* Canceled           */)
                                            .downloadRetry,
 
 .download-state:not(          [state="1"]  /* Finished           */)
-                                           .downloadShow,
-
-.download-state:-moz-any(     [state="6"], /* Blocked (parental) */
-                              [state="7"], /* Scanning           */
-                              [state="9"]) /* Blocked (policy)   */
-                                           > toolbarseparator,
-
-/* The "show blocked info" button is shown only in the downloads panel. */
-.downloadShowBlockedInfo
+                                           .downloadShow
 {
   display: none;
 }
 
 /*** Downloads panel ***/
 
 #downloadsPanel[hasdownloads] #emptyDownloads,
 #downloadsPanel:not([hasdownloads]) #downloadsListBox {
   display: none;
 }
 
 /*** Downloads panel multiview (main view and blocked-downloads subview) ***/
 
-/* Hide all the usual buttons. */
-#downloadsPanel-mainView .download-state[state="8"] .downloadCancel,
-#downloadsPanel-mainView .download-state[state="8"] .downloadConfirmBlock,
-#downloadsPanel-mainView .download-state[state="8"] .downloadChooseUnblock,
-#downloadsPanel-mainView .download-state[state="8"] .downloadChooseOpen,
-#downloadsPanel-mainView .download-state[state="8"] .downloadRetry,
-#downloadsPanel-mainView .download-state[state="8"] .downloadShow {
-  display: none;
-}
-
 /* Make the panel wide enough to show the download list items without improperly
    truncating them. */
 #downloadsPanel-multiView > .panel-viewcontainer,
 #downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack {
   max-width: unset;
 }
 
-/* Show the "show blocked info" button. */
-#downloadsPanel-mainView .download-state[state="8"] .downloadShowBlockedInfo {
-  display: inline;
-}
-
 /* DownloadsSubview styles: */
 
 .subviewbutton.download {
   -moz-binding: url("chrome://browser/content/downloads/download.xml#download-subview-toolbarbutton");
 }
 
 /* Hide all status labels by default and selectively display one at a time,
    depending on the state of the Download. */
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -747,34 +747,16 @@ var DownloadsView = {
                                                 this.richListBox.itemCount - 1);
     }
     this._visibleViewItems.delete(download);
     this._itemsForElements.delete(element);
   },
 
   // User interface event functions
 
-  /**
-   * Helper function to do commands on a specific download item.
-   *
-   * @param aEvent
-   *        Event object for the event being handled.  If the event target is
-   *        not a richlistitem that represents a download, this function will
-   *        walk up the parent nodes until it finds a DOM node that is.
-   * @param aCommand
-   *        The command to be performed.
-   */
-  onDownloadCommand(aEvent, aCommand) {
-    let target = aEvent.target;
-    while (target.nodeName != "richlistitem") {
-      target = target.parentNode;
-    }
-    DownloadsView.itemForElement(target).doCommand(aCommand);
-  },
-
   onDownloadClick(aEvent) {
     // Handle primary clicks only, and exclude the action button.
     if (aEvent.button == 0 &&
         !aEvent.originalTarget.hasAttribute("oncommand")) {
       let target = aEvent.target;
       while (target.nodeName != "richlistitem") {
         target = target.parentNode;
       }
@@ -782,16 +764,21 @@ var DownloadsView = {
       if (download.hasBlockedData) {
         goDoCommand("downloadsCmd_showBlockedInfo");
       } else {
         goDoCommand("downloadsCmd_open");
       }
     }
   },
 
+  onDownloadButton(event) {
+    let target = event.target.closest("richlistitem");
+    DownloadsView.itemForElement(target).onButton();
+  },
+
   /**
    * Handles keypress events on a download item.
    */
   onDownloadKeyPress(aEvent) {
     // Pressing the key on buttons should not invoke the action because the
     // event has already been handled by the button itself.
     if (aEvent.originalTarget.hasAttribute("command") ||
         aEvent.originalTarget.hasAttribute("oncommand")) {
@@ -833,23 +820,16 @@ var DownloadsView = {
   },
 
   /**
    * Mouse listeners to handle selection on hover.
    */
   onDownloadMouseOver(aEvent) {
     if (aEvent.originalTarget.classList.contains("downloadButton")) {
       aEvent.target.classList.add("downloadHoveringButton");
-
-      let button = aEvent.originalTarget;
-      let tooltip = button.getAttribute("tooltiptext");
-      if (tooltip) {
-        button.setAttribute("aria-label", tooltip);
-        button.removeAttribute("tooltiptext");
-      }
     }
     if (!(this.contextMenuOpen || this.subViewOpen) &&
         aEvent.target.parentNode == this.richListBox) {
       this.richListBox.selectedItem = aEvent.target;
     }
   },
 
   onDownloadMouseOut(aEvent) {
@@ -933,16 +913,18 @@ function DownloadsViewItem(download, aEl
   this.download = download;
   this.downloadState = DownloadsCommon.stateOfDownload(download);
   this.element = aElement;
   this.element._shell = this;
 
   this.element.setAttribute("type", "download");
   this.element.classList.add("download-state");
 
+  this.isPanel = true;
+
   this._updateState();
 }
 
 DownloadsViewItem.prototype = {
   __proto__: DownloadsViewUI.DownloadElementShell.prototype,
 
   /**
    * The XUL element corresponding to the associated richlistbox item.
--- a/browser/components/downloads/content/downloadsPanel.inc.xul
+++ b/browser/components/downloads/content/downloadsPanel.inc.xul
@@ -1,12 +1,14 @@
 <!-- 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 downloadsStrings.inc.xul
+
 <commandset>
   <command id="downloadsCmd_doDefault"
            oncommand="goDoCommand('downloadsCmd_doDefault')"/>
   <command id="downloadsCmd_pauseResume"
            oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
   <command id="downloadsCmd_cancel"
            oncommand="goDoCommand('downloadsCmd_cancel')"/>
   <command id="downloadsCmd_unblock"
new file mode 100644
--- /dev/null
+++ b/browser/components/downloads/content/downloadsStrings.inc.xul
@@ -0,0 +1,21 @@
+# Don't add new strings here, use properties files instead. This file won't be
+# necessary anymore once localization is converted to Fluent (bug 1452637).
+
+<stringbundleset id="downloadsStrings"
+  string-download-cancel="&cmd.cancel.label;"
+  string-download-cancel-description="&cancelDownload.label;"
+  string-download-open-file-description="&openFile.label;"
+  string-download-open-or-remove-file="&cmd.chooseOpen.label;"
+  string-download-remove-file="&cmd.removeFile.label;"
+  string-download-remove-file-or-allow="&cmd.chooseUnblock.label;"
+  string-download-retry="&cmd.retry.label;"
+  string-download-retry-description="&retryDownload.label;"
+#ifdef XP_MACOSX
+  string-download-show="&cmd.showMac.label;"
+  string-download-show-description="&cmd.showMac.label;"
+#else
+  string-download-show="&cmd.show.label;"
+  string-download-show-description="&cmd.show.label;"
+#endif
+  string-download-show-more-information-description="&showMoreInformation.label;"
+/>
--- a/browser/components/downloads/jar.mn
+++ b/browser/components/downloads/jar.mn
@@ -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/.
 
 browser.jar:
-*       content/browser/downloads/download.xml           (content/download.xml)
+        content/browser/downloads/download.xml           (content/download.xml)
         content/browser/downloads/downloads.css          (content/downloads.css)
         content/browser/downloads/downloads.js           (content/downloads.js)
         content/browser/downloads/indicator.js           (content/indicator.js)
         content/browser/downloads/allDownloadsView.js    (content/allDownloadsView.js)
 *       content/browser/downloads/contentAreaDownloadsView.xul (content/contentAreaDownloadsView.xul)
         content/browser/downloads/contentAreaDownloadsView.js  (content/contentAreaDownloadsView.js)
         content/browser/downloads/contentAreaDownloadsView.css (content/contentAreaDownloadsView.css)
--- a/browser/components/places/content/places.xul
+++ b/browser/components/places/content/places.xul
@@ -90,16 +90,17 @@
     <command id="OrganizerCommand_search:moreCriteria"
              oncommand="PlacesQueryBuilder.addRow();"/>
     <command id="OrganizerCommand:Back"
              oncommand="PlacesOrganizer.back();"/>
     <command id="OrganizerCommand:Forward"
              oncommand="PlacesOrganizer.forward();"/>
   </commandset>
 #include ../../downloads/content/downloadsCommands.inc.xul
+#include ../../downloads/content/downloadsStrings.inc.xul
 
   <keyset id="placesOrganizerKeyset">
     <!-- Instantiation Keys -->
     <key id="placesKey_close" key="&cmd.close.key;" modifiers="accel"
          oncommand="close();"/>
 
     <!-- Command Keys -->
     <key id="placesKey_find:all"
--- a/browser/config/mozconfigs/linux64/nightly-asan
+++ b/browser/config/mozconfigs/linux64/nightly-asan
@@ -5,15 +5,19 @@ ac_add_options --enable-optimize="-O2 -g
 . $topsrcdir/build/mozconfig.stylo
 
 # ASan specific options on Linux
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.asan
 ac_add_options --disable-elf-hack
 
+# Piggybacking UBSan for now since only a small subset of checks are enabled.
+# A new build can be created when appropriate.
+ac_add_options --enable-undefined-sanitizer
+
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 # Need this to prevent name conflicts with the normal nightly build packages
 export MOZ_PKG_SPECIAL=asan
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/nightly-fuzzing-asan
+++ b/browser/config/mozconfigs/linux64/nightly-fuzzing-asan
@@ -13,15 +13,19 @@ ac_add_options "MOZ_ALLOW_LEGACY_EXTENSI
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.asan
 ac_add_options --disable-elf-hack
 
 ac_add_options --enable-fuzzing
 unset MOZ_STDCXX_COMPAT
 
+# Piggybacking UBSan for now since only a small subset of checks are enabled.
+# A new build can be created when appropriate.
+ac_add_options --enable-undefined-sanitizer
+
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 # Need this to prevent name conflicts with the normal nightly build packages
 export MOZ_PKG_SPECIAL=asan
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/tooltool-manifests/win32/releng.manifest
+++ b/browser/config/tooltool-manifests/win32/releng.manifest
@@ -1,21 +1,21 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "Visual Studio 2017 15.6.6 / SDK 10.0.15063.0",
-    "digest": "c2f0e618877da50f862e5b0ceb13a9affd86490d3779c2b1cb5ba75ea0156adad6df950d1ffbc053d725361fd04b2e57ab17ed5b7b57ffb7f7de2cd82d6edb72",
-    "size": 309779013,
+    "version": "Visual Studio 2017 15.8.4 / SDK 10.0.17134.0",
+    "digest": "ecf1e03f6f98f86775059a43f9e7dc7e326f6643d7c08962d9f614e4f5a65b1ca63fa1cfeb0f1a3c2474bf0d4318dda960b378beb2a44ecf8a91111207f4ece5",
+    "size": 349626009,
     "algorithm": "sha512",
-    "filename": "vs2017_15.6.6.zip",
+    "filename": "vs2017_15.8.4.zip",
     "unpack": true
   },
   {
     "version": "makecab rev d2bc6797648b7a834782714a55d339d2fd4e58c8",
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "makecab.tar.bz2",
     "unpack": true,
--- a/browser/config/tooltool-manifests/win64/releng.manifest
+++ b/browser/config/tooltool-manifests/win64/releng.manifest
@@ -1,21 +1,21 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "Visual Studio 2017 15.6.6 / SDK 10.0.15063.0",
-    "digest": "c2f0e618877da50f862e5b0ceb13a9affd86490d3779c2b1cb5ba75ea0156adad6df950d1ffbc053d725361fd04b2e57ab17ed5b7b57ffb7f7de2cd82d6edb72",
-    "size": 309779013,
+    "version": "Visual Studio 2017 15.8.4 / SDK 10.0.17134.0",
+    "digest": "ecf1e03f6f98f86775059a43f9e7dc7e326f6643d7c08962d9f614e4f5a65b1ca63fa1cfeb0f1a3c2474bf0d4318dda960b378beb2a44ecf8a91111207f4ece5",
+    "size": 349626009,
     "algorithm": "sha512",
-    "filename": "vs2017_15.6.6.zip",
+    "filename": "vs2017_15.8.4.zip",
     "unpack": true
   },
   {
     "version": "makecab rev d2bc6797648b7a834782714a55d339d2fd4e58c8",
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "makecab.tar.bz2",
     "unpack": true,
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 2.0.843
+Current extension version is: 2.0.854
 
-Taken from upstream commit: bf368f3a
+Taken from upstream commit: d0b5aa08
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.843';
-var pdfjsBuild = 'bf368f3a';
+var pdfjsVersion = '2.0.854';
+var pdfjsBuild = 'd0b5aa08';
 var pdfjsSharedUtil = __w_pdfjs_require__(1);
 var pdfjsDisplayAPI = __w_pdfjs_require__(7);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(19);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(20);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(8);
 var pdfjsDisplaySVG = __w_pdfjs_require__(21);
 let pdfjsDisplayWorkerOptions = __w_pdfjs_require__(13);
 let pdfjsDisplayAPICompatibility = __w_pdfjs_require__(10);
@@ -180,50 +180,51 @@ Object.defineProperty(exports, "__esModu
 exports.unreachable = exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.URL = exports.ReadableStream = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isSpace = exports.isString = exports.isNum = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.info = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.getInheritableProperty = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.FormatError = exports.XRefParseException = exports.toRomanNumerals = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.NativeImageDecoding = exports.MissingPDFException = exports.MissingDataException = exports.InvalidPDFException = exports.AbortException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VerbosityLevel = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
 
 __w_pdfjs_require__(2);
 
 var _streams_polyfill = __w_pdfjs_require__(4);
 
 var _url_polyfill = __w_pdfjs_require__(6);
 
-var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
+const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
+const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
 const NativeImageDecoding = {
   NONE: 'none',
   DECODE: 'decode',
   DISPLAY: 'display'
 };
 const PermissionFlag = {
   PRINT: 0x04,
   MODIFY_CONTENTS: 0x08,
   COPY: 0x10,
   MODIFY_ANNOTATIONS: 0x20,
   FILL_INTERACTIVE_FORMS: 0x100,
   COPY_FOR_ACCESSIBILITY: 0x200,
   ASSEMBLE: 0x400,
   PRINT_HIGH_QUALITY: 0x800
 };
-var TextRenderingMode = {
+const TextRenderingMode = {
   FILL: 0,
   STROKE: 1,
   FILL_STROKE: 2,
   INVISIBLE: 3,
   FILL_ADD_TO_PATH: 4,
   STROKE_ADD_TO_PATH: 5,
   FILL_STROKE_ADD_TO_PATH: 6,
   ADD_TO_PATH: 7,
   FILL_STROKE_MASK: 3,
   ADD_TO_PATH_FLAG: 4
 };
-var ImageKind = {
+const ImageKind = {
   GRAYSCALE_1BPP: 1,
   RGB_24BPP: 2,
   RGBA_32BPP: 3
 };
-var AnnotationType = {
+const AnnotationType = {
   TEXT: 1,
   LINK: 2,
   FREETEXT: 3,
   LINE: 4,
   SQUARE: 5,
   CIRCLE: 6,
   POLYGON: 7,
   POLYLINE: 8,
@@ -241,29 +242,29 @@ var AnnotationType = {
   WIDGET: 20,
   SCREEN: 21,
   PRINTERMARK: 22,
   TRAPNET: 23,
   WATERMARK: 24,
   THREED: 25,
   REDACT: 26
 };
-var AnnotationFlag = {
+const AnnotationFlag = {
   INVISIBLE: 0x01,
   HIDDEN: 0x02,
   PRINT: 0x04,
   NOZOOM: 0x08,
   NOROTATE: 0x10,
   NOVIEW: 0x20,
   READONLY: 0x40,
   LOCKED: 0x80,
   TOGGLENOVIEW: 0x100,
   LOCKEDCONTENTS: 0x200
 };
-var AnnotationFieldFlag = {
+const AnnotationFieldFlag = {
   READONLY: 0x0000001,
   REQUIRED: 0x0000002,
   NOEXPORT: 0x0000004,
   MULTILINE: 0x0001000,
   PASSWORD: 0x0002000,
   NOTOGGLETOOFF: 0x0004000,
   RADIO: 0x0008000,
   PUSHBUTTON: 0x0010000,
@@ -274,36 +275,36 @@ var AnnotationFieldFlag = {
   MULTISELECT: 0x0200000,
   DONOTSPELLCHECK: 0x0400000,
   DONOTSCROLL: 0x0800000,
   COMB: 0x1000000,
   RICHTEXT: 0x2000000,
   RADIOSINUNISON: 0x2000000,
   COMMITONSELCHANGE: 0x4000000
 };
-var AnnotationBorderStyleType = {
+const AnnotationBorderStyleType = {
   SOLID: 1,
   DASHED: 2,
   BEVELED: 3,
   INSET: 4,
   UNDERLINE: 5
 };
-var StreamType = {
+const StreamType = {
   UNKNOWN: 0,
   FLATE: 1,
   LZW: 2,
   DCT: 3,
   JPX: 4,
   JBIG: 5,
   A85: 6,
   AHX: 7,
   CCF: 8,
   RL: 9
 };
-var FontType = {
+const FontType = {
   UNKNOWN: 0,
   TYPE1: 1,
   TYPE1C: 2,
   CIDFONTTYPE0: 3,
   CIDFONTTYPE0C: 4,
   TRUETYPE: 5,
   CIDFONTTYPE2: 6,
   TYPE3: 7,
@@ -311,22 +312,22 @@ var FontType = {
   TYPE0: 9,
   MMTYPE1: 10
 };
 const VerbosityLevel = {
   ERRORS: 0,
   WARNINGS: 1,
   INFOS: 5
 };
-var CMapCompressionType = {
+const CMapCompressionType = {
   NONE: 0,
   BINARY: 1,
   STREAM: 2
 };
-var OPS = {
+const OPS = {
   dependency: 1,
   setLineWidth: 2,
   setLineCap: 3,
   setLineJoin: 4,
   setMiterLimit: 5,
   setDash: 6,
   setRenderingIntent: 7,
   setFlatness: 8,
@@ -409,16 +410,28 @@ var OPS = {
   paintImageXObject: 85,
   paintInlineImageXObject: 86,
   paintInlineImageXObjectGroup: 87,
   paintImageXObjectRepeat: 88,
   paintImageMaskXObjectRepeat: 89,
   paintSolidColorImageMask: 90,
   constructPath: 91
 };
+const UNSUPPORTED_FEATURES = {
+  unknown: 'unknown',
+  forms: 'forms',
+  javaScript: 'javaScript',
+  smask: 'smask',
+  shadingPattern: 'shadingPattern',
+  font: 'font'
+};
+const PasswordResponses = {
+  NEED_PASSWORD: 1,
+  INCORRECT_PASSWORD: 2
+};
 let verbosity = VerbosityLevel.WARNINGS;
 function setVerbosityLevel(level) {
   if (Number.isInteger(level)) {
     verbosity = level;
   }
 }
 function getVerbosityLevel() {
   return verbosity;
@@ -439,37 +452,29 @@ function deprecated(details) {
 function unreachable(msg) {
   throw new Error(msg);
 }
 function assert(cond, msg) {
   if (!cond) {
     unreachable(msg);
   }
 }
-var UNSUPPORTED_FEATURES = {
-  unknown: 'unknown',
-  forms: 'forms',
-  javaScript: 'javaScript',
-  smask: 'smask',
-  shadingPattern: 'shadingPattern',
-  font: 'font'
-};
 function isSameOrigin(baseUrl, otherUrl) {
   try {
     var base = new _url_polyfill.URL(baseUrl);
     if (!base.origin || base.origin === 'null') {
       return false;
     }
   } catch (e) {
     return false;
   }
   var other = new _url_polyfill.URL(otherUrl, base);
   return base.origin === other.origin;
 }
-function isValidProtocol(url) {
+function _isValidProtocol(url) {
   if (!url) {
     return false;
   }
   switch (url.protocol) {
     case 'http:':
     case 'https:':
     case 'ftp:':
     case 'mailto:':
@@ -480,17 +485,17 @@ function isValidProtocol(url) {
   }
 }
 function createValidAbsoluteUrl(url, baseUrl) {
   if (!url) {
     return null;
   }
   try {
     var absoluteUrl = baseUrl ? new _url_polyfill.URL(url, baseUrl) : new _url_polyfill.URL(url);
-    if (isValidProtocol(absoluteUrl)) {
+    if (_isValidProtocol(absoluteUrl)) {
       return absoluteUrl;
     }
   } catch (ex) {}
   return null;
 }
 function shadow(obj, prop, value) {
   Object.defineProperty(obj, prop, {
     value,
@@ -506,20 +511,16 @@ function getLookupTableFactory(initializ
     if (initializer) {
       lookup = Object.create(null);
       initializer(lookup);
       initializer = null;
     }
     return lookup;
   };
 }
-var PasswordResponses = {
-  NEED_PASSWORD: 1,
-  INCORRECT_PASSWORD: 2
-};
 var PasswordException = function PasswordExceptionClosure() {
   function PasswordException(msg, code) {
     this.name = 'PasswordException';
     this.message = msg;
     this.code = code;
   }
   PasswordException.prototype = new Error();
   PasswordException.constructor = PasswordException;
@@ -720,17 +721,16 @@ function getInheritableProperty({ dict, 
     if (++loopCount > LOOP_LIMIT) {
       warn(`getInheritableProperty: maximum loop count exceeded for "${key}"`);
       break;
     }
     dict = dict.get('Parent');
   }
   return values;
 }
-var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
 var Util = function UtilClosure() {
   function Util() {}
   var rgbBuf = ['rgb(', 0, ',', 0, ',', 0, ')'];
   Util.makeCssRgb = function Util_makeCssRgb(r, g, b) {
     rgbBuf[1] = r;
     rgbBuf[3] = g;
     rgbBuf[5] = b;
     return rgbBuf.join('');
@@ -826,17 +826,17 @@ function toRomanNumerals(number, lowerCa
   romanBuf.push(ROMAN_NUMBER_MAP[pos]);
   pos = number / 10 | 0;
   number %= 10;
   romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);
   romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
   const romanStr = romanBuf.join('');
   return lowerCase ? romanStr.toLowerCase() : romanStr;
 }
-var PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C, 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160, 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC];
+const PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C, 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160, 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC];
 function stringToPDFString(str) {
   var i,
       n = str.length,
       strBuf = [];
   if (str[0] === '\xFE' && str[1] === '\xFF') {
     for (i = 2; i < n; i += 2) {
       strBuf.push(String.fromCharCode(str.charCodeAt(i) << 8 | str.charCodeAt(i + 1)));
     }
@@ -4221,17 +4221,17 @@ function _fetchDocument(worker, source, 
     return Promise.reject(new Error('Worker was destroyed'));
   }
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
     docId,
-    apiVersion: '2.0.843',
+    apiVersion: '2.0.854',
     source: {
       data: source.data,
       url: source.url,
       password: source.password,
       disableAutoFetch: source.disableAutoFetch,
       rangeChunkSize: source.rangeChunkSize,
       length: source.length
     },
@@ -5548,18 +5548,18 @@ var InternalRenderTask = function Intern
         }
       });
     }
   };
   return InternalRenderTask;
 }();
 var version, build;
 {
-  exports.version = version = '2.0.843';
-  exports.build = build = 'bf368f3a';
+  exports.version = version = '2.0.854';
+  exports.build = build = 'd0b5aa08';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.843';
-var pdfjsBuild = 'bf368f3a';
+var pdfjsVersion = '2.0.854';
+var pdfjsBuild = 'd0b5aa08';
 var pdfjsCoreWorker = __w_pdfjs_require__(1);
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
@@ -322,17 +322,17 @@ var WorkerMessageHandler = {
     });
   },
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '2.0.843';
+    let workerVersion = '2.0.854';
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
     var handler = new _message_handler.MessageHandler(workerHandlerName, docId, port);
     handler.postMessageTransfers = docParams.postMessageTransfers;
@@ -721,50 +721,51 @@ Object.defineProperty(exports, "__esModu
 exports.unreachable = exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.URL = exports.ReadableStream = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isSpace = exports.isString = exports.isNum = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.info = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.getInheritableProperty = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.FormatError = exports.XRefParseException = exports.toRomanNumerals = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.NativeImageDecoding = exports.MissingPDFException = exports.MissingDataException = exports.InvalidPDFException = exports.AbortException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VerbosityLevel = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
 
 __w_pdfjs_require__(3);
 
 var _streams_polyfill = __w_pdfjs_require__(5);
 
 var _url_polyfill = __w_pdfjs_require__(7);
 
-var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
+const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
+const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
 const NativeImageDecoding = {
   NONE: 'none',
   DECODE: 'decode',
   DISPLAY: 'display'
 };
 const PermissionFlag = {
   PRINT: 0x04,
   MODIFY_CONTENTS: 0x08,
   COPY: 0x10,
   MODIFY_ANNOTATIONS: 0x20,
   FILL_INTERACTIVE_FORMS: 0x100,
   COPY_FOR_ACCESSIBILITY: 0x200,
   ASSEMBLE: 0x400,
   PRINT_HIGH_QUALITY: 0x800
 };
-var TextRenderingMode = {
+const TextRenderingMode = {
   FILL: 0,
   STROKE: 1,
   FILL_STROKE: 2,
   INVISIBLE: 3,
   FILL_ADD_TO_PATH: 4,
   STROKE_ADD_TO_PATH: 5,
   FILL_STROKE_ADD_TO_PATH: 6,
   ADD_TO_PATH: 7,
   FILL_STROKE_MASK: 3,
   ADD_TO_PATH_FLAG: 4
 };
-var ImageKind = {
+const ImageKind = {
   GRAYSCALE_1BPP: 1,
   RGB_24BPP: 2,
   RGBA_32BPP: 3
 };
-var AnnotationType = {
+const AnnotationType = {
   TEXT: 1,
   LINK: 2,
   FREETEXT: 3,
   LINE: 4,
   SQUARE: 5,
   CIRCLE: 6,
   POLYGON: 7,
   POLYLINE: 8,
@@ -782,29 +783,29 @@ var AnnotationType = {
   WIDGET: 20,
   SCREEN: 21,
   PRINTERMARK: 22,
   TRAPNET: 23,
   WATERMARK: 24,
   THREED: 25,
   REDACT: 26
 };
-var AnnotationFlag = {
+const AnnotationFlag = {
   INVISIBLE: 0x01,
   HIDDEN: 0x02,
   PRINT: 0x04,
   NOZOOM: 0x08,
   NOROTATE: 0x10,
   NOVIEW: 0x20,
   READONLY: 0x40,
   LOCKED: 0x80,
   TOGGLENOVIEW: 0x100,
   LOCKEDCONTENTS: 0x200
 };
-var AnnotationFieldFlag = {
+const AnnotationFieldFlag = {
   READONLY: 0x0000001,
   REQUIRED: 0x0000002,
   NOEXPORT: 0x0000004,
   MULTILINE: 0x0001000,
   PASSWORD: 0x0002000,
   NOTOGGLETOOFF: 0x0004000,
   RADIO: 0x0008000,
   PUSHBUTTON: 0x0010000,
@@ -815,36 +816,36 @@ var AnnotationFieldFlag = {
   MULTISELECT: 0x0200000,
   DONOTSPELLCHECK: 0x0400000,
   DONOTSCROLL: 0x0800000,
   COMB: 0x1000000,
   RICHTEXT: 0x2000000,
   RADIOSINUNISON: 0x2000000,
   COMMITONSELCHANGE: 0x4000000
 };
-var AnnotationBorderStyleType = {
+const AnnotationBorderStyleType = {
   SOLID: 1,
   DASHED: 2,
   BEVELED: 3,
   INSET: 4,
   UNDERLINE: 5
 };
-var StreamType = {
+const StreamType = {
   UNKNOWN: 0,
   FLATE: 1,
   LZW: 2,
   DCT: 3,
   JPX: 4,
   JBIG: 5,
   A85: 6,
   AHX: 7,
   CCF: 8,
   RL: 9
 };
-var FontType = {
+const FontType = {
   UNKNOWN: 0,
   TYPE1: 1,
   TYPE1C: 2,
   CIDFONTTYPE0: 3,
   CIDFONTTYPE0C: 4,
   TRUETYPE: 5,
   CIDFONTTYPE2: 6,
   TYPE3: 7,
@@ -852,22 +853,22 @@ var FontType = {
   TYPE0: 9,
   MMTYPE1: 10
 };
 const VerbosityLevel = {
   ERRORS: 0,
   WARNINGS: 1,
   INFOS: 5
 };
-var CMapCompressionType = {
+const CMapCompressionType = {
   NONE: 0,
   BINARY: 1,
   STREAM: 2
 };
-var OPS = {
+const OPS = {
   dependency: 1,
   setLineWidth: 2,
   setLineCap: 3,
   setLineJoin: 4,
   setMiterLimit: 5,
   setDash: 6,
   setRenderingIntent: 7,
   setFlatness: 8,
@@ -950,16 +951,28 @@ var OPS = {
   paintImageXObject: 85,
   paintInlineImageXObject: 86,
   paintInlineImageXObjectGroup: 87,
   paintImageXObjectRepeat: 88,
   paintImageMaskXObjectRepeat: 89,
   paintSolidColorImageMask: 90,
   constructPath: 91
 };
+const UNSUPPORTED_FEATURES = {
+  unknown: 'unknown',
+  forms: 'forms',
+  javaScript: 'javaScript',
+  smask: 'smask',
+  shadingPattern: 'shadingPattern',
+  font: 'font'
+};
+const PasswordResponses = {
+  NEED_PASSWORD: 1,
+  INCORRECT_PASSWORD: 2
+};
 let verbosity = VerbosityLevel.WARNINGS;
 function setVerbosityLevel(level) {
   if (Number.isInteger(level)) {
     verbosity = level;
   }
 }
 function getVerbosityLevel() {
   return verbosity;
@@ -980,37 +993,29 @@ function deprecated(details) {
 function unreachable(msg) {
   throw new Error(msg);
 }
 function assert(cond, msg) {
   if (!cond) {
     unreachable(msg);
   }
 }
-var UNSUPPORTED_FEATURES = {
-  unknown: 'unknown',
-  forms: 'forms',
-  javaScript: 'javaScript',
-  smask: 'smask',
-  shadingPattern: 'shadingPattern',
-  font: 'font'
-};
 function isSameOrigin(baseUrl, otherUrl) {
   try {
     var base = new _url_polyfill.URL(baseUrl);
     if (!base.origin || base.origin === 'null') {
       return false;
     }
   } catch (e) {
     return false;
   }
   var other = new _url_polyfill.URL(otherUrl, base);
   return base.origin === other.origin;
 }
-function isValidProtocol(url) {
+function _isValidProtocol(url) {
   if (!url) {
     return false;
   }
   switch (url.protocol) {
     case 'http:':
     case 'https:':
     case 'ftp:':
     case 'mailto:':
@@ -1021,17 +1026,17 @@ function isValidProtocol(url) {
   }
 }
 function createValidAbsoluteUrl(url, baseUrl) {
   if (!url) {
     return null;
   }
   try {
     var absoluteUrl = baseUrl ? new _url_polyfill.URL(url, baseUrl) : new _url_polyfill.URL(url);
-    if (isValidProtocol(absoluteUrl)) {
+    if (_isValidProtocol(absoluteUrl)) {
       return absoluteUrl;
     }
   } catch (ex) {}
   return null;
 }
 function shadow(obj, prop, value) {
   Object.defineProperty(obj, prop, {
     value,
@@ -1047,20 +1052,16 @@ function getLookupTableFactory(initializ
     if (initializer) {
       lookup = Object.create(null);
       initializer(lookup);
       initializer = null;
     }
     return lookup;
   };
 }
-var PasswordResponses = {
-  NEED_PASSWORD: 1,
-  INCORRECT_PASSWORD: 2
-};
 var PasswordException = function PasswordExceptionClosure() {
   function PasswordException(msg, code) {
     this.name = 'PasswordException';
     this.message = msg;
     this.code = code;
   }
   PasswordException.prototype = new Error();
   PasswordException.constructor = PasswordException;
@@ -1261,17 +1262,16 @@ function getInheritableProperty({ dict, 
     if (++loopCount > LOOP_LIMIT) {
       warn(`getInheritableProperty: maximum loop count exceeded for "${key}"`);
       break;
     }
     dict = dict.get('Parent');
   }
   return values;
 }
-var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
 var Util = function UtilClosure() {
   function Util() {}
   var rgbBuf = ['rgb(', 0, ',', 0, ',', 0, ')'];
   Util.makeCssRgb = function Util_makeCssRgb(r, g, b) {
     rgbBuf[1] = r;
     rgbBuf[3] = g;
     rgbBuf[5] = b;
     return rgbBuf.join('');
@@ -1367,17 +1367,17 @@ function toRomanNumerals(number, lowerCa
   romanBuf.push(ROMAN_NUMBER_MAP[pos]);
   pos = number / 10 | 0;
   number %= 10;
   romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);
   romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
   const romanStr = romanBuf.join('');
   return lowerCase ? romanStr.toLowerCase() : romanStr;
 }
-var PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C, 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160, 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC];
+const PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C, 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160, 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC];
 function stringToPDFString(str) {
   var i,
       n = str.length,
       strBuf = [];
   if (str[0] === '\xFE' && str[1] === '\xFF') {
     for (i = 2; i < n; i += 2) {
       strBuf.push(String.fromCharCode(str.charCodeAt(i) << 8 | str.charCodeAt(i + 1)));
     }
@@ -13316,17 +13316,17 @@ var JpegImage = function JpegImageClosur
           index = blocksPerScanline * (j & mask3LSB) | (j & 7) << 3;
           for (x = 0; x < width; x++) {
             data[offset] = output[index + xScaleBlockOffset[x]];
             offset += numComponents;
           }
         }
       }
       let transform = this._decodeTransform;
-      if (!transform && numComponents === 4 && !isSourcePDF) {
+      if (!isSourcePDF && numComponents === 4 && !transform) {
         transform = new Int32Array([-256, 255, -256, 255, -256, 255, -256, 255]);
       }
       if (transform) {
         for (i = 0; i < dataLength;) {
           for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {
             data[i] = (data[i] * transform[k] >> 8) + transform[k + 1];
           }
         }
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -4095,25 +4095,30 @@ class PDFFindBar {
       this._adjustWidth();
     });
     this.updateResultsCount(matchesCount);
   }
   updateResultsCount({ current = 0, total = 0 } = {}) {
     if (!this.findResultsCount) {
       return;
     }
-    let matchesCountMsg = '';
+    let matchesCountMsg = '',
+        limit = MATCHES_COUNT_LIMIT;
     if (total) {
-      if (total > MATCHES_COUNT_LIMIT) {
-        matchesCountMsg = this.l10n.get('find_matches_count_limit', { limit: MATCHES_COUNT_LIMIT.toLocaleString() }, 'More than {{limit}} matches');
+      if (total > limit) {
+        matchesCountMsg = this.l10n.get('find_matches_count_limit', {
+          n: limit,
+          limit: limit.toLocaleString()
+        }, 'More than {{limit}} match' + (limit !== 1 ? 'es' : ''));
       } else {
         matchesCountMsg = this.l10n.get('find_matches_count', {
+          n: total,
           current: current.toLocaleString(),
           total: total.toLocaleString()
-        }, '{{current}} of {{total}} matches');
+        }, '{{current}} of {{total}} match' + (total !== 1 ? 'es' : ''));
       }
     }
     Promise.resolve(matchesCountMsg).then(msg => {
       this.findResultsCount.textContent = msg;
       this.findResultsCount.classList[!total ? 'add' : 'remove']('hidden');
       this._adjustWidth();
     });
   }
@@ -4539,26 +4544,30 @@ class PDFFindController {
     }
     this._updateUIState(state, this.state.findPrevious);
     if (this.selected.pageIdx !== -1) {
       this._updatePage(this.selected.pageIdx);
     }
   }
   _requestMatchesCount() {
     const { pageIdx, matchIdx } = this.selected;
-    let current = 0;
+    let current = 0,
+        total = this.matchesCountTotal;
     if (matchIdx !== -1) {
       for (let i = 0; i < pageIdx; i++) {
         current += this.pageMatches[i] && this.pageMatches[i].length || 0;
       }
       current += matchIdx + 1;
     }
+    if (current > total) {
+      current = total = 0;
+    }
     return {
       current,
-      total: this.matchesCountTotal
+      total
     };
   }
   _updateUIResultsCount() {
     if (!this.onUpdateResultsCount) {
       return;
     }
     const matchesCount = this._requestMatchesCount();
     this.onUpdateResultsCount(matchesCount);
--- a/browser/extensions/pdfjs/moz.yaml
+++ b/browser/extensions/pdfjs/moz.yaml
@@ -15,15 +15,15 @@ origin:
   description: Portable Document Format (PDF) viewer that is built with HTML5
 
   # Full URL for the package's homepage/etc
   # Usually different from repository url
   url: https://github.com/mozilla/pdf.js
 
   # Human-readable identifier for this version/release
   # Generally "version NNN", "tag SSS", "bookmark SSS"
-  release: version 2.0.843
+  release: version 2.0.854
 
   # The package's license, where possible using the mnemonic from
   # https://spdx.org/licenses/
   # Multiple licenses can be specified (as a YAML list)
   # A "LICENSE" file must exist containing the full license text
   license: Apache-2.0
--- a/browser/locales/en-US/pdfviewer/viewer.properties
+++ b/browser/locales/en-US/pdfviewer/viewer.properties
@@ -163,23 +163,30 @@ find_previous.title=Find the previous oc
 find_previous_label=Previous
 find_next.title=Find the next occurrence of the phrase
 find_next_label=Next
 find_highlight=Highlight all
 find_match_case_label=Match case
 find_entire_word_label=Whole words
 find_reached_top=Reached top of document, continued from bottom
 find_reached_bottom=Reached end of document, continued from top
-# LOCALIZATION NOTE (find_matches_count): "{{current}}" and "{{total}}" will be
-# replaced by a number representing the index of the currently active find result,
-# respectively a number representing the total number of matches in the document.
-find_matches_count={{current}} of {{total}} matches
-# LOCALIZATION NOTE (find_matches_count_limit): "{{limit}}" will be replaced by
-# a numerical value.
-find_matches_count_limit=More than {{limit}} matches
+# LOCALIZATION NOTE (find_matches_count): The supported plural forms are
+# [zero|one|two|few|many|other], with [other] as the default value.
+# "{{current}}" and "{{total}}" will be replaced by a number representing the
+# index of the currently active find result, respectively a number representing
+# the total number of matches in the document.
+find_matches_count={[ plural(n) ]}
+find_matches_count[one]={{current}} of {{total}} match
+find_matches_count[other]={{current}} of {{total}} matches
+# LOCALIZATION NOTE (find_matches_count_limit): The supported plural forms are
+# [zero|one|two|few|many|other], with [other] as the default value.
+# "{{limit}}" will be replaced by a numerical value.
+find_matches_count_limit={[ plural(n) ]}
+find_matches_count_limit[one]=More than {{limit}} match
+find_matches_count_limit[other]=More than {{limit}} matches
 find_not_found=Phrase not found
 
 # Error panel labels
 error_more_info=More Information
 error_less_info=Less Information
 error_close=Close
 # LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be
 # replaced by the PDF.JS version and build ID.
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -480,25 +480,19 @@ html|input.urlbar-input {
 #editBMPanel_folderMenuList[open="true"],
 #editBMPanel_folderMenuList:hover:active {
   @hudButtonPressed@
 }
 
 #editBMPanel_folderMenuList > .menulist-dropmarker {
   -moz-appearance: none;
   display: -moz-box;
-  background-color: transparent;
-  border: 0;
-  margin: 0;
-  padding: 0;
+  -moz-box-align: center;
   padding-inline-end: 4px;
   width: 7px;
-}
-
-#editBMPanel_folderMenuList > .menulist-dropmarker > .dropmarker-icon {
   list-style-image: url("chrome://global/skin/icons/panel-dropmarker.png");
 }
 
 /**** folder tree and tag selector ****/
 
 #editBMPanel_folderTree,
 #editBMPanel_tagsSelector {
   -moz-appearance: none;
--- a/browser/themes/shared/downloads/allDownloadsView.inc.css
+++ b/browser/themes/shared/downloads/allDownloadsView.inc.css
@@ -55,21 +55,18 @@
 .downloadDetails {
   opacity: 0.7;
   font-size: 95%;
   /* Use calc() to keep the height consistent with .downloadTarget, so that the
      progress bar can be vertically centered. */
   margin: 4px 0 calc(1em / 0.95 - 1em);
 }
 
-.downloadDetailsNormal,
 .downloadDetailsHover,
-.downloadOpenFile,
-.downloadShowMoreInfo,
-.downloadButtonLabels {
+.downloadDetailsButtonHover {
   display: none;
 }
 
 .downloadButton {
   -moz-appearance: none;
   -moz-box-align: center;
   background: transparent;
   min-width: 0;
@@ -102,22 +99,22 @@
   color: -moz-field;
   border-radius: 50%;
 }
 
 .downloadButton:hover:active > .button-box {
   background-color: -moz-fieldtext;
 }
 
-@itemFocused@ > .downloadButtonArea > .downloadButton:hover > .button-box {
+@itemFocused@ > .downloadButton:hover > .button-box {
   background-color: HighlightText;
   color: Highlight;
 }
 
-@itemFocused@ > .downloadButtonArea > .downloadButton:hover:active > .button-box {
+@itemFocused@ > .downloadButton:hover:active > .button-box {
   background-color: -moz-field;
   color: -moz-fieldtext;
 }
 
 /*** Button icons ***/
 
 .downloadIconCancel > .button-box > .button-icon {
   list-style-image: url("chrome://browser/skin/panel-icon-cancel.svg");
--- a/browser/themes/shared/downloads/downloads.inc.css
+++ b/browser/themes/shared/downloads/downloads.inc.css
@@ -177,55 +177,27 @@
 #downloadsSummaryDetails,
 .downloadDetails {
   opacity: var(--downloads-item-details-opacity);
   /* Use calc() to keep the height consistent with .downloadTarget, so that the
      progress bar can be vertically centered. */
   margin: 4px 0 calc(1em / var(--downloads-item-font-size-factor) - 1em);
 }
 
-/* The following rules control which message is shown under the name of the
-   download, using a set of elements that share the class ".downloadDetails".
-   At any given time, only one of these elements is displayed. We use a set of
-   rules to hide the elements that shouldn't be displayed in each case. */
-
-/* The full status message is only displayed in the Downloads View. */
-.downloadDetailsFull {
-  display: none;
-}
-
 /* When hovering the mouse pointer over the item, instead of the normal message
    we display a more detailed one. */
 @item@:hover > .downloadMainArea > .downloadContainer > .downloadDetailsNormal,
 @item@:not(:hover) > .downloadMainArea > .downloadContainer > .downloadDetailsHover {
   display: none;
 }
 
 /* When hovering the action button in particular, instead of the usual hover
    message we display the command associated with the button. */
 @item@.downloadHoveringButton > .downloadMainArea > .downloadContainer > .downloadDetailsHover,
-@item@:not(.downloadHoveringButton) > .downloadMainArea > .downloadContainer > .downloadButtonLabels {
-  display: none;
-}
-
-/* When hovering the main area of a finished download whose target exists,
-   instead of the usual hover message we display the "Open File" command. */
-@itemFinished@[exists] > .downloadMainArea:hover > .downloadContainer > .downloadDetailsHover,
-@itemNotFinished@ > .downloadMainArea > .downloadContainer > .downloadOpenFile,
-@item@:not([exists]) > .downloadMainArea > .downloadContainer > .downloadOpenFile,
-.downloadMainArea:not(:hover) > .downloadContainer > .downloadOpenFile {
-  display: none;
-}
-
-/* When hovering items blocked by Application Reputation, instead of the other
-   hover messages we display the "Show more information" label. */
-@item@[verdict] > .downloadMainArea > .downloadContainer > .downloadDetailsHover,
-@item@[verdict] > .downloadMainArea > .downloadContainer > .downloadButtonLabels,
-@item@:not([verdict]) > .downloadMainArea > .downloadContainer > .downloadShowMoreInfo,
-@item@:not(:hover) > .downloadMainArea > .downloadContainer > .downloadShowMoreInfo {
+@item@:not(.downloadHoveringButton) > .downloadMainArea > .downloadContainer > .downloadDetailsButtonHover {
   display: none;
 }
 
 @item@[verdict] > toolbarseparator {
   visibility: hidden;
 }
 
 .downloadButton {
@@ -247,23 +219,23 @@
 }
 
 .downloadButton > .button-box > .button-text {
   margin: 0 !important;
   padding: 0;
 }
 
 @itemFinished@[exists] .downloadMainArea:hover,
-@item@:not([verdict]) > .downloadButtonArea:hover,
+@item@:not([verdict]) > .downloadButton:hover,
 @item@[verdict]:hover {
   background-color: var(--arrowpanel-dimmed);
 }
 
 @itemFinished@[exists] > .downloadMainArea:hover:active,
-@item@:not([verdict]) > .downloadButtonArea:hover:active,
+@item@:not([verdict]) > .downloadButton:hover:active,
 @item@[verdict]:hover:active {
   background-color: var(--arrowpanel-dimmed-further);
 }
 
 @item@[verdict="Malware"]:hover,
 @item@[verdict="Malware"]:hover:active {
   background-color: #aa1b08;
   color: white;
@@ -282,21 +254,21 @@
   list-style-image: url("chrome://browser/skin/panel-icon-folder.svg");
 %endif
 }
 
 .downloadIconRetry > .button-box > .button-icon {
   list-style-image: url("chrome://browser/skin/panel-icon-retry.svg");
 }
 
-.downloadShowBlockedInfo > .button-box > .button-icon {
+.downloadIconSubviewArrow > .button-box > .button-icon {
   list-style-image: url("chrome://browser/skin/panel-icon-arrow-right.svg");
 }
 
-.downloadShowBlockedInfo > .button-box > .button-icon:-moz-locale-dir(rtl) {
+.downloadIconSubviewArrow > .button-box > .button-icon:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://browser/skin/panel-icon-arrow-left.svg");
 }
 
 /*** Blocked subview ***/
 
 #downloadsPanel-blockedSubview > .panel-view-body-unscrollable {
   background-image: url("chrome://browser/skin/warning.svg");
   background-size: 32px 32px;
--- a/build/autoconf/frameptr.m4
+++ b/build/autoconf/frameptr.m4
@@ -32,15 +32,16 @@ AC_DEFUN([MOZ_SET_FRAMEPTR_FLAGS], [
   # If we are debugging, profiling, using sanitizers, or on win32 we want a
   # frame pointer.  It is not required to enable frame pointers on AArch64
   # Windows, but we enable it for compatibility with ETW.
   if test -z "$MOZ_OPTIMIZE" -o \
           -n "$MOZ_PROFILING" -o \
           -n "$MOZ_DEBUG" -o \
           -n "$MOZ_MSAN" -o \
           -n "$MOZ_ASAN" -o \
+          -n "$MOZ_UBSAN" -o \
           "$OS_ARCH:$CPU_ARCH" = "WINNT:x86" -o \
 	  "$OS_ARCH:$CPU_ARCH" = "WINNT:aarch64"; then
     MOZ_FRAMEPTR_FLAGS="$MOZ_ENABLE_FRAME_PTR"
   else
     MOZ_FRAMEPTR_FLAGS="$MOZ_DISABLE_FRAME_PTR"
   fi
 ])
--- a/build/autoconf/sanitize.m4
+++ b/build/autoconf/sanitize.m4
@@ -69,16 +69,34 @@ if test -n "$MOZ_TSAN"; then
         LDFLAGS="-fsanitize=thread -rdynamic $LDFLAGS"
     fi
     AC_DEFINE(MOZ_TSAN)
     MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
 fi
 AC_SUBST(MOZ_TSAN)
 
 dnl ========================================================
+dnl = Use UndefinedBehavior Sanitizer (with custom checks)
+dnl ========================================================
+if test -n "$MOZ_UBSAN_CHECKS"; then
+    MOZ_UBSAN=1
+    UBSAN_TXT="$_objdir/ubsan_blacklist.txt"
+    cat $_topsrcdir/build/sanitizers/ubsan_*_blacklist.txt > $UBSAN_TXT
+    UBSAN_FLAGS="-fsanitize=$MOZ_UBSAN_CHECKS -fno-sanitize-recover=$MOZ_UBSAN_CHECKS -fsanitize-blacklist=$UBSAN_TXT"
+    CFLAGS="$UBSAN_FLAGS $CFLAGS"
+    CXXFLAGS="$UBSAN_FLAGS $CXXFLAGS"
+    if test -z "$CLANG_CL"; then
+        LDFLAGS="-fsanitize=undefined -rdynamic $LDFLAGS"
+    fi
+    AC_DEFINE(MOZ_UBSAN)
+    MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
+fi
+AC_SUBST(MOZ_UBSAN)
+
+dnl ========================================================
 dnl = Use UndefinedBehavior Sanitizer to find integer overflows
 dnl ========================================================
 
 MOZ_ARG_ENABLE_BOOL(signed-overflow-sanitizer,
 [  --enable-signed-overflow-sanitizer       Enable UndefinedBehavior Sanitizer (Signed Integer Overflow Parts, default=no)],
    MOZ_SIGNED_OVERFLOW_SANITIZE=1,
    MOZ_SIGNED_OVERFLOW_SANITIZE= )
 MOZ_ARG_ENABLE_BOOL(unsigned-overflow-sanitizer,
--- a/build/docs/toolchains.rst
+++ b/build/docs/toolchains.rst
@@ -46,17 +46,17 @@ 2. Select ``Programming Languages`` -> `
 3. Under ``Windows and Web Development`` uncheck everything except
    ``Universal Windows App Development Tools`` and the items under it
    (should be ``Tools (1.3.1)...`` and the ``Windows 10 SDK``).
 
 Once Visual Studio 2017 Community has been installed, from a checkout
 of mozilla-central, run something like the following to produce a ZIP
 archive::
 
-   $ ./mach python build/windows_toolchain.py create-zip vs2017_15.6.0
+   $ ./mach python build/windows_toolchain.py create-zip vs2017_15.8.4
 
 The produced archive will be the argument to ``create-zip`` + ``.zip``.
 
 Firefox for Android with Gradle
 ===============================
 
 To build Firefox for Android with Gradle in automation, archives
 containing both the Gradle executable and a Maven repository
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -212,18 +212,18 @@ set_config('XCODE_PATH', xcode_path)
 # ==============================================================
 # Normally, we'd use js_option and automatically have those variables
 # propagated to js/src, but things are complicated by possible additional
 # wrappers in CC/CXX, and by other subconfigures that do not handle those
 # options and do need CC/CXX altered.
 option('--with-compiler-wrapper', env='COMPILER_WRAPPER', nargs=1,
        help='Enable compiling with wrappers such as distcc and ccache')
 
-option('--with-ccache', env='CCACHE', nargs='?',
-       help='Enable compiling with ccache')
+js_option('--with-ccache', env='CCACHE', nargs='?',
+          help='Enable compiling with ccache')
 
 
 @depends_if('--with-ccache')
 def ccache(value):
     if len(value):
         return value
     # If --with-ccache was given without an explicit value, we default to
     # 'ccache'.
@@ -527,18 +527,18 @@ def check_compiler(compiler, language, t
     if info.language == 'C++':
         if info.type == 'clang' and info.language_version != cxx14_version:
             append_flag('-std=gnu++14')
         # MSVC headers include C++14 features, but don't guard them
         # with appropriate checks.
         elif info.type == 'clang-cl' and info.language_version != cxx14_version:
             append_flag('-std=c++14')
 
-    # We force clang-cl to emulate Visual C++ 2017 version 15.6.0
-    msvc_version = '19.13.26128'
+    # We force clang-cl to emulate Visual C++ 2017 version 15.8.4
+    msvc_version = '19.15.26726'
     if info.type == 'clang-cl' and info.version != msvc_version:
         # This flag is a direct clang-cl flag that doesn't need -Xclang,
         # add it directly.
         flags.append('-fms-compatibility-version=%s' % msvc_version)
 
     # Check compiler target
     # --------------------------------------------------------------------
     if not info.cpu or info.cpu != target.cpu:
@@ -1278,16 +1278,42 @@ def wrap_system_includes(target, visibil
 set_define('HAVE_VISIBILITY_HIDDEN_ATTRIBUTE',
            depends(visibility_flags)(lambda v: bool(v) or None))
 set_define('HAVE_VISIBILITY_ATTRIBUTE',
            depends(visibility_flags)(lambda v: bool(v) or None))
 set_config('WRAP_SYSTEM_INCLUDES', wrap_system_includes)
 set_config('VISIBILITY_FLAGS', visibility_flags)
 
 
+@depends(c_compiler, using_sccache)
+def depend_cflags(info, using_sccache):
+    if info.type not in ('clang-cl', 'msvc'):
+        return ['-MD', '-MP', '-MF $(MDDEPDIR)/$(@F).pp']
+    elif info.type == 'clang-cl':
+        # clang-cl doesn't accept the normal -MD -MP -MF options that clang
+        # does, but the underlying cc1 binary understands how to generate
+        # dependency files.  These options are based on analyzing what the
+        # normal clang driver sends to cc1 when given the "correct"
+        # dependency options.
+        return [
+            '-Xclang', '-MP',
+            '-Xclang', '-dependency-file',
+            '-Xclang', '$(MDDEPDIR)/$(@F).pp',
+            '-Xclang', '-MT',
+            '-Xclang', '$@'
+        ]
+    elif using_sccache:
+        # sccache supports a special flag to create depfiles
+        # by parsing MSVC's -showIncludes output.
+        return ['-deps$(MDDEPDIR)/$(@F).pp']
+
+
+set_config('_DEPEND_CFLAGS', depend_cflags)
+
+
 @depends(c_compiler, check_build_environment, target)
 @imports('multiprocessing')
 @imports(_from='__builtin__', _import='min')
 def pgo_flags(compiler, build_env, target):
     topobjdir = build_env.topobjdir
     if topobjdir.endswith('/js/src'):
         topobjdir = topobjdir[:-7]
 
@@ -1456,16 +1482,36 @@ js_option('--enable-address-sanitizer', 
 
 @depends_if('--enable-address-sanitizer', '--help')
 def asan(value, _):
     return True
 
 
 add_old_configure_assignment('MOZ_ASAN', asan)
 
+# UBSAN
+# ==============================================================
+
+js_option('--enable-undefined-sanitizer',
+          nargs='*',
+          help='Enable UndefinedBehavior Sanitizer')
+
+@depends_if('--enable-undefined-sanitizer')
+def ubsan(options):
+    default_checks = [
+        'bool',
+        'bounds',
+        'vla-bound',
+    ]
+
+    checks = options if len(options) else default_checks
+
+    return ','.join(checks)
+
+add_old_configure_assignment('MOZ_UBSAN_CHECKS', ubsan)
 
 # Security Hardening
 # ==============================================================
 
 option('--enable-hardening', env='MOZ_SECURITY_HARDENING',
        help='Enables security hardening compiler options')
 
 
--- a/build/moz.configure/windows.configure
+++ b/build/moz.configure/windows.configure
@@ -479,11 +479,37 @@ def alter_path(sdk_bin_path):
     os.environ['PATH'] = path
     return path
 
 
 set_config('PATH', alter_path)
 
 check_prog('MAKECAB', ('makecab.exe',))
 
+
+@depends(c_compiler, using_sccache)
+def need_showincludes_prefix(info, using_sccache):
+    # sccache does its own -showIncludes prefix checking.
+    # clang-cl uses a gcc-style dependency scheme, see toolchain.configure.
+    if info.type == 'msvc' and not using_sccache:
+        return True
+
+
+@depends(c_compiler, when=need_showincludes_prefix)
+@imports(_from='re', _import='compile', _as='re_compile')
+def msvc_showincludes_prefix(c_compiler):
+    pattern = re_compile(br'^([^:]*:.*[ :] )(.*\\stdio.h)$')
+    output = try_invoke_compiler([c_compiler.compiler], 'C', '#include <stdio.h>\n',
+                                 ['-nologo', '-c', '-Fonul', '-showIncludes'])
+    for line in output.splitlines():
+        if line.endswith(b'\\stdio.h'):
+            m = pattern.match(line)
+            if m:
+                return m.group(1)
+    # We should have found the prefix and returned earlier
+    die('Cannot find cl -showIncludes prefix.')
+
+
+set_config('CL_INCLUDES_PREFIX', msvc_showincludes_prefix)
+
 # Make sure that the build system can handle non-ASCII characters in
 # environment variables to prevent silent breakage on non-English systems.
 set_config('NONASCII', b'\241\241')
--- a/build/mozconfig.cache
+++ b/build/mozconfig.cache
@@ -73,22 +73,16 @@ if test -n "$bucket"; then
         ;;
     esac
     export CCACHE="$topsrcdir/sccache2/sccache${suffix}"
     export SCCACHE_VERBOSE_STATS=1
     mk_add_options MOZBUILD_MANAGE_SCCACHE_DAEMON=${topsrcdir}/sccache2/sccache
     mk_add_options "UPLOAD_EXTRA_FILES+=sccache.log.gz"
     case "$platform" in
     win*)
-        # sccache supports a special flag to create depfiles.
-        #TODO: bug 1318370 - move this all into toolchain.configure
-        export _DEPEND_CFLAGS='-deps$(MDDEPDIR)/$(@F).pp'
-        # Windows builds have a default wrapper that needs to be overridden
-        mk_add_options "export CC_WRAPPER="
-        mk_add_options "export CXX_WRAPPER="
         # For now, sccache doesn't support separate PDBs so force debug info to be
         # in object files.
         mk_add_options "export COMPILE_PDB_FLAG="
         mk_add_options "export HOST_PDB_FLAG="
         mk_add_options "export MOZ_DEBUG_FLAGS=-Z7"
         ;;
     esac
 fi
--- a/build/win32/mozconfig.vs2017
+++ b/build/win32/mozconfig.vs2017
@@ -1,29 +1,29 @@
 if [ -z "${VSPATH}" ]; then
     TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
-    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.6.6"
+    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.8.4"
 fi
 
 if [ -d "${VSPATH}" ]; then
     VSWINPATH="$(cd ${VSPATH} && pwd -W)"
 
     export WINDOWSSDKDIR="${VSWINPATH}/SDK"
     export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x86/Microsoft.VC141.CRT"
     export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x86"
     export WIN_DIA_SDK_BIN_DIR="${VSPATH}/DIA SDK/bin"
 
-    export PATH="${VSPATH}/VC/bin/Hostx86/x86:${VSPATH}/VC/bin/Hostx64/x86:${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/10.0.15063.0/x64:${WIN_DIA_SDK_BIN_DIR}:${PATH}"
+    export PATH="${VSPATH}/VC/bin/Hostx86/x86:${VSPATH}/VC/bin/Hostx64/x86:${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/10.0.17134.0/x64:${WIN_DIA_SDK_BIN_DIR}:${PATH}"
     export PATH="${VSPATH}/VC/redist/x86/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x86:${PATH}"
 
-    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.15063.0/ucrt:${VSPATH}/SDK/Include/10.0.15063.0/shared:${VSPATH}/SDK/Include/10.0.15063.0/um:${VSPATH}/SDK/Include/10.0.15063.0/winrt:${VSPATH}/DIA SDK/include"
-    export LIB="${VSPATH}/VC/lib/x86:${VSPATH}/VC/atlmfc/lib/x86:${VSPATH}/SDK/Lib/10.0.15063.0/ucrt/x86:${VSPATH}/SDK/Lib/10.0.15063.0/um/x86:${VSPATH}/DIA SDK/lib"
+    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.17134.0/ucrt:${VSPATH}/SDK/Include/10.0.17134.0/shared:${VSPATH}/SDK/Include/10.0.17134.0/um:${VSPATH}/SDK/Include/10.0.17134.0/winrt:${VSPATH}/DIA SDK/include"
+    export LIB="${VSPATH}/VC/lib/x86:${VSPATH}/VC/atlmfc/lib/x86:${VSPATH}/SDK/Lib/10.0.17134.0/ucrt/x86:${VSPATH}/SDK/Lib/10.0.17134.0/um/x86:${VSPATH}/DIA SDK/lib"
 
     export WIN64_LINK="${VSPATH}/VC/bin/Hostx64/x64/link.exe"
-    export WIN64_LIB="${VSPATH}/VC/lib/x64:${VSPATH}/VC/atlmfc/lib/x64:${VSPATH}/SDK/Lib/10.0.15063.0/ucrt/x64:${VSPATH}/SDK/Lib/10.0.15063.0/um/x64:${VSPATH}/DIA SDK/lib/amd64"
+    export WIN64_LIB="${VSPATH}/VC/lib/x64:${VSPATH}/VC/atlmfc/lib/x64:${VSPATH}/SDK/Lib/10.0.17134.0/ucrt/x64:${VSPATH}/SDK/Lib/10.0.17134.0/um/x64:${VSPATH}/DIA SDK/lib/amd64"
 fi
 
 . $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style WINDOWSSDKDIR
 mk_export_correct_style WIN32_REDIST_DIR
 mk_export_correct_style WIN_UCRT_REDIST_DIR
 mk_export_correct_style WIN_DIA_SDK_BIN_DIR
--- a/build/win64/mozconfig.vs2017
+++ b/build/win64/mozconfig.vs2017
@@ -1,25 +1,25 @@
 if [ -z "${VSPATH}" ]; then
     TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
-    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.6.6"
+    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.8.4"
 fi
 
 if [ -d "${VSPATH}" ]; then
     VSWINPATH="$(cd ${VSPATH} && pwd -W)"
 
     export WINDOWSSDKDIR="${VSWINPATH}/SDK"
     export WIN32_REDIST_DIR=${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT
     export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64"
     export WIN_DIA_SDK_BIN_DIR="${VSPATH}/DIA SDK/bin/amd64"
 
-    export PATH="${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/10.0.15063.0/x64:${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${WIN_DIA_SDK_BIN_DIR}:${PATH}"
+    export PATH="${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/10.0.17134.0/x64:${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${WIN_DIA_SDK_BIN_DIR}:${PATH}"
 
-    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.15063.0/ucrt:${VSPATH}/SDK/Include/10.0.15063.0/shared:${VSPATH}/SDK/Include/10.0.15063.0/um:${VSPATH}/SDK/Include/10.0.15063.0/winrt:${VSPATH}/DIA SDK/include"
-    export LIB="${VSPATH}/VC/lib/x64:${VSPATH}/VC/atlmfc/lib/x64:${VSPATH}/SDK/Lib/10.0.15063.0/ucrt/x64:${VSPATH}/SDK/Lib/10.0.15063.0/um/x64:${VSPATH}/DIA SDK/lib/amd64"
+    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.17134.0/ucrt:${VSPATH}/SDK/Include/10.0.17134.0/shared:${VSPATH}/SDK/Include/10.0.17134.0/um:${VSPATH}/SDK/Include/10.0.17134.0/winrt:${VSPATH}/DIA SDK/include"
+    export LIB="${VSPATH}/VC/lib/x64:${VSPATH}/VC/atlmfc/lib/x64:${VSPATH}/SDK/Lib/10.0.17134.0/ucrt/x64:${VSPATH}/SDK/Lib/10.0.17134.0/um/x64:${VSPATH}/DIA SDK/lib/amd64"
 fi
 
 . $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style WINDOWSSDKDIR
 mk_export_correct_style WIN32_REDIST_DIR
 mk_export_correct_style WIN_UCRT_REDIST_DIR
 mk_export_correct_style WIN_DIA_SDK_BIN_DIR
--- a/build/windows_toolchain.py
+++ b/build/windows_toolchain.py
@@ -19,17 +19,17 @@ import sys
 from mozpack.files import (
     FileFinder,
 )
 from mozpack.mozjar import (
     JarWriter,
 )
 import mozpack.path as mozpath
 
-SDK_RELEASE = '10.0.15063.0'
+SDK_RELEASE = '10.0.17134.0'
 
 PATTERNS = [
     {
         'srcdir': '%(vs_path)s/DIA SDK',
         'dstdir': 'DIA SDK',
         'files': [
             {
                 'pattern': 'bin/**',
@@ -47,17 +47,17 @@ PATTERNS = [
                 'pattern': 'lib/**',
                 'ignore': (
                     'lib/arm/**',
                 ),
             },
         ],
     },
     {
-        'srcdir': '%(vs_path)s/VC/Tools/MSVC/14.13.26128',
+        'srcdir': '%(vs_path)s/VC/Tools/MSVC/14.15.26726',
         'dstdir': 'VC',
         'files': [
             # ATL is needed by Breakpad.
             {
                 'pattern': 'atlmfc/include/**',
             },
             {
                 'pattern': 'atlmfc/lib/x86/atls.*',
@@ -81,17 +81,17 @@ PATTERNS = [
                     'lib/onecore/**',
                     'lib/x64/store/**',
                     'lib/x86/store/**',
                 ),
             },
         ],
     },
     {
-        'srcdir': '%(vs_path)s/VC/Redist/MSVC/14.13.26020',
+        'srcdir': '%(vs_path)s/VC/Redist/MSVC/14.15.26706',
         'dstdir': 'VC/redist',
         'files': [
             {
                 'pattern': 'x64/Microsoft.VC141.CRT/**',
             },
             {
                 'pattern': 'x86/Microsoft.VC141.CRT/**',
             },
--- a/caps/ContentPrincipal.cpp
+++ b/caps/ContentPrincipal.cpp
@@ -152,16 +152,28 @@ ContentPrincipal::GenerateOriginNoSuffix
       (NS_SUCCEEDED(origin->SchemeIs("moz-safe-about", &isBehaved)) && isBehaved &&
        // We generally consider two about:foo origins to be same-origin, but
        // about:blank is special since it can be generated from different sources.
        // We check for moz-safe-about:blank since origin is an innermost URI.
        !origin->GetSpecOrDefault().EqualsLiteral("moz-safe-about:blank")) ||
       (NS_SUCCEEDED(origin->SchemeIs("indexeddb", &isBehaved)) && isBehaved)) {
     rv = origin->GetAsciiSpec(aOriginNoSuffix);
     NS_ENSURE_SUCCESS(rv, rv);
+
+    int32_t pos = aOriginNoSuffix.FindChar('?');
+    int32_t hashPos = aOriginNoSuffix.FindChar('#');
+
+    if (hashPos != kNotFound && (pos == kNotFound || hashPos < pos)) {
+      pos = hashPos;
+    }
+
+    if (pos != kNotFound) {
+      aOriginNoSuffix.Truncate(pos);
+    }
+
     // These URIs could technically contain a '^', but they never should.
     if (NS_WARN_IF(aOriginNoSuffix.FindChar('^', 0) != -1)) {
       aOriginNoSuffix.Truncate();
       return NS_ERROR_FAILURE;
     }
     return NS_OK;
   }
 
--- a/caps/tests/mochitest/browser.ini
+++ b/caps/tests/mochitest/browser.ini
@@ -1,1 +1,2 @@
 [browser_checkloaduri.js]
+[browser_aboutOrigin.js]
new file mode 100644
--- /dev/null
+++ b/caps/tests/mochitest/browser_aboutOrigin.js
@@ -0,0 +1,12 @@
+"use strict";
+
+let tests = [ "about:robots?foo", "about:robots#foo", "about:robots?foo#bar"];
+tests.forEach(async test => {
+  add_task(async () => {
+    await BrowserTestUtils.withNewTab(test, async browser => {
+      await ContentTask.spawn(browser, null, () => {
+        is(content.document.nodePrincipal.origin, "about:robots");
+      });
+    });
+  });
+});
--- a/config/config.mk
+++ b/config/config.mk
@@ -119,20 +119,20 @@ else
   BUILD_TOOLS = $(MOZILLA_DIR)/build/unix
 endif
 
 CONFIG_TOOLS	= $(MOZ_BUILD_ROOT)/config
 AUTOCONF_TOOLS	= $(MOZILLA_DIR)/build/autoconf
 
 ifdef _MSC_VER
 # clang-cl is smart enough to generate dependencies directly.
-ifndef CLANG_CL
+ifeq (,$(CLANG_CL)$(MOZ_USING_SCCACHE))
 CC_WRAPPER ?= $(call py_action,cl)
 CXX_WRAPPER ?= $(call py_action,cl)
-endif # CLANG_CL
+endif # CLANG_CL/MOZ_USING_SCCACHE
 endif # _MSC_VER
 
 CC := $(CC_WRAPPER) $(CC)
 CXX := $(CXX_WRAPPER) $(CXX)
 MKDIR ?= mkdir
 SLEEP ?= sleep
 TOUCH ?= touch
 
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -544,25 +544,32 @@ distclean::
 alltags:
 	$(RM) TAGS
 	find $(topsrcdir) -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' -o -name '*.idl' \) -print | $(TAG_PROGRAM)
 
 define EXPAND_CC_OR_CXX
 $(if $(PROG_IS_C_ONLY_$(1)),$(CC),$(CCC))
 endef
 
+# Workaround a bug of MSVC 2017 Update 8 (see bug 1485224)
+ifeq ($(CC_TYPE)_$(HOST_OS_ARCH)_$(MOZ_PROFILE_GENERATE),msvc_WINNT_1)
+LINKER_OUT=$(subst /,\,$1)
+else
+LINKER_OUT=$1
+endif
+
 #
 # PROGRAM = Foo
 # creates OBJS, links with LIBS to create Foo
 #
 $(PROGRAM): $(PROGOBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(RESFILE) $(GLOBAL_DEPS) $(call mkdir_deps,$(FINAL_TARGET))
 	$(REPORT_BUILD)
 	@$(RM) $@.manifest
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LINKER) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) -IMPLIB:$(basename $(@F)).lib $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_PROGRAM_LDFLAGS) $($(notdir $@)_$(OBJS_VAR_SUFFIX)) $(RESFILE) $(STATIC_LIBS) $(SHARED_LIBS) $(OS_LIBS)
+	$(LINKER) -NOLOGO -OUT:$(call LINKER_OUT,$@) -PDB:$(LINK_PDBFILE) -IMPLIB:$(basename $(@F)).lib $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_PROGRAM_LDFLAGS) $($(notdir $@)_$(OBJS_VAR_SUFFIX)) $(RESFILE) $(STATIC_LIBS) $(SHARED_LIBS) $(OS_LIBS)
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		if test -f '$(srcdir)/$(notdir $@).manifest'; then \
 			echo 'Embedding manifest from $(srcdir)/$(notdir $@).manifest and $@.manifest'; \
 			$(MT) -NOLOGO -MANIFEST '$(win_srcdir)/$(notdir $@).manifest' $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		else \
 			echo 'Embedding manifest from $@.manifest'; \
 			$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
@@ -901,16 +908,17 @@ rust_unlock_unstable += RUSTC_BOOTSTRAP=
 endif
 
 ifdef MOZ_USING_SCCACHE
 sccache_wrap := RUSTC_WRAPPER='$(CCACHE)'
 endif
 
 ifndef MOZ_ASAN
 ifndef MOZ_TSAN
+ifndef MOZ_UBSAN
 ifndef MOZ_CODE_COVERAGE
 # Pass the compilers and flags in use to cargo for use in build scripts.
 # * Don't do this for ASAN/TSAN builds because we don't pass our custom linker (see below)
 #   which will muck things up.
 # * Don't do this for code coverage builds because the way rustc invokes the linker doesn't
 #   work with GCC 6: https://bugzilla.mozilla.org/show_bug.cgi?id=1477305
 #
 # We don't pass HOST_{CC,CXX} down in any form because our host value might not match
@@ -934,16 +942,17 @@ cargo_c_compiler_envs := \
  CC_$(rust_cc_env_name)="$(CC)" \
  CXX_$(rust_cc_env_name)="$(CXX)" \
  CFLAGS_$(rust_cc_env_name)="$(COMPUTED_CFLAGS)" \
  CXXFLAGS_$(rust_cc_env_name)="$(COMPUTED_CXXFLAGS)" \
  AR_$(rust_cc_env_name)="$(AR)" \
  $(NULL)
 endif # WINNT
 endif # MOZ_CODE_COVERAGE
+endif # MOZ_UBSAN
 endif # MOZ_TSAN
 endif # MOZ_ASAN
 
 # We use the + prefix to pass down the jobserver fds to cargo, but we
 # don't use the prefix when make -n is used, so that cargo doesn't run
 # in that case)
 define RUN_CARGO
 $(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)env $(environment_cleaner) $(rust_unlock_unstable) $(sccache_wrap) \
@@ -996,24 +1005,26 @@ cargo_linker_env_var := CARGO_TARGET_$(R
 # already works with the current setup) setup on Windows, and we don't
 # have to pass in any special linker options on Windows.
 ifneq (WINNT,$(OS_ARCH))
 
 # Defining all of this for ASan/TSan builds results in crashes while running
 # some crates's build scripts (!), so disable it for now.
 ifndef MOZ_ASAN
 ifndef MOZ_TSAN
+ifndef MOZ_UBSAN
 # Cargo needs the same linker flags as the C/C++ compiler,
 # but not the final libraries. Filter those out because they
 # cause problems on macOS 10.7; see bug 1365993 for details.
 # Also, we don't want to pass PGO flags until cargo supports them.
 target_cargo_env_vars := \
 	MOZ_CARGO_WRAP_LDFLAGS="$(filter-out -fsanitize=cfi% -framework Cocoa -lobjc AudioToolbox ExceptionHandling -fprofile-%,$(LDFLAGS))" \
 	MOZ_CARGO_WRAP_LD="$(CC)" \
 	$(cargo_linker_env_var)=$(topsrcdir)/build/cargo-linker
+endif # MOZ_UBSAN
 endif # MOZ_TSAN
 endif # MOZ_ASAN
 
 endif # ifneq WINNT
 
 ifdef RUST_LIBRARY_FILE
 
 ifdef RUST_LIBRARY_FEATURES
--- a/dom/base/nsContentCID.h
+++ b/dom/base/nsContentCID.h
@@ -104,20 +104,16 @@
 // {4DC30689-929D-425e-A709-082C6294E542}
 #define NS_XMLFRAGMENTSINK2_CID \
 { 0x4dc30689, 0x929d, 0x425e, { 0xa7, 0x9, 0x8, 0x2c, 0x62, 0x94, 0xe5, 0x42 } }
 
 // {3986B301-097C-11d3-BF87-00105A1B0627}
 #define NS_XULPOPUPLISTENER_CID \
 { 0x3986b301, 0x97c, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
 
-// {1F5C1721-7DC3-11d3-BF87-00105A1B0627}
-#define NS_XULCONTROLLERS_CID \
-{ 0x1f5c1721, 0x7dc3, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
-
 // {3D262D00-8B5A-11d2-8EB0-00805F29F370}
 #define NS_XULTEMPLATEBUILDER_CID \
 { 0x3d262d00, 0x8b5a, 0x11d2, { 0x8e, 0xb0, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
 
 // {1abdcc96-1dd2-11b2-b520-f8f59cdd67bc}
 #define NS_XULTREEBUILDER_CID \
 { 0x1abdcc96, 0x1dd2, 0x11b2, { 0xb5, 0x20, 0xf8, 0xf5, 0x9c, 0xdd, 0x67, 0xbc } }
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1669,16 +1669,30 @@ nsDocument::~nsDocument()
       ScalarAdd(Telemetry::ScalarID::MEDIA_PAGE_COUNT, 1);
       if (mDocTreeHadAudibleMedia) {
         ScalarAdd(Telemetry::ScalarID::MEDIA_PAGE_HAD_MEDIA_COUNT, 1);
       }
       if (mDocTreeHadPlayRevoked) {
         ScalarAdd(Telemetry::ScalarID::MEDIA_PAGE_HAD_PLAY_REVOKED_COUNT, 1);
       }
     }
+
+    // Report the fastblock telemetry probes when the document is dying if
+    // fastblock is enabled and we're not a private document.  We always report
+    // the all probe, and for the rest, report each category's probe depending
+    // on whether the respective bit has been set in our enum set.
+    if (StaticPrefs::browser_contentblocking_enabled() &&
+        StaticPrefs::browser_fastblock_enabled() &&
+        !nsContentUtils::IsInPrivateBrowsing(this)) {
+      for (auto label : mTrackerBlockedReasons) {
+        AccumulateCategorical(label);
+      }
+      // Always accumulate the "all" probe since we will use it as a baseline counter.
+      AccumulateCategorical(Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all);
+    }
   }
 
   ReportUseCounters();
 
   mInDestructor = true;
   mInUnlinkOrDeletion = true;
 
   mozilla::DropJSObjects(this);
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -212,16 +212,17 @@
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/Location.h"
 #include "nsHTMLDocument.h"
 #include "nsWrapperCacheInlines.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "prrng.h"
 #include "nsSandboxFlags.h"
 #include "nsBaseCommandController.h"
+#include "nsXULControllers.h"
 #include "mozilla/dom/AudioContext.h"
 #include "mozilla/dom/BrowserElementDictionariesBinding.h"
 #include "mozilla/dom/cache/CacheStorage.h"
 #include "mozilla/dom/Console.h"
 #include "mozilla/dom/Fetch.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/HashChangeEvent.h"
 #include "mozilla/dom/IntlUtils.h"
@@ -309,19 +310,16 @@ using mozilla::TimeStamp;
   PR_END_MACRO
 
 static LazyLogModule gDOMLeakPRLogOuter("DOMLeakOuter");
 
 static int32_t              gOpenPopupSpamCount               = 0;
 
 nsGlobalWindowOuter::OuterWindowByIdTable *nsGlobalWindowOuter::sOuterWindowsById = nullptr;
 
-// CIDs
-static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
-
 /* static */
 nsPIDOMWindowOuter*
 nsPIDOMWindowOuter::GetFromCurrentInner(nsPIDOMWindowInner* aInner)
 {
   if (!aInner) {
     return nullptr;
   }
 
@@ -2921,20 +2919,19 @@ nsGlobalWindowOuter::IndexedGetterOuter(
 
   return windows->IndexedGetter(aIndex);
 }
 
 nsIControllers*
 nsGlobalWindowOuter::GetControllersOuter(ErrorResult& aError)
 {
   if (!mControllers) {
-    nsresult rv;
-    mControllers = do_CreateInstance(kXULControllersCID, &rv);
-    if (NS_FAILED(rv)) {
-      aError.Throw(rv);
+    mControllers = NS_NewXULControllers();
+    if (!mControllers) {
+      aError.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
 
     // Add in the default controller
     nsCOMPtr<nsIController> controller =
       nsBaseCommandController::CreateWindowController();
     if (!controller) {
       aError.Throw(NS_ERROR_FAILURE);
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -40,16 +40,17 @@
 #include "mozilla/WeakPtr.h"
 #include "Units.h"
 #include "nsContentListDeclarations.h"
 #include "nsExpirationTracker.h"
 #include "nsClassHashtable.h"
 #include "mozilla/CORSMode.h"
 #include "mozilla/dom/DispatcherTrait.h"
 #include "mozilla/dom/DocumentOrShadowRoot.h"
+#include "mozilla/EnumSet.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/NotNull.h"
 #include "mozilla/SegmentedVector.h"
 #include "mozilla/ServoBindingTypes.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include <bitset>                        // for member
@@ -3685,16 +3686,23 @@ public:
   }
 
   void IncrementTrackerBlockedCount()
   {
     MOZ_ASSERT(!GetSameTypeParentDocument());
     ++mNumTrackersBlocked;
   }
 
+  void NoteTrackerBlockedReason(
+    mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED aLabel)
+  {
+    MOZ_ASSERT(!GetSameTypeParentDocument());
+    mTrackerBlockedReasons += aLabel;
+  }
+
   uint32_t NumTrackersFound()
   {
     MOZ_ASSERT(!GetSameTypeParentDocument() || mNumTrackersFound == 0);
 
     return mNumTrackersFound;
   }
 
   uint32_t NumTrackersBlocked()
@@ -4673,16 +4681,19 @@ protected:
   nsCOMPtr<nsIDOMXULCommandDispatcher> mCommandDispatcher; // [OWNER] of the focus tracker
 
   // At the moment, trackers might be blocked by Tracking Protection or FastBlock.
   // In order to know the numbers of trackers detected and blocked, we add
   // these two values here and those are shared by TP and FB.
   uint32_t mNumTrackersFound;
   uint32_t mNumTrackersBlocked;
 
+  mozilla::EnumSet<mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED>
+    mTrackerBlockedReasons;
+
   // document lightweight theme for use with :-moz-lwtheme, :-moz-lwtheme-brighttext
   // and :-moz-lwtheme-darktext
   DocumentTheme                         mDocLWTheme;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
 
 /**
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -110,26 +110,25 @@
 
 #include "nsIColorPicker.h"
 #include "nsIStringEnumerator.h"
 #include "HTMLSplitOnSpacesTokenizer.h"
 #include "nsIController.h"
 #include "nsIMIMEInfo.h"
 #include "nsFrameSelection.h"
 #include "nsBaseCommandController.h"
+#include "nsXULControllers.h"
 
 // input type=date
 #include "js/Date.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Input)
 
 // XXX align=left, hspace, vspace, border? other nav4 attrs
 
-static NS_DEFINE_CID(kXULControllersCID,  NS_XULCONTROLLERS_CID);
-
 namespace mozilla {
 namespace dom {
 
 // First bits are needed for the control type.
 #define NS_OUTER_ACTIVATE_EVENT   (1 << 9)
 #define NS_ORIGINAL_CHECKED_VALUE (1 << 10)
 #define NS_NO_CONTENT_DISPATCH    (1 << 11)
 #define NS_ORIGINAL_INDETERMINATE_VALUE (1 << 12)
@@ -5793,20 +5792,19 @@ HTMLInputElement::GetFiles(bool aRecursi
 nsIControllers*
 HTMLInputElement::GetControllers(ErrorResult& aRv)
 {
   //XXX: what about type "file"?
   if (IsSingleLineTextControl(false))
   {
     if (!mControllers)
     {
-      nsresult rv;
-      mControllers = do_CreateInstance(kXULControllersCID, &rv);
-      if (NS_FAILED(rv)) {
-        aRv.Throw(rv);
+      mControllers = NS_NewXULControllers();
+      if (!mControllers) {
+        aRv.Throw(NS_ERROR_FAILURE);
         return nullptr;
       }
 
       nsCOMPtr<nsIController> controller =
         nsBaseCommandController::CreateEditorController();
       if (!controller) {
         aRv.Throw(NS_ERROR_FAILURE);
         return nullptr;
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -36,18 +36,17 @@
 #include "nsPIDOMWindow.h"
 #include "nsPresContext.h"
 #include "mozilla/PresState.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsTextEditorState.h"
 #include "nsIController.h"
 #include "nsBaseCommandController.h"
-
-static NS_DEFINE_CID(kXULControllersCID,  NS_XULCONTROLLERS_CID);
+#include "nsXULControllers.h"
 
 #define NS_NO_CONTENT_DISPATCH (1 << 0)
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(TextArea)
 
 namespace mozilla {
 namespace dom {
 
@@ -619,20 +618,19 @@ HTMLTextAreaElement::IsDoneAddingChildre
 
 // Controllers Methods
 
 nsIControllers*
 HTMLTextAreaElement::GetControllers(ErrorResult& aError)
 {
   if (!mControllers)
   {
-    nsresult rv;
-    mControllers = do_CreateInstance(kXULControllersCID, &rv);
-    if (NS_FAILED(rv)) {
-      aError.Throw(rv);
+    mControllers = NS_NewXULControllers();
+    if (!mControllers) {
+      aError.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
 
     nsCOMPtr<nsIController> controller =
       nsBaseCommandController::CreateEditorController();
     if (!controller) {
       aError.Throw(NS_ERROR_FAILURE);
       return nullptr;
--- a/dom/webidl/MerchantValidationEvent.webidl
+++ b/dom/webidl/MerchantValidationEvent.webidl
@@ -1,16 +1,19 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this WebIDL file is
  *   https://w3c.github.io/payment-request/#merchantvalidationevent-interface
  *   https://w3c.github.io/payment-request/#merchantvalidationeventinit-dictionary
+ *
+ * Copyright © 2018 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
  */
 
 [Constructor(DOMString type, optional MerchantValidationEventInit eventInitDict),
 SecureContext,
 Exposed=Window,
 Func="mozilla::dom::PaymentRequest::PrefEnabled"]
 interface MerchantValidationEvent : Event {
   readonly attribute DOMString methodName;
--- a/dom/webidl/PaymentAddress.webidl
+++ b/dom/webidl/PaymentAddress.webidl
@@ -1,15 +1,18 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this WebIDL file is
  *   https://www.w3.org/TR/payment-request/#paymentaddress-interface
+ *
+ * Copyright © 2018 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
  */
 
 [SecureContext,
  Func="mozilla::dom::PaymentRequest::PrefEnabled"]
 interface PaymentAddress {
   [Default] object toJSON();
 
   readonly attribute DOMString              country;
--- a/dom/webidl/PaymentMethodChangeEvent.webidl
+++ b/dom/webidl/PaymentMethodChangeEvent.webidl
@@ -1,8 +1,20 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this WebIDL file is
+ *   https://www.w3.org/TR/payment-request/#paymentmethodchangeevent-interface
+ *
+ * Copyright © 2018 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
 [Constructor(DOMString type, optional PaymentMethodChangeEventInit eventInitDict),
  SecureContext,
  Exposed=Window,
  Func="mozilla::dom::PaymentRequest::PrefEnabled"]
 interface PaymentMethodChangeEvent : PaymentRequestUpdateEvent {
     readonly attribute DOMString methodName;
     readonly attribute object?   methodDetails;
 };
--- a/dom/webidl/PaymentRequest.webidl
+++ b/dom/webidl/PaymentRequest.webidl
@@ -1,15 +1,18 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this WebIDL file is
  *   https://www.w3.org/TR/payment-request/#paymentrequest-interface
+ *
+ * Copyright © 2018 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
  */
 
 dictionary PaymentMethodData {
   required DOMString           supportedMethods;
            object              data;
 };
 
 dictionary PaymentCurrencyAmount {
--- a/dom/webidl/PaymentRequestUpdateEvent.webidl
+++ b/dom/webidl/PaymentRequestUpdateEvent.webidl
@@ -1,15 +1,18 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this WebIDL file is
  *   https://www.w3.org/TR/payment-request/#paymentrequestupdateevent-interface
+ *
+ * Copyright © 2018 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
  */
 
 [Constructor(DOMString type,
              optional PaymentRequestUpdateEventInit eventInitDict),
  SecureContext,
  Func="mozilla::dom::PaymentRequest::PrefEnabled"]
 interface PaymentRequestUpdateEvent : Event {
   [Throws]
--- a/dom/webidl/PaymentResponse.webidl
+++ b/dom/webidl/PaymentResponse.webidl
@@ -1,15 +1,18 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this WebIDL file is
  *   https://www.w3.org/TR/payment-request/#paymentresponse-interface
+ *
+ * Copyright © 2018 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
  */
 
 enum PaymentComplete {
   "success",
   "fail",
   "unknown"
 };
 
--- a/dom/xul/nsXULControllers.cpp
+++ b/dom/xul/nsXULControllers.cpp
@@ -10,16 +10,17 @@
 
 */
 
 #include "nsString.h"
 
 #include "nsIControllers.h"
 #include "nsXULControllers.h"
 #include "nsIController.h"
+#include "mozilla/RefPtr.h"
 
 //----------------------------------------------------------------------
 
 nsXULControllers::nsXULControllers()
 : mCurControllerID(0)
 {
 }
 
@@ -37,29 +38,21 @@ nsXULControllers::DeleteControllers()
     nsXULControllerData* controllerData = mControllers.ElementAt(i);
     delete controllerData;    // releases the nsIController
   }
 
   mControllers.Clear();
 }
 
 
-nsresult
-NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult)
+already_AddRefed<nsIControllers>
+NS_NewXULControllers()
 {
-  MOZ_ASSERT(aOuter == nullptr, "no aggregation");
-  if (aOuter)
-    return NS_ERROR_NO_AGGREGATION;
-
-  nsXULControllers* controllers = new nsXULControllers();
-  nsresult rv;
-  NS_ADDREF(controllers);
-  rv = controllers->QueryInterface(aIID, aResult);
-  NS_RELEASE(controllers);
-  return rv;
+  RefPtr<nsXULControllers> controllers = new nsXULControllers();
+  return controllers.forget();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULControllers)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULControllers)
   tmp->DeleteControllers();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULControllers)
--- a/dom/xul/nsXULControllers.h
+++ b/dom/xul/nsXULControllers.h
@@ -38,23 +38,22 @@ public:
                               return NS_OK;
                             }
 
     uint32_t                mControllerID;
     nsCOMPtr<nsIController> mController;
 };
 
 
-nsresult NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult);
+already_AddRefed<nsIControllers> NS_NewXULControllers();
 
 class nsXULControllers : public nsIControllers
 {
 public:
-    friend nsresult
-    NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult);
+    friend already_AddRefed<nsIControllers> NS_NewXULControllers();
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULControllers, nsIControllers)
     NS_DECL_NSICONTROLLERS
 
 protected:
     nsXULControllers();
     virtual ~nsXULControllers(void);
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -1133,23 +1133,17 @@ nsXULElement::IsAttributeMapped(const ns
 }
 
 nsIControllers*
 nsXULElement::GetControllers(ErrorResult& rv)
 {
     if (! Controllers()) {
         nsExtendedDOMSlots* slots = ExtendedDOMSlots();
 
-        rv = NS_NewXULControllers(nullptr, NS_GET_IID(nsIControllers),
-                                  reinterpret_cast<void**>(&slots->mControllers));
-
-        NS_ASSERTION(!rv.Failed(), "unable to create a controllers");
-        if (rv.Failed()) {
-            return nullptr;
-        }
+        slots->mControllers = NS_NewXULControllers();
     }
 
     return Controllers();
 }
 
 already_AddRefed<BoxObject>
 nsXULElement::GetBoxObject(ErrorResult& rv)
 {
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -8,16 +8,17 @@
 #endif
 #include "GPUParent.h"
 #include "gfxConfig.h"
 #include "gfxCrashReporterUtils.h"
 #include "gfxPlatform.h"
 #include "gfxPrefs.h"
 #include "GLContextProvider.h"
 #include "GPUProcessHost.h"
+#include "GPUProcessManager.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/dom/MemoryReportRequest.h"
 #include "mozilla/dom/VideoDecoderManagerChild.h"
 #include "mozilla/dom/VideoDecoderManagerParent.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/gfxVars.h"
@@ -455,23 +456,40 @@ GPUParent::RecvNotifyGpuObservers(const 
   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
   MOZ_ASSERT(obsSvc);
   if (obsSvc) {
     obsSvc->NotifyObservers(nullptr, aTopic.get(), nullptr);
   }
   return IPC_OK();
 }
 
+/* static */ void
+GPUParent::GetGPUProcessName(nsACString& aStr)
+{
+  auto processType = XRE_GetProcessType();
+  unsigned pid = 0;
+  if (processType == GeckoProcessType_GPU) {
+    pid = getpid();
+  } else {
+    MOZ_DIAGNOSTIC_ASSERT(processType == GeckoProcessType_Default);
+    pid = GPUProcessManager::Get()->GPUProcessPid();
+  }
+
+  nsPrintfCString processName("GPU (pid %u)", pid);
+  aStr.Assign(processName);
+}
+
 mozilla::ipc::IPCResult
 GPUParent::RecvRequestMemoryReport(const uint32_t& aGeneration,
                                    const bool& aAnonymize,
                                    const bool& aMinimizeMemoryUsage,
                                    const MaybeFileDesc& aDMDFile)
 {
-  nsPrintfCString processName("GPU (pid %u)", (unsigned)getpid());
+  nsAutoCString processName;
+  GetGPUProcessName(processName);
 
   mozilla::dom::MemoryReportRequestClient::Start(
     aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 GPUParent::RecvShutdownVR()
--- a/gfx/ipc/GPUParent.h
+++ b/gfx/ipc/GPUParent.h
@@ -21,16 +21,21 @@ class VsyncBridgeParent;
 class GPUParent final : public PGPUParent
 {
 public:
   GPUParent();
   ~GPUParent();
 
   static GPUParent* GetSingleton();
 
+  // Gets the name of the GPU process, in the format expected by about:memory.
+  // There must be a GPU process active, and the caller must be either in that
+  // process or the parent process.
+  static void GetGPUProcessName(nsACString& aStr);
+
   bool Init(base::ProcessId aParentPid,
             const char* aParentBuildID,
             MessageLoop* aIOLoop,
             IPC::Channel* aChannel);
   void NotifyDeviceReset();
 
   PAPZInputBridgeParent* AllocPAPZInputBridgeParent(const LayersId& aLayersId) override;
   bool DeallocPAPZInputBridgeParent(PAPZInputBridgeParent* aActor) override;
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1930,16 +1930,27 @@ CompositorBridgeParent::NotifyMemoryPres
   if (mWrBridge) {
     RefPtr<wr::WebRenderAPI> api = mWrBridge->GetWebRenderAPI();
     if (api) {
       api->NotifyMemoryPressure();
     }
   }
 }
 
+void
+CompositorBridgeParent::AccumulateMemoryReport(wr::MemoryReport* aReport)
+{
+  if (mWrBridge) {
+    RefPtr<wr::WebRenderAPI> api = mWrBridge->GetWebRenderAPI();
+    if (api) {
+      api->AccumulateMemoryReport(aReport);
+    }
+  }
+}
+
 RefPtr<WebRenderBridgeParent>
 CompositorBridgeParent::GetWebRenderBridgeParent() const
 {
   return mWrBridge;
 }
 
 Maybe<TimeStamp>
 CompositorBridgeParent::GetTestingTimeStamp() const
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -171,16 +171,17 @@ public:
     return false;
   }
 
   virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr) {
     MOZ_CRASH();
   }
 
   virtual void NotifyMemoryPressure() {}
+  virtual void AccumulateMemoryReport(wr::MemoryReport*) {}
 
 protected:
   ~CompositorBridgeParentBase() override;
 
   bool mCanSend;
 
 private:
   RefPtr<CompositorManagerParent> mCompositorManager;
@@ -234,16 +235,17 @@ public:
 
   // Unused for chrome <-> compositor communication (which this class does).
   // @see CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint
   mozilla::ipc::IPCResult RecvRequestNotifyAfterRemotePaint() override { return IPC_OK(); };
 
   mozilla::ipc::IPCResult RecvAllPluginsCaptured() override;
 
   virtual void NotifyMemoryPressure() override;
+  virtual void AccumulateMemoryReport(wr::MemoryReport*) override;
 
   void ActorDestroy(ActorDestroyReason why) override;
 
   void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
                            const TransactionInfo& aInfo,
                            bool aHitTestUpdate) override;
   void ScheduleComposite(LayerTransactionParent* aLayerTree) override;
   bool SetTestSampleTime(const LayersId& aId,
--- a/gfx/layers/ipc/CompositorManagerParent.cpp
+++ b/gfx/layers/ipc/CompositorManagerParent.cpp
@@ -1,16 +1,17 @@
 /* -*- 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 "mozilla/layers/CompositorManagerParent.h"
 #include "mozilla/gfx/GPUParent.h"
+#include "mozilla/webrender/RenderThread.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CrossProcessCompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/SharedSurfacesParent.h"
 #include "nsAutoPtr.h"
 #include "VsyncSource.h"
 
 namespace mozilla {
@@ -294,10 +295,42 @@ CompositorManagerParent::RecvNotifyMemor
   nsTArray<PCompositorBridgeParent*> compositorBridges;
   ManagedPCompositorBridgeParent(compositorBridges);
   for (auto bridge : compositorBridges) {
     static_cast<CompositorBridgeParentBase*>(bridge)->NotifyMemoryPressure();
   }
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+CompositorManagerParent::RecvReportMemory(ReportMemoryResolver&& aResolver)
+{
+  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+  MemoryReport aggregate;
+  PodZero(&aggregate);
+
+  // Accumulate RenderBackend usage.
+  nsTArray<PCompositorBridgeParent*> compositorBridges;
+  ManagedPCompositorBridgeParent(compositorBridges);
+  for (auto bridge : compositorBridges) {
+    static_cast<CompositorBridgeParentBase*>(bridge)->AccumulateMemoryReport(&aggregate);
+  }
+
+  // Accumulate Renderer usage asynchronously, and resolve.
+  //
+  // Note that the IPDL machinery requires aResolver to be called on this
+  // thread, so we can't just pass it over to the renderer thread. We use
+  // an intermediate MozPromise instead.
+  wr::RenderThread::AccumulateMemoryReport(aggregate)->Then(
+    CompositorThreadHolder::Loop()->SerialEventTarget(), __func__,
+    [resolver = std::move(aResolver)](MemoryReport aReport) {
+      resolver(aReport);
+    },
+    [](bool) {
+      MOZ_ASSERT_UNREACHABLE();
+    }
+  );
+
+  return IPC_OK();
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/CompositorManagerParent.h
+++ b/gfx/layers/ipc/CompositorManagerParent.h
@@ -41,16 +41,18 @@ public:
                                           const gfx::IntSize& aSurfaceSize);
 
   mozilla::ipc::IPCResult RecvAddSharedSurface(const wr::ExternalImageId& aId,
                                                const SurfaceDescriptorShared& aDesc) override;
   mozilla::ipc::IPCResult RecvRemoveSharedSurface(const wr::ExternalImageId& aId) override;
 
   virtual mozilla::ipc::IPCResult RecvNotifyMemoryPressure() override;
 
+  virtual mozilla::ipc::IPCResult RecvReportMemory(ReportMemoryResolver&&) override;
+
   void BindComplete();
   void ActorDestroy(ActorDestroyReason aReason) override;
 
   bool DeallocPCompositorBridgeParent(PCompositorBridgeParent* aActor) override;
   PCompositorBridgeParent* AllocPCompositorBridgeParent(const CompositorBridgeOptions& aOpt) override;
 
 private:
   static StaticRefPtr<CompositorManagerParent> sInstance;
--- a/gfx/layers/ipc/PCompositorManager.ipdl
+++ b/gfx/layers/ipc/PCompositorManager.ipdl
@@ -12,16 +12,17 @@ include "mozilla/layers/WebRenderMessage
 
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using mozilla::TimeDuration from "mozilla/TimeStamp.h";
 using mozilla::CSSToLayoutDeviceScale from "Units.h";
 using mozilla::gfx::IntSize from "mozilla/gfx/2D.h";
 using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
 using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
 using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
+using mozilla::wr::MemoryReport from "mozilla/webrender/WebRenderTypes.h";
 
 namespace mozilla {
 namespace layers {
 
 struct WidgetCompositorOptions {
   CSSToLayoutDeviceScale scale;
   TimeDuration vsyncRate;
   CompositorOptions options;
@@ -72,12 +73,14 @@ parent:
    * See gfx/layers/ipc/PCompositorBridge.ipdl for more details.
    */
   async PCompositorBridge(CompositorBridgeOptions options);
 
   async AddSharedSurface(ExternalImageId aId, SurfaceDescriptorShared aDesc);
   async RemoveSharedSurface(ExternalImageId aId);
 
   async NotifyMemoryPressure();
+
+  async ReportMemory() returns (MemoryReport aReport);
 };
 
 } // layers
 } // mozilla
--- a/gfx/layers/wr/ClipManager.cpp
+++ b/gfx/layers/wr/ClipManager.cpp
@@ -8,16 +8,17 @@
 
 #include "DisplayItemClipChain.h"
 #include "FrameMetrics.h"
 #include "LayersLogging.h"
 #include "mozilla/layers/StackingContextHelper.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "nsDisplayList.h"
+#include "nsStyleStructInlines.h"
 #include "UnitTransforms.h"
 
 #define CLIP_LOG(...)
 //#define CLIP_LOG(...) printf_stderr("CLIP: " __VA_ARGS__)
 //#define CLIP_LOG(...) if (XRE_IsContentProcess()) printf_stderr("CLIP: " __VA_ARGS__)
 
 namespace mozilla {
 namespace layers {
@@ -57,17 +58,17 @@ void
 ClipManager::BeginList(const StackingContextHelper& aStackingContext)
 {
   if (aStackingContext.AffectsClipPositioning()) {
     PushOverrideForASR(
         mItemClipStack.empty() ? nullptr : mItemClipStack.top().mASR,
         aStackingContext.ReferenceFrameId());
   }
 
-  ItemClips clips(nullptr, nullptr);
+  ItemClips clips(nullptr, nullptr, false);
   if (!mItemClipStack.empty()) {
     clips.CopyOutputsFrom(mItemClipStack.top());
   }
   mItemClipStack.push(clips);
 }
 
 void
 ClipManager::EndList(const StackingContextHelper& aStackingContext)
@@ -141,48 +142,99 @@ ClipManager::ClipIdAfterOverride(const M
 void
 ClipManager::BeginItem(nsDisplayItem* aItem,
                        const StackingContextHelper& aStackingContext)
 {
   CLIP_LOG("processing item %p\n", aItem);
 
   const DisplayItemClipChain* clip = aItem->GetClipChain();
   const ActiveScrolledRoot* asr = aItem->GetActiveScrolledRoot();
-  if (aItem->GetType() == DisplayItemType::TYPE_STICKY_POSITION) {
+  DisplayItemType type = aItem->GetType();
+  if (type == DisplayItemType::TYPE_STICKY_POSITION) {
     // For sticky position items, the ASR is computed differently depending
     // on whether the item has a fixed descendant or not. But for WebRender
     // purposes we always want to use the ASR that would have been used if it
     // didn't have fixed descendants, which is stored as the "container ASR" on
     // the sticky item.
     asr = static_cast<nsDisplayStickyPosition*>(aItem)->GetContainerASR();
   }
 
-  ItemClips clips(asr, clip);
+  // In most cases we can combine the leaf of the clip chain with the clip rect
+  // of the display item. This reduces the number of clip items, which avoids
+  // some overhead further down the pipeline.
+  bool separateLeaf = false;
+  if (clip && clip->mASR == asr && clip->mClip.GetRoundedRectCount() == 0) {
+    switch (type) {
+      case DisplayItemType::TYPE_BLEND_CONTAINER:
+      case DisplayItemType::TYPE_BLEND_MODE:
+      case DisplayItemType::TYPE_FILTER:
+      case DisplayItemType::TYPE_FIXED_POSITION:
+      case DisplayItemType::TYPE_MASK:
+      case DisplayItemType::TYPE_OPACITY:
+      case DisplayItemType::TYPE_OWN_LAYER:
+      case DisplayItemType::TYPE_PERSPECTIVE:
+      case DisplayItemType::TYPE_RESOLUTION:
+      case DisplayItemType::TYPE_SCROLL_INFO_LAYER:
+      case DisplayItemType::TYPE_STICKY_POSITION:
+      case DisplayItemType::TYPE_SUBDOCUMENT:
+      case DisplayItemType::TYPE_SVG_WRAPPER:
+      case DisplayItemType::TYPE_TABLE_BLEND_CONTAINER:
+      case DisplayItemType::TYPE_TABLE_BLEND_MODE:
+      case DisplayItemType::TYPE_TABLE_FIXED_POSITION:
+      case DisplayItemType::TYPE_TRANSFORM:
+      case DisplayItemType::TYPE_WRAP_LIST:
+        // Container display items are not currently supported because the clip
+        // rect of a stacking context is not handled the same as normal display
+        // items.
+        break;
+      case DisplayItemType::TYPE_TEXT:
+        // Text with shadows interprets the text display item clip rect and
+        // clips from the clip chain differently.
+        if (aItem->Frame()->StyleText()->HasTextShadow()) {
+          break;
+        }
+        MOZ_FALLTHROUGH;
+      default:
+        separateLeaf = true;
+        break;
+    }
+  }
+
+  ItemClips clips(asr, clip, separateLeaf);
   MOZ_ASSERT(!mItemClipStack.empty());
   if (clips.HasSameInputs(mItemClipStack.top())) {
     // Early-exit because if the clips are the same as aItem's previous sibling,
     // then we don't need to do do the work of popping the old stuff and then
     // pushing it right back on for the new item. Note that if aItem doesn't
     // have a previous sibling, that means BeginList would have been called
     // just before this, which will have pushed a ItemClips(nullptr, nullptr)
     // onto mItemClipStack, so the HasSameInputs check should return false.
     CLIP_LOG("early-exit for %p\n", aItem);
     return;
   }
+
   // Pop aItem's previous sibling's stuff from mBuilder in preparation for
   // pushing aItem's stuff.
   mItemClipStack.top().Unapply(mBuilder);
   mItemClipStack.pop();
 
   // Zoom display items report their bounds etc using the parent document's
   // APD because zoom items act as a conversion layer between the two different
   // APDs.
-  int32_t auPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
-  if (aItem->GetType() == DisplayItemType::TYPE_ZOOM) {
+  int32_t auPerDevPixel;
+  if (type == DisplayItemType::TYPE_ZOOM) {
     auPerDevPixel = static_cast<nsDisplayZoom*>(aItem)->GetParentAppUnitsPerDevPixel();
+  } else {
+    auPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
+  }
+
+  // If the leaf of the clip chain is going to be merged with the display item's
+  // clip rect, then we should create a clip chain id from the leaf's parent.
+  if (separateLeaf) {
+    clip = clip->mParent;
   }
 
   // There are two ASR chains here that we need to be fully defined. One is the
   // ASR chain pointed to by |asr|. The other is the
   // ASR chain pointed to by clip->mASR. We pick the leafmost
   // of these two chains because that one will include the other. Calling
   // DefineScrollLayers with this leafmost ASR will recursively define all the
   // ASRs that we care about for this item, but will not actually push
@@ -233,17 +285,17 @@ ClipManager::BeginItem(nsDisplayItem* aI
     // between the |asr| and this |aItem|. Instead we just leave clips.mScrollId
     // empty and things seem to work out.
     // XXX: there might be cases where things don't just "work out", in which
     // case we might need to do something smarter here.
   }
 
   // Now that we have the scroll id and a clip id for the item, push it onto
   // the WR stack.
-  clips.Apply(mBuilder);
+  clips.Apply(mBuilder, auPerDevPixel);
   mItemClipStack.push(clips);
 
   CLIP_LOG("done setup for %p\n", aItem);
 }
 
 Maybe<wr::WrClipId>
 ClipManager::DefineScrollLayers(const ActiveScrolledRoot* aASR,
                                 nsDisplayItem* aItem,
@@ -363,53 +415,63 @@ ClipManager::DefineClipChain(const Displ
 ClipManager::~ClipManager()
 {
   MOZ_ASSERT(!mBuilder);
   MOZ_ASSERT(mCacheStack.empty());
   MOZ_ASSERT(mItemClipStack.empty());
 }
 
 ClipManager::ItemClips::ItemClips(const ActiveScrolledRoot* aASR,
-                                  const DisplayItemClipChain* aChain)
+                                  const DisplayItemClipChain* aChain,
+                                  bool aSeparateLeaf)
   : mASR(aASR)
   , mChain(aChain)
+  , mSeparateLeaf(aSeparateLeaf)
   , mApplied(false)
 {
 }
 
 void
-ClipManager::ItemClips::Apply(wr::DisplayListBuilder* aBuilder)
+ClipManager::ItemClips::Apply(wr::DisplayListBuilder* aBuilder,
+                              int32_t aAppUnitsPerDevPixel)
 {
   MOZ_ASSERT(!mApplied);
   mApplied = true;
-  if (mScrollId) {
-    aBuilder->PushClipAndScrollInfo(*mScrollId,
-                                    mClipChainId.ptrOr(nullptr));
+
+  Maybe<wr::LayoutRect> clipLeaf;
+  if (mSeparateLeaf) {
+    MOZ_ASSERT(mChain);
+    clipLeaf.emplace(wr::ToRoundedLayoutRect(LayoutDeviceRect::FromAppUnits(
+      mChain->mClip.GetClipRect(), aAppUnitsPerDevPixel)));
   }
+
+  aBuilder->PushClipAndScrollInfo(mScrollId.ptrOr(nullptr),
+                                  mClipChainId.ptrOr(nullptr),
+                                  clipLeaf);
 }
 
 void
 ClipManager::ItemClips::Unapply(wr::DisplayListBuilder* aBuilder)
 {
   if (mApplied) {
     mApplied = false;
-    if (mScrollId) {
-      aBuilder->PopClipAndScrollInfo();
-    }
+    aBuilder->PopClipAndScrollInfo(mScrollId.ptrOr(nullptr));
   }
 }
 
 bool
 ClipManager::ItemClips::HasSameInputs(const ItemClips& aOther)
 {
   return mASR == aOther.mASR &&
-         mChain == aOther.mChain;
+         mChain == aOther.mChain &&
+         mSeparateLeaf == aOther.mSeparateLeaf;
 }
 
 void
 ClipManager::ItemClips::CopyOutputsFrom(const ItemClips& aOther)
 {
   mScrollId = aOther.mScrollId;
   mClipChainId = aOther.mClipChainId;
+  mSeparateLeaf = aOther.mSeparateLeaf;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/ClipManager.h
+++ b/gfx/layers/wr/ClipManager.h
@@ -117,30 +117,33 @@ private:
   // is why we need a stack.
   std::unordered_map<wr::WrClipId,
                      std::stack<Maybe<wr::WrClipId>>,
                      wr::WrClipId::HashFn> mASROverride;
 
   // This holds some clip state for a single nsDisplayItem
   struct ItemClips {
     ItemClips(const ActiveScrolledRoot* aASR,
-              const DisplayItemClipChain* aChain);
+              const DisplayItemClipChain* aChain,
+              bool aSeparateLeaf);
 
     // These are the "inputs" - they come from the nsDisplayItem
     const ActiveScrolledRoot* mASR;
     const DisplayItemClipChain* mChain;
+    bool mSeparateLeaf;
 
     // These are the "outputs" - they are pushed to WR as needed
     Maybe<wr::WrClipId> mScrollId;
     Maybe<wr::WrClipChainId> mClipChainId;
 
     // State tracking
     bool mApplied;
 
-    void Apply(wr::DisplayListBuilder* aBuilder);
+    void Apply(wr::DisplayListBuilder* aBuilder,
+               int32_t aAppUnitsPerDevPixel);
     void Unapply(wr::DisplayListBuilder* aBuilder);
     bool HasSameInputs(const ItemClips& aOther);
     void CopyOutputsFrom(const ItemClips& aOther);
   };
 
   // A stack of ItemClips corresponding to the nsDisplayItem ancestry. Each
   // time we recurse into a nsDisplayItem's child list, this stack size
   // increases by one. The topmost item on the stack is for the display item
--- a/gfx/layers/wr/WebRenderMessageUtils.h
+++ b/gfx/layers/wr/WebRenderMessageUtils.h
@@ -172,11 +172,17 @@ template<>
 struct ParamTraits<mozilla::wr::WebRenderError>
   : public ContiguousEnumSerializer<
         mozilla::wr::WebRenderError,
         mozilla::wr::WebRenderError::INITIALIZE,
         mozilla::wr::WebRenderError::Sentinel>
 {
 };
 
+template<>
+struct ParamTraits<mozilla::wr::MemoryReport>
+  : public PlainOldDataSerializer<mozilla::wr::MemoryReport>
+{
+};
+
 } // namespace IPC
 
 #endif // GFX_WEBRENDERMESSAGEUTILS_H
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -626,16 +626,109 @@ static uint32_t GetSkiaGlyphCacheSize()
 
     return cacheSize;
 #else
     return kDefaultGlyphCacheSize;
 #endif // MOZ_WIDGET_ANDROID
 }
 #endif
 
+class WebRenderMemoryReporter final : public nsIMemoryReporter {
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIMEMORYREPORTER
+
+private:
+  ~WebRenderMemoryReporter() = default;
+};
+
+// Memory reporter for WebRender.
+//
+// The reporting within WebRender is manual and incomplete. We could do a much
+// more thorough job by depending on the malloc_size_of crate, but integrating
+// that into WebRender is tricky [1].
+//
+// So the idea is to start with manual reporting for the large allocations
+// detected by DMD, and see how much that can cover in practice (which may
+// require a few rounds of iteration). If that approach turns out to be
+// fundamentally insufficient, we can either duplicate more of the malloc_size_of
+// functionality in WebRender, or deal with the complexity of a gecko-only
+// crate dependency.
+//
+// [1] See https://bugzilla.mozilla.org/show_bug.cgi?id=1480293#c1
+struct WebRenderMemoryReporterHelper {
+  WebRenderMemoryReporterHelper(nsIHandleReportCallback* aCallback, nsISupports* aData)
+    : mCallback(aCallback), mData(aData)
+  {}
+  nsCOMPtr<nsIHandleReportCallback> mCallback;
+  nsCOMPtr<nsISupports> mData;
+
+  void Report(size_t aBytes, const char* aName) const
+  {
+    // Generally, memory reporters pass the empty string as the process name to
+    // indicate "current process". However, if we're using a GPU process, the
+    // measurements will actually take place in that process, and it's easier to
+    // just note that here rather than trying to invoke the memory reporter in
+    // the GPU process.
+    nsAutoCString processName;
+    if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
+      GPUParent::GetGPUProcessName(processName);
+    }
+
+    nsPrintfCString path("explicit/gfx/webrender/%s", aName);
+    mCallback->Callback(processName, path,
+                        nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
+                        aBytes, EmptyCString(), mData);
+  }
+};
+
+static void
+FinishAsyncMemoryReport()
+{
+  nsCOMPtr<nsIMemoryReporterManager> imgr =
+    do_GetService("@mozilla.org/memory-reporter-manager;1");
+  if (imgr) {
+    imgr->EndReport();
+  }
+}
+
+NS_IMPL_ISUPPORTS(WebRenderMemoryReporter, nsIMemoryReporter)
+
+NS_IMETHODIMP
+WebRenderMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
+                                        nsISupports* aData, bool aAnonymize)
+{
+  MOZ_ASSERT(XRE_IsParentProcess());
+  MOZ_ASSERT(NS_IsMainThread());
+  layers::CompositorManagerChild* manager = CompositorManagerChild::GetInstance();
+  if (!manager) {
+    FinishAsyncMemoryReport();
+    return NS_OK;
+  }
+
+  WebRenderMemoryReporterHelper helper(aHandleReport, aData);
+  manager->SendReportMemory(
+    [=](wr::MemoryReport aReport) {
+      helper.Report(aReport.primitive_stores, "primitive-stores");
+      helper.Report(aReport.clip_stores, "clip-stores");
+      helper.Report(aReport.gpu_cache_metadata, "gpu-cache/metadata");
+      helper.Report(aReport.gpu_cache_cpu_mirror, "gpu-cache/cpu-mirror");
+      helper.Report(aReport.render_tasks, "render-tasks");
+      helper.Report(aReport.hit_testers, "hit-testers");
+      FinishAsyncMemoryReport();
+    },
+    [](mozilla::ipc::ResponseRejectReason aReason) {
+      FinishAsyncMemoryReport();
+    }
+  );
+
+  return NS_OK;
+}
+
+
 void
 gfxPlatform::Init()
 {
     MOZ_RELEASE_ASSERT(!XRE_IsGPUProcess(), "GFX: Not allowed in GPU process.");
     MOZ_RELEASE_ASSERT(NS_IsMainThread(), "GFX: Not in main thread.");
 
     if (gEverInitialized) {
         MOZ_CRASH("Already started???");
@@ -818,16 +911,20 @@ gfxPlatform::Init()
 
     // Request the imgITools service, implicitly initializing ImageLib.
     nsCOMPtr<imgITools> imgTools = do_GetService("@mozilla.org/image/tools;1");
     if (!imgTools) {
       MOZ_CRASH("Could not initialize ImageLib");
     }
 
     RegisterStrongMemoryReporter(new GfxMemoryImageReporter());
+    if (XRE_IsParentProcess() && gfxVars::UseWebRender()) {
+      RegisterStrongAsyncMemoryReporter(new WebRenderMemoryReporter());
+    }
+
 #ifdef USE_SKIA
     RegisterStrongMemoryReporter(new SkMemoryReporter());
 #endif
     mlg::InitializeMemoryReporters();
 
 #ifdef USE_SKIA
     uint32_t skiaCacheSize = GetSkiaGlyphCacheSize();
     if (skiaCacheSize != kDefaultGlyphCacheSize) {
--- a/gfx/webrender/res/brush_image.glsl
+++ b/gfx/webrender/res/brush_image.glsl
@@ -43,17 +43,17 @@ ImageBrushData fetch_image_data(int addr
 }
 
 #ifdef WR_FEATURE_ALPHA_PASS
 vec2 transform_point_snapped(
     vec2 local_pos,
     RectWithSize local_rect,
     mat4 transform
 ) {
-    vec2 snap_offset = compute_snap_offset(local_pos, transform, local_rect, vec2(0.5));
+    vec2 snap_offset = compute_snap_offset(local_pos, transform, local_rect);
     vec4 world_pos = transform * vec4(local_pos, 0.0, 1.0);
     vec2 device_pos = world_pos.xy / world_pos.w * uDevicePixelRatio;
 
     return device_pos + snap_offset;
 }
 #endif
 
 void brush_vs(
--- a/gfx/webrender/res/clip_shared.glsl
+++ b/gfx/webrender/res/clip_shared.glsl
@@ -69,18 +69,17 @@ ClipVertexInfo write_clip_tile_vertex(Re
             local_clip_rect
         );
 
         vec2 snap_offsets = compute_snap_offset_impl(
             device_pos,
             clip_transform.m,
             local_clip_rect,
             RectWithSize(snap_positions.xy, snap_positions.zw - snap_positions.xy),
-            snap_positions,
-            vec2(0.5)
+            snap_positions
         );
 
         device_pos -= snap_offsets;
     }
 
     vec2 world_pos = device_pos / uDevicePixelRatio;
 
     vec4 pos = prim_transform.m * vec4(world_pos, 0.0, 1.0);
--- a/gfx/webrender/res/prim_shared.glsl
+++ b/gfx/webrender/res/prim_shared.glsl
@@ -109,18 +109,17 @@ VertexInfo write_vertex(RectWithSize ins
 
     // Clamp to the two local clip rects.
     vec2 clamped_local_pos = clamp_rect(local_pos, local_clip_rect);
 
     /// Compute the snapping offset.
     vec2 snap_offset = compute_snap_offset(
         clamped_local_pos,
         transform.m,
-        snap_rect,
-        vec2(0.5)
+        snap_rect
     );
 
     // Transform the current vertex to world space.
     vec4 world_pos = transform.m * vec4(clamped_local_pos, 0.0, 1.0);
 
     // Convert the world positions to device pixel space.
     vec2 device_pos = world_pos.xy / world_pos.w * uDevicePixelRatio;
 
--- a/gfx/webrender/res/ps_text_run.glsl
+++ b/gfx/webrender/res/ps_text_run.glsl
@@ -56,74 +56,96 @@ struct TextRun {
     vec2 offset;
 };
 
 TextRun fetch_text_run(int address) {
     vec4 data[3] = fetch_from_resource_cache_3(address);
     return TextRun(data[0], data[1], data[2].xy);
 }
 
-VertexInfo write_text_vertex(vec2 clamped_local_pos,
-                             RectWithSize local_clip_rect,
+VertexInfo write_text_vertex(RectWithSize local_clip_rect,
                              float z,
                              Transform transform,
                              PictureTask task,
                              vec2 text_offset,
-                             RectWithSize snap_rect,
+                             vec2 glyph_offset,
+                             RectWithSize glyph_rect,
                              vec2 snap_bias) {
-    // Transform the current vertex to world space.
-    vec4 world_pos = transform.m * vec4(clamped_local_pos, 0.0, 1.0);
+    // The offset to snap the glyph rect to a device pixel
+    vec2 snap_offset = vec2(0.0);
+    mat2 local_transform;
 
-    // Convert the world positions to device pixel space.
-    float device_scale = uDevicePixelRatio / world_pos.w;
-    vec2 device_pos = world_pos.xy * device_scale;
-    vec2 snap_offset = vec2(0.0);
-
-#if defined(WR_FEATURE_GLYPH_TRANSFORM)
+#ifdef WR_FEATURE_GLYPH_TRANSFORM
     bool remove_subpx_offset = true;
 #else
     bool remove_subpx_offset = transform.is_axis_aligned;
 #endif
     // Compute the snapping offset only if the scroll node transform is axis-aligned.
     if (remove_subpx_offset) {
+        // Transform from local space to device space.
+        float device_scale = uDevicePixelRatio / transform.m[3].w;
+        mat2 device_transform = mat2(transform.m) * device_scale;
+
         // Ensure the transformed text offset does not contain a subpixel translation
         // such that glyph snapping is stable for equivalent glyph subpixel positions.
-        vec2 world_text_offset = mat2(transform.m) * text_offset;
-        vec2 device_text_pos = (transform.m[3].xy + world_text_offset) * device_scale;
-        snap_offset += floor(device_text_pos + 0.5) - device_text_pos;
+        vec2 device_text_pos = device_transform * text_offset + transform.m[3].xy * device_scale;
+        snap_offset = floor(device_text_pos + 0.5) - device_text_pos;
+
+        // Snap the glyph offset to a device pixel, using an appropriate bias depending
+        // on whether subpixel positioning is required.
+        vec2 device_glyph_offset = device_transform * glyph_offset;
+        snap_offset += floor(device_glyph_offset + snap_bias) - device_glyph_offset;
 
-#ifdef WR_FEATURE_GLYPH_TRANSFORM
-        // For transformed subpixels, we just need to align the glyph origin to a device pixel.
-        // The transformed text offset has already been snapped, so remove it from the glyph
-        // origin when snapping the glyph.
-        vec2 rough_offset = snap_rect.p0 - world_text_offset * device_scale;
-        snap_offset += floor(rough_offset + snap_bias) - rough_offset;
-#else
-        // The transformed text offset has already been snapped, so remove it from the transform
-        // when snapping the glyph.
-        mat4 snap_transform = transform.m;
-        snap_transform[3].xy = -world_text_offset;
-        snap_offset += compute_snap_offset(
-            clamped_local_pos,
-            snap_transform,
-            snap_rect,
-            snap_bias
-        );
+        // Transform from device space back to local space.
+        local_transform = inverse(device_transform);
+
+#ifndef WR_FEATURE_GLYPH_TRANSFORM
+        // If not using transformed subpixels, the glyph rect is actually in local space.
+        // So convert the snap offset back to local space.
+        snap_offset = local_transform * snap_offset;
 #endif
     }
 
+    // Actually translate the glyph rect to a device pixel using the snap offset.
+    glyph_rect.p0 += snap_offset;
+
+#ifdef WR_FEATURE_GLYPH_TRANSFORM
+    // The glyph rect is in device space, so transform it back to local space.
+    RectWithSize local_rect = transform_rect(glyph_rect, local_transform);
+
+    // Select the corner of the glyph's local space rect that we are processing.
+    vec2 local_pos = local_rect.p0 + local_rect.size * aPosition.xy;
+
+    // If the glyph's local rect would fit inside the local clip rect, then select a corner from
+    // the device space glyph rect to reduce overdraw of clipped pixels in the fragment shader.
+    // Otherwise, fall back to clamping the glyph's local rect to the local clip rect.
+    if (rect_inside_rect(local_rect, local_clip_rect)) {
+        local_pos = local_transform * (glyph_rect.p0 + glyph_rect.size * aPosition.xy);
+    }
+#else
+    // Select the corner of the glyph rect that we are processing.
+    vec2 local_pos = glyph_rect.p0 + glyph_rect.size * aPosition.xy;
+#endif
+
+    // Clamp to the local clip rect.
+    local_pos = clamp_rect(local_pos, local_clip_rect);
+
+    // Map the clamped local space corner into device space.
+    vec4 world_pos = transform.m * vec4(local_pos, 0.0, 1.0);
+    vec2 device_pos = world_pos.xy / world_pos.w * uDevicePixelRatio;
+
     // Apply offsets for the render task to get correct screen location.
-    vec2 final_pos = device_pos + snap_offset -
+    vec2 final_pos = device_pos -
                      task.content_origin +
                      task.common_data.task_rect.p0;
 
     gl_Position = uTransform * vec4(final_pos, z, 1.0);
 
     VertexInfo vi = VertexInfo(
-        clamped_local_pos,
+        local_pos,
         snap_offset,
         world_pos
     );
 
     return vi;
 }
 
 void main(void) {
@@ -151,42 +173,23 @@ void main(void) {
 #ifdef WR_FEATURE_GLYPH_TRANSFORM
     // Transform from local space to glyph space.
     mat2 glyph_transform = mat2(transform.m) * uDevicePixelRatio;
 
     // Compute the glyph rect in glyph space.
     RectWithSize glyph_rect = RectWithSize(res.offset + glyph_transform * (text.offset + glyph.offset),
                                            res.uv_rect.zw - res.uv_rect.xy);
 
-    // Transform the glyph rect back to local space.
-    mat2 inv = inverse(glyph_transform);
-    RectWithSize local_rect = transform_rect(glyph_rect, inv);
-
-    // Select the corner of the glyph's local space rect that we are processing.
-    vec2 local_pos = local_rect.p0 + local_rect.size * aPosition.xy;
-
-    // If the glyph's local rect would fit inside the local clip rect, then select a corner from
-    // the device space glyph rect to reduce overdraw of clipped pixels in the fragment shader.
-    // Otherwise, fall back to clamping the glyph's local rect to the local clip rect.
-    local_pos = rect_inside_rect(local_rect, ph.local_clip_rect) ?
-                    inv * (glyph_rect.p0 + glyph_rect.size * aPosition.xy) :
-                    clamp_rect(local_pos, ph.local_clip_rect);
 #else
     // Scale from glyph space to local space.
     float scale = res.scale / uDevicePixelRatio;
 
     // Compute the glyph rect in local space.
     RectWithSize glyph_rect = RectWithSize(scale * res.offset + text.offset + glyph.offset,
                                            scale * (res.uv_rect.zw - res.uv_rect.xy));
-
-    // Select the corner of the glyph rect that we are processing.
-    vec2 local_pos = glyph_rect.p0 + glyph_rect.size * aPosition.xy;
-
-    // Clamp to the local clip rect.
-    local_pos = clamp_rect(local_pos, ph.local_clip_rect);
 #endif
 
     vec2 snap_bias;
     // In subpixel mode, the subpixel offset has already been
     // accounted for while rasterizing the glyph. However, we
     // must still round with a subpixel bias rather than rounding
     // to the nearest whole pixel, depending on subpixel direciton.
     switch (subpx_dir) {
@@ -204,24 +207,25 @@ void main(void) {
         case SUBPX_DIR_VERTICAL:
             snap_bias = vec2(0.5, 0.125);
             break;
         case SUBPX_DIR_MIXED:
             snap_bias = vec2(0.125);
             break;
     }
 
-    VertexInfo vi = write_text_vertex(local_pos,
-                                      ph.local_clip_rect,
+    VertexInfo vi = write_text_vertex(ph.local_clip_rect,
                                       ph.z,
                                       transform,
                                       task,
                                       text.offset,
+                                      glyph.offset,
                                       glyph_rect,
                                       snap_bias);
+    glyph_rect.p0 += vi.snap_offset;
 
 #ifdef WR_FEATURE_GLYPH_TRANSFORM
     vec2 f = (glyph_transform * vi.local_pos - glyph_rect.p0) / glyph_rect.size;
     vUvClip = vec4(f, 1.0 - f);
 #else
     vec2 f = (vi.local_pos - glyph_rect.p0) / glyph_rect.size;
 #endif
 
--- a/gfx/webrender/res/snap.glsl
+++ b/gfx/webrender/res/snap.glsl
@@ -22,45 +22,42 @@ vec4 compute_snap_positions(mat4 transfo
     return world_snap;
 }
 
 vec2 compute_snap_offset_impl(
     vec2 reference_pos,
     mat4 transform,
     RectWithSize snap_rect,
     RectWithSize reference_rect,
-    vec4 snap_positions,
-    vec2 snap_bias) {
+    vec4 snap_positions) {
 
     /// World offsets applied to the corners of the snap rectangle.
-    vec4 snap_offsets = floor(snap_positions + snap_bias.xyxy) - snap_positions;
+    vec4 snap_offsets = floor(snap_positions + 0.5) - snap_positions;
 
     /// Compute the position of this vertex inside the snap rectangle.
     vec2 normalized_snap_pos = (reference_pos - reference_rect.p0) / reference_rect.size;
 
     /// Compute the actual world offset for this vertex needed to make it snap.
     return mix(snap_offsets.xy, snap_offsets.zw, normalized_snap_pos);
 }
 
 // Compute a snapping offset in world space (adjusted to pixel ratio),
 // given local position on the transform and a snap rectangle.
 vec2 compute_snap_offset(vec2 local_pos,
                          mat4 transform,
-                         RectWithSize snap_rect,
-                         vec2 snap_bias) {
+                         RectWithSize snap_rect) {
     vec4 snap_positions = compute_snap_positions(
         transform,
         snap_rect
     );
 
     vec2 snap_offsets = compute_snap_offset_impl(
         local_pos,
         transform,
         snap_rect,
         snap_rect,
-        snap_positions,
-        snap_bias
+        snap_positions
     );
 
     return snap_offsets;
 }
 
 #endif //WR_VERTEX_SHADER
--- a/gfx/webrender/src/clip.rs
+++ b/gfx/webrender/src/clip.rs
@@ -1,28 +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::{BorderRadius, ClipMode, ComplexClipRegion, DeviceIntRect, DevicePixelScale, ImageMask};
 use api::{ImageRendering, LayoutRect, LayoutSize, LayoutPoint, LayoutVector2D, LocalClip};
 use api::{BoxShadowClipMode, LayoutToWorldScale, LineOrientation, LineStyle, PicturePixel, WorldPixel};
 use api::{PictureRect, LayoutPixel, WorldPoint, WorldSize, WorldRect, LayoutToWorldTransform};
+use api::{VoidPtrToSizeFn};
 use border::{ensure_no_corner_overlap};
 use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowClipSource, BoxShadowCacheKey};
 use clip_scroll_tree::{ClipScrollTree, CoordinateSystemId, ROOT_SPATIAL_NODE_INDEX, SpatialNodeIndex};
 use ellipse::Ellipse;
 use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks};
 use gpu_types::{BoxShadowStretchMode};
 use internal_types::FastHashSet;
 use prim_store::{ClipData, ImageMaskData, SpaceMapper};
 use render_task::to_cache_size;
 use resource_cache::{ImageRequest, ResourceCache};
 use std::{cmp, u32};
-use util::{extract_inner_rect_safe, pack_as_float, project_rect, recycle_vec, ScaleOffset};
+use std::os::raw::c_void;
+use util::{extract_inner_rect_safe, pack_as_float, project_rect, ScaleOffset};
 
 /*
 
  Module Overview
 
  There are a number of data structures involved in the clip module:
 
  ClipStore - Main interface used by other modules.
@@ -342,26 +344,16 @@ impl ClipStore {
             clip_nodes: Vec::new(),
             clip_chain_nodes: Vec::new(),
             clip_node_indices: Vec::new(),
             clip_node_info: Vec::new(),
             clip_node_collectors: Vec::new(),
         }
     }
 
-    pub fn recycle(self) -> Self {
-        ClipStore {
-            clip_nodes: recycle_vec(self.clip_nodes),
-            clip_chain_nodes: recycle_vec(self.clip_chain_nodes),
-            clip_node_indices: recycle_vec(self.clip_node_indices),
-            clip_node_info: recycle_vec(self.clip_node_info),
-            clip_node_collectors: recycle_vec(self.clip_node_collectors),
-        }
-    }
-
     pub fn add_clip_items(
         &mut self,
         clip_items: Vec<ClipItem>,
         spatial_node_index: SpatialNodeIndex,
     ) -> ClipItemRange {
         debug_assert!(!clip_items.is_empty());
 
         let range = ClipItemRange {
@@ -624,16 +616,28 @@ impl ClipStore {
             clips_range,
             has_non_root_coord_system,
             has_non_local_clips,
             local_clip_rect,
             pic_clip_rect,
             needs_mask,
         })
     }
+
+    /// Reports the heap usage of this clip store.
+    pub fn malloc_size_of(&self, op: VoidPtrToSizeFn) -> usize {
+        let mut size = 0;
+        unsafe {
+            size += op(self.clip_nodes.as_ptr() as *const c_void);
+            size += op(self.clip_chain_nodes.as_ptr() as *const c_void);
+            size += op(self.clip_node_indices.as_ptr() as *const c_void);
+            size += op(self.clip_node_info.as_ptr() as *const c_void);
+        }
+        size
+    }
 }
 
 #[derive(Debug)]
 pub struct LineDecorationClipSource {
     rect: LayoutRect,
     style: LineStyle,
     orientation: LineOrientation,
     wavy_line_thickness: f32,
--- a/gfx/webrender/src/display_list_flattener.rs
+++ b/gfx/webrender/src/display_list_flattener.rs
@@ -18,28 +18,28 @@ use clip_scroll_tree::{ClipScrollTree, S
 use euclid::vec2;
 use frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig};
 use glyph_rasterizer::FontInstance;
 use gpu_cache::GpuCacheHandle;
 use gpu_types::BrushFlags;
 use hit_test::{HitTestingItem, HitTestingRun};
 use image::simplify_repeated_primitive;
 use internal_types::{FastHashMap, FastHashSet};
-use picture::{PictureCompositeMode, PictureId, PicturePrimitive};
+use picture::{PictureCompositeMode, PictureIdGenerator, PicturePrimitive};
 use prim_store::{BrushKind, BrushPrimitive, BrushSegmentDescriptor};
 use prim_store::{EdgeAaSegmentMask, ImageSource};
 use prim_store::{BorderSource, BrushSegment, PrimitiveContainer, PrimitiveIndex, PrimitiveStore};
 use prim_store::{OpacityBinding, ScrollNodeAndClipChain, TextRunPrimitive};
 use render_backend::{DocumentView};
 use resource_cache::{FontInstanceMap, ImageRequest};
 use scene::{Scene, ScenePipeline, StackingContextHelpers};
 use spatial_node::{SpatialNodeType, StickyFrameInfo};
 use std::{f32, iter, mem};
 use tiling::{CompositeOps, ScrollbarPrimitive};
-use util::{MaxRect, RectHelpers, recycle_vec};
+use util::{MaxRect, RectHelpers};
 
 static DEFAULT_SCROLLBAR_COLOR: ColorF = ColorF {
     r: 0.3,
     g: 0.3,
     b: 0.3,
     a: 0.6,
 };
 
@@ -88,16 +88,19 @@ impl ClipIdToIndexMapper {
 /// members are typically those that are destructured into the FrameBuilder.
 pub struct DisplayListFlattener<'a> {
     /// The scene that we are currently flattening.
     scene: &'a Scene,
 
     /// The ClipScrollTree that we are currently building during flattening.
     clip_scroll_tree: &'a mut ClipScrollTree,
 
+    /// A counter for generating unique picture ids.
+    picture_id_generator: &'a mut PictureIdGenerator,
+
     /// The map of all font instances.
     font_instances: FontInstanceMap,
 
     /// A set of pipelines that the caller has requested be made available as
     /// output textures.
     output_pipelines: &'a FastHashSet<PipelineId>,
 
     /// The data structure that converting between ClipId and the various index
@@ -123,55 +126,53 @@ pub struct DisplayListFlattener<'a> {
     pub hit_testing_runs: Vec<HitTestingRun>,
 
     /// The store which holds all complex clipping information.
     pub clip_store: ClipStore,
 
     /// The configuration to use for the FrameBuilder. We consult this in
     /// order to determine the default font.
     pub config: FrameBuilderConfig,
-
-    pub next_picture_id: u64,
 }
 
 impl<'a> DisplayListFlattener<'a> {
     pub fn create_frame_builder(
-        old_builder: FrameBuilder,
         scene: &Scene,
         clip_scroll_tree: &mut ClipScrollTree,
         font_instances: FontInstanceMap,
         view: &DocumentView,
         output_pipelines: &FastHashSet<PipelineId>,
         frame_builder_config: &FrameBuilderConfig,
         new_scene: &mut Scene,
         scene_id: u64,
+        picture_id_generator: &mut PictureIdGenerator,
     ) -> FrameBuilder {
         // We checked that the root pipeline is available on the render backend.
         let root_pipeline_id = scene.root_pipeline_id.unwrap();
         let root_pipeline = scene.pipelines.get(&root_pipeline_id).unwrap();
 
         let background_color = root_pipeline
             .background_color
             .and_then(|color| if color.a > 0.0 { Some(color) } else { None });
 
         let mut flattener = DisplayListFlattener {
             scene,
             clip_scroll_tree,
             font_instances,
             config: *frame_builder_config,
             output_pipelines,
             id_to_index_mapper: ClipIdToIndexMapper::default(),
-            hit_testing_runs: recycle_vec(old_builder.hit_testing_runs),
-            scrollbar_prims: recycle_vec(old_builder.scrollbar_prims),
+            hit_testing_runs: Vec::new(),
+            scrollbar_prims: Vec::new(),
             shadow_stack: Vec::new(),
             sc_stack: Vec::new(),
-            next_picture_id: old_builder.next_picture_id,
             pipeline_clip_chain_stack: vec![ClipChainId::NONE],
-            prim_store: old_builder.prim_store.recycle(),
-            clip_store: old_builder.clip_store.recycle(),
+            prim_store: PrimitiveStore::new(),
+            clip_store: ClipStore::new(),
+            picture_id_generator,
         };
 
         flattener.push_root(
             root_pipeline_id,
             &root_pipeline.viewport_size,
             &root_pipeline.content_size,
         );
         flattener.setup_viewport_offset(view.inner_rect, view.accumulated_scale_factor());
@@ -882,22 +883,16 @@ impl<'a> DisplayListFlattener<'a> {
             }
             self.add_primitive_to_hit_testing_list(info, clip_and_scroll);
             self.add_primitive_to_draw_list(
                 prim_index,
             );
         }
     }
 
-    fn get_next_picture_id(&mut self) -> PictureId {
-        let id = PictureId(self.next_picture_id);
-        self.next_picture_id += 1;
-        id
-    }
-
     pub fn push_stacking_context(
         &mut self,
         pipeline_id: PipelineId,
         composite_ops: CompositeOps,
         transform_style: TransformStyle,
         is_backface_visible: bool,
         is_pipeline_root: bool,
         spatial_node: ClipId,
@@ -967,17 +962,17 @@ impl<'a> DisplayListFlattener<'a> {
             //           During culling, we can check if there is actually
             //           perspective present, and skip the plane splitting
             //           completely when that is not the case.
             composite_mode = Some(PictureCompositeMode::Blit);
         }
 
         // Add picture for this actual stacking context contents to render into.
         let leaf_picture = PicturePrimitive::new_image(
-            self.get_next_picture_id(),
+            self.picture_id_generator.next(),
             composite_mode,
             participating_in_3d_context,
             pipeline_id,
             frame_output_pipeline_id,
             true,
         );
 
         // Create a brush primitive that draws this picture.
@@ -996,17 +991,17 @@ impl<'a> DisplayListFlattener<'a> {
 
         // Create a chain of pictures based on presence of filters,
         // mix-blend-mode and/or 3d rendering context containers.
         let mut current_prim_index = leaf_prim_index;
 
         // For each filter, create a new image with that composite mode.
         for filter in &composite_ops.filters {
             let mut filter_picture = PicturePrimitive::new_image(
-                self.get_next_picture_id(),
+                self.picture_id_generator.next(),
                 Some(PictureCompositeMode::Filter(*filter)),
                 false,
                 pipeline_id,
                 None,
                 true,
             );
 
             filter_picture.add_primitive(current_prim_index);
@@ -1021,17 +1016,17 @@ impl<'a> DisplayListFlattener<'a> {
                 None,
                 PrimitiveContainer::Brush(filter_prim),
             );
         }
 
         // Same for mix-blend-mode.
         if let Some(mix_blend_mode) = composite_ops.mix_blend_mode {
             let mut blend_picture = PicturePrimitive::new_image(
-                self.get_next_picture_id(),
+                self.picture_id_generator.next(),
                 Some(PictureCompositeMode::MixBlend(mix_blend_mode)),
                 false,
                 pipeline_id,
                 None,
                 true,
             );
 
             blend_picture.add_primitive(current_prim_index);
@@ -1048,17 +1043,17 @@ impl<'a> DisplayListFlattener<'a> {
             );
         }
 
         if establishes_3d_context {
             // If establishing a 3d context, we need to add a picture
             // that will be the container for all the planes and any
             // un-transformed content.
             let mut container_picture = PicturePrimitive::new_image(
-                self.get_next_picture_id(),
+                self.picture_id_generator.next(),
                 None,
                 false,
                 pipeline_id,
                 None,
                 true,
             );
 
             container_picture.add_primitive(current_prim_index);
@@ -1323,17 +1318,17 @@ impl<'a> DisplayListFlattener<'a> {
         // the local clip rect to primitives.
         let apply_local_clip_rect = shadow.blur_radius == 0.0;
 
         // Create a picture that the shadow primitives will be added to. If the
         // blur radius is 0, the code in Picture::prepare_for_render will
         // detect this and mark the picture to be drawn directly into the
         // parent picture, which avoids an intermediate surface and blur.
         let shadow_pic = PicturePrimitive::new_image(
-            self.get_next_picture_id(),
+            self.picture_id_generator.next(),
             Some(PictureCompositeMode::Filter(FilterOp::Blur(std_deviation))),
             false,
             pipeline_id,
             None,
             apply_local_clip_rect,
         );
 
         // Create the primitive to draw the shadow picture into the scene.
--- a/gfx/webrender/src/frame_builder.rs
+++ b/gfx/webrender/src/frame_builder.rs
@@ -53,17 +53,16 @@ pub struct FrameBuilderConfig {
 }
 
 /// A builder structure for `tiling::Frame`
 pub struct FrameBuilder {
     screen_rect: DeviceUintRect,
     background_color: Option<ColorF>,
     window_size: DeviceUintSize,
     scene_id: u64,
-    pub next_picture_id: u64,
     pub prim_store: PrimitiveStore,
     pub clip_store: ClipStore,
     pub hit_testing_runs: Vec<HitTestingRun>,
     pub config: FrameBuilderConfig,
     pub scrollbar_prims: Vec<ScrollbarPrimitive>,
 }
 
 pub struct FrameBuildingContext<'a> {
@@ -123,27 +122,27 @@ impl<'a> PrimitiveContext<'a> {
         PrimitiveContext {
             spatial_node,
             spatial_node_index,
         }
     }
 }
 
 impl FrameBuilder {
+    #[cfg(feature = "replay")]
     pub fn empty() -> Self {
         FrameBuilder {
             hit_testing_runs: Vec::new(),
             scrollbar_prims: Vec::new(),
             prim_store: PrimitiveStore::new(),
             clip_store: ClipStore::new(),
             screen_rect: DeviceUintRect::zero(),
             window_size: DeviceUintSize::zero(),
             background_color: None,
             scene_id: 0,
-            next_picture_id: 0,
             config: FrameBuilderConfig {
                 enable_scrollbars: false,
                 default_font_render_mode: FontRenderMode::Mono,
                 dual_source_blending_is_enabled: true,
                 dual_source_blending_is_supported: false,
                 chase_primitive: ChasePrimitive::Nothing,
             },
         }
@@ -161,17 +160,16 @@ impl FrameBuilder {
             scrollbar_prims: flattener.scrollbar_prims,
             prim_store: flattener.prim_store,
             clip_store: flattener.clip_store,
             screen_rect,
             background_color,
             window_size,
             scene_id,
             config: flattener.config,
-            next_picture_id: flattener.next_picture_id,
         }
     }
 
     /// 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,
         clip_scroll_tree: &ClipScrollTree,
--- a/gfx/webrender/src/gpu_cache.rs
+++ b/gfx/webrender/src/gpu_cache.rs
@@ -20,22 +20,24 @@
 //! will be invoked to build the data.
 //!
 //! After ```end_frame``` has occurred, callers can
 //! use the ```get_address``` API to get the allocated
 //! address in the GPU cache of a given resource slot
 //! for this frame.
 
 use api::{PremultipliedColorF, TexelRect};
+use api::{VoidPtrToSizeFn};
 use device::FrameId;
 use euclid::TypedRect;
 use profiler::GpuCacheProfileCounters;
 use renderer::MAX_VERTEX_TEXTURE_WIDTH;
 use std::{mem, u16, u32};
 use std::ops::Add;
+use std::os::raw::c_void;
 
 
 pub const GPU_CACHE_INITIAL_HEIGHT: u32 = 512;
 const FRAMES_BEFORE_EVICTION: usize = 10;
 const NEW_ROWS_PER_RESIZE: u32 = 512;
 
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
@@ -335,16 +337,28 @@ impl Texture {
             free_lists: FreeBlockLists::new(),
             pending_blocks: Vec::new(),
             updates: Vec::new(),
             occupied_list_head: None,
             allocated_block_count: 0,
         }
     }
 
+    // Reports the CPU heap usage of this Texture struct.
+    fn malloc_size_of(&self, op: VoidPtrToSizeFn) -> usize {
+        let mut size = 0;
+        unsafe {
+            size += op(self.blocks.as_ptr() as *const c_void);
+            size += op(self.rows.as_ptr() as *const c_void);
+            size += op(self.pending_blocks.as_ptr() as *const c_void);
+            size += op(self.updates.as_ptr() as *const c_void);
+        }
+        size
+    }
+
     // Push new data into the cache. The ```pending_block_index``` field represents
     // where the data was pushed into the texture ```pending_blocks``` array.
     // Return the allocated address for this data.
     fn push_data(
         &mut self,
         pending_block_index: Option<usize>,
         block_count: usize,
         frame_id: FrameId,
@@ -640,9 +654,14 @@ impl GpuCache {
     /// freed or pending slot will panic!
     pub fn get_address(&self, id: &GpuCacheHandle) -> GpuCacheAddress {
         let location = id.location.expect("handle not requested or allocated!");
         let block = &self.texture.blocks[location.block_index.0];
         debug_assert_eq!(block.epoch, location.epoch);
         debug_assert_eq!(block.last_access_time, self.frame_id);
         block.address
     }
+
+    /// Reports the CPU heap usage of this GpuCache struct.
+    pub fn malloc_size_of(&self, op: VoidPtrToSizeFn) -> usize {
+        self.texture.malloc_size_of(op)
+    }
 }
--- a/gfx/webrender/src/hit_test.rs
+++ b/gfx/webrender/src/hit_test.rs
@@ -1,19 +1,20 @@
 /* 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::{BorderRadius, ClipMode, HitTestFlags, HitTestItem, HitTestResult, ItemTag, LayoutPoint};
-use api::{LayoutPrimitiveInfo, LayoutRect, PipelineId, WorldPoint};
+use api::{LayoutPrimitiveInfo, LayoutRect, PipelineId, VoidPtrToSizeFn, WorldPoint};
 use clip::{ClipNodeIndex, ClipChainNode, ClipNode, ClipItem, ClipStore};
 use clip::{ClipChainId, rounded_rectangle_contains_point};
 use clip_scroll_tree::{SpatialNodeIndex, ClipScrollTree};
 use internal_types::FastHashMap;
 use prim_store::ScrollNodeAndClipChain;
+use std::os::raw::c_void;
 use util::LayoutToWorldFastTransform;
 
 /// A copy of important clip scroll node data to use during hit testing. This a copy of
 /// data from the ClipScrollTree that will persist as a new frame is under construction,
 /// allowing hit tests consistent with the currently rendered frame.
 pub struct HitTestSpatialNode {
     /// The pipeline id of this node.
     pipeline_id: PipelineId,
@@ -331,16 +332,31 @@ impl HitTester {
 
         result.items.dedup();
         result
     }
 
     pub fn get_pipeline_root(&self, pipeline_id: PipelineId) -> &HitTestSpatialNode {
         &self.spatial_nodes[self.pipeline_root_nodes[&pipeline_id].0]
     }
+
+    // Reports the CPU heap usage of this HitTester struct.
+    pub fn malloc_size_of(&self, op: VoidPtrToSizeFn) -> usize {
+        let mut size = 0;
+        unsafe {
+            size += op(self.runs.as_ptr() as *const c_void);
+            size += op(self.spatial_nodes.as_ptr() as *const c_void);
+            size += op(self.clip_nodes.as_ptr() as *const c_void);
+            size += op(self.clip_chains.as_ptr() as *const c_void);
+            // We can't measure pipeline_root_nodes because we don't have the
+            // real machinery from the malloc_size_of crate. We could estimate
+            // it but it should generally be very small so we don't bother.
+        }
+        size
+    }
 }
 
 #[derive(Clone, Copy, PartialEq)]
 enum ClippedIn {
     ClippedIn,
     NotClippedIn,
 }
 
--- a/gfx/webrender/src/picture.rs
+++ b/gfx/webrender/src/picture.rs
@@ -73,16 +73,39 @@ pub enum PictureSurface {
 // doing deep compares of picture content, these
 // may be the same across display lists, but that's
 // not currently supported.
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct PictureId(pub u64);
 
+// TODO(gw): Having to generate globally unique picture
+//           ids for caching is not ideal. We should be
+//           able to completely remove this once we cache
+//           pictures based on their content, rather than
+//           the current cache key structure.
+pub struct PictureIdGenerator {
+    next: u64,
+}
+
+impl PictureIdGenerator {
+    pub fn new() -> Self {
+        PictureIdGenerator {
+            next: 0,
+        }
+    }
+
+    pub fn next(&mut self) -> PictureId {
+        let id = PictureId(self.next);
+        self.next += 1;
+        id
+    }
+}
+
 // Cache key that determines whether a pre-existing
 // picture in the texture cache matches the content
 // of the current picture.
 #[derive(Clone, Debug, Hash, PartialEq, Eq)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct PictureCacheKey {
     // NOTE: We specifically want to ensure that we
--- a/gfx/webrender/src/prim_store.rs
+++ b/gfx/webrender/src/prim_store.rs
@@ -25,17 +25,17 @@ use picture::{PictureCompositeMode, Pict
 use render_backend::FrameId;
 use render_task::{BlitSource, RenderTask, RenderTaskCacheKey};
 use render_task::{RenderTaskCacheKeyKind, RenderTaskId, RenderTaskCacheEntryHandle};
 use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
 use resource_cache::{ImageProperties, ImageRequest, ResourceCache};
 use scene::SceneProperties;
 use segment::SegmentBuilder;
 use std::{cmp, fmt, mem, usize};
-use util::{ScaleOffset, MatrixHelpers, pack_as_float, recycle_vec, project_rect, raster_rect_to_device_pixels};
+use util::{ScaleOffset, MatrixHelpers, pack_as_float, project_rect, raster_rect_to_device_pixels};
 
 
 const MIN_BRUSH_SPLIT_AREA: f32 = 256.0 * 256.0;
 pub const VECS_PER_SEGMENT: usize = 2;
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub struct ScrollNodeAndClipChain {
     pub spatial_node_index: SpatialNodeIndex,
@@ -1381,23 +1381,16 @@ pub struct PrimitiveStore {
 impl PrimitiveStore {
     pub fn new() -> PrimitiveStore {
         PrimitiveStore {
             primitives: Vec::new(),
             chase_id: None,
         }
     }
 
-    pub fn recycle(self) -> Self {
-        PrimitiveStore {
-            primitives: recycle_vec(self.primitives),
-            chase_id: self.chase_id,
-        }
-    }
-
     pub fn get_pic(&self, index: PrimitiveIndex) -> &PicturePrimitive {
         self.primitives[index.0].as_pic()
     }
 
     pub fn get_pic_mut(&mut self, index: PrimitiveIndex) -> &mut PicturePrimitive {
         self.primitives[index.0].as_pic_mut()
     }
 
--- a/gfx/webrender/src/render_backend.rs
+++ b/gfx/webrender/src/render_backend.rs
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use api::{ApiMsg, BuiltDisplayList, ClearCache, DebugCommand};
 #[cfg(feature = "debugger")]
 use api::{BuiltDisplayListIter, SpecificDisplayItem};
 use api::{DeviceIntPoint, DevicePixelScale, DeviceUintPoint, DeviceUintRect, DeviceUintSize};
 use api::{DocumentId, DocumentLayer, ExternalScrollId, FrameMsg, HitTestFlags, HitTestResult};
 use api::{IdNamespace, LayoutPoint, PipelineId, RenderNotifier, SceneMsg, ScrollClamping};
+use api::{MemoryReport, VoidPtrToSizeFn};
 use api::{ScrollLocation, ScrollNodeState, TransactionMsg, ResourceUpdate, ImageKey};
 use api::{NotificationRequest, Checkpoint};
 use api::channel::{MsgReceiver, Payload};
 #[cfg(feature = "capture")]
 use api::CaptureBits;
 #[cfg(feature = "replay")]
 use api::CapturedDocument;
 use clip_scroll_tree::{SpatialNodeIndex, ClipScrollTree};
@@ -35,16 +36,17 @@ use scene_builder::*;
 #[cfg(feature = "serialize")]
 use serde::{Serialize, Deserialize};
 #[cfg(feature = "debugger")]
 use serde_json;
 #[cfg(any(feature = "capture", feature = "replay"))]
 use std::path::PathBuf;
 use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
 use std::mem::replace;
+use std::os::raw::c_void;
 use std::sync::mpsc::{channel, Sender, Receiver};
 use std::u32;
 #[cfg(feature = "replay")]
 use tiling::Frame;
 use time::precise_time_ns;
 use util::drain_filter;
 
 #[cfg_attr(feature = "capture", derive(Serialize))]
@@ -379,16 +381,17 @@ pub struct RenderBackend {
     resource_cache: ResourceCache,
 
     frame_config: FrameBuilderConfig,
     documents: FastHashMap<DocumentId, Document>,
 
     notifier: Box<RenderNotifier>,
     recorder: Option<Box<ApiRecordingReceiver>>,
     sampler: Option<Box<AsyncPropertySampler + Send>>,
+    size_of_op: Option<VoidPtrToSizeFn>,
 
     last_scene_id: u64,
 }
 
 impl RenderBackend {
     pub fn new(
         api_rx: MsgReceiver<ApiMsg>,
         payload_rx: Receiver<Payload>,
@@ -397,16 +400,17 @@ impl RenderBackend {
         low_priority_scene_tx: Sender<SceneBuilderRequest>,
         scene_rx: Receiver<SceneBuilderResult>,
         default_device_pixel_ratio: f32,
         resource_cache: ResourceCache,
         notifier: Box<RenderNotifier>,
         frame_config: FrameBuilderConfig,
         recorder: Option<Box<ApiRecordingReceiver>>,
         sampler: Option<Box<AsyncPropertySampler + Send>>,
+        size_of_op: Option<VoidPtrToSizeFn>,
     ) -> RenderBackend {
         // The namespace_id should start from 1.
         NEXT_NAMESPACE_ID.fetch_add(1, Ordering::Relaxed);
 
         RenderBackend {
             api_rx,
             payload_rx,
             result_tx,
@@ -417,16 +421,17 @@ impl RenderBackend {
             default_device_pixel_ratio,
             resource_cache,
             gpu_cache: GpuCache::new(),
             frame_config,
             documents: FastHashMap::default(),
             notifier,
             recorder,
             sampler,
+            size_of_op,
             last_scene_id: 0,
         }
     }
 
     fn process_scene_msg(
         &mut self,
         document_id: DocumentId,
         message: SceneMsg,
@@ -729,16 +734,19 @@ impl RenderBackend {
                 let pending_update = self.resource_cache.pending_updates();
                 let msg = ResultMsg::UpdateResources {
                     updates: pending_update,
                     cancel_rendering: true,
                 };
                 self.result_tx.send(msg).unwrap();
                 self.notifier.wake_up();
             }
+            ApiMsg::ReportMemory(tx) => {
+                tx.send(self.report_memory()).unwrap();
+            }
             ApiMsg::DebugCommand(option) => {
                 let msg = match option {
                     DebugCommand::EnableDualSourceBlending(enable) => {
                         // Set in the config used for any future documents
                         // that are created.
                         self.frame_config
                             .dual_source_blending_is_enabled = enable;
 
@@ -1134,16 +1142,37 @@ impl RenderBackend {
 
             doc.clip_scroll_tree.print_with(&mut builder);
 
             debug_root.add(builder.build());
         }
 
         serde_json::to_string(&debug_root).unwrap()
     }
+
+    fn size_of<T>(&self, ptr: *const T) -> usize {
+        let op = self.size_of_op.as_ref().unwrap();
+        unsafe { op(ptr as *const c_void) }
+    }
+
+    fn report_memory(&self) -> MemoryReport {
+        let mut report = MemoryReport::default();
+        let op = self.size_of_op.as_ref().unwrap();
+        report.gpu_cache_metadata = self.gpu_cache.malloc_size_of(*op);
+        for (_id, doc) in &self.documents {
+            if let Some(ref fb) = doc.frame_builder {
+                report.primitive_stores += self.size_of(fb.prim_store.primitives.as_ptr());
+                report.clip_stores += fb.clip_store.malloc_size_of(*op);
+            }
+            report.hit_testers +=
+                doc.hit_tester.as_ref().map_or(0, |ht| ht.malloc_size_of(*op));
+        }
+
+        report
+    }
 }
 
 fn get_blob_image_updates(updates: &[ResourceUpdate]) -> Vec<ImageKey> {
     let mut requests = Vec::new();
     for update in updates {
         match *update {
             ResourceUpdate::AddImage(ref img) => {
                 if img.data.is_blob() {
--- a/gfx/webrender/src/renderer.rs
+++ b/gfx/webrender/src/renderer.rs
@@ -8,16 +8,17 @@
 //! is accessible through [`Renderer`][renderer]
 //!
 //! [renderer]: struct.Renderer.html
 
 use api::{BlobImageHandler, ColorF, DeviceIntPoint, DeviceIntRect, DeviceIntSize};
 use api::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, DocumentId, Epoch, ExternalImageId};
 use api::{ExternalImageType, FontRenderMode, FrameMsg, ImageFormat, PipelineId};
 use api::{ImageRendering};
+use api::{MemoryReport, VoidPtrToSizeFn};
 use api::{RenderApiSender, RenderNotifier, TexelRect, TextureTarget};
 use api::{channel};
 use api::DebugCommand;
 use api::channel::PayloadReceiverHelperMethods;
 use batch::{BatchKind, BatchTextures, BrushBatchKind};
 #[cfg(any(feature = "capture", feature = "replay"))]
 use capture::{CaptureConfig, ExternalCaptureImage, PlainExternalImage};
 use debug_colors;
@@ -50,16 +51,17 @@ use render_task::{RenderTask, RenderTask
 use resource_cache::ResourceCache;
 
 use std;
 use std::cmp;
 use std::collections::VecDeque;
 use std::collections::hash_map::Entry;
 use std::f32;
 use std::mem;
+use std::os::raw::c_void;
 use std::path::PathBuf;
 use std::rc::Rc;
 use std::sync::Arc;
 use std::sync::mpsc::{channel, Receiver, Sender};
 use std::thread;
 use texture_cache::TextureCache;
 use thread_profiler::{register_thread_with_profiler, write_profile};
 use tiling::{AlphaRenderTarget, ColorRenderTarget};
@@ -1375,16 +1377,19 @@ pub struct Renderer {
     /// application to provide external buffers for image data.
     external_image_handler: Option<Box<ExternalImageHandler>>,
 
     /// Optional trait object that allows the client
     /// application to provide a texture handle to
     /// copy the WR output to.
     output_image_handler: Option<Box<OutputImageHandler>>,
 
+    /// Optional function pointer for memory reporting.
+    size_of_op: Option<VoidPtrToSizeFn>,
+
     // Currently allocated FBOs for output frames.
     output_targets: FastHashMap<u32, FrameOutput>,
 
     pub renderer_errors: Vec<RendererError>,
 
     /// List of profile results from previous frames. Can be retrieved
     /// via get_frame_profiles().
     cpu_profiles: VecDeque<CpuProfile>,
@@ -1665,16 +1670,17 @@ impl Renderer {
                         if let Some(ref thread_listener) = *thread_listener_for_rayon_end {
                             thread_listener.thread_stopped(&format!("WRWorker#{}", idx));
                         }
                     })
                     .build();
                 Arc::new(worker.unwrap())
             });
         let sampler = options.sampler;
+        let size_of_op = options.size_of_op;
 
         let blob_image_handler = options.blob_image_handler.take();
         let thread_listener_for_render_backend = thread_listener.clone();
         let thread_listener_for_scene_builder = thread_listener.clone();
         let thread_listener_for_lp_scene_builder = thread_listener.clone();
         let scene_builder_hooks = options.scene_builder_hooks;
         let rb_thread_name = format!("WRRenderBackend#{}", options.renderer_id.unwrap_or(0));
         let scene_thread_name = format!("WRSceneBuilder#{}", options.renderer_id.unwrap_or(0));
@@ -1746,16 +1752,17 @@ impl Renderer {
                 low_priority_scene_tx,
                 scene_rx,
                 device_pixel_ratio,
                 resource_cache,
                 backend_notifier,
                 config,
                 recorder,
                 sampler,
+                size_of_op,
             );
             backend.run(backend_profile_counters);
             if let Some(ref thread_listener) = *thread_listener_for_render_backend {
                 thread_listener.thread_stopped(&rb_thread_name);
             }
         })?;
 
         let ext_debug_marker = device.supports_extension("GL_EXT_debug_marker");
@@ -1799,16 +1806,17 @@ impl Renderer {
             transforms_texture,
             prim_header_i_texture,
             prim_header_f_texture,
             render_task_texture,
             pipeline_info: PipelineInfo::default(),
             dither_matrix_texture,
             external_image_handler: None,
             output_image_handler: None,
+            size_of_op: options.size_of_op,
             output_targets: FastHashMap::default(),
             cpu_profiles: VecDeque::new(),
             gpu_profiles: VecDeque::new(),
             gpu_cache_texture,
             gpu_cache_frame_id: FrameId::new(0),
             gpu_cache_overflow: false,
             texture_cache_upload_pbo,
             texture_resolver,
@@ -4028,16 +4036,36 @@ impl Renderer {
         self.device.delete_fbo(self.read_fbo);
         #[cfg(feature = "replay")]
         for (_, ext) in self.owned_external_images {
             self.device.delete_external_texture(ext);
         }
         self.device.end_frame();
     }
 
+    fn size_of<T>(&self, ptr: *const T) -> usize {
+        let op = self.size_of_op.as_ref().unwrap();
+        unsafe { op(ptr as *const c_void) }
+    }
+
+    /// Collects a memory report.
+    pub fn report_memory(&self) -> MemoryReport {
+        let mut report = MemoryReport::default();
+        if let CacheBus::PixelBuffer{ref cpu_blocks, ..} = self.gpu_cache_texture.bus {
+            report.gpu_cache_cpu_mirror += self.size_of(cpu_blocks.as_ptr());
+        }
+
+        for (_id, doc) in &self.active_documents {
+            report.render_tasks += self.size_of(doc.frame.render_tasks.tasks.as_ptr());
+            report.render_tasks += self.size_of(doc.frame.render_tasks.task_data.as_ptr());
+        }
+
+        report
+    }
+
     // Sets the blend mode. Blend is unconditionally set if the "show overdraw" debugging mode is
     // enabled.
     fn set_blend(&self, mut blend: bool, framebuffer_kind: FramebufferKind) {
         if framebuffer_kind == FramebufferKind::Main &&
                 self.debug_flags.contains(DebugFlags::SHOW_OVERDRAW) {
             blend = true
         }
         self.device.set_blend(blend)
@@ -4187,16 +4215,17 @@ pub struct RendererOptions {
     pub enable_clear_scissor: bool,
     pub max_texture_size: Option<u32>,
     pub scatter_gpu_cache_updates: bool,
     pub upload_method: UploadMethod,
     pub workers: Option<Arc<ThreadPool>>,
     pub blob_image_handler: Option<Box<BlobImageHandler>>,
     pub recorder: Option<Box<ApiRecordingReceiver>>,
     pub thread_listener: Option<Box<ThreadListener + Send + Sync>>,
+    pub size_of_op: Option<VoidPtrToSizeFn>,
     pub cached_programs: Option<Rc<ProgramCache>>,
     pub debug_flags: DebugFlags,
     pub renderer_id: Option<u64>,
     pub disable_dual_source_blending: bool,
     pub scene_builder_hooks: Option<Box<SceneBuilderHooks + Send>>,
     pub sampler: Option<Box<AsyncPropertySampler + Send>>,
     pub chase_primitive: ChasePrimitive,
     pub support_low_priority_transactions: bool,
@@ -4222,16 +4251,17 @@ impl Default for RendererOptions {
             scatter_gpu_cache_updates: false,
             // This is best as `Immediate` on Angle, or `Pixelbuffer(Dynamic)` on GL,
             // but we are unable to make this decision here, so picking the reasonable medium.
             upload_method: UploadMethod::PixelBuffer(VertexUsageHint::Stream),
             workers: None,
             blob_image_handler: None,
             recorder: None,
             thread_listener: None,
+            size_of_op: None,
             renderer_id: None,
             cached_programs: None,
             disable_dual_source_blending: false,
             scene_builder_hooks: None,
             sampler: None,
             chase_primitive: ChasePrimitive::Nothing,
             support_low_priority_transactions: false,
         }
--- a/gfx/webrender/src/scene_builder.rs
+++ b/gfx/webrender/src/scene_builder.rs
@@ -5,16 +5,17 @@
 use api::{AsyncBlobImageRasterizer, BlobImageRequest, BlobImageParams, BlobImageResult};
 use api::{DocumentId, PipelineId, ApiMsg, FrameMsg, ResourceUpdate, Epoch};
 use api::{BuiltDisplayList, ColorF, LayoutSize, NotificationRequest, Checkpoint};
 use api::channel::MsgSender;
 use frame_builder::{FrameBuilderConfig, FrameBuilder};
 use clip_scroll_tree::ClipScrollTree;
 use display_list_flattener::DisplayListFlattener;
 use internal_types::{FastHashMap, FastHashSet};
+use picture::PictureIdGenerator;
 use resource_cache::FontInstanceMap;
 use render_backend::DocumentView;
 use renderer::{PipelineInfo, SceneBuilderHooks};
 use scene::Scene;
 use std::sync::mpsc::{channel, Receiver, Sender};
 use std::mem::replace;
 use time::precise_time_ns;
 use util::drain_filter;
@@ -134,16 +135,17 @@ pub enum SceneSwapResult {
 
 pub struct SceneBuilder {
     documents: FastHashMap<DocumentId, Scene>,
     rx: Receiver<SceneBuilderRequest>,
     tx: Sender<SceneBuilderResult>,
     api_tx: MsgSender<ApiMsg>,
     config: FrameBuilderConfig,
     hooks: Option<Box<SceneBuilderHooks + Send>>,
+    picture_id_generator: PictureIdGenerator,
 }
 
 impl SceneBuilder {
     pub fn new(
         config: FrameBuilderConfig,
         api_tx: MsgSender<ApiMsg>,
         hooks: Option<Box<SceneBuilderHooks + Send>>,
     ) -> (Self, Sender<SceneBuilderRequest>, Receiver<SceneBuilderResult>) {
@@ -152,16 +154,17 @@ impl SceneBuilder {
         (
             SceneBuilder {
                 documents: FastHashMap::default(),
                 rx: in_rx,
                 tx: out_tx,
                 api_tx,
                 config,
                 hooks,
+                picture_id_generator: PictureIdGenerator::new(),
             },
             in_tx,
             out_rx,
         )
     }
 
     /// The scene builder thread's event loop.
     pub fn run(&mut self) {
@@ -219,25 +222,25 @@ impl SceneBuilder {
             let scene_build_start_time = precise_time_ns();
 
             let mut built_scene = None;
             if item.scene.has_root_pipeline() {
                 let mut clip_scroll_tree = ClipScrollTree::new();
                 let mut new_scene = Scene::new();
 
                 let frame_builder = DisplayListFlattener::create_frame_builder(
-                    FrameBuilder::empty(),
                     &item.scene,
                     &mut clip_scroll_tree,
                     item.font_instances,
                     &item.view,
                     &item.output_pipelines,
                     &self.config,
                     &mut new_scene,
                     item.scene_id,
+                    &mut self.picture_id_generator,
                 );
 
                 built_scene = Some(BuiltScene {
                     scene: new_scene,
                     frame_builder,
                     clip_scroll_tree,
                 });
             }
@@ -295,25 +298,25 @@ impl SceneBuilder {
 
         let mut built_scene = None;
         if scene.has_root_pipeline() {
             if let Some(request) = txn.request_scene_build.take() {
                 let mut clip_scroll_tree = ClipScrollTree::new();
                 let mut new_scene = Scene::new();
 
                 let frame_builder = DisplayListFlattener::create_frame_builder(
-                    FrameBuilder::empty(),
                     &scene,
                     &mut clip_scroll_tree,
                     request.font_instances,
                     &request.view,
                     &request.output_pipelines,
                     &self.config,
                     &mut new_scene,
                     request.scene_id,
+                    &mut self.picture_id_generator,
                 );
 
                 built_scene = Some(BuiltScene {
                     scene: new_scene,
                     frame_builder,
                     clip_scroll_tree,
                 });
             }
--- a/gfx/webrender/src/util.rs
+++ b/gfx/webrender/src/util.rs
@@ -371,32 +371,16 @@ pub fn extract_inner_rect_safe<U>(
     rect: &TypedRect<f32, U>,
     radii: &BorderRadius,
 ) -> Option<TypedRect<f32, U>> {
     // value of `k==1.0` is used for extraction of the corner rectangles
     // see `SEGMENT_CORNER_*` in `clip_shared.glsl`
     extract_inner_rect_impl(rect, radii, 1.0)
 }
 
-/// Consumes the old vector and returns a new one that may reuse the old vector's allocated
-/// memory.
-pub fn recycle_vec<T>(mut old_vec: Vec<T>) -> Vec<T> {
-    if old_vec.capacity() > 2 * old_vec.len() {
-        // Avoid reusing the buffer if it is a lot larger than it needs to be. This prevents
-        // a frame with exceptionally large allocations to cause subsequent frames to retain
-        // more memory than they need.
-        return Vec::with_capacity(old_vec.len());
-    }
-
-    old_vec.clear();
-
-    old_vec
-}
-
-
 #[cfg(test)]
 pub mod test {
     use super::*;
     use euclid::{Point2D, Angle, Transform3D};
     use std::f32::consts::PI;
 
     #[test]
     fn inverse_project() {
--- a/gfx/webrender_api/src/api.rs
+++ b/gfx/webrender_api/src/api.rs
@@ -4,16 +4,17 @@
 
 extern crate serde_bytes;
 
 use app_units::Au;
 use channel::{self, MsgSender, Payload, PayloadSender, PayloadSenderHelperMethods};
 use std::cell::Cell;
 use std::fmt;
 use std::marker::PhantomData;
+use std::os::raw::c_void;
 use std::path::PathBuf;
 use std::sync::Arc;
 use std::u32;
 use {BuiltDisplayList, BuiltDisplayListDescriptor, ColorF, DeviceIntPoint, DeviceUintRect};
 use {DeviceUintSize, ExternalScrollId, FontInstanceKey, FontInstanceOptions};
 use {FontInstancePlatformOptions, FontKey, FontVariation, GlyphDimensions, GlyphIndex, ImageData};
 use {ImageDescriptor, ImageKey, ItemTag, LayoutPoint, LayoutSize, LayoutTransform, LayoutVector2D};
 use {NativeFontHandle, WorldPoint, NormalizedRect};
@@ -662,16 +663,18 @@ pub enum ApiMsg {
     /// An opaque handle that must be passed to the render notifier. It is used by Gecko
     /// to forward gecko-specific messages to the render thread preserving the ordering
     /// within the other messages.
     ExternalEvent(ExternalEvent),
     /// Removes all resources associated with a namespace.
     ClearNamespace(IdNamespace),
     /// Flush from the caches anything that isn't necessary, to free some memory.
     MemoryPressure,
+    /// Collects a memory report.
+    ReportMemory(MsgSender<MemoryReport>),
     /// Change debugging options.
     DebugCommand(DebugCommand),
     /// Wakes the render backend's event loop up. Needed when an event is communicated
     /// through another channel.
     WakeUp,
     WakeSceneBuilder,
     FlushSceneBuilder(MsgSender<()>),
     ShutDown,
@@ -685,16 +688,17 @@ impl fmt::Debug for ApiMsg {
             ApiMsg::GetGlyphIndices(..) => "ApiMsg::GetGlyphIndices",
             ApiMsg::CloneApi(..) => "ApiMsg::CloneApi",
             ApiMsg::AddDocument(..) => "ApiMsg::AddDocument",
             ApiMsg::UpdateDocument(..) => "ApiMsg::UpdateDocument",
             ApiMsg::DeleteDocument(..) => "ApiMsg::DeleteDocument",
             ApiMsg::ExternalEvent(..) => "ApiMsg::ExternalEvent",
             ApiMsg::ClearNamespace(..) => "ApiMsg::ClearNamespace",
             ApiMsg::MemoryPressure => "ApiMsg::MemoryPressure",
+            ApiMsg::ReportMemory(..) => "ApiMsg::ReportMemory",
             ApiMsg::DebugCommand(..) => "ApiMsg::DebugCommand",
             ApiMsg::ShutDown => "ApiMsg::ShutDown",
             ApiMsg::WakeUp => "ApiMsg::WakeUp",
             ApiMsg::WakeSceneBuilder => "ApiMsg::WakeSceneBuilder",
             ApiMsg::FlushSceneBuilder(..) => "ApiMsg::FlushSceneBuilder",
         })
     }
 }
@@ -730,16 +734,44 @@ pub type PipelineSourceId = u32;
 pub struct PipelineId(pub PipelineSourceId, pub u32);
 
 impl PipelineId {
     pub fn dummy() -> Self {
         PipelineId(0, 0)
     }
 }
 
+/// Collection of heap sizes, in bytes.
+#[repr(C)]
+#[derive(Clone, Debug, Default, Deserialize, Serialize)]
+pub struct MemoryReport {
+    pub primitive_stores: usize,
+    pub clip_stores: usize,
+    pub gpu_cache_metadata: usize,
+    pub gpu_cache_cpu_mirror: usize,
+    pub render_tasks: usize,
+    pub hit_testers: usize,
+}
+
+impl ::std::ops::AddAssign for MemoryReport {
+    fn add_assign(&mut self, other: MemoryReport) {
+        self.primitive_stores += other.primitive_stores;
+        self.clip_stores += other.clip_stores;
+        self.gpu_cache_metadata += other.gpu_cache_metadata;
+        self.gpu_cache_cpu_mirror += other.gpu_cache_cpu_mirror;
+        self.render_tasks += other.render_tasks;
+        self.hit_testers += other.hit_testers;
+    }
+}
+
+/// A C function that takes a pointer to a heap allocation and returns its size.
+///
+/// This is borrowed from the malloc_size_of crate, upon which we want to avoid
+/// a dependency from WebRender.
+pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
 
 #[repr(C)]
 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
 pub struct ResourceId(pub u32);
 
 /// An opaque pointer-sized value.
 #[repr(C)]
 #[derive(Clone, Deserialize, Serialize)]
@@ -892,16 +924,22 @@ impl RenderApi {
         let msg = ApiMsg::ExternalEvent(evt);
         self.api_sender.send(msg).unwrap();
     }
 
     pub fn notify_memory_pressure(&self) {
         self.api_sender.send(ApiMsg::MemoryPressure).unwrap();
     }
 
+    pub fn report_memory(&self) -> MemoryReport {
+        let (tx, rx) = channel::msg_channel().unwrap();
+        self.api_sender.send(ApiMsg::ReportMemory(tx)).unwrap();
+        rx.recv().unwrap()
+    }
+
     pub fn shut_down(&self) {
         self.api_sender.send(ApiMsg::ShutDown).unwrap();
     }
 
     /// Create a new unique key that can be used for
     /// animated property bindings.
     pub fn generate_property_binding_key<T: Copy>(&self) -> PropertyBindingKey<T> {
         let new_id = self.next_unique_id();
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -138,16 +138,46 @@ RenderThread::Loop()
 // static
 bool
 RenderThread::IsInRenderThread()
 {
   return sRenderThread && sRenderThread->mThread->thread_id() == PlatformThread::CurrentId();
 }
 
 void
+RenderThread::DoAccumulateMemoryReport(MemoryReport aReport, const RefPtr<MemoryReportPromise::Private>& aPromise)
+{
+  MOZ_ASSERT(IsInRenderThread());
+  for (auto& r: mRenderers) {
+    wr_renderer_accumulate_memory_report(r.second->GetRenderer(), &aReport);
+  }
+
+  aPromise->Resolve(aReport, __func__);
+}
+
+// static
+RefPtr<MemoryReportPromise>
+RenderThread::AccumulateMemoryReport(MemoryReport aInitial)
+{
+  RefPtr<MemoryReportPromise::Private> p = new MemoryReportPromise::Private(__func__);
+  MOZ_ASSERT(!IsInRenderThread());
+  MOZ_ASSERT(Get());
+  Get()->Loop()->PostTask(
+    NewRunnableMethod<MemoryReport, RefPtr<MemoryReportPromise::Private>>(
+      "wr::RenderThread::DoAccumulateMemoryReport",
+      Get(),
+      &RenderThread::DoAccumulateMemoryReport,
+      aInitial, p
+    )
+  );
+
+  return p;
+}
+
+void
 RenderThread::AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer)
 {
   MOZ_ASSERT(IsInRenderThread());
 
   if (mHasShutdown) {
     return;
   }
 
--- a/gfx/webrender_bindings/RenderThread.h
+++ b/gfx/webrender_bindings/RenderThread.h
@@ -8,29 +8,32 @@
 #define MOZILLA_LAYERS_RENDERTHREAD_H
 
 #include "base/basictypes.h"            // for DISALLOW_EVIL_CONSTRUCTORS
 #include "base/platform_thread.h"       // for PlatformThreadId
 #include "base/thread.h"                // for Thread
 #include "base/message_loop.h"
 #include "nsISupportsImpl.h"
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
+#include "mozilla/MozPromise.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/webrender/webrender_ffi.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/webrender/WebRenderTypes.h"
 #include "mozilla/layers/SynchronousTask.h"
 
 #include <list>
 #include <queue>
 #include <unordered_map>
 
 namespace mozilla {
 namespace wr {
 
+typedef MozPromise<MemoryReport, bool, true> MemoryReportPromise;
+
 class RendererOGL;
 class RenderTextureHost;
 class RenderThread;
 
 /// A rayon thread pool that is shared by all WebRender instances within a process.
 class WebRenderThreadPool {
 public:
   WebRenderThreadPool();
@@ -101,16 +104,21 @@ public:
   /// In most cases it is best to post RendererEvents through WebRenderAPI instead
   /// of scheduling directly to this message loop (so as to preserve the ordering
   /// of the messages).
   static MessageLoop* Loop();
 
   /// Can be called from any thread.
   static bool IsInRenderThread();
 
+  // Can be called from any thread. Dispatches an event to the Renderer thread
+  // to iterate over all Renderers, accumulates memory statistics, and resolves
+  // the return promise.
+  static RefPtr<MemoryReportPromise> AccumulateMemoryReport(MemoryReport aInitial);
+
   /// Can only be called from the render thread.
   void AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer);
 
   /// Can only be called from the render thread.
   void RemoveRenderer(wr::WindowId aWindowId);
 
   /// Can only be called from the render thread.
   RendererOGL* GetRenderer(wr::WindowId aWindowId);
@@ -182,16 +190,18 @@ public:
 
 private:
   explicit RenderThread(base::Thread* aThread);
 
   void DeferredRenderTextureHostDestroy();
   void ShutDownTask(layers::SynchronousTask* aTask);
   void ProgramCacheTask();
 
+  void DoAccumulateMemoryReport(MemoryReport, const RefPtr<MemoryReportPromise::Private>&);
+
   ~RenderThread();
 
   base::Thread* const mThread;
 
   WebRenderThreadPool mThreadPool;
   UniquePtr<WebRenderProgramCache> mProgramCache;
 
   std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -19,16 +19,18 @@
 //#define WRDL_LOG(...) printf_stderr("WRDL(%p): " __VA_ARGS__)
 //#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): " __VA_ARGS__)
 
 namespace mozilla {
 namespace wr {
 
 using layers::Stringify;
 
+MOZ_DEFINE_MALLOC_SIZE_OF(WebRenderMallocSizeOf)
+
 class NewRenderer : public RendererEvent
 {
 public:
   NewRenderer(wr::DocumentHandle** aDocHandle,
               layers::CompositorBridgeParent* aBridge,
               uint32_t* aMaxTextureSize,
               bool* aUseANGLE,
               bool* aUseDComp,
@@ -67,16 +69,17 @@ public:
     *mUseANGLE = compositor->UseANGLE();
     *mUseDComp = compositor->UseDComp();
 
     bool supportLowPriorityTransactions = true; // TODO only for main windows.
     wr::Renderer* wrRenderer = nullptr;
     if (!wr_window_new(aWindowId, mSize.width, mSize.height, supportLowPriorityTransactions,
                        compositor->gl(),
                        aRenderThread.ThreadPool().Raw(),
+                       &WebRenderMallocSizeOf,
                        mDocHandle, &wrRenderer,
                        mMaxTextureSize)) {
       // wr_window_new puts a message into gfxCriticalNote if it returns false
       return;
     }
     MOZ_ASSERT(wrRenderer);
 
     RefPtr<RenderThread> thread = &aRenderThread;
@@ -512,16 +515,22 @@ WebRenderAPI::Resume()
 
 void
 WebRenderAPI::NotifyMemoryPressure()
 {
   wr_api_notify_memory_pressure(mDocHandle);
 }
 
 void
+WebRenderAPI::AccumulateMemoryReport(MemoryReport* aReport)
+{
+  wr_api_accumulate_memory_report(mDocHandle, aReport);
+}
+
+void
 WebRenderAPI::WakeSceneBuilder()
 {
     wr_api_wake_scene_builder(mDocHandle);
 }
 
 void
 WebRenderAPI::FlushSceneBuilder()
 {
@@ -813,16 +822,19 @@ DisplayListBuilder::PushStackingContext(
                                         const gfx::Matrix4x4* aTransform,
                                         wr::TransformStyle aTransformStyle,
                                         const gfx::Matrix4x4* aPerspective,
                                         const wr::MixBlendMode& aMixBlendMode,
                                         const nsTArray<wr::WrFilterOp>& aFilters,
                                         bool aIsBackfaceVisible,
                                         const wr::GlyphRasterSpace& aRasterSpace)
 {
+  MOZ_ASSERT(mClipChainLeaf.isNothing(),
+             "Non-empty leaf from clip chain given, but not used with SC!");
+
   wr::LayoutTransform matrix;
   if (aTransform) {
     matrix = ToLayoutTransform(*aTransform);
   }
   const wr::LayoutTransform* maybeTransform = aTransform ? &matrix : nullptr;
   wr::LayoutTransform perspective;
   if (aPerspective) {
     perspective = ToLayoutTransform(*aPerspective);
@@ -969,66 +981,77 @@ DisplayListBuilder::DefineScrollLayer(co
       Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
 
    auto clipId = wr::WrClipId { numericScrollId };
    mScrollIds[aViewId] = clipId;
    return clipId;
 }
 
 void
-DisplayListBuilder::PushClipAndScrollInfo(const wr::WrClipId& aScrollId,
-                                          const wr::WrClipChainId* aClipChainId)
+DisplayListBuilder::PushClipAndScrollInfo(const wr::WrClipId* aScrollId,
+                                          const wr::WrClipChainId* aClipChainId,
+                                          const Maybe<wr::LayoutRect>& aClipChainLeaf)
 {
-  WRDL_LOG("PushClipAndScroll s=%zu c=%s\n", mWrState, aScrollId.id,
-      aClipChainId ? Stringify(aClipChainId->id).c_str() : "none");
-  wr_dp_push_clip_and_scroll_info(mWrState, aScrollId.id,
-      aClipChainId ? &(aClipChainId->id) : nullptr);
+  if (aScrollId) {
+    WRDL_LOG("PushClipAndScroll s=%zu c=%s\n", mWrState, aScrollId->id,
+        aClipChainId ? Stringify(aClipChainId->id).c_str() : "none");
+    wr_dp_push_clip_and_scroll_info(mWrState, aScrollId->id,
+        aClipChainId ? &(aClipChainId->id) : nullptr);
+  }
+  mClipChainLeaf = aClipChainLeaf;
 }
 
 void
-DisplayListBuilder::PopClipAndScrollInfo()
+DisplayListBuilder::PopClipAndScrollInfo(const wr::WrClipId* aScrollId)
 {
-  WRDL_LOG("PopClipAndScroll\n", mWrState);
-  wr_dp_pop_clip_and_scroll_info(mWrState);
+  if (aScrollId) {
+    WRDL_LOG("PopClipAndScroll\n", mWrState);
+    wr_dp_pop_clip_and_scroll_info(mWrState);
+  }
+  mClipChainLeaf.reset();
 }
 
 void
 DisplayListBuilder::PushRect(const wr::LayoutRect& aBounds,
                              const wr::LayoutRect& aClip,
                              bool aIsBackfaceVisible,
                              const wr::ColorF& aColor)
 {
+  wr::LayoutRect clip = MergeClipLeaf(aClip);
   WRDL_LOG("PushRect b=%s cl=%s c=%s\n", mWrState,
       Stringify(aBounds).c_str(),
-      Stringify(aClip).c_str(),
+      Stringify(clip).c_str(),
       Stringify(aColor).c_str());
-  wr_dp_push_rect(mWrState, aBounds, aClip, aIsBackfaceVisible, aColor);
+  wr_dp_push_rect(mWrState, aBounds, clip,
+                  aIsBackfaceVisible, aColor);
 }
 
 void
 DisplayListBuilder::PushClearRect(const wr::LayoutRect& aBounds)
 {
-  WRDL_LOG("PushClearRect b=%s\n", mWrState,
-      Stringify(aBounds).c_str());
-  wr_dp_push_clear_rect(mWrState, aBounds);
+  wr::LayoutRect clip = MergeClipLeaf(aBounds);
+  WRDL_LOG("PushClearRect b=%s c=%s\n", mWrState,
+      Stringify(aBounds).c_str(), Stringify(clip).c_str());
+  wr_dp_push_clear_rect(mWrState, aBounds, clip);
 }
 
 void
 DisplayListBuilder::PushLinearGradient(const wr::LayoutRect& aBounds,
                                        const wr::LayoutRect& aClip,
                                        bool aIsBackfaceVisible,
                                        const wr::LayoutPoint& aStartPoint,
                                        const wr::LayoutPoint& aEndPoint,
                                        const nsTArray<wr::GradientStop>& aStops,
                                        wr::ExtendMode aExtendMode,
                                        const wr::LayoutSize aTileSize,
                                        const wr::LayoutSize aTileSpacing)
 {
   wr_dp_push_linear_gradient(mWrState,
-                             aBounds, aClip, aIsBackfaceVisible,
+                             aBounds, MergeClipLeaf(aClip),
+                             aIsBackfaceVisible,
                              aStartPoint, aEndPoint,
                              aStops.Elements(), aStops.Length(),
                              aExtendMode,
                              aTileSize, aTileSpacing);
 }
 
 void
 DisplayListBuilder::PushRadialGradient(const wr::LayoutRect& aBounds,
@@ -1037,17 +1060,18 @@ DisplayListBuilder::PushRadialGradient(c
                                        const wr::LayoutPoint& aCenter,
                                        const wr::LayoutSize& aRadius,
                                        const nsTArray<wr::GradientStop>& aStops,
                                        wr::ExtendMode aExtendMode,
                                        const wr::LayoutSize aTileSize,
                                        const wr::LayoutSize aTileSpacing)
 {
   wr_dp_push_radial_gradient(mWrState,
-                             aBounds, aClip, aIsBackfaceVisible,
+                             aBounds, MergeClipLeaf(aClip),
+                             aIsBackfaceVisible,
                              aCenter, aRadius,
                              aStops.Elements(), aStops.Length(),
                              aExtendMode,
                              aTileSize, aTileSpacing);
 }
 
 void
 DisplayListBuilder::PushImage(const wr::LayoutRect& aBounds,
@@ -1056,50 +1080,54 @@ DisplayListBuilder::PushImage(const wr::
                               wr::ImageRendering aFilter,
                               wr::ImageKey aImage,
                               bool aPremultipliedAlpha,
                               const wr::ColorF& aColor)
 {
   wr::LayoutSize size;
   size.width = aBounds.size.width;
   size.height = aBounds.size.height;
-  PushImage(aBounds, aClip, aIsBackfaceVisible, size, size, aFilter, aImage, aPremultipliedAlpha, aColor);
+  PushImage(aBounds, aClip, aIsBackfaceVisible, size, size,
+            aFilter, aImage, aPremultipliedAlpha, aColor);
 }
 
 void
 DisplayListBuilder::PushImage(const wr::LayoutRect& aBounds,
                               const wr::LayoutRect& aClip,
                               bool aIsBackfaceVisible,
                               const wr::LayoutSize& aStretchSize,
                               const wr::LayoutSize& aTileSpacing,
                               wr::ImageRendering aFilter,
                               wr::ImageKey aImage,
                               bool aPremultipliedAlpha,
                               const wr::ColorF& aColor)
 {
+  wr::LayoutRect clip = MergeClipLeaf(aClip);
   WRDL_LOG("PushImage b=%s cl=%s s=%s t=%s\n", mWrState,
       Stringify(aBounds).c_str(),
-      Stringify(aClip).c_str(), Stringify(aStretchSize).c_str(),
+      Stringify(clip).c_str(), Stringify(aStretchSize).c_str(),
       Stringify(aTileSpacing).c_str());
-  wr_dp_push_image(mWrState, aBounds, aClip, aIsBackfaceVisible, aStretchSize, aTileSpacing, aFilter, aImage, aPremultipliedAlpha, aColor);
+  wr_dp_push_image(mWrState, aBounds, clip, aIsBackfaceVisible,
+                   aStretchSize, aTileSpacing, aFilter, aImage,
+                   aPremultipliedAlpha, aColor);
 }
 
 void
 DisplayListBuilder::PushYCbCrPlanarImage(const wr::LayoutRect& aBounds,
                                          const wr::LayoutRect& aClip,
                                          bool aIsBackfaceVisible,
                                          wr::ImageKey aImageChannel0,
                                          wr::ImageKey aImageChannel1,
                                          wr::ImageKey aImageChannel2,
                                          wr::WrYuvColorSpace aColorSpace,
                                          wr::ImageRendering aRendering)
 {
   wr_dp_push_yuv_planar_image(mWrState,
                               aBounds,
-                              aClip,
+                              MergeClipLeaf(aClip),
                               aIsBackfaceVisible,
                               aImageChannel0,
                               aImageChannel1,
                               aImageChannel2,
                               aColorSpace,
                               aRendering);
 }
 
@@ -1109,17 +1137,17 @@ DisplayListBuilder::PushNV12Image(const 
                                   bool aIsBackfaceVisible,
                                   wr::ImageKey aImageChannel0,
                                   wr::ImageKey aImageChannel1,
                                   wr::WrYuvColorSpace aColorSpace,
                                   wr::ImageRendering aRendering)
 {
   wr_dp_push_yuv_NV12_image(mWrState,
                             aBounds,
-                            aClip,
+                            MergeClipLeaf(aClip),
                             aIsBackfaceVisible,
                             aImageChannel0,
                             aImageChannel1,
                             aColorSpace,
                             aRendering);
 }
 
 void
@@ -1127,136 +1155,141 @@ DisplayListBuilder::PushYCbCrInterleaved
                                               const wr::LayoutRect& aClip,
                                               bool aIsBackfaceVisible,
                                               wr::ImageKey aImageChannel0,
                                               wr::WrYuvColorSpace aColorSpace,
                                               wr::ImageRendering aRendering)
 {
   wr_dp_push_yuv_interleaved_image(mWrState,
                                    aBounds,
-                                   aClip,
+                                   MergeClipLeaf(aClip),
                                    aIsBackfaceVisible,
                                    aImageChannel0,
                                    aColorSpace,
                                    aRendering);
 }
 
 void
 DisplayListBuilder::PushIFrame(const wr::LayoutRect& aBounds,
                                bool aIsBackfaceVisible,
                                PipelineId aPipeline,
                                bool aIgnoreMissingPipeline)
 {
-  wr_dp_push_iframe(mWrState, aBounds, aIsBackfaceVisible, aPipeline, aIgnoreMissingPipeline);
+  wr_dp_push_iframe(mWrState, aBounds, MergeClipLeaf(aBounds),
+                    aIsBackfaceVisible, aPipeline, aIgnoreMissingPipeline);
 }
 
 void
 DisplayListBuilder::PushBorder(const wr::LayoutRect& aBounds,
                                const wr::LayoutRect& aClip,
                                bool aIsBackfaceVisible,
                                const wr::BorderWidths& aWidths,
                                const Range<const wr::BorderSide>& aSides,
                                const wr::BorderRadius& aRadius)
 {
   MOZ_ASSERT(aSides.length() == 4);
   if (aSides.length() != 4) {
     return;
   }
-  wr_dp_push_border(mWrState, aBounds, aClip, aIsBackfaceVisible,
+  wr_dp_push_border(mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
                     aWidths, aSides[0], aSides[1], aSides[2], aSides[3], aRadius);
 }
 
 void
 DisplayListBuilder::PushBorderImage(const wr::LayoutRect& aBounds,
                                     const wr::LayoutRect& aClip,
                                     bool aIsBackfaceVisible,
                                     const wr::BorderWidths& aWidths,
                                     wr::ImageKey aImage,
                                     const uint32_t aWidth,
                                     const uint32_t aHeight,
                                     const wr::SideOffsets2D<uint32_t>& aSlice,
                                     const wr::SideOffsets2D<float>& aOutset,
                                     const wr::RepeatMode& aRepeatHorizontal,
                                     const wr::RepeatMode& aRepeatVertical)
 {
-  wr_dp_push_border_image(mWrState, aBounds, aClip, aIsBackfaceVisible,
-                          aWidths, aImage, aWidth, aHeight, aSlice, aOutset,
-                          aRepeatHorizontal, aRepeatVertical);
+  wr_dp_push_border_image(mWrState, aBounds, MergeClipLeaf(aClip),
+                          aIsBackfaceVisible, aWidths, aImage, aWidth, aHeight,
+                          aSlice, aOutset, aRepeatHorizontal, aRepeatVertical);
 }
 
 void
 DisplayListBuilder::PushBorderGradient(const wr::LayoutRect& aBounds,
                                        const wr::LayoutRect& aClip,
                                        bool aIsBackfaceVisible,
                                        const wr::BorderWidths& aWidths,
                                        const uint32_t aWidth,
                                        const uint32_t aHeight,
                                        const wr::SideOffsets2D<uint32_t>& aSlice,
                                        const wr::LayoutPoint& aStartPoint,
                                        const wr::LayoutPoint& aEndPoint,
                                        const nsTArray<wr::GradientStop>& aStops,
                                        wr::ExtendMode aExtendMode,
                                        const wr::SideOffsets2D<float>& aOutset)
 {
-  wr_dp_push_border_gradient(mWrState, aBounds, aClip, aIsBackfaceVisible,
-                             aWidths, aWidth, aHeight, aSlice, aStartPoint, aEndPoint,
+  wr_dp_push_border_gradient(mWrState, aBounds, MergeClipLeaf(aClip),
+                             aIsBackfaceVisible, aWidths, aWidth, aHeight,
+                             aSlice, aStartPoint, aEndPoint,
                              aStops.Elements(), aStops.Length(),
                              aExtendMode, aOutset);
 }
 
 void
 DisplayListBuilder::PushBorderRadialGradient(const wr::LayoutRect& aBounds,
                                              const wr::LayoutRect& aClip,
                                              bool aIsBackfaceVisible,
                                              const wr::BorderWidths& aWidths,
                                              const wr::LayoutPoint& aCenter,
                                              const wr::LayoutSize& aRadius,
                                              const nsTArray<wr::GradientStop>& aStops,
                                              wr::ExtendMode aExtendMode,
                                              const wr::SideOffsets2D<float>& aOutset)
 {
   wr_dp_push_border_radial_gradient(
-    mWrState, aBounds, aClip, aIsBackfaceVisible, aWidths, aCenter,
-    aRadius, aStops.Elements(), aStops.Length(),
+    mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
+    aWidths, aCenter, aRadius, aStops.Elements(), aStops.Length(),
     aExtendMode, aOutset);
 }
 
 void
 DisplayListBuilder::PushText(const wr::LayoutRect& aBounds,
                              const wr::LayoutRect& aClip,
                              bool aIsBackfaceVisible,
                              const wr::ColorF& aColor,
                              wr::FontInstanceKey aFontKey,
                              Range<const wr::GlyphInstance> aGlyphBuffer,
                              const wr::GlyphOptions* aGlyphOptions)
 {
-  wr_dp_push_text(mWrState, aBounds, aClip, aIsBackfaceVisible,
+  wr_dp_push_text(mWrState, aBounds, MergeClipLeaf(aClip),
+                  aIsBackfaceVisible,
                   aColor,
                   aFontKey,
                   &aGlyphBuffer[0], aGlyphBuffer.length(),
                   aGlyphOptions);
 }
 
 void
 DisplayListBuilder::PushLine(const wr::LayoutRect& aClip,
                              bool aIsBackfaceVisible,
                              const wr::Line& aLine)
 {
- wr_dp_push_line(mWrState, &aClip, aIsBackfaceVisible,
-                 &aLine.bounds, aLine.wavyLineThickness, aLine.orientation,
-                 &aLine.color, aLine.style);
+  wr::LayoutRect clip = MergeClipLeaf(aClip);
+  wr_dp_push_line(mWrState, &clip, aIsBackfaceVisible,
+                  &aLine.bounds, aLine.wavyLineThickness, aLine.orientation,
+                  &aLine.color, aLine.style);
 }
 
 void
 DisplayListBuilder::PushShadow(const wr::LayoutRect& aRect,
                                const wr::LayoutRect& aClip,
                                bool aIsBackfaceVisible,
                                const wr::Shadow& aShadow)
 {
-  wr_dp_push_shadow(mWrState, aRect, aClip, aIsBackfaceVisible, aShadow);
+  wr_dp_push_shadow(mWrState, aRect, MergeClipLeaf(aClip),
+                    aIsBackfaceVisible, aShadow);
 }
 
 void
 DisplayListBuilder::PopAllShadows()
 {
   wr_dp_pop_all_shadows(mWrState);
 }
 
@@ -1267,18 +1300,18 @@ DisplayListBuilder::PushBoxShadow(const 
                                   const wr::LayoutRect& aBoxBounds,
                                   const wr::LayoutVector2D& aOffset,
                                   const wr::ColorF& aColor,
                                   const float& aBlurRadius,
                                   const float& aSpreadRadius,
                                   const wr::BorderRadius& aBorderRadius,
                                   const wr::BoxShadowClipMode& aClipMode)
 {
-  wr_dp_push_box_shadow(mWrState, aRect, aClip, aIsBackfaceVisible,
-                        aBoxBounds, aOffset, aColor,
+  wr_dp_push_box_shadow(mWrState, aRect, MergeClipLeaf(aClip),
+                        aIsBackfaceVisible, aBoxBounds, aOffset, aColor,
                         aBlurRadius, aSpreadRadius, aBorderRadius,
                         aClipMode);
 }
 
 Maybe<layers::FrameMetrics::ViewID>
 DisplayListBuilder::GetContainingFixedPosScrollTarget(const ActiveScrolledRoot* aAsr)
 {
   return mActiveFixedPosTracker
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -204,16 +204,17 @@ public:
 
   void Pause();
   bool Resume();
 
   void WakeSceneBuilder();
   void FlushSceneBuilder();
 
   void NotifyMemoryPressure();
+  void AccumulateMemoryReport(wr::MemoryReport*);
 
   wr::WrIdNamespace GetNamespace();
   uint32_t GetMaxTextureSize() const { return mMaxTextureSize; }
   bool GetUseANGLE() const { return mUseANGLE; }
   bool GetUseDComp() const { return mUseDComp; }
   layers::SyncHandle GetSyncHandle() const { return mSyncHandle; }
 
   void Capture();
@@ -332,19 +333,20 @@ public:
                                  const wr::LayoutVector2D& aAppliedOffset);
 
   Maybe<wr::WrClipId> GetScrollIdForDefinedScrollLayer(layers::FrameMetrics::ViewID aViewId) const;
   wr::WrClipId DefineScrollLayer(const layers::FrameMetrics::ViewID& aViewId,
                                  const Maybe<wr::WrClipId>& aParentId,
                                  const wr::LayoutRect& aContentRect, // TODO: We should work with strongly typed rects
                                  const wr::LayoutRect& aClipRect);
 
-  void PushClipAndScrollInfo(const wr::WrClipId& aScrollId,
-                             const wr::WrClipChainId* aClipChainId);
-  void PopClipAndScrollInfo();
+  void PushClipAndScrollInfo(const wr::WrClipId* aScrollId,
+                             const wr::WrClipChainId* aClipChainId,
+                             const Maybe<wr::LayoutRect>& aClipChainLeaf);
+  void PopClipAndScrollInfo(const wr::WrClipId* aScrollId);
 
   void PushRect(const wr::LayoutRect& aBounds,
                 const wr::LayoutRect& aClip,
                 bool aIsBackfaceVisible,
                 const wr::ColorF& aColor);
 
   void PushClearRect(const wr::LayoutRect& aBounds);
 
@@ -520,23 +522,36 @@ public:
   private:
     FixedPosScrollTargetTracker* mParentTracker;
     DisplayListBuilder& mBuilder;
     const ActiveScrolledRoot* mAsr;
     layers::FrameMetrics::ViewID mScrollId;
   };
 
 protected:
+  wr::LayoutRect MergeClipLeaf(const wr::LayoutRect& aClip)
+  {
+    if (mClipChainLeaf) {
+      return wr::IntersectLayoutRect(*mClipChainLeaf, aClip);
+    }
+    return aClip;
+  }
+
   wr::WrState* mWrState;
 
   // Track each scroll id that we encountered. We use this structure to
   // ensure that we don't define a particular scroll layer multiple times,
   // as that results in undefined behaviour in WR.
   std::unordered_map<layers::FrameMetrics::ViewID, wr::WrClipId> mScrollIds;
 
+  // Contains the current leaf of the clip chain to be merged with the
+  // display item's clip rect when pushing an item. May be set to Nothing() if
+  // there is no clip rect to merge with.
+  Maybe<wr::LayoutRect> mClipChainLeaf;
+
   FixedPosScrollTargetTracker* mActiveFixedPosTracker;
 
   friend class WebRenderAPI;
 };
 
 Maybe<wr::ImageFormat>
 SurfaceFormatToImageFormat(gfx::SurfaceFormat aFormat);
 
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -346,16 +346,33 @@ static inline wr::LayoutRect ToLayoutRec
 }
 
 static inline wr::LayoutRect ToRoundedLayoutRect(const mozilla::LayoutDeviceRect& aRect) {
   auto rect = aRect;
   rect.Round();
   return wr::ToLayoutRect(rect);
 }
 
+static inline wr::LayoutRect IntersectLayoutRect(const wr::LayoutRect& aRect,
+                                                 const wr::LayoutRect& aOther)
+{
+  wr::LayoutRect r;
+  r.origin.x = std::max(aRect.origin.x, aOther.origin.x);
+  r.origin.y = std::max(aRect.origin.y, aOther.origin.y);
+  r.size.width = std::min(aRect.origin.x + aRect.size.width,
+                          aOther.origin.x + aOther.size.width) - r.origin.x;
+  r.size.height = std::min(aRect.origin.y + aRect.size.height,
+                           aOther.origin.y + aOther.size.height) - r.origin.y;
+  if (r.size.width < 0 || r.size.height < 0) {
+    r.size.width = 0;
+    r.size.height = 0;
+  }
+  return r;
+}
+
 static inline wr::LayoutSize ToLayoutSize(const mozilla::LayoutDeviceSize& size)
 {
   wr::LayoutSize ls;
   ls.width = size.width;
   ls.height = size.height;
   return ls;
 }
 
--- a/gfx/webrender_bindings/revision.txt
+++ b/gfx/webrender_bindings/revision.txt
@@ -1,1 +1,1 @@
-0f142521b86f201a0f0957cc852aa14923ebfc73
+da76f6aad61c1ba769566861ec41b42d511fa456
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -633,16 +633,22 @@ pub extern "C" fn wr_renderer_current_ep
 /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC
 #[no_mangle]
 pub unsafe extern "C" fn wr_renderer_delete(renderer: *mut Renderer) {
     let renderer = Box::from_raw(renderer);
     renderer.deinit();
     // let renderer go out of scope and get dropped
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn wr_renderer_accumulate_memory_report(renderer: &mut Renderer,
+                                                              report: &mut MemoryReport) {
+    *report += renderer.report_memory();
+}
+
 // cbindgen doesn't support tuples, so we have a little struct instead, with
 // an Into implementation to convert from the tuple to the struct.
 #[repr(C)]
 pub struct WrPipelineEpoch {
     pipeline_id: WrPipelineId,
     epoch: WrEpoch,
 }
 
@@ -892,16 +898,17 @@ fn env_var_to_bool(key: &'static str) ->
 // Call MakeCurrent before this.
 #[no_mangle]
 pub extern "C" fn wr_window_new(window_id: WrWindowId,
                                 window_width: u32,
                                 window_height: u32,
                                 support_low_priority_transactions: bool,
                                 gl_context: *mut c_void,
                                 thread_pool: *mut WrThreadPool,
+                                size_of_op: VoidPtrToSizeFn,
                                 out_handle: &mut *mut DocumentHandle,
                                 out_renderer: &mut *mut Renderer,
                                 out_max_texture_size: *mut u32)
                                 -> bool {
     assert!(unsafe { is_in_render_thread() });
 
     let recorder: Option<Box<ApiRecordingReceiver>> = if unsafe { gfx_use_wrench() } {
         let name = format!("wr-record-{}.bin", window_id.0);
@@ -935,16 +942,17 @@ pub extern "C" fn wr_window_new(window_i
     let opts = RendererOptions {
         enable_aa: true,
         enable_subpixel_aa: true,
         support_low_priority_transactions,
         recorder: recorder,
         blob_image_handler: Some(Box::new(Moz2dBlobImageHandler::new(workers.clone()))),
         workers: Some(workers.clone()),
         thread_listener: Some(Box::new(GeckoProfilerThreadListener::new())),
+        size_of_op: Some(size_of_op),
         resource_override_path: unsafe {
             let override_charptr = gfx_wr_resource_path_override();
             if override_charptr.is_null() {
                 None
             } else {
                 match CStr::from_ptr(override_charptr).to_str() {
                     Ok(override_str) => Some(PathBuf::from(override_str)),
                     _ => None
@@ -1036,16 +1044,24 @@ pub unsafe extern "C" fn wr_api_shut_dow
     dh.api.shut_down();
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn wr_api_notify_memory_pressure(dh: &mut DocumentHandle) {
     dh.api.notify_memory_pressure();
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn wr_api_accumulate_memory_report(
+    dh: &mut DocumentHandle,
+    report: &mut MemoryReport
+) {
+    *report += dh.api.report_memory();
+}
+
 /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC
 #[no_mangle]
 pub unsafe extern "C" fn wr_api_clear_all_caches(dh: &mut DocumentHandle) {
     dh.api.send_debug_cmd(DebugCommand::ClearCaches(ClearCache::all()));
 }
 
 fn make_transaction(do_async: bool) -> Transaction {
     let mut transaction = Transaction::new();
@@ -1923,22 +1939,23 @@ pub extern "C" fn wr_dp_push_clip_and_sc
 pub extern "C" fn wr_dp_pop_clip_and_scroll_info(state: &mut WrState) {
     debug_assert!(unsafe { is_in_main_thread() });
     state.frame_builder.dl_builder.pop_clip_id();
 }
 
 #[no_mangle]
 pub extern "C" fn wr_dp_push_iframe(state: &mut WrState,
                                     rect: LayoutRect,
+                                    clip: LayoutRect,
                                     is_backface_visible: bool,
                                     pipeline_id: WrPipelineId,
                                     ignore_missing_pipeline: bool) {
     debug_assert!(unsafe { is_in_main_thread() });
 
-    let mut prim_info = LayoutPrimitiveInfo::new(rect);
+    let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
     prim_info.is_backface_visible = is_backface_visible;
     prim_info.tag = state.current_tag;
     state.frame_builder.dl_builder.push_iframe(&prim_info, pipeline_id, ignore_missing_pipeline);
 }
 
 #[no_mangle]
 pub extern "C" fn wr_dp_push_rect(state: &mut WrState,
                                   rect: LayoutRect,
@@ -1951,20 +1968,21 @@ pub extern "C" fn wr_dp_push_rect(state:
     prim_info.is_backface_visible = is_backface_visible;
     prim_info.tag = state.current_tag;
     state.frame_builder.dl_builder.push_rect(&prim_info,
                                              color);
 }
 
 #[no_mangle]
 pub extern "C" fn wr_dp_push_clear_rect(state: &mut WrState,
-                                        rect: LayoutRect) {
+                                        rect: LayoutRect,
+                                        clip: LayoutRect) {
     debug_assert!(unsafe { !is_in_render_thread() });
 
-    let prim_info = LayoutPrimitiveInfo::new(rect);
+    let prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
     state.frame_builder.dl_builder.push_clear_rect(&prim_info);
 }
 
 #[no_mangle]
 pub extern "C" fn wr_dp_push_image(state: &mut WrState,
                                    bounds: LayoutRect,
                                    clip: LayoutRect,
                                    is_backface_visible: bool,
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -466,16 +466,35 @@ struct WrPipelineInfo {
   FfiVec<PipelineId> removed_pipelines;
 
   bool operator==(const WrPipelineInfo& aOther) const {
     return epochs == aOther.epochs &&
            removed_pipelines == aOther.removed_pipelines;
   }
 };
 
+// Collection of heap sizes, in bytes.
+struct MemoryReport {
+  uintptr_t primitive_stores;
+  uintptr_t clip_stores;
+  uintptr_t gpu_cache_metadata;
+  uintptr_t gpu_cache_cpu_mirror;
+  uintptr_t render_tasks;
+  uintptr_t hit_testers;
+
+  bool operator==(const MemoryReport& aOther) const {
+    return primitive_stores == aOther.primitive_stores &&
+           clip_stores == aOther.clip_stores &&
+           gpu_cache_metadata == aOther.gpu_cache_metadata &&
+           gpu_cache_cpu_mirror == aOther.gpu_cache_cpu_mirror &&
+           render_tasks == aOther.render_tasks &&
+           hit_testers == aOther.hit_testers;
+  }
+};
+
 template<typename T, typename U>
 struct TypedSize2D {
   T width;
   T height;
 
   bool operator==(const TypedSize2D& aOther) const {
     return width == aOther.width &&
            height == aOther.height;
@@ -979,16 +998,22 @@ struct WrOpacityProperty {
   float opacity;
 
   bool operator==(const WrOpacityProperty& aOther) const {
     return id == aOther.id &&
            opacity == aOther.opacity;
   }
 };
 
+// A C function that takes a pointer to a heap allocation and returns its size.
+//
+// This is borrowed from the malloc_size_of crate, upon which we want to avoid
+// a dependency from WebRender.
+using VoidPtrToSizeFn = uintptr_t(*)(const void*);
+
 extern "C" {
 
 extern void AddBlobFont(WrFontInstanceKey aInstanceKey,
                         WrFontKey aFontKey,
                         float aSize,
                         const FontInstanceOptions *aOptions,
                         const FontInstancePlatformOptions *aPlatformOptions,
                         const FontVariation *aVariations,
@@ -1057,16 +1082,21 @@ WR_INLINE
 bool remove_program_binary_disk_cache(const nsAString *aProfPath)
 WR_FUNC;
 
 WR_INLINE
 const VecU8 *wr_add_ref_arc(const ArcVecU8 *aArc)
 WR_FUNC;
 
 WR_INLINE
+void wr_api_accumulate_memory_report(DocumentHandle *aDh,
+                                     MemoryReport *aReport)
+WR_FUNC;
+
+WR_INLINE
 void wr_api_capture(DocumentHandle *aDh,
                     const char *aPath,
                     uint32_t aBitsRaw)
 WR_FUNC;
 
 WR_INLINE
 void wr_api_clear_all_caches(DocumentHandle *aDh)
 WR_DESTRUCTOR_SAFE_FUNC;
@@ -1276,33 +1306,35 @@ void wr_dp_push_box_shadow(WrState *aSta
                            float aBlurRadius,
                            float aSpreadRadius,
                            BorderRadius aBorderRadius,
                            BoxShadowClipMode aClipMode)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_clear_rect(WrState *aState,
-                           LayoutRect aRect)
+                           LayoutRect aRect,
+                           LayoutRect aClip)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_clip(WrState *aState,
                      uintptr_t aClipId)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_clip_and_scroll_info(WrState *aState,
                                      uintptr_t aScrollId,
                                      const uint64_t *aClipChainId)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_iframe(WrState *aState,
                        LayoutRect aRect,
+                       LayoutRect aClip,
                        bool aIsBackfaceVisible,
                        WrPipelineId aPipelineId,
                        bool aIgnoreMissingPipeline)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_image(WrState *aState,
                       LayoutRect aBounds,
@@ -1484,16 +1516,21 @@ void wr_program_cache_delete(WrProgramCa
 WR_DESTRUCTOR_SAFE_FUNC;
 
 WR_INLINE
 WrProgramCache *wr_program_cache_new(const nsAString *aProfPath,
                                      WrThreadPool *aThreadPool)
 WR_FUNC;
 
 WR_INLINE
+void wr_renderer_accumulate_memory_report(Renderer *aRenderer,
+                                          MemoryReport *aReport)
+WR_FUNC;
+
+WR_INLINE
 bool wr_renderer_current_epoch(Renderer *aRenderer,
                                WrPipelineId aPipelineId,
                                WrEpoch *aOutEpoch)
 WR_FUNC;
 
 WR_INLINE
 void wr_renderer_delete(Renderer *aRenderer)
 WR_DESTRUCTOR_SAFE_FUNC;
@@ -1772,16 +1809,17 @@ WR_FUNC;
 
 WR_INLINE
 bool wr_window_new(WrWindowId aWindowId,
                    uint32_t aWindowWidth,
                    uint32_t aWindowHeight,
                    bool aSupportLowPriorityTransactions,
                    void *aGlContext,
                    WrThreadPool *aThreadPool,
+                   VoidPtrToSizeFn aSizeOfOp,
                    DocumentHandle **aOutHandle,
                    Renderer **aOutRenderer,
                    uint32_t *aOutMaxTextureSize)
 WR_FUNC;
 
 } // extern "C"
 
 } // namespace wr
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -630,37 +630,43 @@ LoadInfoToParentLoadInfoForwarder(nsILoa
                                   ParentLoadInfoForwarderArgs* aForwarderArgsOut)
 {
   if (!aLoadInfo) {
     *aForwarderArgsOut = ParentLoadInfoForwarderArgs(false, void_t(),
                                                      nsILoadInfo::TAINTING_BASIC,
                                                      false, // serviceWorkerTaintingSynthesized
                                                      false, // isTracker
                                                      false, // isTrackerBlocked
+                                                     mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all, // trackerBlockedReason
                                                      false  // documentHasUserInteracted
                                                     );
     return;
   }
 
   OptionalIPCServiceWorkerDescriptor ipcController = void_t();
   Maybe<ServiceWorkerDescriptor> controller(aLoadInfo->GetController());
   if (controller.isSome()) {
     ipcController = controller.ref().ToIPC();
   }
 
   uint32_t tainting = nsILoadInfo::TAINTING_BASIC;
   Unused << aLoadInfo->GetTainting(&tainting);
 
+  mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED label =
+    mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all;
+  Unused << aLoadInfo->GetTrackerBlockedReason(&label);
+
   *aForwarderArgsOut = ParentLoadInfoForwarderArgs(
     aLoadInfo->GetAllowInsecureRedirectToDataURI(),
     ipcController,
     tainting,
     aLoadInfo->GetServiceWorkerTaintingSynthesized(),
     aLoadInfo->GetIsTracker(),
     aLoadInfo->GetIsTrackerBlocked(),
+    label,
     aLoadInfo->GetDocumentHasUserInteracted()
   );
 }
 
 nsresult
 MergeParentLoadInfoForwarder(ParentLoadInfoForwarderArgs const& aForwarderArgs,
                              nsILoadInfo* aLoadInfo)
 {
@@ -685,16 +691,17 @@ MergeParentLoadInfoForwarder(ParentLoadI
     aLoadInfo->SynthesizeServiceWorkerTainting(
       static_cast<LoadTainting>(aForwarderArgs.tainting()));
   } else {
     aLoadInfo->MaybeIncreaseTainting(aForwarderArgs.tainting());
   }
 
   MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetIsTracker(aForwarderArgs.isTracker()));
   MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetIsTrackerBlocked(aForwarderArgs.isTrackerBlocked()));
+  MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetTrackerBlockedReason(aForwarderArgs.trackerBlockedReason()));
   MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetDocumentHasUserInteracted(aForwarderArgs.documentHasUserInteracted()));
 
   return NS_OK;
 }
 
 void
 LoadInfoToChildLoadInfoForwarder(nsILoadInfo* aLoadInfo,
                                  ChildLoadInfoForwarderArgs* aForwarderArgsOut)
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -39,16 +39,17 @@
 #include "gc/FreeOp.h"
 #include "gc/Policy.h"
 #include "jit/AtomicOperations.h"
 #include "js/CharacterEncoding.h"
 #include "js/StableStringChars.h"
 #include "js/UniquePtr.h"
 #include "js/Utility.h"
 #include "js/Vector.h"
+#include "util/Unicode.h"
 #include "util/Windows.h"
 #include "vm/JSContext.h"
 #include "vm/JSFunction.h"
 
 #include "vm/JSObject-inl.h"
 
 using namespace std;
 
@@ -56,175 +57,56 @@ using mozilla::IsAsciiAlpha;
 using mozilla::IsAsciiDigit;
 
 using JS::AutoCheckCannotGC;
 using JS::AutoStableStringChars;
 
 namespace js {
 namespace ctypes {
 
-template <typename CharT>
-size_t
-GetDeflatedUTF8StringLength(JSContext* maybecx, const CharT* chars,
-                            size_t nchars)
-{
-    size_t nbytes;
-    const CharT* end;
-    unsigned c, c2;
-
-    nbytes = nchars;
-    for (end = chars + nchars; chars != end; chars++) {
-        c = *chars;
-        if (c < 0x80) {
-            continue;
-        }
-        if (0xD800 <= c && c <= 0xDFFF) {
-            /* Surrogate pair. */
-            chars++;
-
-            /* nbytes sets 1 length since this is surrogate pair. */
-            nbytes--;
-            if (c >= 0xDC00 || chars == end) {
-                goto bad_surrogate;
-            }
-            c2 = *chars;
-            if (c2 < 0xDC00 || c2 > 0xDFFF) {
-                goto bad_surrogate;
-            }
-            c = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
-        }
-        c >>= 11;
-        nbytes++;
-        while (c) {
-            c >>= 5;
-            nbytes++;
-        }
-    }
-    return nbytes;
-
-  bad_surrogate:
-    if (maybecx) {
-        js::gc::AutoSuppressGC suppress(maybecx);
-        char buffer[10];
-        SprintfLiteral(buffer, "0x%x", c);
-        JS_ReportErrorNumberASCII(maybecx, GetErrorMessage, nullptr, JSMSG_BAD_SURROGATE_CHAR,
-                                  buffer);
-    }
-    return (size_t) -1;
-}
-
-template size_t
-GetDeflatedUTF8StringLength(JSContext* maybecx, const Latin1Char* chars,
-                            size_t nchars);
-
-template size_t
-GetDeflatedUTF8StringLength(JSContext* maybecx, const char16_t* chars,
-                            size_t nchars);
-
-static size_t
-GetDeflatedUTF8StringLength(JSContext* maybecx, JSLinearString* str)
-{
-    size_t length = str->length();
-
-    JS::AutoCheckCannotGC nogc;
-    return str->hasLatin1Chars()
-           ? GetDeflatedUTF8StringLength(maybecx, str->latin1Chars(nogc), length)
-           : GetDeflatedUTF8StringLength(maybecx, str->twoByteChars(nogc), length);
-}
-
-template <typename CharT>
+static bool
+HasUnpairedSurrogate(const char16_t* chars, size_t nchars, char16_t* unpaired)
+{
+  for (const char16_t* end = chars + nchars; chars != end; chars++) {
+    char16_t c = *chars;
+    if (unicode::LeadSurrogateMin <= c && c <= unicode::TrailSurrogateMax) {
+      chars++;
+      if (c >= unicode::TrailSurrogateMin || chars == end) {
+        *unpaired = c;
+        return true;
+      }
+      char16_t c2 = *chars;
+      if (c2 < unicode::TrailSurrogateMin || c2 > unicode::TrailSurrogateMax) {
+        *unpaired = c;
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 bool
-DeflateStringToUTF8Buffer(JSContext* maybecx, const CharT* src, size_t srclen,
-                          char* dst, size_t* dstlenp)
-{
-    size_t i, utf8Len;
-    char16_t c, c2;
-    uint32_t v;
-    uint8_t utf8buf[6];
-
-    size_t dstlen = *dstlenp;
-    size_t origDstlen = dstlen;
-
-    while (srclen) {
-        c = *src++;
-        srclen--;
-        if (c >= 0xDC00 && c <= 0xDFFF) {
-            goto badSurrogate;
-        }
-        if (c < 0xD800 || c > 0xDBFF) {
-            v = c;
-        } else {
-            if (srclen < 1) {
-                goto badSurrogate;
-            }
-            c2 = *src;
-            if ((c2 < 0xDC00) || (c2 > 0xDFFF)) {
-                goto badSurrogate;
-            }
-            src++;
-            srclen--;
-            v = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
-        }
-        if (v < 0x0080) {
-            /* no encoding necessary - performance hack */
-            if (dstlen == 0) {
-                goto bufferTooSmall;
-            }
-            *dst++ = (char) v;
-            utf8Len = 1;
-        } else {
-            utf8Len = js::OneUcs4ToUtf8Char(utf8buf, v);
-            if (utf8Len > dstlen) {
-                goto bufferTooSmall;
-            }
-            for (i = 0; i < utf8Len; i++) {
-                *dst++ = (char) utf8buf[i];
-            }
-        }
-        dstlen -= utf8Len;
-    }
-    *dstlenp = (origDstlen - dstlen);
+ReportErrorIfUnpairedSurrogatePresent(JSContext* cx, JSLinearString* str)
+{
+  if (str->hasLatin1Chars()) {
     return true;
-
-badSurrogate:
-    *dstlenp = (origDstlen - dstlen);
-    /* Delegate error reporting to the measurement function. */
-    if (maybecx) {
-        GetDeflatedUTF8StringLength(maybecx, src - 1, srclen + 1);
-    }
-    return false;
-
-bufferTooSmall:
-    *dstlenp = (origDstlen - dstlen);
-    if (maybecx) {
-        js::gc::AutoSuppressGC suppress(maybecx);
-        JS_ReportErrorNumberASCII(maybecx, GetErrorMessage, nullptr,
-                                  JSMSG_BUFFER_TOO_SMALL);
-    }
-    return false;
-}
-
-template bool
-DeflateStringToUTF8Buffer(JSContext* maybecx, const Latin1Char* src, size_t srclen,
-                          char* dst, size_t* dstlenp);
-
-template bool
-DeflateStringToUTF8Buffer(JSContext* maybecx, const char16_t* src, size_t srclen,
-                          char* dst, size_t* dstlenp);
-
-static bool
-DeflateStringToUTF8Buffer(JSContext* maybecx, JSLinearString* str, char* dst,
-                          size_t* dstlenp)
-{
-    size_t length = str->length();
-
+  }
+
+  char16_t unpaired;
+  {
     JS::AutoCheckCannotGC nogc;
-    return str->hasLatin1Chars()
-           ? DeflateStringToUTF8Buffer(maybecx, str->latin1Chars(nogc), length, dst, dstlenp)
-           : DeflateStringToUTF8Buffer(maybecx, str->twoByteChars(nogc), length, dst, dstlenp);
+    if (!HasUnpairedSurrogate(str->twoByteChars(nogc), str->length(), &unpaired)) {
+      return true;
+    }
+  }
+
+  char buffer[10];
+  SprintfLiteral(buffer, "0x%x", unpaired);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_SURROGATE_CHAR, buffer);
+  return false;
 }
 
 /*******************************************************************************
 ** JSAPI function prototypes
 *******************************************************************************/
 
 // We use an enclosing struct here out of paranoia about the ability of gcc 4.4
 // (and maybe 4.5) to correctly compile this if it were a template function.
@@ -995,30 +877,34 @@ GetErrorMessage(void* userRef, const uns
 {
   if (0 < errorNumber && errorNumber < CTYPESERR_LIMIT) {
     return &ErrorFormatString[errorNumber];
   }
   return nullptr;
 }
 
 static JS::UniqueChars
-EncodeLatin1(JSContext* cx, AutoString& str)
-{
-  return JS_EncodeStringToLatin1(cx, NewUCString(cx, str.finish()));
+EncodeUTF8(JSContext* cx, AutoString& str)
+{
+  RootedString string(cx, NewUCString(cx, str.finish()));
+  if (!string) {
+    return nullptr;
+  }
+  return JS_EncodeStringToUTF8(cx, string);
 }
 
 static const char*
 CTypesToSourceForError(JSContext* cx, HandleValue val, JS::UniqueChars& bytes)
 {
   if (val.isObject()) {
       RootedObject obj(cx, &val.toObject());
       if (CType::IsCType(obj) || CData::IsCDataMaybeUnwrap(&obj)) {
           RootedValue v(cx, ObjectValue(*obj));
           RootedString str(cx, JS_ValueToSource(cx, v));
-          bytes = JS_EncodeStringToLatin1(cx, str);
+          bytes = JS_EncodeStringToUTF8(cx, str);
           return bytes.get();
       }
   }
   return ValueToSourceForError(cx, val, bytes);
 }
 
 static void
 BuildCStyleFunctionTypeSource(JSContext* cx, HandleObject typeObj,
@@ -1187,16 +1073,61 @@ GetFieldName(HandleObject structObj, uns
   }
   return nullptr;
 }
 
 static void
 BuildTypeSource(JSContext* cx, JSObject* typeObj_, bool makeShort,
                 AutoString& result);
 
+static JS::UniqueChars
+TypeSourceForError(JSContext* cx, JSObject* typeObj)
+{
+  AutoString source;
+  BuildTypeSource(cx, typeObj, true, source);
+  if (!source)
+    return nullptr;
+  return EncodeUTF8(cx, source);
+}
+
+static JS::UniqueChars
+FunctionTypeSourceForError(JSContext* cx, HandleObject funObj)
+{
+  AutoString funSource;
+  BuildFunctionTypeSource(cx, funObj, funSource);
+  if (!funSource)
+    return nullptr;
+  return EncodeUTF8(cx, funSource);
+}
+
+static JS::UniqueChars
+ConversionPositionForError(JSContext* cx, ConversionType convType, HandleObject funObj,
+                           unsigned argIndex)
+{
+  AutoString posSource;
+  BuildConversionPosition(cx, convType, funObj, argIndex, posSource);
+  if (!posSource)
+    return nullptr;
+  return EncodeUTF8(cx, posSource);
+}
+
+class IndexCString final
+{
+    char indexStr[21]; // space for UINT64_MAX plus terminating null
+    static_assert(sizeof(size_t) <= 8, "index array too small");
+
+  public:
+    explicit IndexCString(size_t index)
+    {
+      SprintfLiteral(indexStr, "%zu", index);
+    }
+
+    const char* get() const { return indexStr; }
+};
+
 static bool
 ConvError(JSContext* cx, const char* expectedStr, HandleValue actual,
           ConversionType convType,
           HandleObject funObj = nullptr, unsigned argIndex = 0,
           HandleObject arrObj = nullptr, unsigned arrIndex = 0)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
@@ -1206,259 +1137,209 @@ ConvError(JSContext* cx, const char* exp
 
   if (arrObj) {
     MOZ_ASSERT(CType::IsCType(arrObj));
 
     switch (CType::GetTypeCode(arrObj)) {
     case TYPE_array: {
       MOZ_ASSERT(!funObj);
 
-      char indexStr[16];
-      SprintfLiteral(indexStr, "%u", arrIndex);
-
-      AutoString arrSource;
-      BuildTypeSource(cx, arrObj, true, arrSource);
-      if (!arrSource) {
-          return false;
-      }
-      JS::UniqueChars arrStr = EncodeLatin1(cx, arrSource);
+      IndexCString indexStr(arrIndex);
+
+      JS::UniqueChars arrStr = TypeSourceForError(cx, arrObj);
       if (!arrStr) {
         return false;
       }
 
-      JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                                 CTYPESMSG_CONV_ERROR_ARRAY,
-                                 valStr, indexStr, arrStr.get());
+      JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                               CTYPESMSG_CONV_ERROR_ARRAY,
+                               valStr, indexStr.get(), arrStr.get());
       break;
     }
     case TYPE_struct: {
-      JSFlatString* name = GetFieldName(arrObj, arrIndex);
+      RootedString name(cx, GetFieldName(arrObj, arrIndex));
       MOZ_ASSERT(name);
-      JS::UniqueChars nameStr = JS_EncodeStringToLatin1(cx, name);
+      JS::UniqueChars nameStr = JS_EncodeStringToUTF8(cx, name);
       if (!nameStr) {
         return false;
       }
 
-      AutoString structSource;
-      BuildTypeSource(cx, arrObj, true, structSource);
-      if (!structSource) {
-          return false;
-      }
-      JS::UniqueChars structStr = EncodeLatin1(cx, structSource);
+      JS::UniqueChars structStr = TypeSourceForError(cx, arrObj);
       if (!structStr) {
         return false;
       }
 
       JS::UniqueChars posStr;
       if (funObj) {
-        AutoString posSource;
-        BuildConversionPosition(cx, convType, funObj, argIndex, posSource);
-        if (!posSource) {
-            return false;
-        }
-        posStr = EncodeLatin1(cx, posSource);
+        posStr = ConversionPositionForError(cx, convType, funObj, argIndex);
         if (!posStr) {
           return false;
         }
       }
 
-      JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                                 CTYPESMSG_CONV_ERROR_STRUCT,
-                                 valStr, nameStr.get(), expectedStr, structStr.get(),
-                                 (posStr ? posStr.get() : ""));
+      JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                               CTYPESMSG_CONV_ERROR_STRUCT,
+                               valStr, nameStr.get(), expectedStr, structStr.get(),
+                               (posStr ? posStr.get() : ""));
       break;
     }
     default:
       MOZ_CRASH("invalid arrObj value");
     }
     return false;
   }
 
   switch (convType) {
   case ConversionType::Argument: {
     MOZ_ASSERT(funObj);
 
-    char indexStr[16];
-    SprintfLiteral(indexStr, "%u", argIndex + 1);
-
-    AutoString funSource;
-    BuildFunctionTypeSource(cx, funObj, funSource);
-    if (!funSource) {
-        return false;
-    }
-    JS::UniqueChars funStr = EncodeLatin1(cx, funSource);
+    IndexCString indexStr(argIndex + 1);
+
+    JS::UniqueChars funStr = FunctionTypeSourceForError(cx, funObj);
     if (!funStr) {
       return false;
     }
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                               CTYPESMSG_CONV_ERROR_ARG,
-                               valStr, indexStr, funStr.get());
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                             CTYPESMSG_CONV_ERROR_ARG,
+                             valStr, indexStr.get(), funStr.get());
     break;
   }
   case ConversionType::Finalizer: {
     MOZ_ASSERT(funObj);
 
-    AutoString funSource;
-    BuildFunctionTypeSource(cx, funObj, funSource);
-    if (!funSource) {
-        return false;
-    }
-    JS::UniqueChars funStr = EncodeLatin1(cx, funSource);
+    JS::UniqueChars funStr = FunctionTypeSourceForError(cx, funObj);
     if (!funStr) {
       return false;
     }
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                               CTYPESMSG_CONV_ERROR_FIN, valStr, funStr.get());
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                             CTYPESMSG_CONV_ERROR_FIN, valStr, funStr.get());
     break;
   }
   case ConversionType::Return: {
     MOZ_ASSERT(funObj);
 
-    AutoString funSource;
-    BuildFunctionTypeSource(cx, funObj, funSource);
-    if (!funSource) {
-        return false;
-    }
-    JS::UniqueChars funStr = EncodeLatin1(cx, funSource);
+    JS::UniqueChars funStr = FunctionTypeSourceForError(cx, funObj);
     if (!funStr) {
       return false;
     }
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                               CTYPESMSG_CONV_ERROR_RET, valStr, funStr.get());
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                             CTYPESMSG_CONV_ERROR_RET, valStr, funStr.get());
     break;
   }
   case ConversionType::Setter:
   case ConversionType::Construct:
     MOZ_ASSERT(!funObj);
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                               CTYPESMSG_CONV_ERROR_SET, valStr, expectedStr);
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                             CTYPESMSG_CONV_ERROR_SET, valStr, expectedStr);
     break;
   }
 
   return false;
 }
 
 static bool
 ConvError(JSContext* cx, HandleObject expectedType, HandleValue actual,
           ConversionType convType,
           HandleObject funObj = nullptr, unsigned argIndex = 0,
           HandleObject arrObj = nullptr, unsigned arrIndex = 0)
 {
   MOZ_ASSERT(CType::IsCType(expectedType));
 
-  AutoString expectedSource;
-  BuildTypeSource(cx, expectedType, true, expectedSource);
-  if (!expectedSource) {
-      return false;
-  }
-  JS::UniqueChars expectedStr = EncodeLatin1(cx, expectedSource);
+  JS::UniqueChars expectedStr = TypeSourceForError(cx, expectedType);
   if (!expectedStr) {
     return false;
   }
 
   return ConvError(cx, expectedStr.get(), actual, convType, funObj, argIndex,
                    arrObj, arrIndex);
 }
 
 static bool
 ArgumentConvError(JSContext* cx, HandleValue actual, const char* funStr,
                   unsigned argIndex)
 {
+  MOZ_ASSERT(JS::StringIsASCII(funStr));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
-  char indexStr[16];
-  SprintfLiteral(indexStr, "%u", argIndex + 1);
-
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_CONV_ERROR_ARG, valStr, indexStr, funStr);
+  IndexCString indexStr(argIndex + 1);
+
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_CONV_ERROR_ARG, valStr, indexStr.get(), funStr);
   return false;
 }
 
 static bool
 ArgumentLengthError(JSContext* cx, const char* fun, const char* count,
                     const char* s)
 {
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_WRONG_ARG_LENGTH, fun, count, s);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_WRONG_ARG_LENGTH, fun, count, s);
   return false;
 }
 
 static bool
 ArrayLengthMismatch(JSContext* cx, unsigned expectedLength, HandleObject arrObj,
                     unsigned actualLength, HandleValue actual,
                     ConversionType convType)
 {
   MOZ_ASSERT(arrObj && CType::IsCType(arrObj));
 
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
-  char expectedLengthStr[16];
-  SprintfLiteral(expectedLengthStr, "%u", expectedLength);
-  char actualLengthStr[16];
-  SprintfLiteral(actualLengthStr, "%u", actualLength);
-
-  AutoString arrSource;
-  BuildTypeSource(cx, arrObj, true, arrSource);
-  if (!arrSource) {
-      return false;
-  }
-  JS::UniqueChars arrStr = EncodeLatin1(cx, arrSource);
+  IndexCString expectedLengthStr(expectedLength);
+  IndexCString actualLengthStr(actualLength);
+
+  JS::UniqueChars arrStr = TypeSourceForError(cx, arrObj);
   if (!arrStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_ARRAY_MISMATCH,
-                             valStr, arrStr.get(), expectedLengthStr, actualLengthStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_ARRAY_MISMATCH,
+                           valStr, arrStr.get(), expectedLengthStr.get(), actualLengthStr.get());
   return false;
 }
 
 static bool
 ArrayLengthOverflow(JSContext* cx, unsigned expectedLength, HandleObject arrObj,
                     unsigned actualLength, HandleValue actual,
                     ConversionType convType)
 {
   MOZ_ASSERT(arrObj && CType::IsCType(arrObj));
 
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
-  char expectedLengthStr[16];
-  SprintfLiteral(expectedLengthStr, "%u", expectedLength);
-  char actualLengthStr[16];
-  SprintfLiteral(actualLengthStr, "%u", actualLength);
-
-  AutoString arrSource;
-  BuildTypeSource(cx, arrObj, true, arrSource);
-  if (!arrSource) {
-      return false;
-  }
-  JS::UniqueChars arrStr = EncodeLatin1(cx, arrSource);
+  IndexCString expectedLengthStr(expectedLength);
+  IndexCString actualLengthStr(actualLength);
+
+  JS::UniqueChars arrStr = TypeSourceForError(cx, arrObj);
   if (!arrStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_ARRAY_OVERFLOW,
-                             valStr, arrStr.get(), expectedLengthStr, actualLengthStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_ARRAY_OVERFLOW,
+                           valStr, arrStr.get(), expectedLengthStr.get(), actualLengthStr.get());
   return false;
 }
 
 static bool
 ArgumentRangeMismatch(JSContext* cx, const char* func, const char* range)
 {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_ARG_RANGE_MISMATCH, func, range);
@@ -1480,23 +1361,23 @@ CannotConstructError(JSContext* cx, cons
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_CANNOT_CONSTRUCT, type);
   return false;
 }
 
 static bool
 DuplicateFieldError(JSContext* cx, Handle<JSFlatString*> name)
 {
-  JS::UniqueChars nameStr = JS_EncodeStringToLatin1(cx, name);
+  JS::UniqueChars nameStr = JS_EncodeStringToUTF8(cx, name);
   if (!nameStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_DUPLICATE_FIELD, nameStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_DUPLICATE_FIELD, nameStr.get());
   return false;
 }
 
 static bool
 EmptyFinalizerCallError(JSContext* cx, const char* funName)
 {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_EMPTY_FIN_CALL, funName);
@@ -1504,29 +1385,24 @@ EmptyFinalizerCallError(JSContext* cx, c
 }
 
 static bool
 EmptyFinalizerError(JSContext* cx, ConversionType convType,
                     HandleObject funObj = nullptr, unsigned argIndex = 0)
 {
   JS::UniqueChars posStr;
   if (funObj) {
-    AutoString posSource;
-    BuildConversionPosition(cx, convType, funObj, argIndex, posSource);
-    if (!posSource) {
-        return false;
-    }
-    posStr = EncodeLatin1(cx, posSource);
+    posStr = ConversionPositionForError(cx, convType, funObj, argIndex);
     if (!posStr) {
       return false;
     }
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_EMPTY_FIN, (posStr ? posStr.get() : ""));
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_EMPTY_FIN, (posStr ? posStr.get() : ""));
   return false;
 }
 
 static bool
 FieldCountMismatch(JSContext* cx,
                    unsigned expectedCount, HandleObject structObj,
                    unsigned actualCount, HandleValue actual,
                    ConversionType convType,
@@ -1535,399 +1411,379 @@ FieldCountMismatch(JSContext* cx,
   MOZ_ASSERT(structObj && CType::IsCType(structObj));
 
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
-  AutoString structSource;
-  BuildTypeSource(cx, structObj, true, structSource);
-  if (!structSource) {
-      return false;
-  }
-  JS::UniqueChars structStr = EncodeLatin1(cx, structSource);
+  JS::UniqueChars structStr = TypeSourceForError(cx, structObj);
   if (!structStr) {
     return false;
   }
 
-  char expectedCountStr[16];
-  SprintfLiteral(expectedCountStr, "%u", expectedCount);
-  char actualCountStr[16];
-  SprintfLiteral(actualCountStr, "%u", actualCount);
+  IndexCString expectedCountStr(expectedCount);
+  IndexCString actualCountStr(actualCount);
 
   JS::UniqueChars posStr;
   if (funObj) {
-    AutoString posSource;
-    BuildConversionPosition(cx, convType, funObj, argIndex, posSource);
-    if (!posSource) {
-        return false;
-    }
-    posStr = EncodeLatin1(cx, posSource);
+    posStr = ConversionPositionForError(cx, convType, funObj, argIndex);
     if (!posStr) {
       return false;
     }
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_MISMATCH,
-                             valStr, structStr.get(), expectedCountStr, actualCountStr,
-                             (posStr ? posStr.get() : ""));
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_MISMATCH,
+                           valStr, structStr.get(), expectedCountStr.get(), actualCountStr.get(),
+                           (posStr ? posStr.get() : ""));
   return false;
 }
 
 static bool
 FieldDescriptorCountError(JSContext* cx, HandleValue typeVal, size_t length)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  char lengthStr[16];
-  SprintfLiteral(lengthStr, "%zu", length);
-
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_COUNT, valStr, lengthStr);
+  IndexCString lengthStr(length);
+
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_COUNT, valStr, lengthStr.get());
   return false;
 }
 
 static bool
 FieldDescriptorNameError(JSContext* cx, HandleId id)
 {
   JS::UniqueChars idBytes;
   RootedValue idVal(cx, IdToValue(id));
   const char* propStr = CTypesToSourceForError(cx, idVal, idBytes);
   if (!propStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_NAME, propStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_NAME, propStr);
   return false;
 }
 
 static bool
 FieldDescriptorSizeError(JSContext* cx, HandleObject typeObj, HandleId id)
 {
   RootedValue typeVal(cx, ObjectValue(*typeObj));
   JS::UniqueChars typeBytes;
   const char* typeStr = CTypesToSourceForError(cx, typeVal, typeBytes);
   if (!typeStr) {
     return false;
   }
 
   RootedString idStr(cx, IdToString(cx, id));
-  JS::UniqueChars propStr = JS_EncodeStringToLatin1(cx, idStr);
+  JS::UniqueChars propStr = JS_EncodeStringToUTF8(cx, idStr);
   if (!propStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_SIZE, typeStr, propStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_SIZE, typeStr, propStr.get());
   return false;
 }
 
 static bool
 FieldDescriptorNameTypeError(JSContext* cx, HandleValue typeVal)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_NAMETYPE, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_NAMETYPE, valStr);
   return false;
 }
 
 static bool
 FieldDescriptorTypeError(JSContext* cx, HandleValue poroVal, HandleId id)
 {
   JS::UniqueChars typeBytes;
   const char* typeStr = CTypesToSourceForError(cx, poroVal, typeBytes);
   if (!typeStr) {
     return false;
   }
 
   RootedString idStr(cx, IdToString(cx, id));
-  JS::UniqueChars propStr = JS_EncodeStringToLatin1(cx, idStr);
+  JS::UniqueChars propStr = JS_EncodeStringToUTF8(cx, idStr);
   if (!propStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_TYPE, typeStr, propStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_TYPE, typeStr, propStr.get());
   return false;
 }
 
 static bool
 FieldMissingError(JSContext* cx, JSObject* typeObj, JSFlatString* name_)
 {
   JS::UniqueChars typeBytes;
   RootedString name(cx, name_);
   RootedValue typeVal(cx, ObjectValue(*typeObj));
   const char* typeStr = CTypesToSourceForError(cx, typeVal, typeBytes);
   if (!typeStr) {
     return false;
   }
 
-  JS::UniqueChars nameStr = JS_EncodeStringToLatin1(cx, name);
+  JS::UniqueChars nameStr = JS_EncodeStringToUTF8(cx, name);
   if (!nameStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_MISSING, typeStr, nameStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_MISSING, typeStr, nameStr.get());
   return false;
 }
 
 static bool
 FinalizerSizeError(JSContext* cx, HandleObject funObj, HandleValue actual)
 {
   MOZ_ASSERT(CType::IsCType(funObj));
 
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
-  AutoString funSource;
-  BuildFunctionTypeSource(cx, funObj, funSource);
-  if (!funSource) {
-      return false;
-  }
-  JS::UniqueChars funStr = EncodeLatin1(cx, funSource);
+  JS::UniqueChars funStr = FunctionTypeSourceForError(cx, funObj);
   if (!funStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIN_SIZE_ERROR, funStr.get(), valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIN_SIZE_ERROR, funStr.get(), valStr);
   return false;
 }
 
 static bool
 FunctionArgumentLengthMismatch(JSContext* cx,
                                unsigned expectedCount, unsigned actualCount,
                                HandleObject funObj, HandleObject typeObj,
                                bool isVariadic)
 {
-  AutoString funSource;
+  JS::UniqueChars funStr;
   Value slot = JS_GetReservedSlot(funObj, SLOT_REFERENT);
   if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) {
-    BuildFunctionTypeSource(cx, funObj, funSource);
+    funStr = FunctionTypeSourceForError(cx, funObj);
   } else {
-    BuildFunctionTypeSource(cx, typeObj, funSource);
-  }
-  if (!funSource) {
-      return false;
-  }
-  JS::UniqueChars funStr = EncodeLatin1(cx, funSource);
+    funStr = FunctionTypeSourceForError(cx, typeObj);
+  }
   if (!funStr) {
     return false;
   }
 
-  char expectedCountStr[16];
-  SprintfLiteral(expectedCountStr, "%u", expectedCount);
-  char actualCountStr[16];
-  SprintfLiteral(actualCountStr, "%u", actualCount);
+  IndexCString expectedCountStr(expectedCount);
+  IndexCString actualCountStr(actualCount);
 
   const char* variadicStr = isVariadic ? " or more": "";
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_ARG_COUNT_MISMATCH,
-                             funStr.get(), expectedCountStr, variadicStr,
-                             actualCountStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_ARG_COUNT_MISMATCH,
+                           funStr.get(), expectedCountStr.get(), variadicStr,
+                           actualCountStr.get());
   return false;
 }
 
 static bool
 FunctionArgumentTypeError(JSContext* cx,
                           uint32_t index, HandleValue typeVal, const char* reason)
 {
+  MOZ_ASSERT(JS::StringIsASCII(reason));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  char indexStr[16];
-  SprintfLiteral(indexStr, "%u", index + 1);
-
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_ARG_TYPE_ERROR,
-                             indexStr, reason, valStr);
+  IndexCString indexStr(index + 1);
+
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_ARG_TYPE_ERROR,
+                           indexStr.get(), reason, valStr);
   return false;
 }
 
 static bool
 FunctionReturnTypeError(JSContext* cx, HandleValue type, const char* reason)
 {
+  MOZ_ASSERT(JS::StringIsASCII(reason));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, type, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_RET_TYPE_ERROR, reason, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_RET_TYPE_ERROR, reason, valStr);
   return false;
 }
 
 static bool
 IncompatibleCallee(JSContext* cx, const char* funName, HandleObject actualObj)
 {
+  MOZ_ASSERT(JS::StringIsASCII(funName));
+
   JS::UniqueChars valBytes;
   RootedValue val(cx, ObjectValue(*actualObj));
   const char* valStr = CTypesToSourceForError(cx, val, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INCOMPATIBLE_CALLEE, funName, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_INCOMPATIBLE_CALLEE, funName, valStr);
   return false;
 }
 
 static bool
 IncompatibleThisProto(JSContext* cx, const char* funName,
                       const char* actualType)
 {
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INCOMPATIBLE_THIS,
-                             funName, actualType);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                            CTYPESMSG_INCOMPATIBLE_THIS,
+                            funName, actualType);
   return false;
 }
 
 static bool
 IncompatibleThisProto(JSContext* cx, const char* funName, HandleValue actualVal)
 {
+  MOZ_ASSERT(JS::StringIsASCII(funName));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actualVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INCOMPATIBLE_THIS_VAL,
-                             funName, "incompatible object", valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_INCOMPATIBLE_THIS_VAL,
+                           funName, "incompatible object", valStr);
   return false;
 }
 
 static bool
 IncompatibleThisType(JSContext* cx, const char* funName, const char* actualType)
 {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_INCOMPATIBLE_THIS_TYPE,
                             funName, actualType);
   return false;
 }
 
 static bool
 IncompatibleThisType(JSContext* cx, const char* funName, const char* actualType,
                      HandleValue actualVal)
 {
+  MOZ_ASSERT(JS::StringIsASCII(funName));
+  MOZ_ASSERT(JS::StringIsASCII(actualType));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actualVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INCOMPATIBLE_THIS_VAL,
-                             funName, actualType, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_INCOMPATIBLE_THIS_VAL,
+                           funName, actualType, valStr);
   return false;
 }
 
 static bool
 InvalidIndexError(JSContext* cx, HandleValue val)
 {
   JS::UniqueChars idBytes;
   const char* indexStr = CTypesToSourceForError(cx, val, idBytes);
   if (!indexStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INVALID_INDEX, indexStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_INVALID_INDEX, indexStr);
   return false;
 }
 
 static bool
 InvalidIndexError(JSContext* cx, HandleId id)
 {
   RootedValue idVal(cx, IdToValue(id));
   return InvalidIndexError(cx, idVal);
 }
 
 static bool
 InvalidIndexRangeError(JSContext* cx, size_t index, size_t length)
 {
-  char indexStr[16];
-  SprintfLiteral(indexStr, "%zu", index);
-
-  char lengthStr[16];
-  SprintfLiteral(lengthStr,"%zu", length);
+  IndexCString indexStr(index);
+  IndexCString lengthStr(length);
 
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
-                            CTYPESMSG_INVALID_RANGE, indexStr, lengthStr);
+                            CTYPESMSG_INVALID_RANGE, indexStr.get(), lengthStr.get());
   return false;
 }
 
 static bool
 NonPrimitiveError(JSContext* cx, HandleObject typeObj)
 {
   MOZ_ASSERT(CType::IsCType(typeObj));
 
-  AutoString typeSource;
-  BuildTypeSource(cx, typeObj, true, typeSource);
-  if (!typeSource) {
-      return false;
-  }
-  JS::UniqueChars typeStr = EncodeLatin1(cx, typeSource);
+  JS::UniqueChars typeStr = TypeSourceForError(cx, typeObj);
   if (!typeStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_NON_PRIMITIVE, typeStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_NON_PRIMITIVE, typeStr.get());
   return false;
 }
 
 static bool
 NonStringBaseError(JSContext* cx, HandleValue thisVal)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, thisVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_NON_STRING_BASE, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_NON_STRING_BASE, valStr);
   return false;
 }
 
 static bool
 NullPointerError(JSContext* cx, const char* action, HandleObject obj)
 {
+  MOZ_ASSERT(JS::StringIsASCII(action));
+
   JS::UniqueChars valBytes;
   RootedValue val(cx, ObjectValue(*obj));
   const char* valStr = CTypesToSourceForError(cx, val, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_NULL_POINTER, action, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_NULL_POINTER, action, valStr);
   return false;
 }
 
 static bool
 PropNameNonStringError(JSContext* cx, HandleId id, HandleValue actual,
                        ConversionType convType,
                        HandleObject funObj = nullptr, unsigned argIndex = 0)
 {
@@ -1941,153 +1797,136 @@ PropNameNonStringError(JSContext* cx, Ha
   RootedValue idVal(cx, IdToValue(id));
   const char* propStr = CTypesToSourceForError(cx, idVal, idBytes);
   if (!propStr) {
     return false;
   }
 
   JS::UniqueChars posStr;
   if (funObj) {
-    AutoString posSource;
-    BuildConversionPosition(cx, convType, funObj, argIndex, posSource);
-    if (!posSource) {
-        return false;
-    }
-    posStr = EncodeLatin1(cx, posSource);
+    posStr = ConversionPositionForError(cx, convType, funObj, argIndex);
     if (!posStr) {
       return false;
     }
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_PROP_NONSTRING, propStr, valStr,
-                             (posStr ? posStr.get() : ""));
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_PROP_NONSTRING, propStr, valStr,
+                           (posStr ? posStr.get() : ""));
   return false;
 }
 
 static bool
 SizeOverflow(JSContext* cx, const char* name, const char* limit)
 {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_SIZE_OVERFLOW, name, limit);
   return false;
 }
 
 static bool
 TypeError(JSContext* cx, const char* expected, HandleValue actual)
 {
+  MOZ_ASSERT(JS::StringIsASCII(expected));
+
   JS::UniqueChars bytes;
   const char* src = CTypesToSourceForError(cx, actual, bytes);
   if (!src) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_TYPE_ERROR, expected, src);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_TYPE_ERROR, expected, src);
   return false;
 }
 
 static bool
 TypeOverflow(JSContext* cx, const char* expected, HandleValue actual)
 {
+  MOZ_ASSERT(JS::StringIsASCII(expected));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_TYPE_OVERFLOW, valStr, expected);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_TYPE_OVERFLOW, valStr, expected);
   return false;
 }
 
 static bool
 UndefinedSizeCastError(JSContext* cx, HandleObject targetTypeObj)
 {
-  AutoString targetTypeSource;
-  BuildTypeSource(cx, targetTypeObj, true, targetTypeSource);
-  if (!targetTypeSource) {
-      return false;
-  }
-  JS::UniqueChars targetTypeStr = EncodeLatin1(cx, targetTypeSource);
+  JS::UniqueChars targetTypeStr = TypeSourceForError(cx, targetTypeObj);
   if (!targetTypeStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_UNDEFINED_SIZE_CAST, targetTypeStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_UNDEFINED_SIZE_CAST, targetTypeStr.get());
   return false;
 }
 
 static bool
 SizeMismatchCastError(JSContext* cx,
                       HandleObject sourceTypeObj, HandleObject targetTypeObj,
                       size_t sourceSize, size_t targetSize)
 {
-  AutoString sourceTypeSource;
-  BuildTypeSource(cx, sourceTypeObj, true, sourceTypeSource);
-  if (!sourceTypeSource) {
-      return false;
-  }
-  JS::UniqueChars sourceTypeStr = EncodeLatin1(cx, sourceTypeSource);
+  JS::UniqueChars sourceTypeStr = TypeSourceForError(cx, sourceTypeObj);
   if (!sourceTypeStr) {
     return false;
   }
 
-  AutoString targetTypeSource;
-  BuildTypeSource(cx, targetTypeObj, true, targetTypeSource);
-  if (!targetTypeSource) {
-      return false;
-  }
-  JS::UniqueChars targetTypeStr = EncodeLatin1(cx, targetTypeSource);
+  JS::UniqueChars targetTypeStr = TypeSourceForError(cx, targetTypeObj);
   if (!targetTypeStr) {
     return false;
   }
 
-  char sourceSizeStr[16];
-  char targetSizeStr[16];
-  SprintfLiteral(sourceSizeStr, "%zu", sourceSize);
-  SprintfLiteral(targetSizeStr, "%zu", targetSize);
-
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_SIZE_MISMATCH_CAST,
-                             targetTypeStr.get(), sourceTypeStr.get(),
-                             targetSizeStr, sourceSizeStr);
+  IndexCString sourceSizeStr(sourceSize);
+  IndexCString targetSizeStr(targetSize);
+
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_SIZE_MISMATCH_CAST,
+                           targetTypeStr.get(), sourceTypeStr.get(),
+                           targetSizeStr.get(), sourceSizeStr.get());
   return false;
 }
 
 static bool
 UndefinedSizePointerError(JSContext* cx, const char* action, HandleObject obj)
 {
+  MOZ_ASSERT(JS::StringIsASCII(action));
+
   JS::UniqueChars valBytes;
   RootedValue val(cx, ObjectValue(*obj));
   const char* valStr = CTypesToSourceForError(cx, val, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_UNDEFINED_SIZE, action, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_UNDEFINED_SIZE, action, valStr);
   return false;
 }
 
 static bool
 VariadicArgumentTypeError(JSContext* cx, uint32_t index, HandleValue actual)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
-  char indexStr[16];
-  SprintfLiteral(indexStr, "%u", index + 1);
-
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_VARG_TYPE_ERROR, indexStr, valStr);
+  IndexCString indexStr(index + 1);
+
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_VARG_TYPE_ERROR, indexStr.get(), valStr);
   return false;
 }
 
 MOZ_MUST_USE JSObject*
 GetThisObject(JSContext* cx, const CallArgs& args, const char* msg)
 {
   if (!args.thisv().isObject()) {
     IncompatibleThisProto(cx, msg, args.thisv());
@@ -3706,59 +3545,62 @@ ImplicitConvert(JSContext* cx,
       }
 
     } else if (convType == ConversionType::Argument && val.isString()) {
       // Convert the string for the ffi call. This requires allocating space
       // which the caller assumes ownership of.
       // TODO: Extend this so we can safely convert strings at other times also.
       JSString* sourceString = val.toString();
       size_t sourceLength = sourceString->length();
-      JSLinearString* sourceLinear = sourceString->ensureLinear(cx);
-      if (!sourceLinear) {
+      Rooted<JSFlatString*> sourceFlat(cx, sourceString->ensureFlat(cx));
+      if (!sourceFlat) {
         return false;
       }
 
       switch (CType::GetTypeCode(baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
-        // Convert from UTF-16 to UTF-8.
-        size_t nbytes = GetDeflatedUTF8StringLength(cx, sourceLinear);
-        if (nbytes == (size_t) -1) {
+        // Reject if unpaired surrogate characters are present.
+        if (!ReportErrorIfUnpairedSurrogatePresent(cx, sourceFlat)) {
           return false;
         }
 
+        // Convert from UTF-16 to UTF-8.
+        size_t nbytes = JS::GetDeflatedUTF8StringLength(sourceFlat);
+
         char** charBuffer = static_cast<char**>(buffer);
         *charBuffer = cx->pod_malloc<char>(nbytes + 1);
         if (!*charBuffer) {
           return false;
         }
 
-        ASSERT_OK(DeflateStringToUTF8Buffer(cx, sourceLinear, *charBuffer, &nbytes));
+        JS::DeflateStringToUTF8Buffer(sourceFlat, mozilla::RangedPtr<char>(*charBuffer, nbytes),
+                                      &nbytes);
         (*charBuffer)[nbytes] = 0;
         *freePointer = true;
         break;
       }
       case TYPE_char16_t: {
         // Copy the char16_t string data. (We could provide direct access to the
         // JSString's buffer, but this approach is safer if the caller happens
         // to modify the string.)
         char16_t** char16Buffer = static_cast<char16_t**>(buffer);
         *char16Buffer = cx->pod_malloc<char16_t>(sourceLength + 1);
         if (!*char16Buffer) {
           return false;
         }
 
         *freePointer = true;
-        if (sourceLinear->hasLatin1Chars()) {
+        if (sourceFlat->hasLatin1Chars()) {
             AutoCheckCannotGC nogc;
-            CopyAndInflateChars(*char16Buffer, sourceLinear->latin1Chars(nogc), sourceLength);
+            CopyAndInflateChars(*char16Buffer, sourceFlat->latin1Chars(nogc), sourceLength);
         } else {
             AutoCheckCannotGC nogc;
-            mozilla::PodCopy(*char16Buffer, sourceLinear->twoByteChars(nogc), sourceLength);
+            mozilla::PodCopy(*char16Buffer, sourceFlat->twoByteChars(nogc), sourceLength);
         }
         (*char16Buffer)[sourceLength] = 0;
         break;
       }
       default:
         return ConvError(cx, targetType, val, convType, funObj, argIndex,
                          arrObj, arrIndex);
       }
@@ -3828,41 +3670,42 @@ ImplicitConvert(JSContext* cx,
     MOZ_ASSERT(!funObj);
 
     RootedObject baseType(cx, ArrayType::GetBaseType(targetType));
     size_t targetLength = ArrayType::GetLength(targetType);
 
     if (val.isString()) {
       JSString* sourceString = val.toString();
       size_t sourceLength = sourceString->length();
-      JSLinearString* sourceLinear = sourceString->ensureLinear(cx);
-      if (!sourceLinear) {
+      Rooted<JSFlatString*> sourceFlat(cx, sourceString->ensureFlat(cx));
+      if (!sourceFlat) {
         return false;
       }
 
       switch (CType::GetTypeCode(baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
-        // Convert from UTF-16 or Latin1 to UTF-8.
-        size_t nbytes =
-          GetDeflatedUTF8StringLength(cx, sourceLinear);
-        if (nbytes == (size_t) -1) {
+        // Reject if unpaired surrogate characters are present.
+        if (!ReportErrorIfUnpairedSurrogatePresent(cx, sourceFlat)) {
           return false;
         }
 
+        // Convert from UTF-16 or Latin1 to UTF-8.
+        size_t nbytes = JS::GetDeflatedUTF8StringLength(sourceFlat);
+
         if (targetLength < nbytes) {
           MOZ_ASSERT(!funObj);
           return ArrayLengthOverflow(cx, targetLength, targetType, nbytes, val,
                                      convType);
         }
 
         char* charBuffer = static_cast<char*>(buffer);
-        ASSERT_OK(DeflateStringToUTF8Buffer(cx, sourceLinear, charBuffer,
-                                            &nbytes));
+        JS::DeflateStringToUTF8Buffer(sourceFlat, mozilla::RangedPtr<char>(charBuffer, nbytes),
+                                      &nbytes);
 
         if (targetLength > nbytes) {
           charBuffer[nbytes] = 0;
         }
 
         break;
       }
       case TYPE_char16_t: {
@@ -3870,22 +3713,22 @@ ImplicitConvert(JSContext* cx,
         // if there's space.
         if (targetLength < sourceLength) {
           MOZ_ASSERT(!funObj);
           return ArrayLengthOverflow(cx, targetLength, targetType,
                                      sourceLength, val, convType);
         }
 
         char16_t* dest = static_cast<char16_t*>(buffer);
-        if (sourceLinear->hasLatin1Chars()) {
+        if (sourceFlat->hasLatin1Chars()) {
             AutoCheckCannotGC nogc;
-            CopyAndInflateChars(dest, sourceLinear->latin1Chars(nogc), sourceLength);
+            CopyAndInflateChars(dest, sourceFlat->latin1Chars(nogc), sourceLength);
         } else {
             AutoCheckCannotGC nogc;
-            mozilla::PodCopy(dest, sourceLinear->twoByteChars(nogc), sourceLength);
+            mozilla::PodCopy(dest, sourceFlat->twoByteChars(nogc), sourceLength);
         }
 
         if (targetLength > sourceLength) {
           dest[sourceLength] = 0;
         }
 
         break;
       }
@@ -5822,31 +5665,33 @@ ArrayType::ConstructData(JSContext* cx,
                                     "an array object or integer");
       }
 
     } else if (args[0].isString()) {
       // We were given a string. Size the array to the appropriate length,
       // including space for the terminator.
       JSString* sourceString = args[0].toString();
       size_t sourceLength = sourceString->length();
-      JSLinearString* sourceLinear = sourceString->ensureLinear(cx);
-      if (!sourceLinear) {
+      Rooted<JSFlatString*> sourceFlat(cx, sourceString->ensureFlat(cx));
+      if (!sourceFlat) {
         return false;
       }
 
       switch (CType::GetTypeCode(baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
-        // Determine the UTF-8 length.
-        length = GetDeflatedUTF8StringLength(cx, sourceLinear);
-        if (length == (size_t) -1) {
+        // Reject if unpaired surrogate characters are present.
+        if (!ReportErrorIfUnpairedSurrogatePresent(cx, sourceFlat)) {
           return false;
         }
 
+        // Determine the UTF-8 length.
+        length = JS::GetDeflatedUTF8StringLength(sourceFlat);
+
         ++length;
         break;
       }
       case TYPE_char16_t:
         length = sourceLength + 1;
         break;
       default:
         return ConvError(cx, obj, args[0], ConversionType::Construct);
@@ -6326,17 +6171,17 @@ StructType::Create(JSContext* cx, unsign
 
 bool
 StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsObj_)
 {
   RootedObject typeObj(cx, typeObj_);
   RootedObject fieldsObj(cx, fieldsObj_);
 
   uint32_t len;
-  ASSERT_OK(JS_GetArrayLength(cx, fieldsObj, &len));
+  MOZ_ALWAYS_TRUE(JS_GetArrayLength(cx, fieldsObj, &len));
 
   // Get the common prototype for CData objects of this type from
   // ctypes.CType.prototype.
   RootedObject dataProto(cx, CType::GetProtoFromType(cx, typeObj, SLOT_STRUCTDATAPROTO));
   if (!dataProto) {
     return false;
   }
 
@@ -7266,17 +7111,17 @@ FunctionType::Create(JSContext* cx, unsi
 
     if (!isArray) {
       return ArgumentTypeMismatch(cx, "third ", "FunctionType", "an array");
     }
 
     arrayObj = &args[2].toObject();
 
     uint32_t len;
-    ASSERT_OK(JS_GetArrayLength(cx, arrayObj, &len));
+    MOZ_ALWAYS_TRUE(JS_GetArrayLength(cx, arrayObj, &len));
 
     if (!argTypes.resize(len)) {
       JS_ReportOutOfMemory(cx);
       return false;
     }
   }
 
   // Pull out the argument types from the array, if any.
@@ -9178,17 +9023,17 @@ Int64::Construct(JSContext* cx,
       return TypeOverflow(cx, "int64", args[0]);
     }
     return ArgumentConvError(cx, args[0], "Int64", 0);
   }
 
   // Get ctypes.Int64.prototype from the 'prototype' property of the ctor.
   RootedValue slot(cx);
   RootedObject callee(cx, &args.callee());
-  ASSERT_OK(JS_GetProperty(cx, callee, "prototype", &slot));
+  MOZ_ALWAYS_TRUE(JS_GetProperty(cx, callee, "prototype", &slot));
   RootedObject proto(cx, slot.toObjectOrNull());
   MOZ_ASSERT(JS_GetClass(proto) == &sInt64ProtoClass);
 
   JSObject* result = Int64Base::Construct(cx, proto, i, false);
   if (!result) {
     return false;
   }
 
@@ -9369,17 +9214,17 @@ UInt64::Construct(JSContext* cx,
       return TypeOverflow(cx, "uint64", args[0]);
     }
     return ArgumentConvError(cx, args[0], "UInt64", 0);
   }
 
   // Get ctypes.UInt64.prototype from the 'prototype' property of the ctor.
   RootedValue slot(cx);
   RootedObject callee(cx, &args.callee());
-  ASSERT_OK(JS_GetProperty(cx, callee, "prototype", &slot));
+  MOZ_ALWAYS_TRUE(JS_GetProperty(cx, callee, "prototype", &slot));
   RootedObject proto(cx, &slot.toObject());
   MOZ_ASSERT(JS_GetClass(proto) == &sUInt64ProtoClass);
 
   JSObject* result = Int64Base::Construct(cx, proto, u, true);
   if (!result) {
     return false;
   }
 
--- a/js/src/ctypes/CTypes.h
+++ b/js/src/ctypes/CTypes.h
@@ -265,39 +265,26 @@ PrependString(JSContext* cx, StringBuild
     for (size_t i = 0; i < alen; i++) {
       v[i] = chars[i];
     }
   } else {
     memcpy(v.begin(), linear->twoByteChars(nogc), alen * sizeof(char16_t));
   }
 }
 
-template <typename CharT>
-extern size_t
-GetDeflatedUTF8StringLength(JSContext* maybecx, const CharT* chars,
-                            size_t charsLength);
-
-template <typename CharT>
 MOZ_MUST_USE bool
-DeflateStringToUTF8Buffer(JSContext* maybecx, const CharT* src, size_t srclen,
-                          char* dst, size_t* dstlenp);
+ReportErrorIfUnpairedSurrogatePresent(JSContext* cx, JSLinearString* str);
 
 MOZ_MUST_USE JSObject*
 GetThisObject(JSContext* cx, const CallArgs& args, const char* msg);
 
 /*******************************************************************************
 ** Function and struct API definitions
 *******************************************************************************/
 
-MOZ_ALWAYS_INLINE void
-ASSERT_OK(bool ok)
-{
-  MOZ_ASSERT(ok);
-}
-
 // for JS error reporting
 enum ErrorNum {
 #define MSG_DEF(name, count, exception, format) \
   name,
 #include "ctypes/ctypes.msg"
 #undef MSG_DEF
   CTYPESERR_LIMIT
 };
--- a/js/src/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -114,66 +114,66 @@ Library::Create(JSContext* cx, HandleVal
     return nullptr;
   }
 
   PRLibSpec libSpec;
   RootedFlatString pathStr(cx, JS_FlattenString(cx, path.toString()));
   if (!pathStr) {
     return nullptr;
   }
+#ifdef XP_WIN
+  // On Windows, converting to native charset may corrupt path string.
+  // So, we have to use Unicode path directly.
   AutoStableStringChars pathStrChars(cx);
   if (!pathStrChars.initTwoByte(cx, pathStr)) {
     return nullptr;
   }
-#ifdef XP_WIN
-  // On Windows, converting to native charset may corrupt path string.
-  // So, we have to use Unicode path directly.
   char16ptr_t pathChars = pathStrChars.twoByteChars();
   libSpec.value.pathname_u = pathChars;
   libSpec.type = PR_LibSpec_PathnameU;
 #else
   // Convert to platform native charset if the appropriate callback has been
   // provided.
-  char* pathBytes;
+  JS::UniqueChars pathBytes;
   if (callbacks && callbacks->unicodeToNative) {
-    pathBytes =
-      callbacks->unicodeToNative(cx, pathStrChars.twoByteChars(), pathStr->length());
+    AutoStableStringChars pathStrChars(cx);
+    if (!pathStrChars.initTwoByte(cx, pathStr)) {
+      return nullptr;
+    }
+
+    pathBytes.reset(callbacks->unicodeToNative(cx, pathStrChars.twoByteChars(),
+                                               pathStr->length()));
+    if (!pathBytes) {
+      return nullptr;
+    }
+  } else {
+    // Fallback: assume the platform native charset is UTF-8. This is true
+    // for Mac OS X, Android, and probably Linux.
+    if (!ReportErrorIfUnpairedSurrogatePresent(cx, pathStr)) {
+      return nullptr;
+    }
+
+    size_t nbytes = JS::GetDeflatedUTF8StringLength(pathStr);
+
+    pathBytes.reset(static_cast<char*>(JS_malloc(cx, nbytes + 1)));
     if (!pathBytes) {
       return nullptr;
     }
 
-  } else {
-    // Fallback: assume the platform native charset is UTF-8. This is true
-    // for Mac OS X, Android, and probably Linux.
-    size_t nbytes =
-      GetDeflatedUTF8StringLength(cx, pathStrChars.twoByteChars(), pathStr->length());
-    if (nbytes == (size_t) -1) {
-      return nullptr;
-    }
-
-    pathBytes = static_cast<char*>(JS_malloc(cx, nbytes + 1));
-    if (!pathBytes) {
-      return nullptr;
-    }
-
-    ASSERT_OK(DeflateStringToUTF8Buffer(cx, pathStrChars.twoByteChars(),
-                pathStr->length(), pathBytes, &nbytes));
+    JS::DeflateStringToUTF8Buffer(pathStr, mozilla::RangedPtr<char>(pathBytes.get(), nbytes),
+                                  &nbytes);
     pathBytes[nbytes] = 0;
   }
 
-  libSpec.value.pathname = pathBytes;
+  libSpec.value.pathname = pathBytes.get();
   libSpec.type = PR_LibSpec_Pathname;
 #endif
 
   PRLibrary* library = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW);
 
-#ifndef XP_WIN
-  JS_free(cx, pathBytes);
-#endif
-
   if (!library) {
 #define MAX_ERROR_LEN 1024
     char error[MAX_ERROR_LEN] = "Cannot get error from NSPR.";
     uint32_t errorLen = PR_GetErrorTextLength();
     if (errorLen && errorLen < MAX_ERROR_LEN) {
       PR_GetErrorText(error);
     }
 #undef MAX_ERROR_LEN
--- a/js/src/devtools/automation/winbuildenv.sh
+++ b/js/src/devtools/automation/winbuildenv.sh
@@ -5,17 +5,17 @@ mk_add_options() {
   echo "$@"
 }
 
 topsrcdir="$SOURCE"
 
 # Tooltool installs in parent of topsrcdir for spidermonkey builds.
 # Resolve that path since the mozconfigs assume tooltool installs in
 # topsrcdir.
-export VSPATH="$(cd ${topsrcdir}/.. && pwd)/vs2017_15.6.6"
+export VSPATH="$(cd ${topsrcdir}/.. && pwd)/vs2017_15.8.4"
 
 # When running on a developer machine, several variables will already
 # have the right settings and we will need to keep them since the
 # Windows mozconfigs overwrite them.
 echo "export ORIGINAL_INCLUDE=$INCLUDE"
 echo "export ORIGINAL_LIB=$LIB"
 echo "export ORIGINAL_LIBPATH=$LIBPATH"
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1694,19 +1694,19 @@ JS::GetFirstArgumentAsTypeHint(JSContext
 
     UniqueChars bytes;
     const char* source = ValueToSourceForError(cx, args.get(0), bytes);
     if (!source) {
         ReportOutOfMemory(cx);
         return false;
     }
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                               "Symbol.toPrimitive",
-                               "\"string\", \"number\", or \"default\"", source);
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                             "Symbol.toPrimitive",
+                             "\"string\", \"number\", or \"default\"", source);
     return false;
 }
 
 JS_PUBLIC_API(JSObject*)
 JS_InitClass(JSContext* cx, HandleObject obj, HandleObject parent_proto,
              const JSClass* clasp, JSNative constructor, unsigned nargs,
              const JSPropertySpec* ps, const JSFunctionSpec* fs,
              const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs)
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -1156,27 +1156,27 @@ js::ValueToSourceForError(JSContext* cx,
             return "<<error converting value to string>>";
         }
     } else if (val.isString()) {
         if (!sb.append("the string ")) {
             return "<<error converting value to string>>";
         }
     } else {
         MOZ_ASSERT(val.isBoolean() || val.isSymbol());
-        bytes = EncodeLatin1(cx, str);
+        bytes = StringToNewUTF8CharsZ(cx, *str);
         return bytes.get();
     }
     if (!sb.append(str)) {
         return "<<error converting value to string>>";
     }
     str = sb.finishString();
     if (!str) {
         return "<<error converting value to string>>";
     }
-    bytes = EncodeLatin1(cx, str);
+    bytes = StringToNewUTF8CharsZ(cx, *str);
     return bytes.get();
 }
 
 bool
 js::GetInternalError(JSContext* cx, unsigned errorNumber, MutableHandleValue error)
 {
     FixedInvokeArgs<1> args(cx);
     args[0].set(Int32Value(errorNumber));
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -1620,57 +1620,16 @@ fi
 fi # ! SKIP_COMPILER_CHECKS
 
 AC_DEFINE(CPP_THROW_NEW, [throw()])
 AC_LANG_C
 
 MOZ_EXPAND_LIBS
 
 dnl ========================================================
-dnl =
-dnl = Build depencency options
-dnl =
-dnl ========================================================
-MOZ_ARG_HEADER(Build dependencies)
-
-if test "$GNU_CC" -a "$GNU_CXX"; then
-  _DEPEND_CFLAGS='-MD -MP -MF $(MDDEPDIR)/$(@F).pp'
-else
-  # clang-cl doesn't accept the normal -MD -MP -MF options that clang does, but
-  # the underlying cc1 binary understands how to generate dependency files.
-  # These options are based on analyzing what the normal clang driver sends to
-  # cc1 when given the "correct" dependency options.
-  if test -n "$CLANG_CL"; then
-   _DEPEND_CFLAGS='-Xclang -MP -Xclang -dependency-file -Xclang $(MDDEPDIR)/$(@F).pp -Xclang -MT -Xclang $@'
-  fi
-  dnl Don't override this for MSVC
-  if test -z "$_WIN32_MSVC"; then
-    _USE_CPP_INCLUDE_FLAG=
-    _DEFINES_CFLAGS='$(ACDEFINES) -D_JS_CONFDEFS_H_ -DMOZILLA_CLIENT'
-    _DEFINES_CXXFLAGS='$(ACDEFINES) -D_JS_CONFDEFS_H_ -DMOZILLA_CLIENT'
-  else
-    echo '#include <stdio.h>' > dummy-hello.c
-    changequote(,)
-    dnl This output is localized, split at the first double space or colon and space.
-    _CL_PREFIX_REGEX="^\([^:]*:.*[ :] \)\(.*\\\stdio.h\)$"
-    CL_INCLUDES_PREFIX=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\1/p'`
-    _CL_STDIO_PATH=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\2/p'`
-    changequote([,])
-    if ! test -e "$_CL_STDIO_PATH"; then
-        AC_MSG_ERROR([Unable to parse cl -showIncludes prefix. This compiler's locale has an unsupported formatting.])
-    fi
-    if test -z "$CL_INCLUDES_PREFIX"; then
-        AC_MSG_ERROR([Cannot find cl -showIncludes prefix.])
-    fi
-    AC_SUBST(CL_INCLUDES_PREFIX)
-    rm -f dummy-hello.c
-  fi
-fi
-
-dnl ========================================================
 dnl = Link js shell to system readline
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(readline,
 [  --enable-readline       Link js shell to system readline library],
     JS_WANT_READLINE=1,
     JS_WANT_READLINE= )
 
 JS_BUNDLED_EDITLINE=
@@ -1800,17 +1759,16 @@ HOST_CFLAGS=`echo \
     $_COMPILATION_HOST_CFLAGS \
     $HOST_CFLAGS`
 
 HOST_CXXFLAGS=`echo \
     $_WARNINGS_HOST_CXXFLAGS \
     $_COMPILATION_HOST_CXXFLAGS \
     $HOST_CXXFLAGS`
 
-AC_SUBST(_DEPEND_CFLAGS)
 AC_SUBST(MOZ_SYSTEM_NSPR)
 
 OS_CFLAGS="$CFLAGS"
 OS_CXXFLAGS="$CXXFLAGS"
 OS_CPPFLAGS="$CPPFLAGS"
 OS_COMPILE_CFLAGS="$COMPILE_CFLAGS"
 OS_COMPILE_CXXFLAGS="$COMPILE_CXXFLAGS"
 OS_LDFLAGS="$LDFLAGS"
--- a/js/src/vm/JSFunction-inl.h
+++ b/js/src/vm/JSFunction-inl.h
@@ -17,17 +17,17 @@
 #include "vm/JSObject-inl.h"
 
 namespace js {
 
 inline const char*
 GetFunctionNameBytes(JSContext* cx, JSFunction* fun, UniqueChars* bytes)
 {
     if (JSAtom* name = fun->explicitName()) {
-        *bytes = EncodeLatin1(cx, name);
+        *bytes = StringToNewUTF8CharsZ(cx, *name);
         return bytes->get();
     }
     return js_anonymous_str;
 }
 
 inline bool
 CanReuseFunctionForClone(JSContext* cx, HandleFunction fun)
 {
--- a/js/src/vm/JSFunction.cpp
+++ b/js/src/vm/JSFunction.cpp
@@ -2701,30 +2701,30 @@ js::ReportIncompatibleMethod(JSContext* 
     } else {
         MOZ_ASSERT(thisv.isUndefined() || thisv.isNull());
     }
 #endif
 
     if (JSFunction* fun = ReportIfNotFunction(cx, args.calleev())) {
         UniqueChars funNameBytes;
         if (const char* funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
-            JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                                       clasp->name, funName, InformalValueTypeName(thisv));
+            JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                     clasp->name, funName, InformalValueTypeName(thisv));
         }
     }
 }
 
 void
 js::ReportIncompatible(JSContext* cx, const CallArgs& args)
 {
     if (JSFunction* fun = ReportIfNotFunction(cx, args.calleev())) {
         UniqueChars funNameBytes;
         if (const char* funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
-            JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
-                                       funName, "method", InformalValueTypeName(args.thisv()));
+            JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
+                                     funName, "method", InformalValueTypeName(args.thisv()));
         }
     }
 }
 
 namespace JS {
 namespace detail {
 
 JS_PUBLIC_API(void)
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -90,30 +90,30 @@ js::ReportNotObject(JSContext* cx, Handl
 
 void
 js::ReportNotObjectArg(JSContext* cx, const char* nth, const char* fun, HandleValue v)
 {
     MOZ_ASSERT(!v.isObject());
 
     UniqueChars bytes;
     if (const char* chars = ValueToSourceForError(cx, v, bytes)) {
-        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT_ARG,
-                                   nth, fun, chars);
+        JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT_ARG,
+                                 nth, fun, chars);
     }
 }
 
 void
 js::ReportNotObjectWithName(JSContext* cx, const char* name, HandleValue v)
 {
     MOZ_ASSERT(!v.isObject());
 
     UniqueChars bytes;
     if (const char* chars = ValueToSourceForError(cx, v, bytes)) {
-        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT_NAME,
-                                   name, chars);
+        JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT_NAME,
+                                 name, chars);
     }
 }
 
 JS_PUBLIC_API(const char*)
 JS::InformalValueTypeName(const Value& v)
 {
     if (v.isObject()) {
         return v.toObject().getClass()->name;
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1919,18 +1919,18 @@ js::ReportIncompatibleSelfHostedMethod(J
         MOZ_ASSERT(iter.callee(cx)->isSelfHostedOrIntrinsic() &&
                    !iter.callee(cx)->isBoundFunction());
         UniqueChars funNameBytes;
         const char* funName = GetFunctionNameBytes(cx, iter.callee(cx), &funNameBytes);
         if (!funName) {
             return false;
         }
         if (strcmp(funName, "IsTypedArrayEnsuringArrayBuffer") != 0) {
-            JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
-                                       funName, "method", InformalValueTypeName(args.thisv()));
+            JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
+                                     funName, "method", InformalValueTypeName(args.thisv()));
             return false;
         }
         ++iter;
     }
 
     MOZ_ASSERT_UNREACHABLE("How did we not find a useful self-hosted frame?");
     return false;
 }
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -279,18 +279,16 @@ nsresult NS_NewHTMLCopyTextEncoder(nsIDo
 nsresult NS_NewTextEncoder(nsIDocumentEncoder** aResult);
 nsresult NS_NewContentPolicy(nsIContentPolicy** aResult);
 
 nsresult NS_NewEventListenerService(nsIEventListenerService** aResult);
 nsresult NS_NewGlobalMessageManager(nsISupports** aResult);
 nsresult NS_NewParentProcessMessageManager(nsISupports** aResult);
 nsresult NS_NewChildProcessMessageManager(nsISupports** aResult);
 
-nsresult NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult);
-
 #define MAKE_CTOR(ctor_, iface_, func_)                   \
 static nsresult                                           \
 ctor_(nsISupports* aOuter, REFNSIID aIID, void** aResult) \
 {                                                         \
   *aResult = nullptr;                                      \
   if (aOuter)                                             \
     return NS_ERROR_NO_AGGREGATION;                       \
   iface_* inst;                                           \
@@ -336,17 +334,16 @@ MAKE_CTOR(CreateTextEncoder,            
 MAKE_CTOR(CreateHTMLCopyTextEncoder,      nsIDocumentEncoder,          NS_NewHTMLCopyTextEncoder)
 MAKE_CTOR(CreateXMLContentSerializer,     nsIContentSerializer,        NS_NewXMLContentSerializer)
 MAKE_CTOR(CreateHTMLContentSerializer,    nsIContentSerializer,        NS_NewHTMLContentSerializer)
 MAKE_CTOR(CreateXHTMLContentSerializer,   nsIContentSerializer,        NS_NewXHTMLContentSerializer)
 MAKE_CTOR(CreatePlainTextSerializer,      nsIContentSerializer,        NS_NewPlainTextSerializer)
 MAKE_CTOR(CreateContentPolicy,            nsIContentPolicy,            NS_NewContentPolicy)
 #ifdef MOZ_XUL
 MAKE_CTOR(CreateXULDocument,              nsIDocument,                 NS_NewXULDocument)
-// NS_NewXULControllers
 #endif
 MAKE_CTOR(CreateContentDLF,               nsIDocumentLoaderFactory,    NS_NewContentDocumentLoaderFactory)
 MAKE_CTOR(CreateEventListenerService,     nsIEventListenerService,     NS_NewEventListenerService)
 MAKE_CTOR(CreateGlobalMessageManager,     nsISupports,                 NS_NewGlobalMessageManager)
 MAKE_CTOR(CreateParentMessageManager,     nsISupports,                 NS_NewParentProcessMessageManager)
 MAKE_CTOR(CreateChildMessageManager,      nsISupports,                 NS_NewChildProcessMessageManager)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDataDocumentContentPolicy)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsNoDataProtocolContentPolicy)
@@ -458,17 +455,16 @@ NS_DEFINE_NAMED_CID(NS_XMLCONTENTSERIALI
 NS_DEFINE_NAMED_CID(NS_XHTMLCONTENTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_HTMLCONTENTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_PLAINTEXTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_PARSERUTILS_CID);
 NS_DEFINE_NAMED_CID(NS_SCRIPTABLEUNESCAPEHTML_CID);
 NS_DEFINE_NAMED_CID(NS_CONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_DATADOCUMENTCONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_NODATAPROTOCOLCONTENTPOLICY_CID);
-NS_DEFINE_NAMED_CID(NS_XULCONTROLLERS_CID);
 #ifdef MOZ_XUL
 NS_DEFINE_NAMED_CID(NS_XULDOCUMENT_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_CONTENT_DOCUMENT_LOADER_FACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_JSPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_JSURI_CID);
 NS_DEFINE_NAMED_CID(NS_JSURIMUTATOR_CID);
 NS_DEFINE_NAMED_CID(NS_PLUGINDOCLOADERFACTORY_CID);
@@ -552,17 +548,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_HTMLCONTENTSERIALIZER_CID, false, nullptr, CreateHTMLContentSerializer },
   { &kNS_XHTMLCONTENTSERIALIZER_CID, false, nullptr, CreateXHTMLContentSerializer },
   { &kNS_PLAINTEXTSERIALIZER_CID, false, nullptr, CreatePlainTextSerializer },
   { &kNS_PARSERUTILS_CID, false, nullptr, nsParserUtilsConstructor },
   { &kNS_SCRIPTABLEUNESCAPEHTML_CID, false, nullptr, nsParserUtilsConstructor },
   { &kNS_CONTENTPOLICY_CID, false, nullptr, CreateContentPolicy },
   { &kNS_DATADOCUMENTCONTENTPOLICY_CID, false, nullptr, nsDataDocumentContentPolicyConstructor },
   { &kNS_NODATAPROTOCOLCONTENTPOLICY_CID, false, nullptr, nsNoDataProtocolContentPolicyConstructor },
-  { &kNS_XULCONTROLLERS_CID, false, nullptr, NS_NewXULControllers },
 #ifdef MOZ_XUL
   { &kNS_XULDOCUMENT_CID, false, nullptr, CreateXULDocument },
 #endif
   { &kNS_CONTENT_DOCUMENT_LOADER_FACTORY_CID, false, nullptr, CreateContentDLF },
   { &kNS_JSPROTOCOLHANDLER_CID, false, nullptr, nsJSProtocolHandler::Create },
   { &kNS_JSURI_CID, false, nullptr, nsJSURIMutatorConstructor }, // do_CreateInstance returns mutator
   { &kNS_JSURIMUTATOR_CID, false, nullptr, nsJSURIMutatorConstructor },
   { &kNS_PLUGINDOCLOADERFACTORY_CID, false, nullptr, CreateContentDLF },
@@ -644,17 +639,16 @@ static const mozilla::Module::ContractID
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "text/html", &kNS_HTMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "application/vnd.mozilla.xul+xml", &kNS_XMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "text/plain", &kNS_PLAINTEXTSERIALIZER_CID },
   { NS_PARSERUTILS_CONTRACTID, &kNS_PARSERUTILS_CID },
   { NS_SCRIPTABLEUNESCAPEHTML_CONTRACTID, &kNS_SCRIPTABLEUNESCAPEHTML_CID },
   { NS_CONTENTPOLICY_CONTRACTID, &kNS_CONTENTPOLICY_CID },
   { NS_DATADOCUMENTCONTENTPOLICY_CONTRACTID, &kNS_DATADOCUMENTCONTENTPOLICY_CID },
   { NS_NODATAPROTOCOLCONTENTPOLICY_CONTRACTID, &kNS_NODATAPROTOCOLCONTENTPOLICY_CID },
-  { "@mozilla.org/xul/xul-controllers;1", &kNS_XULCONTROLLERS_CID },
   { CONTENT_DLF_CONTRACTID, &kNS_CONTENT_DOCUMENT_LOADER_FACTORY_CID },
   { NS_JSPROTOCOLHANDLER_CONTRACTID, &kNS_JSPROTOCOLHANDLER_CID },
   { PLUGIN_DLF_CONTRACTID, &kNS_PLUGINDOCLOADERFACTORY_CID },
   { NS_STYLESHEETSERVICE_CONTRACTID, &kNS_STYLESHEETSERVICE_CID },
   { NS_SDBCONNECTION_CONTRACTID, &kNS_SDBCONNECTION_CID },
   { "@mozilla.org/dom/localStorage-manager;1", &kNS_DOMLOCALSTORAGEMANAGER_CID },
   { "@mozilla.org/dom/sessionStorage-manager;1", &kNS_DOMSESSIONSTORAGEMANAGER_CID },
   { DOMREQUEST_SERVICE_CONTRACTID, &kDOMREQUEST_SERVICE_CID },
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -4977,18 +4977,16 @@ nsGridContainerFrame::ReflowInFlowChild(
                                         const GridReflowInput& aState,
                                         const LogicalRect&     aContentArea,
                                         ReflowOutput&   aDesiredSize,
                                         nsReflowStatus&        aStatus)
 {
   nsPresContext* pc = PresContext();
   ComputedStyle* containerSC = Style();
   WritingMode wm = aState.mReflowInput->GetWritingMode();
-  LogicalMargin pad(aState.mReflowInput->ComputedLogicalPadding());
-  const LogicalPoint padStart(wm, pad.IStart(wm), pad.BStart(wm));
   const bool isGridItem = !!aGridItemInfo;
   MOZ_ASSERT(isGridItem == !aChild->IsPlaceholderFrame());
   LogicalRect cb(wm);
   WritingMode childWM = aChild->GetWritingMode();
   bool isConstrainedBSize = false;
   nscoord toFragmentainerEnd;
   // The part of the child's grid area that's in previous container fragments.
   nscoord consumedGridAreaBSize = 0;
@@ -5041,24 +5039,24 @@ nsGridContainerFrame::ReflowInFlowChild(
     };
     SetProp(eLogicalAxisBlock, isOrthogonal ? IBaselinePadProperty() :
                                               BBaselinePadProperty());
     SetProp(eLogicalAxisInline, isOrthogonal ? BBaselinePadProperty() :
                                                IBaselinePadProperty());
   } else {
     // By convention, for frames that perform CSS Box Alignment, we position
     // placeholder children at the start corner of their alignment container,
-    // and in this case that's usually the grid's padding box.
+    // and in this case that's usually the grid's content-box.
     // ("Usually" - the exception is when the grid *also* forms the
     // abs.pos. containing block. In that case, the alignment container isn't
-    // the padding box -- it's some grid area instead.  But that case doesn't
+    // the content-box -- it's some grid area instead.  But that case doesn't
     // require any special handling here, because we handle it later using a
     // special flag (STATIC_POS_IS_CB_ORIGIN) which will make us ignore the
     // placeholder's position entirely.)
-    cb = aContentArea - padStart;
+    cb = aContentArea;
     aChild->AddStateBits(PLACEHOLDER_STATICPOS_NEEDS_CSSALIGN);
   }
 
   LogicalSize reflowSize(cb.Size(wm));
   if (isConstrainedBSize) {
     reflowSize.BSize(wm) = toFragmentainerEnd;
   }
   LogicalSize childCBSize = reflowSize.ConvertTo(childWM, wm);
--- a/layout/reftests/css-grid/grid-abspos-items-015-ref.html
+++ b/layout/reftests/css-grid/grid-abspos-items-015-ref.html
@@ -33,17 +33,17 @@ separator { clear:both; display:block; h
   writing-mode: vertical-lr; direction:rtl;
   z-index:1;
 }
 
 abs1,abs2,abs3,abs4 {
   grid-area: 2 / 2 / 3 / 3;
   position: absolute;
 }
-abs1 { height:97px; top:-12px; left:-37px; background:lime; }
+abs1 { height:97px; top:-12px; left:-30px; background:lime; }
 abs2 { right:-18px; left:3px; background:pink; }
 abs3 { top: -20px; left:-35px; right:-26px; background:cyan; }
 abs4 { top:-6px; bottom:-53px; background:silver; }
 abs1::before { content:"1";}
 abs2::before { content:"2";}
 abs3::before { content:"3";}
 abs4::before { content:"4";}
 
@@ -62,19 +62,19 @@ abs4::before { content:"4";}
 
 .hl abs2, .hr abs2 { top:-25px; }
 .hl abs2 { left:-43px; }
 .hr abs2 { left:-32px; right:-29px; }
 .vl abs2, .vr abs2, .vrl abs2, .vlr abs2 { left:-38px; right:-41px; }
 .vr abs2, .vrl abs2 { left:-55px; right:-24px; }
 .vrl abs2 { top:-16px; }
 
-.hr abs1 { left: 94px; }
-.vl abs1, .vr abs1, .vrl abs1, .vlr abs1 { top:-6px; left:-32px; }
-.vr abs1, .vrl abs1 { left:71px; }
+.hr abs1 { left: 91px; }
+.vl abs1, .vr abs1, .vrl abs1, .vlr abs1 { top:-6px; left:-25px; }
+.vr abs1, .vrl abs1 { left:68px; }
 .vrl abs1 { top:-17px; }
 
 .hl abs4 { left:51px; }
 .hr abs4 { left:10px; }
 .vl abs4, .vr abs4, .vrl abs4, .vlr abs4 { top:0px; bottom:-41px; left:-25px; }
 .vr abs4, .vrl abs4 { left:68px; }
 .vrl abs4 { top:-11px; bottom:-29px; }
 
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-002-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-002-ref.html
@@ -6,31 +6,32 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 1px 2px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      height: 32px;
-      width: 26px;
+      height: 30px;
+      width: 22px;
     }
     .small > .container {
-      height: 4px;
-      width: 8px;
+      height: 2px;
+      width: 4px;
     }
 
     .container > * {
       background: teal;
       height: 6px;
       width: 8px;
     }
     .big   .alignStart  { margin-top:  0px; }
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-img-002-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-img-002-ref.html
@@ -6,31 +6,32 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 1px 2px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      height: 42px;
-      width: 26px;
+      height: 40px;
+      width: 22px;
     }
     .small > .container {
-      height: 4px;
-      width: 8px;
+      height: 2px;
+      width: 4px;
       margin-bottom: 20px; /* to reduce overlap between overflowing images */
     }
 
     .container > * {
       display: block;
     }
     .big   .alignStart  { margin-top:   0px; }
     .big   .alignCenter { margin-top:  13px; }
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-rtl-003-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-rtl-003-ref.html
@@ -6,40 +6,41 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 1px 2px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      height: 32px;
-      width: 26px;
+      height: 30px;
+      width: 22px;
     }
     .small > .container {
-      height: 4px;
-      width: 8px;
+      height: 2px;
+      width: 4px;
     }
 
     .container > * {
       background: teal;
       height: 6px;
       width: 8px;
     }
-    .big   > .container > * { margin-left: 18px; }
-    .small > .container > * { margin-left:  0px; }
+    .big   > .container > * { margin-left: 14px; }
+    .small > .container > * { margin-left: -4px; }
 
     .big   .alignStart  { margin-top:  0px; }
     .big   .alignCenter { margin-top: 13px; }
     .big   .alignEnd    { margin-top: 26px; }
     .small .alignStart  { margin-top:  0px; }
     .small .alignCenter { margin-top: -1px; }
     .small .alignEnd    { margin-top: -2px; }
   </style>
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-rtl-004-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-rtl-004-ref.html
@@ -6,40 +6,41 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 1px 2px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      height: 32px;
-      width: 26px;
+      height: 30px;
+      width: 22px;
     }
     .small > .container {
-      height: 4px;
-      width: 8px;
+      height: 2px;
+      width: 4px;
     }
 
     .container > * {
       background: teal;
       height: 6px;
       width: 8px;
     }
-    .big   > .container > * { margin-left: 18px; }
-    .small > .container > * { margin-left:  0px; }
+    .big   > .container > * { margin-left: 14px; }
+    .small > .container > * { margin-left: -4px; }
 
     .big   .alignStart  { margin-top:  0px; }
     .big   .alignCenter { margin-top: 13px; }
     .big   .alignEnd    { margin-top: 26px; }
     .small .alignStart  { margin-top:  0px; }
     .small .alignCenter { margin-top: -1px; }
     .small .alignEnd    { margin-top: -2px; }
   </style>
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-vertWM-003-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-vertWM-003-ref.html
@@ -6,45 +6,46 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 2px 1px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      width: 32px;
-      height: 26px;
+      width: 30px;
+      height: 22px;
     }
     .small > .container {
-      width: 4px;
-      height: 8px;
+      width: 2px;
+      height: 4px;
       margin-right: 10px; /* To avoid overlap between overflowing kids */
     }
 
     .container > * {
       background: teal;
       width: 6px;
       height: 8px;
     }
-    .big   .alignStart  { margin-left: 26px; }
-    .big   .alignCenter { margin-left: 13px; }
-    .big   .alignEnd    { margin-left:  0px; }
-    .small .alignStart  { margin-left: -2px; }
-    .small .alignCenter { margin-left: -1px; }
-    .small .alignEnd    { margin-left:  0px; }
+    .big   .alignStart  { margin-left: 24px; }
+    .big   .alignCenter { margin-left: 11px; }
+    .big   .alignEnd    { margin-left: -2px; }
+    .small .alignStart  { margin-left: -4px; }
+    .small .alignCenter { margin-left: -3px; }
+    .small .alignEnd    { margin-left: -2px; }
   </style>
 </head>
 <body>
   <div class="big">
     <!-- The various align-self values, from
          https://www.w3.org/TR/css-align-3/#propdef-align-self -->
     <!-- auto | normal | stretch -->
     <div class="container"><div class="alignStart"><!--auto--></div></div>
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-vertWM-004-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-align-self-vertWM-004-ref.html
@@ -6,45 +6,46 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 2px 1px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      width: 32px;
-      height: 26px;
+      width: 30px;
+      height: 22px;
     }
     .small > .container {
-      width: 4px;
-      height: 8px;
+      width: 2px;
+      height: 4px;
       margin-right: 10px; /* To avoid overlap between overflowing kids */
     }
 
     .container > * {
       background: teal;
       width: 6px;
       height: 8px;
     }
-    .big   .alignStart  { margin-left: 26px; }
-    .big   .alignCenter { margin-left: 13px; }
-    .big   .alignEnd    { margin-left:  0px; }
-    .small .alignStart  { margin-left: -2px; }
-    .small .alignCenter { margin-left: -1px; }
-    .small .alignEnd    { margin-left:  0px; }
+    .big   .alignStart  { margin-left: 24px; }
+    .big   .alignCenter { margin-left: 11px; }
+    .big   .alignEnd    { margin-left: -2px; }
+    .small .alignStart  { margin-left: -4px; }
+    .small .alignCenter { margin-left: -3px; }
+    .small .alignEnd    { margin-left: -2px; }
   </style>
 </head>
 <body>
   <div class="big">
     <!-- The various align-self values, from
          https://www.w3.org/TR/css-align-3/#propdef-align-self -->
     <!-- auto | normal | stretch -->
     <div class="container"><div class="alignStart"><!--auto--></div></div>
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-002-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-002-ref.html
@@ -6,31 +6,32 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 2px 1px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      width: 32px;
-      height: 26px;
+      width: 30px;
+      height: 22px;
     }
     .small > .container {
-      width: 4px;
-      height: 8px;
+      width: 2px;
+      height: 4px;
       margin-right: 10px; /* To avoid overlap between overflowing kids */
     }
 
     .container > * {
       background: teal;
       width: 6px;
       height: 8px;
     }
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-img-002-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-img-002-ref.html
@@ -6,31 +6,32 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 2px 1px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      width: 42px;
-      height: 26px;
+      width: 40px;
+      height: 22px;
     }
     .small > .container {
-      width: 4px;
-      height: 8px;
+      width: 2px;
+      height: 4px;
       margin-bottom: 20px; /* to reduce overlap between overflowing images */
     }
 
     .container > * {
       display: block;
     }
     .big   .alignStart  { margin-left:  0px; }
     .big   .alignCenter { margin-left: 17px; }
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-rtl-003-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-rtl-003-ref.html
@@ -6,45 +6,46 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 2px 1px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      width: 32px;
-      height: 26px;
+      width: 30px;
+      height: 22px;
     }
     .small > .container {
-      width: 4px;
-      height: 8px;
+      width: 2px;
+      height: 4px;
       margin-right: 10px; /* To avoid overlap between overflowing kids */
     }
 
     .container > * {
       background: teal;
       width: 6px;
       height: 8px;
     }
-    .big   .alignStart  { margin-left: 26px; }
-    .big   .alignCenter { margin-left: 13px; }
-    .big   .alignEnd    { margin-left:  0px; }
-    .small .alignStart  { margin-left: -2px; }
-    .small .alignCenter { margin-left: -1px; }
-    .small .alignEnd    { margin-left:  0px; }
+    .big   .alignStart  { margin-left: 24px; }
+    .big   .alignCenter { margin-left: 11px; }
+    .big   .alignEnd    { margin-left: -2px; }
+    .small .alignStart  { margin-left: -4px; }
+    .small .alignCenter { margin-left: -3px; }
+    .small .alignEnd    { margin-left: -2px; }
   </style>
 </head>
 <body>
   <div class="big">
     <!-- The various justify-self values, from
          https://www.w3.org/TR/css-align-3/#propdef-justify-self -->
     <!-- auto | normal | stretch -->
     <div class="container"><div class="alignStart"><!--auto--></div></div>
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-rtl-004-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-rtl-004-ref.html
@@ -6,45 +6,46 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 2px 1px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      width: 32px;
-      height: 26px;
+      width: 30px;
+      height: 22px;
     }
     .small > .container {
-      width: 4px;
-      height: 8px;
+      width: 2px;
+      height: 4px;
       margin-right: 10px; /* To avoid overlap between overflowing kids */
     }
 
     .container > * {
       background: teal;
       width: 6px;
       height: 8px;
     }
-    .big   .alignStart  { margin-left: 26px; }
-    .big   .alignCenter { margin-left: 13px; }
-    .big   .alignEnd    { margin-left:  0px; }
-    .small .alignStart  { margin-left: -2px; }
-    .small .alignCenter { margin-left: -1px; }
-    .small .alignEnd    { margin-left:  0px; }
+    .big   .alignStart  { margin-left: 24px; }
+    .big   .alignCenter { margin-left: 11px; }
+    .big   .alignEnd    { margin-left: -2px; }
+    .small .alignStart  { margin-left: -4px; }
+    .small .alignCenter { margin-left: -3px; }
+    .small .alignEnd    { margin-left: -2px; }
   </style>
 </head>
 <body>
   <div class="big">
     <!-- The various justify-self values, from
          https://www.w3.org/TR/css-align-3/#propdef-justify-self -->
     <!-- auto | normal | stretch -->
     <div class="container"><div class="alignStart"><!--auto--></div></div>
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-vertWM-003-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-vertWM-003-ref.html
@@ -6,40 +6,41 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 1px 2px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      height: 32px;
-      width: 26px;
+      height: 30px;
+      width: 22px;
     }
     .small > .container {
-      height: 4px;
-      width: 8px;
+      height: 2px;
+      width: 4px;
     }
 
     .container > * {
       background: teal;
       height: 6px;
       width: 8px;
     }
-    .big   > .container > * { margin-left: 18px; }
-    .small > .container > * { margin-left:  0px; }
+    .big   > .container > * { margin-left: 14px; }
+    .small > .container > * { margin-left: -4px; }
 
     .big   .alignStart  { margin-top:  0px; }
     .big   .alignCenter { margin-top: 13px; }
     .big   .alignEnd    { margin-top: 26px; }
     .small .alignStart  { margin-top:  0px; }
     .small .alignCenter { margin-top: -1px; }
     .small .alignEnd    { margin-top: -2px; }
   </style>
--- a/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-vertWM-004-ref.html
+++ b/layout/reftests/w3c-css/submitted/align3/grid-abspos-staticpos-justify-self-vertWM-004-ref.html
@@ -6,40 +6,41 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>CSS Reference</title>
   <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
   <style>
     .container {
       display: block;
+      padding: 1px 2px;
       border: 1px solid black;
       background: yellow;
       margin-bottom: 5px;
       margin-right: 5px;
       float: left; /* For testing in "rows" of containers */
     }
     br { clear: both }
 
     .big > .container {
-      height: 32px;
-      width: 26px;
+      height: 30px;
+      width: 22px;
     }
     .small > .container {
-      height: 4px;
-      width: 8px;
+      height: 2px;
+      width: 4px;
     }
 
     .container > * {
       background: teal;
       height: 6px;
       width: 8px;
     }
-    .big   > .container > * { margin-left: 18px; }
-    .small > .container > * { margin-left:  0px; }
+    .big   > .container > * { margin-left: 14px; }
+    .small > .container > * { margin-left: -4px; }
 
     .big   .alignStart  { margin-top:  0px; }
     .big   .alignCenter { margin-top: 13px; }
     .big   .alignEnd    { margin-top: 26px; }
     .small .alignStart  { margin-top:  0px; }
     .small .alignCenter { margin-top: -1px; }
     .small .alignEnd    { margin-top: -2px; }
   </style>
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -20,17 +20,16 @@
 <!--
     The separated permission file is for bouncer.apk. Since it's removed,
      we can merge the permission declaration back. See Bug 1411809.
  -->
 #include FennecManifest_permissions.xml.in
 
     <application android:label="@string/moz_app_displayname"
                  android:icon="@mipmap/ic_launcher"
-                 android:roundIcon="@mipmap/ic_launcher_round"
                  android:logo="@drawable/logo"
                  android:name="@MOZ_ANDROID_APPLICATION_CLASS@"
                  android:hardwareAccelerated="true"
                  android:supportsRtl="true"
                  android:allowBackup="false"
                  >
 
         <meta-data android:name="com.sec.android.support.multiwindow" android:value="true"/>
deleted file mode 100644
--- a/mobile/android/branding/beta/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@color/ic_launcher_background"/>
-    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
-</adaptive-icon>
\ No newline at end of file
index c1f62aea1ffdd97ede9e5ae307a2ff10bb9f55f4..28099dbc39336f5e58792779f32f864a1e731839
GIT binary patch
literal 5869
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
Dmx=&5
deleted file mode 100644
index 416de79b2d69d0b10e1dc450104f6eb47d1cd804..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 0ada4a2216145f24d31f13f2513d8259b6414b75..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index ec5cc4da2a7cb0a98a59b4dcc4e089975ec1f2e6..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
index f821c1ba04e67ba9210bb42115e09ca6b76c76ce..e348b2504b40290d0650514b4d6790c0ae718938
GIT binary patch
literal 9065
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
b9m@X)S6qOksZT!}00000NkvXXu0mjfT~UA=
deleted file mode 100644
index 917c88b0a2e1561d1dd522112645f5d996f952fa..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
index 380ea12189941f44bcfee98df3390ccf03e1588a..0108740ce6015c81af54e4694dfabf9905902f72
GIT binary patch
literal 15274
zc$@*MJ5|JqP)<h;3K|Lk000e1NJLTq0058x0058(1^@s6=SJeV00292Nkl<ZcmeF0
z1#DZ((?`$DtnDzhDLsb5gK{53{Fs@U|IEzH%*@Qp_?VfQxhaNi-`!72d==-)@z<nI
z{^TQ#cD0G{9{px^E!6mz5T0ix@Npo^e=riBXPT+8exqw^YcAY^uw_r5%>mZ%ABt>z
z#F##6v@F|C{H>Q>Ese4#1iY8m10Ul*6p5Y{YD^z~9dC6rGw(y^Li7kgH!vSqUu$7C
zD$?_mEohz--9u&<Mdv~8?|=vRH1MjLK;u$F=4Zv<c<KGpYCDoS3`jxYE{Glk@P$YY
z0sg^%7?OWRs4)#Z%WK>g;p5m=;8rj~1i4Eg^a4BuEG0Qm*Al44rGILx%XY0_Pdyn@
z`-0AZn6MslR{$R1Pr%VYL`+SfTI(uYe%beJZa4#Jg!I9XBzg=Aw^HOYz$*c$2~^{m
zo6|GrF3vqm3d81u+nKTy?u6(e0KAu%0AKtczsA?Fg<Vp(?6Tk3yl^xC=`N5q#-(sG
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
deleted file mode 100644
index d384d9820fa1bd38fdd9c75f8d47609d1b777634..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
index 641c89d0f8a7088d6fe5e8423e39c012c96cd3d7..8cc48d273f744dfb488cbdb8b2e8090dc6ee0f43
GIT binary patch
literal 21325
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
deleted file mode 100644
index 7ee9393bdc74895ccdab43f72e2fe73d884fa49e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/mobile/android/branding/nightly/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@color/ic_launcher_background"/>
-    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
-</adaptive-icon>
\ No newline at end of file
index 784016389ef5dd5312c0624239546c5cb0bb9791..68e024ad268a55660e551cd4a6c5e67be2bf1d74
GIT binary patch
literal 6307
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
Z{6E`mbnAOk?A-tW002ovPDHLkV1hkQ+yDRo
deleted file mode 100644
index e19c8b60efd74736ca7d9159f01871bf031ce460..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index b93c26c940f39757a1a5e73a593faffde93ecf5e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 3c1c1ce651e66d7c955210b9a278cca954a54c01..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
index 3903137597784d8804a3b69336fcf5cb4ec53137..0b5e1a175255ab488e045c6326e10d62a9b71c9b
GIT binary patch
literal 9490
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
deleted file mode 100644
index 0bc6173180fe2abb39870d6ca6e104ee0514826e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
index 8467a05aad9c3e40550d2f7d232263b475998e56..1ee12f2419eb598a36570c2f6ff76d7df0faff69
GIT binary patch
literal 16480
zc$@%AK()V#P)<h;3K|Lk000e1NJLTq0058x0058(1^@s6=SJeV002NINkl<ZcmeF$
z1&rIs7sv7M8{0`XyJcqjZ<!<=Gcz+YGc%OiV`gS%W@cvQyT#%{z%cWV&ZlVW)@qJ#
ztNf&=d1DZM^u|$ya?1G=5y~m29Re!n$BmZ3*DgaJ|F8_GoZpwPHta!#^9q5!gh3Bq
zPzF>^=`kq2-|}X<Bz9z;`#3}H+XygaK;@K{ueaZyw7MKmgCb9kHK@Mh^)jF(r<^bL
z7)dI48KE1#hLi;v?{VJsH(|TGf-<1^lw-EF_@?8-q-6tgK41U=M<5sMP4$h}mI0L$
zpRW$yiwb=Wc@NMa28;sR0<9Zy{nZ$8{pV#si>929PU=Ov^)0Mm0D%XXu*872Ayp_h
zc$uth$e2r8%7DsQDC*0T&(f9dF=TTfK4A=D2^a?|Y{<A*Q+>(4WkAK0ll<)B;clYl
zErZt);{gF+B4q&yNGQm9Co<xKSpbv)m7~6xeuYlE`;pCq6bcOh5<z4fP)Se(xc;7u
zIOnD^p#OTtUD}0&)s;YcVcR_r(*;x-OQk?LpsYd<A{s0YW#tf+!N>v}s}ZE0K+om*
zcjm$*O(e<pF0am4&VC2wbwK+dxd@&}nIxzbh{@pV?HNAv;WD8AL?$UlRSiJdBT;H1
zO2#6px=?)!)vZt!C`V8>C<{a_TB=Qt0W^rp6>2U>9m@I&;ZsDtk0d{#A^D@a>DB4F
zDtjzh7bFkj62`<7AtEacn0aK~tr<JxxiX-CBV*3&jnT^^YE7_KL}UcY?u1H!NLT<u
z8z>TwCR)mBv)UB#84X&u(2;NCr1uA#%1kE$1FALh{S%!;Q0z?#>`KtO0nco~sMB5}
zF6ZTUM7&QpqUyt?8j!(=Acns)LnjTycGg2=Q$($RvU?VaVnR4efT2Jv5DC}fwc@@_
zFN??K+sKL;%x)imYd|!pX22|3LJXoL*c~A-HMstkj5*~^qM4TIM@Rbuj6a#f(-$q3
zfX-PjGa#D^j;i<SPPpi?>O6mSdQ7UKlU^I_olt6R#Oa0zhyf9x1TZDvvtphX!g~TJ
zFgCL9_n2{Y;42Upq$L6-S}c0sIAC{%K>dR2Z^fA77e;hub|#%uCy>v)#+>wOOcH;o
z0(8k5rfPntmM1+G^q<qevHGHm{z5=Qj~@t$oe;GvVvR=GfR0B~DjXGaT$TDh3h8Pv
zM|}<zIWP(&LwJNy%Jhl!3hXZ6C29!#tr>mv>j0eib2qy5dY_c^Ct)-uyEzATe0Zq>
zG=0+rQ|wg7Q(N@>UovjP#B&}RG5gQMIkp;;+#itw9H(dTJ3=Hn5sH23lco4x^tsX@
z`8KkAGiI0Xz$c6}fyx3b0Sh28_w7#LRo3Clwv0LWWu|7fp|avGlnZGabnEN5^=oig
zb$+P;G;@P_gS~`$&p4{HEBRcDG)=tVuAyJ>M>F_@!3uSlhCNVD7mNlW3MYQ55UwRo
zoS0{<CBNfa$WHZ`6&k@408sNl@(aTdhzDdAkIhbl*J(C^w>5Vhz9U^Y0P^5yNIRfg
z_hawQSG9XUGuCeE7NmmnNhWs5lLOl#7qo76_C5U`;`io%lRDbId$57Swb;Fk@j(C-
zh{V7VO8>rz!4eC}BK~~~Y~Zk;p-%<^!dSCGyoK?YxFakE762OTBzWohyuP_h{g9p{
zLqMbySl&<MbIY@TkJ|PONTzKx_Xd-2cFmJVD~(E2kPDippM6)~Q=s%D2A{mSV5Vs7
z@tOdQ#y}BC5ejiX!K2qL5Gleaeacudup)b-pob5K*MJj%0Yrn<5d9CVgr3NhYV(W|
z@Vdc!>rp@iDHrSjs#4%JU%~EO4`{c5rmfq!j83RmeOo)eXtXk5J9y;Zn$wV9?fU13
z<XA!~`W@F_EHzz=+O<%kO@I;55CIgf#p4MfTuYoj#eNA#R@~%?_P&B~S=gfy0tgd;
zT@Uz+pDwZ(Ah77O(q=0rgc)>zPu7Ln>JX7*ASpgNzacw!f4bcPI%~bU%8ZgHOu|{&
zBTt|V`qu(uTiQ47%@^D;aCeAL)u0o$Hptlqd$7hw0~+E0mG%u}01a3cAV8aYwp}O(
zRNOITMX|;AuE6RouvJsoV}JmhS|BLxV;M^CB>+<aU#$r>BO&2Ig$*Y6A;H{L*`>Ov
zT>+ZDPUB8GW#5t`i&mOIftC=Fv7}H+dwza{OYR!_6p?iAeq0APt)_w;_S@7!i!26^
zfJh9S$Ue}ZEK=RO(s6KqtcoOBgk+CSs6y}M^R(8^qv`V+v>QGfJDpS<q&BOok!`b>
zm0H1T3+R_9pwd>Mm{>@nfdqWNGW;?I93QHZ;5N-<``#zD8$gpVigoLrG6{PvmmFG|
zVug@2VkhuT{;h;gtbX2I1F}UteUBRvSn6t{oK*tjV=!nS3Mc@G0*c}ZGysxF(Y1Oo
zeU=$dr{ROJIwT1Ik`UNn9LO!m)A;6>G(7()e#QeUdX$xhr`YFxWcNH~q6;1Xgn)hm
z{0NSCIEyC!UJ;R4@bd~#GZqpW9G%6@uEh@hUvC$HX028?E>q#Z<tvlaN{4XdH$-h#
z<s``m*-2O4Ibt$EkN(GQpvAdbi|SWAvWjSg;$Ffv7LWnNqW9R*RCMcFz%zu-)dL{`
zzJWkMTc8z~B)EB(Z*F{!rVqb|iWFG(;_$@xQAjB8T-eKl(Hi_VQ0yN-+$e~cZ=h1p
z#5^ww>Xw1pF_5+)$h^k)->%J3D`o%lfTpcgbAq3=XXZ@n!f3+2xHn1)rE<RUw!Y)J
zOM9hK9WM!>LK~j|69J?OC556mjUb9gAkd^bb!OBC8_;LMXp9Yk6~fU90y|u_1ttZp
z_4E1ew&!X2t{xma#G~w(UtKZ1vKGE(1hfbH8yHpu6qfTNNH!KpbdCQ7wxk#kf%;{j
zVI)-A;I$mj=Kaq6PXn67B*j{LJ{=^iHC>ZKheuX)`V<RG;Rd<PE1y1-YHV&$wv!~0
zNMjY&!UipZZvwo)Bj@G{mHoBH7!V7rLa9OlC`ISqeVMS?7IYfe6IT<Wu|S7a+>?U&
z-`4T<O;6#@X@X<|ET@Rz&jA7g7xuSc82@kYEuiH%&h+nJRm03&6q6-`42dnrj!BX!
z%<OC&X6B_Z<MM7evBL~@z;QSZCr->vvV|5)m+w$hz2EvypVYZ^+Wobz0?vQk=hP|a
zo)OINJn!=s%wPdhy%44+0ad~Os1o&Y0CR?|IoGi7R2V-7f^-7aIg`g6cFR2$p!c1=
z;gF~i+>m;*AXDiKB$)=80mfLMl#pRSE5h0UM)^!7Z3YGx5j6Vn>NUjIWF9jmA)%Xf
zX+}*ZruMUMWIOx!Y-fCQA6d79uGKm5(NAE-@oVt<YNS|jT!3T-p51Kt+z&~oI}iqW
z*z&3aR1m@}Kn9WoUL3-GHKbzyi@iPI?FF=BfCa=F<}zr?FDW3(>p|2#2C~T?bLGaz
z^R5S{_eg-=d)AgmMK$?RLd=Z+QRKkTQy&bOGH5TLUYkdwF&`cFK>)^w)PqcugX4Vo
zey>RWY@7)b)1&O#x`A+bm{lhpPXc7RKzZ`_r3TY`$GPSF?+{N;LlA=YT@^Vn59FF`
zlR=cg^BZvD4E=U7)En>lAXIs_<-!CYZokSWrvL*I!oIbT9s=>?3wi7jpSwo_^p3MO
zztz;#`y$hJ!xcuQXfLF{zKFj1LR1it`8hDYs~Fa=<j-L2Gx>8ML9b*Q62NHZJsbd&
zB<7~`zfE)NE(oiHt*Q`tR*58qZURpqfb}6H#{L(pE`%EZQ^6#Q>uD@V05}}FgQ(fz
zEbD`@GoVx70r6TMb@=Xk96)b9`?jy+drym`gQz_FQW+@4Ky48Njiu-?By~Sz7bJVH
z7%VS`%7M*&tsMjEaL0Fk&F)`Z0rfE7>g-opakp?(X`2+fF+6+#9@h`C1HxSZsn%?@
zQDyMp03kpHXx#hCK(YX)&wzG%9*<c0ihC45=W>B}^qI$9W;}K3ObAoGa8>jAncugP
zT5YhG5qVfRij~KOr@Ss4bKt4L*yf$wc-{qw2zWtxy6(VHeHp_8lRzhelltL#^C1=N
zrNQ6PD`I_+15-(uk}4me!;->|8HiTF)S8&6`*0q)`ZxC&fZny{<^|p1=sKhIs+0ty
zgyC>0^ZE_}-y^lqxXNS4T#)7jQIQ%MZur!<n7nOs9=gIRTR5s2YTLI86n9}+4PLVh
z0<fRE0^Ne}7Qo<K79IiHR|URE**>b`$Exgm#>d0xlHV~l`B0v^CcZ}i^!igSJyHd=
zYmG94D8-`2;SAIl*>L4sK-|7@#!ADNc0yJeP#UPi{#&<j)2A=U)Bd2?#}q?j$Ex}x
z$sq1P;K8d`z={wuM>)a`pvM7Kl1a%yesrqj86P?)!&LnxJapBk?-2mK_Jm&^AJl5s
z_+Bko)^`-OaEP=hB>9v><c79`R3HiA#?O6=(d#!rtp;9DzRAo&Gq=rU0C5{qK|N&&
zoIT|DAPwFa5^kV)B1gIH3YT(}%ME7=z<KZaFn07-Cezb+{C!6L>Hxj$e&0TQL2cFV
zR}36S81&`vR0pTJ0@={#!c)|a3|#xEZ_?Rx7eEbboXfYZmO<i-xiBh-TaXyk@q?%r
ztpFn+f?&mk+O41`K{WEm(52i@qnfIS9kYxmir-9GQ_Ybuy6Am8@bI_))d70<$+w)d
zwEwVgdtsmTJCzj3xnF*-RE6B|MgSud!qzJ`F!l3`zz@rzDTk!`PR67ISpsz*@3n`)
z;+ZgJtqW=f9;w{|2#5mZge?InQWI1eR29aQh0F7ydBix=!>97F!#4lb0Q$t~?L+E*
z<EP5!xJWyp$eG8n_sSKhsLqwg)?T>^i3eM^MKs&O^lyJichemZ*4)qpsF~WTQeNu=
z+K6UfXObR7iJ%|94E^v$khrE<VS>$wzZ>u<yp#ed{g_-pETA@YIp8=d6fA;~<>ztM
zF|YWm0QBLbq&Bpe?*t)_ZmR+~O28?aBrLj@*9EXR&p7vD5jJh?kfD*d#rTgeA{`rt
zFm$1)s7e*@0YuY~8PtkC{MW9A02c;?7*oF)RQGPflaz)o1*&Mw1!p#BVj%(z#LJpA
z4_(Itmf!Lh2j~myviF36etSn1sEuDqaps=FmzifDrn?!NH+9j0M%R5zbDW7^|AKhO
zE>J38ea}_MD$d-&QOc@X+=48IOyNKGaP%p|jtU8&5pRsFw!r}cpx6kD>u(em5DST0
z&jv|ZkPx6g2osAw%ewo$=r0P;=hh}?hn{~)rl?udTsef5fKviVm3tZ_fRXW(9or+k
znns5TUGqVubhmE$-?EK#VhR(dm^hiK$pj1*0^bL(#50whr8ikmg;GJS9wdC#(G;HO
z7L5tFVf-Bkx?sXtx#7%JBpbep!Le{U?`2g;K|0iy*3z|{b@a`D5r97YXsOK`<ClTQ
z>5-zk^7u|$JI_?~Kt`9tB|hxh8?$e3f>+n*K+Qm;!k!wbK!HvXQjEC^popx~A)RWH
zjZKp7n<UvcO*|4o3e<cD7B6p?fD|_&i+U>b?A7>d7dR?pSuwTSG5#2cc9tMOq@p=?
zYH^jRu${xy=tCy^Kf&5lU-=gS=nHGJ*VKId;n)-_iG`yapz@U6Rj2AET70;3N5t58
zieJ;H93U0UK$O=&?XFtQ)YL%Nzz;KguY;E~$###j|B~&D{9)WR&&8)eEJ(QuO+qH9
zWqpLNJr>pQzzD$X@S_sa`UXTd0bLA?0Lt+&;;59XHYlVJ9>-K`4QYKsqD3ch`mtO8
ztN?xPG+7pSa<x)wMJB~SRDz{Mc}n1NO!VCYv}IeDsp+g2!UB!T0n&kj93W=KdNm>F
zAS0+H1YtxN#?%`TDr#}f8*Zh$y9=J@oHcVma+N4)LDGf<yhp60_Qb<-6%uE4OM&i^
z)b4_)lS8DO^j#sUXpTpfr|Zh9&1^MuURUo!roDG_+PZiBSpoXuy6j);o_<r;02D2b
zmWQ%pb+YXexGDo=eAv9DOS5HifYfY&!X7|srcDl%;D>j?6VH?|=n{qzI&O2-n>Nth
z9f4Qig|NWj?$Z_^ngEl5*3@2l9R9KMAT|XH7z(31B=y@7)dh4(hyuZeyHda7sEt^7
zW@l}_50Tm?Qv>(s!6!}pSpYi!l(9qmgL!wU&!S8U0V)Q>hjMjs?;kusTeftWZW|lI
zEJWns%=F0>$O}?}S~{aXfge)~yVPnC-Q81M`KH@2F%CSA;^2<u?JVwvvQ$uu`{;Yk
z3Fvttk_q5m8l&4JwT&3<LR1`z<ZkDA9GI*M**)cMD6G|y7SH3fbzl6m0QBW`$$M*_
z|F*8N^6NrUIdsh(Ajbo_Sy&#z?(8z%v<jqhfNTxq0C}OAQ6E1{XH+K$dJ5DSNZ5MO
zooxK{cBqFgIF1TA;9%P%t)8h)1n>Ao^u6eKl&=tjb4d<Sm!!TKqgx1`GpD1;yZM*{
zQkhvsIV$9oFoaI_EBXHVhw?6E{-gkXbnVo_`MUpFt@Nr?EI{tOPB}pCc;ygg!6{vp
zw*YP15ivQH<qBlsaRJf+__ZVtUr7(1Frr?MNGF?I@#brZMiuye!9hl+#%<>X-3w(&
z7ZM?Oz$zL~yAKE;;)F7CzmpKvw~~2NAYO^OxZ%kK$F`vaBKf0|CK8#`S-<}3KPf<8
zS{uKt?g!^ZMiA880dmKxY~8R~Sm`D*yWJIb?T#54OY!SHfLs+K|3+Oe%m{)WK;aBT
z5w&`ZM~55!^EyT@8-;-(K$U<~tUj|q5}-TY3u&oPd(>*`Pdo-vE9b7U7L}3Ic98gE
z1)j+9J<0-Pp>g5S4s0%9xtVTu{+qRHU-u^i=v@!`rGHHK>|guZJ0qSeKqV%+dR+}5
zd>EZf*|{sms}%#JLz#ic4^x7f5);-EYW*p+rnv3=>)89--OxV-UT9%BVD+&zVtNpz
z2^gXNxMOHM_Gn}VA}KW10wm!+qHu3<8m<)J!c$)4?w%9fQ`#ikDAQ9X@!$tH|0Do?
z>9qD4p<n-XCdxOI15|FJow0)jN4w*;bW>r=)(Fv{b7-^!&t2g7VMbU_sP!3CGR@@m
zTiJHe2BtSpLZcsoh6RN(c-+2QW9NrvAd102{V_+=c-(y<-}X^_X;OcJPHh*WG7t^m
zKw(wJ1<3;JhAsf@WNsR~K%|pAlJzHD@+Sf4YwP2W)O7Ibju8Z0fLtKvrbH#iy0VGZ
zvoo<BJL8#5%*(;?LhxqNb<<Oxh9PViOml+qYi?)XZ#L50HVFW=8U+2bVR1pRW42JN
zLV)dyfzCLj5u}FNBaWv3NoznU#F)ZE7Ya?LyE71Fe#d_BE<mEO&^Sih!c(qPjXtE+
z`6#EI@S3>;WK;Ly;b7=`g+4R|<pSiU@pJJ%E>L#dS&gscf$VzNRNJuYt}qson`MI^
z7=nh(z>|)TGJ3_$j9z{_(Y|T$JP7>!;f9-8x#7x%rc`}wpBy5AXbR#Mq#5DqhtvOz
zlhCyQvaG-pSzpu*_Ynt^fF=jSRS_ri(f~*)IM!o{A3~Dc#&rKlJot$2K>_sjb<q=1
z-nSByZu7m`>P(~<APYco7%PKh?hB{RxRaS_*uA?;oFoJ_!LLKufMjAnBbQyz*i{=y
zC)*HsGw}3CyQ}!F+Sqn+xGDz;z=estPFg*Xq8NY8G6tTr7JpG6l9rzVi^2&y;V6Ot
zy2vm)o<|qocf65>NvCw;(>d#YR~-~U7p_mg+%}!%T7^dhIy@pR2B<icRo!*y)CUia
z4P)(2!sO^QVZX+7rWm>W8b+_Yk#wq!{ZfS-9_1I$C{xWe7n^4a+RRpqqz#=hh!fP|
z%NTswBdIM;AOk7+*b=Wzt2RQWQ&b@ks+y@T3TyQ~Xtn=|b@%zeoB{gkDZ3VV{-SS<
zr(>5a2$#G&6|})_9T1!_<AkY7o5w6r7J~fw>Y110gPi-ViE+knzJ;Ba{FZ3nSRSS{
z=pZkCIWQ<!h00TQH(cSW4^CS_cLL&RNK#mPHhqshnSo_vK-noCg;6QZ`UtTXS%{=$
zvam`j4^XQ^r}J&r-skV;4A3{$Mo;Qw%_H$@Ck*-h&+Qt)xE@GX-tS!f;9vy>DmBpB
zjuAq0{|MLq`-jQeUGP0n-ra{PH0Tna<A75YAls%GA~Dd~m+z+z;VI9ewseT0)e~rK
z5OL!e76fHz)+Xo%Ef9@`#6n}+IN<0a4Dxh7-Ndb1PUN|dY|RBA_4T!_7wziYdHM3b
zqkiaVe`POxfx!YK?iV7=C4{-^<U&z;gr_`=QG<Oq-o~w;`~oI3`N`DK1*Zg<a<6kx
z;R|Lz6HoV2{5XS0t$|aYL@<#syk-KwmLf(`cD2H3T48H;dahK77g8luD3s6*+VLsz
z1J>MfzyN*b%>9F5+h5%wUOd0P_>z3XUJj5AVWKN!UoJEUe`L9QE=b#PslnLBtz7?s
zkLBUYP70QrW4B!%wo0=vSBdTpA~I<0&s9jnhn^4DF2hSQ<{dvt*dHO8eGlAJUlg6N
z%~aR~Rqlm=av%f<0(7VQgzWTVzjwd@{m<#!8&iMyOmxiJH@>IeufMfp47u{;C2y<p
z)24RpPpm+?q^~VV62kPJeO&!-|AQFaQy?f&p316I9UuoL3l#Qpy-+uW7n}x9e=K|j
zbiXj~*h%X1x=3atfN~*1(eb-X)?0{TF5uX!-oR_N-<qC&pMRNa7N)+jF8+Dw1rLr&
z05VmM?C66~AQu*Qyd;E4(DOi7{p){WGM)P#9B7J_$N}xZ0fO@IW!v^%7C~n}WCj)u
zz{M|v-wnXkp!$UQ$4=5%Xd!Yh3sKBOy^TO+aGdv;0Z295pU6%>=9RBL{qjeSEa|)D
z>)*ZK_R0W#;)IP$7BvpLUTJ?>D#ZXn$%#|H!X9U5j;I(WTO@y7s=;W<#}yLJetjlj
zd}hYSH{Z!M|MMZx0jK~J4lHHLQ#s?BBS7vY(B20ofha|N;3@F1`y-zOnxKNaAey=h
zBF7U6E&y#mVWQSX)B%D+J|5PPwEM$XJY)2AYDwR(w;j(jzJLCSKd+v~ubn!*ru%<q
zKpUV}lnYSxBgz$($W;>wAi>az+ccwTx=BPL8JPxr4_&VjO^p)NeWv#BX5q2N(SPVt
zqE3wJ_qp@emvYC~FMxVq4<NvWq8KLTXqfF-weaOY6^%pEgl>v@+zF_UJstTy$S?A@
z^Mr-RO;Mlkcp{k%qC(LMBF5{TGH5I|;{0s_AAdT&@!9{}ng|Am&%WlY)>E%|&j}Y+
z2I#`Itryq*zE5>chCxvbP|57Fe{ieq;`hKAo!-y>seN?Q2+;}xAABDbc&J*)=%$<5
zdD*W}o(J@xTCr|DD;{t*W1BbrFF?Phxnn!xH$eGCU{r*}4Q~plnt8eXlK=j+4c#%w
z1eOisefKp;Ujy?MU<?q@zOd-H32Fn0qeOsMpcIP9T8F7xr-z9Y>J5m4alYSu-Y(%W
z|D6zcK36^>ef>>uTJv9(0s7Xu?g#2#?H}3}AjH;ACU$`ElpoIlAEuKQ+xBgt88uOX
zkIKQp_rUML(;C^$rc1twF`4ycK$fNq9=eJ}_rE`zfA~Z26sQ_TX@F8l%2(CPLYBMk
zg&WG8F^a!w%p^S@Bm&0ZeetEJGmpSr3FcRT1~Tv)8B6Xni63Uz4f9eMszw?u+J1~e
z%??xGKxEMp1^wf~!~d&Gof?-tIsL%KR~+|Gl>z$p`tFYcU3*m50jR`Cmw@AjGiO}e
z5Qh)r(G;8Z-aZqmbQqFDlLMrC0EGcte)(O-x86PjmjFrykZ-QaOo9r%8JGkGIz#{i
z02LsqQd8V7RUSq8CD7RiCWTId_l|SWFFOk+ApI6Foj;X9eK=vs>PeI<E)En%348me
zNwh%;uG&~^EL4bs`ZPTFzatt_<2TPuKDGOq$G)@@K>xV%_l*axI`v9TuqKv_JbY1X
zr02fp#~l+7T3LtN_S`xHj|zhxEWU?$J_H&(Zw8n&jkxXNFA#U85v9;NKq(J_9w<s-
zL@*>UGwvaZ>JYiLg{4yHnma&1cLcHsx(VLXPRIMtr$PqVWniuWJV1I74KM33e|d{M
zl%WuCf7k~_*Gt&f-=rKI3!NxMtp#U&piAi0`Q7ug&yJpR%!?`kbp9z@moE!e+<@{I
zC1R}qDL2vwy<nPY!-oC0GZ{DW0;@c;i=F|iGd04k-}?e4O+b72DzrbyVj=3)2%zje
zmDdhL)uEzd=yLm208$W-L)wBkL$5oE@C&a5tuP~y{1C_hY`yfbY5E4^93pZ2kOgL<
z-eIEFK}#OW3cyif|E^&R)_pKS4>q{`dFkgS9(D8!D*^PSwL4B6(o3!YFH8{(kd*<X
z4+0vSqO-3v%I5K{XbaDb`ryrgW5>dP=Gbm-z4)^j44w+n%Fm&}0tAS%s#ye(Kt+J4
zwBA)6o)UnPsk|7}kxQw6<DX$51Ov&>!R)bs7z1ILvEr~Pv?m~U9~ngnd-|tHJR8dR
zW35mYrW_!}sUM0+m-TVgvy;!a9(2?TDgkuCx`~I^b>pY0s1E2x296K1Ab~q0J=gs{
z!fj(4X=Yut??d3BydE$z1Ca(l4`HECw>`<t-#(8d?&9kjdHBLuKwKrVrQo>|Pg4R?
zF?^+AOI1*yv<dM9WS|xf(D=@qW@<E~w?LAIF$^}8E$FgnaT^g_h%6|gXx1V|8cnpQ
zS>emp3Pldk6rA|cnC5Z)-1?;W^Q|+FtOn4x*G@iHY5!kik;%I5KQ@-k4Pma4E>GvJ
zNiNL7#D}S@&4!6BSjDj+%PNp<i?6xm`=4WC`$oc`F9*nh!&ROlkQ7kli-783t77)0
zD&{b08=`R#Q2llKzV$}b$^{@`#v%Ik?4KW#890O$E1J~n36eul{M#-)Lmhc3id=Q1
zNP!gfQQ_E6B#b_IfNf`Ws{?fL`t}=}rg^HT>W4P;;Myuix_IBSJ6;SBKJ4s{u(LCQ
z4txudRi3=|ki4&JA^SJqz^y<0BB9qnYadgjFwPiC+2=|_8r5K_4v^C<0Vr!jGyx*0
zMveZjy#amX639R@h<*!Z%0eNgSNi)BmM?CC3y)){TS3G~UlS$Dg5xTXhQ@B;$WN#2
ze)=F|M|D3tdG-<2O!W8Gwf<#iyywn^;nEk?b^occq`3zwolu<nx2yWFskM_S(?R(G
zcpBw|E%8+jm9pc$&xW6Ujr})WO&IngiZY07$sqz}*Y@>L86+2&>e-ilt>b#r4kY7X
zKs7=Jzxt*bfFuPxh_8cmJD>rB4O<45FKW@>h!Ig(lPt5-dg!I~UWT&f8EhLo=-VnB
z@{N?8FB>B2Z+~L+AxFHj5<uTyH~sc&rf>ZIn!yu4RnvW^M3Q1q<r9jE^6xb)nLJFi
za7Sk+k;+h>hw?RYSMBve)huv41vB?GD)30Nh+Dt^1*W!ao-yC102p`74QJ(QR8?hE
zNysV~FZDnzNG8Dus;|z_H{Oa~wGcAEgJdhjw}NO34!IIF!jwZ6Hc>WWp&UN7>CI4&
z*Yk|bf@4FN2Lm?=^DfQU_mUw@ck2E7A9d8*DgkuS`iZA~V#fzBdHEr)|6%C$t&2>q
zKxJV}S&wr-TT?w|z`3Kl8{;WQd2H!HV<GCb6)N;elQwt!=mJLWxE1C5xe}FvVU<TI
zs0vcK;#ADMDtx7HGTkdiQ1b_vcfmW+iw3~}8qzW7UT2}O3e;<_7;Z6;d!eEkXMj{^
z?CF~ZB`60X1PEa8QbRBT(|<Prqtmb6^Z3;ts{)Yv+G#siKI6(m_Izi3`=>SCcu?1*
z&U#pdFy>eILd?9hRl=5d1j*G!dEVWDlf#p@eT8U+3Ozg$ZvFAM*>&9&s4yt^I#tyO
zpbALk@D%wUx8ndb3275D!8>#b^S}IdRDTW06-3(5x(-O~j##i6*+7`GVyHDsfdn^g
zhy8s`x_*ilP~sSB5Be`Ln5ByN{x#It<T<;}xz9xv0J7@$o%OAY8(!bzJDCNjJdDl3
z|9H?+33sMr;CYVn<ls1}gQpRXSz~^vh`UWT{_4l<zVRxuEJOKzvFf-`Sc7e!H3l()
zh#)Gzrxa)fN|nJ>zGzxyJ}4ds(}g%CIQbYBeCmx@Cj*i~`vx#kK44~NWLjX=P?OLz
zvsA}T*QdhHOenKqEU)u+__K^`t&a?nX8ZS_vFF(*U0Dv01JQTZH$UI!^*^tZC1iQ%
zDof{~>Vm0liw8}Wu)|D}!{R`rQJ!*DXf{9^w674KnKHU%Bb$EtV<vZOL;0Rnm@+jI
z!DJc6$c%#dLj!ojLwJ34#8YHZOfuCZ8J{BUMxb@?y#e6hLYI3*qaX=%V;WC<0Q27e
zA|%4TR-kn=WNj#lzsA6#TEwDygmKos5DQY|WsEeYvEbNLUbR8rD5$jol4SckTW-1k
z$ZH<4s~jMAK4{&<e+>A;ub&N&>w~IgV`W=YJ33=0Q;5#JkDjGG78<v$$;Uw1t*lUo
z>HQ<z@#Bja+kD3i82LAh%~m8a7-InN`ul0DTEXCPN7HxA5!9A1Mh*5ss1XfDAdR|2
z`$w6+WfS9nxSr0Y9f$(u**T~(XetpT8N{Q2flkEG>z>2l^B;k9olW$2KsF61tcey|
zH+06zMjIC%Wg)^SVPD@gf+2^;)?+=0yu)kIj;`MFrB9#1h3|?F2%vACHvZb-aNdX7
zS%N{?C5<_Rv9j%{u{P{ftyv)oZQJ>HJ_as4GSemp(jITl#4x^X6Z>zufywRL=r*S?
zX^H?U2ndFTs2{SNfn$#R-?Ex;$wH`up$Cjny&^iVJ-`PEAnm41UU4IPFZ?;tj=iW_
zK=}`NSGg3JsF%V^kAx*3do#6Dk3kY<UF|K9PTBW&RY)0F)o4>w8E!VF#Mb*8O%g9d
zo7n&{1v*rC0}Z4({e?|WKJ@tj2L#a9*6uxLzQ5?(v1AxgxJw$vDs+GVX-GX`x9*T>
za%h}z^+%Y<``Fq-<DSas-4Am}qlCEAB8j^gPoeu8cmsW?ejo85lN=hI1F3A=IDN@s
zq6YEkG`l`~F_V{GhYE9u)SMu)%NXetk{SGEi&_4;_n?OQ+}-oEwpoCzIl@jX3M>n{
z411}4smumR3yjy=bo_+e2cdHn&;}F=9X80u#$L1OS*t&KzyN*rlsisd7OuL?;037&
zreYWq<#?b9rz`gBh{zLE4h>pk)kc9;oxBFIppa=-g&dfA#okkn!f2;<#$A9+UK4;Z
z89P6D5#v9*YzCro6)OK<mv{^@5fa4=Jo;=Fzx(Bm`s4s@hqUQ{11OVs4b0OCOZ*7Q
zp>e~Q&W&_4i10*P11$<IpqLp;)7^W{-uTKBFFRm>-g4}Zm!CQB0aq(kTb?*uTit97
z2ciOiN{=B=`6*2=Luso#XsiNR)ycua0#ecz3zCJybNUL5=Ro2rkD4`RK~jJZCQI4&
zZ=a)e!yTx=rx>2{F~nfv{eXcaVaa>`p8kiQmK$it1MP&g?EoaR+YK^S`rZ77>w$Uz
zwfu<bu!|OD!I4~zbO2Gjsr`o^pStyfFPJ!BfKK6*;9cu~^_!YEu)b>&j93p;u0qaM
z*9wONBTtz0Q>@z9Y>OPA93D(b*m5DUpg3R^g5%WcZb7mD<$Y?<x_KMh-hVz~0Ck`M
zDa3Rz$taQ<f)z_R<h=Ky2m8Q)`{L$q$hx)<AdV06MOdXfcoYMqMA7wProt|{2SQr~
z!VCJyn$usp=~*kDJLfN$`tG`kPY(FQFKL^YOnSgnnN$?z0OP1o(Y+}@Bh^@lEIgpG
z;mU!>RikpnDQR0coH1KFq09p1K|0-L^PB#MbaEQ<j1Q$MdLTuXjAODE(v4a0+$Xc>
z73X5QfO3VZ2arh}c$}gIR;o5(9^b?<&<g14bVh-4&(o`OHS+u#$^O01x#{Ice|gRT
zU2xj2mo5yKpWiVt21O>W`cOHgx8S&;%&Jh=7YmJN;Sp`0Ema^Fma<T$ON_GXgDgl8
z%oGa`KnRmpZ)E#_eHIZpU=u9}X|xZ?61;(aR(<rn1cxj}GH@@GL31DWo+%DxO5hOb
zQo}eCi59S~m&|ye83huonN}VuNk_(Sy#AEU|Nihh=M2!t?{~u~s|Sy{R7BTOgklvc
zPU%sQxzLm!Nv7jVo^=7v2aOU39`*kZlX8r<6Y2^8vcNd^2*CiY9Xpx4^=3MI_u>x^
z(KzBTlJN<~e|#D7$T-T=2MCbDm<~xig6T#qeA*LP@~USc5zfItdw{hyVwK0j<LnUv
zmYax%WO?5KC|97CAE8A#;j4jZHZQ#L1xud>$eaN>cmBT(KmR_jx-8Uv_l+dA0J&zm
zstP%M7oz+(=D~(0GOHjxqlxt3@yOv&WLgkU;X-6<W&MsvafnkOo&%D$YBPTO26q4a
zCrsRY6KShu7q~rzmVkO=33z%A23nCMBV_S3{=$VE{y*;}SUevwAnub2;x=@qoX}MW
zQ4gR#V-Ns0gyjm<@nW>G0L{Rp1LFOAo_h5^9DO0cTme#me0S~mXNH1#FP!l~D2!0<
zh1`inUBLrsTf6Gy0wE@YEY1CoB3B{@pd1)SrNrKI!kj{sSlBe+0|88I-^QIk{Q)D_
zU4@AwbP%Al4<ZN|0HHq*Pxk>*4IqW}KBhw)k05c(idVms1y6V=CN6$n0i9`xI{?h`
zHX?bAg=kqC(<gQ^(E(@%p4dy#Mp^aI0j3*m9Q)1J*WdQVSC1YHKmdI8)H|QCG(6<1
zGYSNlT!k_VP9+s8noM+*!ci$}nq3bh7$lA`X@cZyW;sBJ?m;Em_H!_DpzN3h%EBbR
zMupHEA7kt9e#