Merge m-c to autoland. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 18 Jul 2017 12:52:05 -0400
changeset 418166 022731a92cfe0516310e86016241f8977c8cc758
parent 418165 7b3e8c8aaecac0485dd0c4fca74788fc4535c121 (current diff)
parent 418123 dece50457378ac4934afe9fb3c2a8054e8894588 (diff)
child 418167 0684def627444396286a76cfd2d261b373511c17
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to autoland. a=merge
browser/components/extensions/test/browser/browser-common.ini
dom/plugins/ipc/PPluginStream.ipdl
dom/plugins/ipc/PluginStreamChild.cpp
dom/plugins/ipc/PluginStreamChild.h
dom/plugins/ipc/PluginStreamParent.cpp
dom/plugins/ipc/PluginStreamParent.h
toolkit/components/extensions/Extension.jsm
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -618,36 +618,41 @@ DocAccessibleParent::MaybeInitWindowEmul
     nsIntRect rootRect = rootDocument->Bounds();
     rect.x = rootRect.x - rect.x;
     rect.y -= rootRect.y;
 
     auto tab = static_cast<dom::TabParent*>(Manager());
     tab->GetDocShellIsActive(&isActive);
   }
 
-  IAccessibleHolder hWndAccHolder;
-  HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
-  HWND hWnd = nsWinUtils::CreateNativeWindow(kClassNameTabContent,
-                                             parentWnd, rect.x, rect.y,
-                                             rect.width, rect.height,
-                                             isActive);
-  if (hWnd) {
-    // Attach accessible document to the emulated native window
-    ::SetPropW(hWnd, kPropNameDocAccParent, (HANDLE)this);
-    SetEmulatedWindowHandle(hWnd);
+  nsWinUtils::NativeWindowCreateProc onCreate([this](HWND aHwnd) -> void {
+    IAccessibleHolder hWndAccHolder;
+
+    ::SetPropW(aHwnd, kPropNameDocAccParent, reinterpret_cast<HANDLE>(this));
+
+    SetEmulatedWindowHandle(aHwnd);
+
     IAccessible* rawHWNDAcc = nullptr;
-    if (SUCCEEDED(::AccessibleObjectFromWindow(hWnd, OBJID_WINDOW,
+    if (SUCCEEDED(::AccessibleObjectFromWindow(aHwnd, OBJID_WINDOW,
                                                IID_IAccessible,
                                                (void**)&rawHWNDAcc))) {
       hWndAccHolder.Set(IAccessibleHolder::COMPtrType(rawHWNDAcc));
     }
-  }
+
+    Unused << SendEmulatedWindow(reinterpret_cast<uintptr_t>(mEmulatedWindowHandle),
+                                 hWndAccHolder);
+  });
 
-  Unused << SendEmulatedWindow(reinterpret_cast<uintptr_t>(mEmulatedWindowHandle),
-                               hWndAccHolder);
+  HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
+  DebugOnly<HWND> hWnd = nsWinUtils::CreateNativeWindow(kClassNameTabContent,
+                                                        parentWnd,
+                                                        rect.x, rect.y,
+                                                        rect.width, rect.height,
+                                                        isActive, &onCreate);
+  MOZ_ASSERT(hWnd);
 }
 
 /**
  * @param aCOMProxy COM Proxy to the document in the content process.
  */
 void
 DocAccessibleParent::SendParentCOMProxy()
 {
--- a/accessible/windows/msaa/DocAccessibleWrap.cpp
+++ b/accessible/windows/msaa/DocAccessibleWrap.cpp
@@ -158,22 +158,25 @@ DocAccessibleWrap::DoInitialUpdate()
         rect.x = rootRect.x - rect.x;
         rect.y -= rootRect.y;
 
         nsCOMPtr<nsISupports> container = mDocumentNode->GetContainer();
         nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
         docShell->GetIsActive(&isActive);
       }
 
+      RefPtr<DocAccessibleWrap> self(this);
+      nsWinUtils::NativeWindowCreateProc onCreate([self](HWND aHwnd) -> void {
+        ::SetPropW(aHwnd, kPropNameDocAcc, reinterpret_cast<HANDLE>(self.get()));
+      });
+
       HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
       mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd,
                                              rect.x, rect.y,
-                                             rect.width, rect.height, isActive);
-
-      ::SetPropW(static_cast<HWND>(mHWND), kPropNameDocAcc, (HANDLE)this);
-
+                                             rect.width, rect.height, isActive,
+                                             &onCreate);
     } else {
       DocAccessible* parentDocument = ParentDocument();
       if (parentDocument)
         mHWND = parentDocument->GetNativeWindow();
     }
   }
 }
--- a/accessible/windows/msaa/nsWinUtils.cpp
+++ b/accessible/windows/msaa/nsWinUtils.cpp
@@ -105,31 +105,27 @@ nsWinUtils::RegisterNativeWindow(LPCWSTR
   wc.lpszMenuName = nullptr;
   wc.lpszClassName = aWindowClass;
   ::RegisterClassW(&wc);
 }
 
 HWND
 nsWinUtils::CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd,
                                int aX, int aY, int aWidth, int aHeight,
-                               bool aIsActive)
+                               bool aIsActive,
+                               NativeWindowCreateProc* aOnCreateProc)
 {
-  HWND hwnd = ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass,
-                                L"NetscapeDispatchWnd",
-                                WS_CHILD | (aIsActive ? WS_VISIBLE : 0),
-                                aX, aY, aWidth, aHeight,
-                                aParentWnd,
-                                nullptr,
-                                GetModuleHandle(nullptr),
-                                nullptr);
-  if (hwnd) {
-    // Mark this window so that ipc related code can identify it.
-    ::SetPropW(hwnd, kPropNameTabContent, (HANDLE)1);
-  }
-  return hwnd;
+  return ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass,
+                           L"NetscapeDispatchWnd",
+                           WS_CHILD | (aIsActive ? WS_VISIBLE : 0),
+                           aX, aY, aWidth, aHeight,
+                           aParentWnd,
+                           nullptr,
+                           GetModuleHandle(nullptr),
+                           aOnCreateProc);
 }
 
 void
 nsWinUtils::ShowNativeWindow(HWND aWnd)
 {
   ::ShowWindow(aWnd, SW_SHOW);
 }
 
@@ -144,16 +140,31 @@ nsWinUtils::HideNativeWindow(HWND aWnd)
 LRESULT CALLBACK
 WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
   // Note, this window's message handling should not invoke any call that
   // may result in a cross-process ipc call. Doing so may violate RPC
   // message semantics.
 
   switch (msg) {
+    case WM_CREATE:
+    {
+      // Mark this window so that ipc related code can identify it.
+      ::SetPropW(hWnd, kPropNameTabContent, reinterpret_cast<HANDLE>(1));
+
+      auto createStruct = reinterpret_cast<CREATESTRUCT*>(lParam);
+      auto createProc = reinterpret_cast<nsWinUtils::NativeWindowCreateProc*>(
+        createStruct->lpCreateParams);
+
+      if (createProc && *createProc) {
+        (*createProc)(hWnd);
+      }
+
+      return 0;
+    }
     case WM_GETOBJECT:
     {
       // Do explicit casting to make it working on 64bit systems (see bug 649236
       // for details).
       int32_t objId = static_cast<DWORD>(lParam);
       if (objId == OBJID_CLIENT) {
         IAccessible* msaaAccessible = nullptr;
         DocAccessible* document =
--- a/accessible/windows/msaa/nsWinUtils.h
+++ b/accessible/windows/msaa/nsWinUtils.h
@@ -3,16 +3,17 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsWinUtils_h_
 #define nsWinUtils_h_
 
+#include <functional>
 #include <windows.h>
 
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsCOMPtr.h"
 
 class nsIContent;
 
 namespace mozilla {
@@ -52,22 +53,40 @@ public:
    */
   static bool IsWindowEmulationStarted() { return sWindowEmulationStarted; }
 
   /**
    * Helper to register window class.
    */
   static void RegisterNativeWindow(LPCWSTR aWindowClass);
 
+  typedef std::function<void(HWND)> NativeWindowCreateProc;
+
   /**
    * Helper to create a window.
+   *
+   * NB: If additional setup needs to be done once the window has been created,
+   *     you should do so via aOnCreateProc. Hooks will fire during the
+   *     CreateNativeWindow call, thus triggering events in the AT.
+   *     Using aOnCreateProc guarantees that your additional initialization will
+   *     have completed prior to the AT receiving window creation events.
+   *
+   *     For example:
+   *
+   *     nsWinUtils::NativeWindowCreateProc onCreate([](HWND aHwnd) -> void {
+   *       DoSomeAwesomeInitializationStuff(aHwnd);
+   *       DoMoreAwesomeInitializationStuff(aHwnd);
+   *     });
+   *     HWND hwnd = nsWinUtils::CreateNativeWindow(..., &onCreate);
+   *     // Doing further initialization work to hwnd on this line is too late!
    */
   static HWND CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd,
                                  int aX, int aY, int aWidth, int aHeight,
-                                 bool aIsActive);
+                                 bool aIsActive,
+                                 NativeWindowCreateProc* aOnCreateProc = nullptr);
 
   /**
    * Helper to show window.
    */
   static void ShowNativeWindow(HWND aWnd);
 
   /**
    * Helper to hide window.
--- a/browser/components/extensions/ExtensionPopups.jsm
+++ b/browser/components/extensions/ExtensionPopups.jsm
@@ -224,16 +224,17 @@ class BasePopup {
     browser.setAttribute("disableglobalhistory", "true");
     browser.setAttribute("transparent", "true");
     browser.setAttribute("class", "webextension-popup-browser");
     browser.setAttribute("webextension-view-type", "popup");
     browser.setAttribute("tooltip", "aHTMLTooltip");
     browser.setAttribute("contextmenu", "contentAreaContextMenu");
     browser.setAttribute("autocompletepopup", "PopupAutoComplete");
     browser.setAttribute("selectmenulist", "ContentSelectDropdown");
+    browser.setAttribute("selectmenuconstrained", "false");
     browser.sameProcessAsFrameLoader = this.extension.groupFrameLoader;
 
     if (this.extension.remote) {
       browser.setAttribute("remote", "true");
       browser.setAttribute("remoteType", E10SUtils.EXTENSION_REMOTE_TYPE);
     }
 
     // We only need flex sizing for the sake of the slide-in sub-views of the
--- a/browser/components/translation/test/browser.ini
+++ b/browser/components/translation/test/browser.ini
@@ -3,11 +3,12 @@ support-files =
   bing.sjs
   yandex.sjs
   fixtures/bug1022725-fr.html
   fixtures/result-da39a3ee5e.txt
   fixtures/result-yandex-d448894848.json
 
 [browser_translation_bing.js]
 [browser_translation_yandex.js]
+skip-if = os == 'win' && !e10s # bug 1374446
 [browser_translation_telemetry.js]
 [browser_translation_infobar.js]
 [browser_translation_exceptions.js]
--- 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: 1.8.532
+Current extension version is: 1.8.557
 
-Taken from upstream commit: 95093a52
+Taken from upstream commit: 4a74cc41
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -3688,18 +3688,18 @@ var _UnsupportedManager = function Unsup
       for (var i = 0, ii = listeners.length; i < ii; i++) {
         listeners[i](featureId);
       }
     }
   };
 }();
 var version, build;
 {
-  exports.version = version = '1.8.532';
-  exports.build = build = '95093a52';
+  exports.version = version = '1.8.557';
+  exports.build = build = '4a74cc41';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports._UnsupportedManager = _UnsupportedManager;
@@ -4738,18 +4738,18 @@ var _text_layer = __w_pdfjs_require__(5)
 var _svg = __w_pdfjs_require__(4);
 
 var isWorker = typeof window === 'undefined';
 if (!_util.globalScope.PDFJS) {
   _util.globalScope.PDFJS = {};
 }
 var PDFJS = _util.globalScope.PDFJS;
 {
-  PDFJS.version = '1.8.532';
-  PDFJS.build = '95093a52';
+  PDFJS.version = '1.8.557';
+  PDFJS.build = '4a74cc41';
 }
 PDFJS.pdfBug = false;
 if (PDFJS.verbosity !== undefined) {
   (0, _util.setVerbosityLevel)(PDFJS.verbosity);
 }
 delete PDFJS.verbosity;
 Object.defineProperty(PDFJS, 'verbosity', {
   get() {
@@ -10067,18 +10067,18 @@ exports.TilingPattern = TilingPattern;
 
 /***/ }),
 /* 13 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '1.8.532';
-var pdfjsBuild = '95093a52';
+var pdfjsVersion = '1.8.557';
+var pdfjsBuild = '4a74cc41';
 var pdfjsSharedUtil = __w_pdfjs_require__(0);
 var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
 var pdfjsDisplayAPI = __w_pdfjs_require__(3);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(5);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(2);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(1);
 var pdfjsDisplaySVG = __w_pdfjs_require__(4);
 exports.PDFJS = pdfjsDisplayGlobal.PDFJS;
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -39799,18 +39799,18 @@ exports.Type1Parser = Type1Parser;
 
 /***/ }),
 /* 35 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '1.8.532';
-var pdfjsBuild = '95093a52';
+var pdfjsVersion = '1.8.557';
+var pdfjsBuild = '4a74cc41';
 var pdfjsCoreWorker = __w_pdfjs_require__(17);
 ;
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 36 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
--- a/browser/extensions/pdfjs/content/web/viewer.html
+++ b/browser/extensions/pdfjs/content/web/viewer.html
@@ -210,18 +210,18 @@ See https://github.com/adobe-type-tools/
                   <button id="zoomIn" class="toolbarButton zoomIn" title="Zoom In" tabindex="22" data-l10n-id="zoom_in">
                     <span data-l10n-id="zoom_in_label">Zoom In</span>
                    </button>
                 </div>
                 <span id="scaleSelectContainer" class="dropdownToolbarButton">
                   <select id="scaleSelect" title="Zoom" tabindex="23" data-l10n-id="zoom">
                     <option id="pageAutoOption" title="" value="auto" selected="selected" data-l10n-id="page_scale_auto">Automatic Zoom</option>
                     <option id="pageActualOption" title="" value="page-actual" data-l10n-id="page_scale_actual">Actual Size</option>
-                    <option id="pageFitOption" title="" value="page-fit" data-l10n-id="page_scale_fit">Fit Page</option>
-                    <option id="pageWidthOption" title="" value="page-width" data-l10n-id="page_scale_width">Full Width</option>
+                    <option id="pageFitOption" title="" value="page-fit" data-l10n-id="page_scale_fit">Page Fit</option>
+                    <option id="pageWidthOption" title="" value="page-width" data-l10n-id="page_scale_width">Page Width</option>
                     <option id="customScaleOption" title="" value="custom" disabled="disabled" hidden="true"></option>
                     <option title="" value="0.5" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 50 }'>50%</option>
                     <option title="" value="0.75" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 75 }'>75%</option>
                     <option title="" value="1" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 100 }'>100%</option>
                     <option title="" value="1.25" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 125 }'>125%</option>
                     <option title="" value="1.5" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 150 }'>150%</option>
                     <option title="" value="2" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 200 }'>200%</option>
                     <option title="" value="3" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 300 }'>300%</option>
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -1419,23 +1419,25 @@ let PDFViewerApplication = {
         if (!this.isViewerEmbedded) {
           pdfViewer.focus();
         }
         return pagesPromise;
       }).then(() => {
         if (!initialParams.destination && !initialParams.bookmark && !initialParams.hash) {
           return;
         }
-        if (this.hasEqualPageSizes) {
+        if (pdfViewer.hasEqualPageSizes) {
           return;
         }
         this.initialDestination = initialParams.destination;
         this.initialBookmark = initialParams.bookmark;
         pdfViewer.currentScaleValue = pdfViewer.currentScaleValue;
         this.setInitialView(initialParams.hash);
+      }).then(function () {
+        pdfViewer.update();
       });
     });
     pdfDocument.getPageLabels().then(labels => {
       if (!labels || this.viewerPrefs['disablePageLabels']) {
         return;
       }
       let i = 0,
           numLabels = labels.length;
@@ -1582,26 +1584,16 @@ let PDFViewerApplication = {
     let pagesOverview = this.pdfViewer.getPagesOverview();
     let printContainer = this.appConfig.printContainer;
     let printService = PDFPrintServiceFactory.instance.createPrintService(this.pdfDocument, pagesOverview, printContainer, this.l10n);
     this.printService = printService;
     this.forceRendering();
     printService.layout();
     this.externalServices.reportTelemetry({ type: 'print' });
   },
-  get hasEqualPageSizes() {
-    let firstPage = this.pdfViewer.getPageView(0);
-    for (let i = 1, ii = this.pagesCount; i < ii; ++i) {
-      let pageView = this.pdfViewer.getPageView(i);
-      if (pageView.width !== firstPage.width || pageView.height !== firstPage.height) {
-        return false;
-      }
-    }
-    return true;
-  },
   afterPrint: function pdfViewSetupAfterPrint() {
     if (this.printService) {
       this.printService.destroy();
       this.printService = null;
     }
     this.forceRendering();
   },
   rotatePages(delta) {
@@ -1951,23 +1943,25 @@ function webViewerUpdateViewarea(evt) {
   PDFViewerApplication.appConfig.toolbar.viewBookmark.href = href;
   PDFViewerApplication.appConfig.secondaryToolbar.viewBookmarkButton.href = href;
   PDFViewerApplication.pdfHistory.updateCurrentBookmark(location.pdfOpenParams, location.pageNumber);
   let currentPage = PDFViewerApplication.pdfViewer.getPageView(PDFViewerApplication.page - 1);
   let loading = currentPage.renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED;
   PDFViewerApplication.toolbar.updateLoadingIndicatorState(loading);
 }
 function webViewerResize() {
-  let currentScaleValue = PDFViewerApplication.pdfViewer.currentScaleValue;
+  let { pdfDocument, pdfViewer } = PDFViewerApplication;
+  if (!pdfDocument) {
+    return;
+  }
+  let currentScaleValue = pdfViewer.currentScaleValue;
   if (currentScaleValue === 'auto' || currentScaleValue === 'page-fit' || currentScaleValue === 'page-width') {
-    PDFViewerApplication.pdfViewer.currentScaleValue = currentScaleValue;
-  } else if (!currentScaleValue) {
-    PDFViewerApplication.pdfViewer.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
-  }
-  PDFViewerApplication.pdfViewer.update();
+    pdfViewer.currentScaleValue = currentScaleValue;
+  }
+  pdfViewer.update();
 }
 function webViewerHashchange(evt) {
   if (PDFViewerApplication.pdfHistory.isHashChangeUnlocked) {
     let hash = evt.hash;
     if (!hash) {
       return;
     }
     if (!PDFViewerApplication.isInitialViewSet) {
@@ -2358,325 +2352,317 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.SimpleLinkService = exports.PDFLinkService = undefined;
 
 var _dom_events = __webpack_require__(2);
 
 var _ui_utils = __webpack_require__(0);
 
-var PDFLinkService = function PDFLinkServiceClosure() {
-  function PDFLinkService(options) {
-    options = options || {};
-    this.eventBus = options.eventBus || (0, _dom_events.getGlobalEventBus)();
+class PDFLinkService {
+  constructor({ eventBus } = {}) {
+    this.eventBus = eventBus || (0, _dom_events.getGlobalEventBus)();
     this.baseUrl = null;
     this.pdfDocument = null;
     this.pdfViewer = null;
     this.pdfHistory = null;
     this._pagesRefCache = null;
   }
-  PDFLinkService.prototype = {
-    setDocument: function PDFLinkService_setDocument(pdfDocument, baseUrl) {
-      this.baseUrl = baseUrl;
-      this.pdfDocument = pdfDocument;
-      this._pagesRefCache = Object.create(null);
-    },
-    setViewer: function PDFLinkService_setViewer(pdfViewer) {
-      this.pdfViewer = pdfViewer;
-    },
-    setHistory: function PDFLinkService_setHistory(pdfHistory) {
-      this.pdfHistory = pdfHistory;
-    },
-    get pagesCount() {
-      return this.pdfDocument ? this.pdfDocument.numPages : 0;
-    },
-    get page() {
-      return this.pdfViewer.currentPageNumber;
-    },
-    set page(value) {
-      this.pdfViewer.currentPageNumber = value;
-    },
-    navigateTo(dest) {
-      let goToDestination = ({ namedDest, explicitDest }) => {
-        let destRef = explicitDest[0],
-            pageNumber;
-        if (destRef instanceof Object) {
-          pageNumber = this._cachedPageNumber(destRef);
-          if (pageNumber === null) {
-            this.pdfDocument.getPageIndex(destRef).then(pageIndex => {
-              this.cachePageRef(pageIndex + 1, destRef);
-              goToDestination({
-                namedDest,
-                explicitDest
-              });
-            }).catch(() => {
-              console.error(`PDFLinkService.navigateTo: "${destRef}" is not ` + `a valid page reference, for dest="${dest}".`);
+  setDocument(pdfDocument, baseUrl) {
+    this.baseUrl = baseUrl;
+    this.pdfDocument = pdfDocument;
+    this._pagesRefCache = Object.create(null);
+  }
+  setViewer(pdfViewer) {
+    this.pdfViewer = pdfViewer;
+  }
+  setHistory(pdfHistory) {
+    this.pdfHistory = pdfHistory;
+  }
+  get pagesCount() {
+    return this.pdfDocument ? this.pdfDocument.numPages : 0;
+  }
+  get page() {
+    return this.pdfViewer.currentPageNumber;
+  }
+  set page(value) {
+    this.pdfViewer.currentPageNumber = value;
+  }
+  navigateTo(dest) {
+    let goToDestination = ({ namedDest, explicitDest }) => {
+      let destRef = explicitDest[0],
+          pageNumber;
+      if (destRef instanceof Object) {
+        pageNumber = this._cachedPageNumber(destRef);
+        if (pageNumber === null) {
+          this.pdfDocument.getPageIndex(destRef).then(pageIndex => {
+            this.cachePageRef(pageIndex + 1, destRef);
+            goToDestination({
+              namedDest,
+              explicitDest
             });
-            return;
-          }
-        } else if ((destRef | 0) === destRef) {
-          pageNumber = destRef + 1;
-        } else {
-          console.error(`PDFLinkService.navigateTo: "${destRef}" is not ` + `a valid destination reference, for dest="${dest}".`);
-          return;
-        }
-        if (!pageNumber || pageNumber < 1 || pageNumber > this.pagesCount) {
-          console.error(`PDFLinkService.navigateTo: "${pageNumber}" is not ` + `a valid page number, for dest="${dest}".`);
-          return;
-        }
-        this.pdfViewer.scrollPageIntoView({
-          pageNumber,
-          destArray: explicitDest
-        });
-        if (this.pdfHistory) {
-          this.pdfHistory.push({
-            dest: explicitDest,
-            hash: namedDest,
-            page: pageNumber
-          });
-        }
-      };
-      new Promise((resolve, reject) => {
-        if (typeof dest === 'string') {
-          this.pdfDocument.getDestination(dest).then(destArray => {
-            resolve({
-              namedDest: dest,
-              explicitDest: destArray
-            });
+          }).catch(() => {
+            console.error(`PDFLinkService.navigateTo: "${destRef}" is not ` + `a valid page reference, for dest="${dest}".`);
           });
           return;
         }
-        resolve({
-          namedDest: '',
-          explicitDest: dest
+      } else if ((destRef | 0) === destRef) {
+        pageNumber = destRef + 1;
+      } else {
+        console.error(`PDFLinkService.navigateTo: "${destRef}" is not ` + `a valid destination reference, for dest="${dest}".`);
+        return;
+      }
+      if (!pageNumber || pageNumber < 1 || pageNumber > this.pagesCount) {
+        console.error(`PDFLinkService.navigateTo: "${pageNumber}" is not ` + `a valid page number, for dest="${dest}".`);
+        return;
+      }
+      this.pdfViewer.scrollPageIntoView({
+        pageNumber,
+        destArray: explicitDest
+      });
+      if (this.pdfHistory) {
+        this.pdfHistory.push({
+          dest: explicitDest,
+          hash: namedDest,
+          page: pageNumber
         });
-      }).then(data => {
-        if (!(data.explicitDest instanceof Array)) {
-          console.error(`PDFLinkService.navigateTo: "${data.explicitDest}" is` + ` not a valid destination array, for dest="${dest}".`);
-          return;
-        }
-        goToDestination(data);
-      });
-    },
-    getDestinationHash(dest) {
+      }
+    };
+    new Promise((resolve, reject) => {
       if (typeof dest === 'string') {
-        return this.getAnchorUrl('#' + escape(dest));
-      }
-      if (dest instanceof Array) {
-        let str = JSON.stringify(dest);
-        return this.getAnchorUrl('#' + escape(str));
-      }
-      return this.getAnchorUrl('');
-    },
-    getAnchorUrl: function PDFLinkService_getAnchorUrl(anchor) {
-      return (this.baseUrl || '') + anchor;
-    },
-    setHash: function PDFLinkService_setHash(hash) {
-      var pageNumber, dest;
-      if (hash.indexOf('=') >= 0) {
-        var params = (0, _ui_utils.parseQueryString)(hash);
-        if ('search' in params) {
-          this.eventBus.dispatch('findfromurlhash', {
-            source: this,
-            query: params['search'].replace(/"/g, ''),
-            phraseSearch: params['phrase'] === 'true'
+        this.pdfDocument.getDestination(dest).then(destArray => {
+          resolve({
+            namedDest: dest,
+            explicitDest: destArray
           });
+        });
+        return;
+      }
+      resolve({
+        namedDest: '',
+        explicitDest: dest
+      });
+    }).then(data => {
+      if (!(data.explicitDest instanceof Array)) {
+        console.error(`PDFLinkService.navigateTo: "${data.explicitDest}" is` + ` not a valid destination array, for dest="${dest}".`);
+        return;
+      }
+      goToDestination(data);
+    });
+  }
+  getDestinationHash(dest) {
+    if (typeof dest === 'string') {
+      return this.getAnchorUrl('#' + escape(dest));
+    }
+    if (dest instanceof Array) {
+      let str = JSON.stringify(dest);
+      return this.getAnchorUrl('#' + escape(str));
+    }
+    return this.getAnchorUrl('');
+  }
+  getAnchorUrl(anchor) {
+    return (this.baseUrl || '') + anchor;
+  }
+  setHash(hash) {
+    let pageNumber, dest;
+    if (hash.indexOf('=') >= 0) {
+      let params = (0, _ui_utils.parseQueryString)(hash);
+      if ('search' in params) {
+        this.eventBus.dispatch('findfromurlhash', {
+          source: this,
+          query: params['search'].replace(/"/g, ''),
+          phraseSearch: params['phrase'] === 'true'
+        });
+      }
+      if ('nameddest' in params) {
+        if (this.pdfHistory) {
+          this.pdfHistory.updateNextHashParam(params.nameddest);
         }
-        if ('nameddest' in params) {
-          if (this.pdfHistory) {
-            this.pdfHistory.updateNextHashParam(params.nameddest);
-          }
-          this.navigateTo(params.nameddest);
-          return;
-        }
-        if ('page' in params) {
-          pageNumber = params.page | 0 || 1;
-        }
-        if ('zoom' in params) {
-          var zoomArgs = params.zoom.split(',');
-          var zoomArg = zoomArgs[0];
-          var zoomArgNumber = parseFloat(zoomArg);
-          if (zoomArg.indexOf('Fit') === -1) {
-            dest = [null, { name: 'XYZ' }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null, zoomArgs.length > 2 ? zoomArgs[2] | 0 : null, zoomArgNumber ? zoomArgNumber / 100 : zoomArg];
+        this.navigateTo(params.nameddest);
+        return;
+      }
+      if ('page' in params) {
+        pageNumber = params.page | 0 || 1;
+      }
+      if ('zoom' in params) {
+        let zoomArgs = params.zoom.split(',');
+        let zoomArg = zoomArgs[0];
+        let zoomArgNumber = parseFloat(zoomArg);
+        if (zoomArg.indexOf('Fit') === -1) {
+          dest = [null, { name: 'XYZ' }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null, zoomArgs.length > 2 ? zoomArgs[2] | 0 : null, zoomArgNumber ? zoomArgNumber / 100 : zoomArg];
+        } else {
+          if (zoomArg === 'Fit' || zoomArg === 'FitB') {
+            dest = [null, { name: zoomArg }];
+          } else if (zoomArg === 'FitH' || zoomArg === 'FitBH' || zoomArg === 'FitV' || zoomArg === 'FitBV') {
+            dest = [null, { name: zoomArg }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null];
+          } else if (zoomArg === 'FitR') {
+            if (zoomArgs.length !== 5) {
+              console.error('PDFLinkService.setHash: Not enough parameters for "FitR".');
+            } else {
+              dest = [null, { name: zoomArg }, zoomArgs[1] | 0, zoomArgs[2] | 0, zoomArgs[3] | 0, zoomArgs[4] | 0];
+            }
           } else {
-            if (zoomArg === 'Fit' || zoomArg === 'FitB') {
-              dest = [null, { name: zoomArg }];
-            } else if (zoomArg === 'FitH' || zoomArg === 'FitBH' || zoomArg === 'FitV' || zoomArg === 'FitBV') {
-              dest = [null, { name: zoomArg }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null];
-            } else if (zoomArg === 'FitR') {
-              if (zoomArgs.length !== 5) {
-                console.error('PDFLinkService_setHash: ' + 'Not enough parameters for \'FitR\'.');
-              } else {
-                dest = [null, { name: zoomArg }, zoomArgs[1] | 0, zoomArgs[2] | 0, zoomArgs[3] | 0, zoomArgs[4] | 0];
-              }
-            } else {
-              console.error('PDFLinkService_setHash: \'' + zoomArg + '\' is not a valid zoom value.');
-            }
+            console.error(`PDFLinkService.setHash: "${zoomArg}" is not ` + 'a valid zoom value.');
           }
         }
-        if (dest) {
-          this.pdfViewer.scrollPageIntoView({
-            pageNumber: pageNumber || this.page,
-            destArray: dest,
-            allowNegativeOffset: true
-          });
-        } else if (pageNumber) {
-          this.page = pageNumber;
-        }
-        if ('pagemode' in params) {
-          this.eventBus.dispatch('pagemode', {
-            source: this,
-            mode: params.pagemode
-          });
-        }
-      } else {
-        dest = unescape(hash);
-        try {
-          dest = JSON.parse(dest);
-          if (!(dest instanceof Array)) {
-            dest = dest.toString();
-          }
-        } catch (ex) {}
-        if (typeof dest === 'string' || isValidExplicitDestination(dest)) {
-          if (this.pdfHistory) {
-            this.pdfHistory.updateNextHashParam(dest);
-          }
-          this.navigateTo(dest);
-          return;
+      }
+      if (dest) {
+        this.pdfViewer.scrollPageIntoView({
+          pageNumber: pageNumber || this.page,
+          destArray: dest,
+          allowNegativeOffset: true
+        });
+      } else if (pageNumber) {
+        this.page = pageNumber;
+      }
+      if ('pagemode' in params) {
+        this.eventBus.dispatch('pagemode', {
+          source: this,
+          mode: params.pagemode
+        });
+      }
+    } else {
+      dest = unescape(hash);
+      try {
+        dest = JSON.parse(dest);
+        if (!(dest instanceof Array)) {
+          dest = dest.toString();
         }
-        console.error('PDFLinkService_setHash: \'' + unescape(hash) + '\' is not a valid destination.');
-      }
-    },
-    executeNamedAction: function PDFLinkService_executeNamedAction(action) {
-      switch (action) {
-        case 'GoBack':
-          if (this.pdfHistory) {
-            this.pdfHistory.back();
-          }
-          break;
-        case 'GoForward':
-          if (this.pdfHistory) {
-            this.pdfHistory.forward();
-          }
-          break;
-        case 'NextPage':
-          if (this.page < this.pagesCount) {
-            this.page++;
-          }
-          break;
-        case 'PrevPage':
-          if (this.page > 1) {
-            this.page--;
-          }
-          break;
-        case 'LastPage':
-          this.page = this.pagesCount;
-          break;
-        case 'FirstPage':
-          this.page = 1;
-          break;
-        default:
-          break;
-      }
-      this.eventBus.dispatch('namedaction', {
-        source: this,
-        action
-      });
-    },
-    onFileAttachmentAnnotation(params = {}) {
-      this.eventBus.dispatch('fileattachmentannotation', {
-        source: this,
-        id: params.id,
-        filename: params.filename,
-        content: params.content
-      });
-    },
-    cachePageRef: function PDFLinkService_cachePageRef(pageNum, pageRef) {
-      var refStr = pageRef.num + ' ' + pageRef.gen + ' R';
-      this._pagesRefCache[refStr] = pageNum;
-    },
-    _cachedPageNumber: function PDFLinkService_cachedPageNumber(pageRef) {
-      var refStr = pageRef.num + ' ' + pageRef.gen + ' R';
-      return this._pagesRefCache && this._pagesRefCache[refStr] || null;
-    }
-  };
-  function isValidExplicitDestination(dest) {
-    if (!(dest instanceof Array)) {
-      return false;
-    }
-    var destLength = dest.length,
-        allowNull = true;
-    if (destLength < 2) {
-      return false;
-    }
-    var page = dest[0];
-    if (!(typeof page === 'object' && typeof page.num === 'number' && (page.num | 0) === page.num && typeof page.gen === 'number' && (page.gen | 0) === page.gen) && !(typeof page === 'number' && (page | 0) === page && page >= 0)) {
-      return false;
-    }
-    var zoom = dest[1];
-    if (!(typeof zoom === 'object' && typeof zoom.name === 'string')) {
-      return false;
-    }
-    switch (zoom.name) {
-      case 'XYZ':
-        if (destLength !== 5) {
-          return false;
+      } catch (ex) {}
+      if (typeof dest === 'string' || isValidExplicitDestination(dest)) {
+        if (this.pdfHistory) {
+          this.pdfHistory.updateNextHashParam(dest);
+        }
+        this.navigateTo(dest);
+        return;
+      }
+      console.error(`PDFLinkService.setHash: "${unescape(hash)}" is not ` + 'a valid destination.');
+    }
+  }
+  executeNamedAction(action) {
+    switch (action) {
+      case 'GoBack':
+        if (this.pdfHistory) {
+          this.pdfHistory.back();
+        }
+        break;
+      case 'GoForward':
+        if (this.pdfHistory) {
+          this.pdfHistory.forward();
+        }
+        break;
+      case 'NextPage':
+        if (this.page < this.pagesCount) {
+          this.page++;
+        }
+        break;
+      case 'PrevPage':
+        if (this.page > 1) {
+          this.page--;
         }
         break;
-      case 'Fit':
-      case 'FitB':
-        return destLength === 2;
-      case 'FitH':
-      case 'FitBH':
-      case 'FitV':
-      case 'FitBV':
-        if (destLength !== 3) {
-          return false;
-        }
+      case 'LastPage':
+        this.page = this.pagesCount;
         break;
-      case 'FitR':
-        if (destLength !== 6) {
-          return false;
-        }
-        allowNull = false;
+      case 'FirstPage':
+        this.page = 1;
         break;
       default:
-        return false;
-    }
-    for (var i = 2; i < destLength; i++) {
-      var param = dest[i];
-      if (!(typeof param === 'number' || allowNull && param === null)) {
+        break;
+    }
+    this.eventBus.dispatch('namedaction', {
+      source: this,
+      action
+    });
+  }
+  onFileAttachmentAnnotation({ id, filename, content }) {
+    this.eventBus.dispatch('fileattachmentannotation', {
+      source: this,
+      id,
+      filename,
+      content
+    });
+  }
+  cachePageRef(pageNum, pageRef) {
+    let refStr = pageRef.num + ' ' + pageRef.gen + ' R';
+    this._pagesRefCache[refStr] = pageNum;
+  }
+  _cachedPageNumber(pageRef) {
+    let refStr = pageRef.num + ' ' + pageRef.gen + ' R';
+    return this._pagesRefCache && this._pagesRefCache[refStr] || null;
+  }
+}
+function isValidExplicitDestination(dest) {
+  if (!(dest instanceof Array)) {
+    return false;
+  }
+  let destLength = dest.length,
+      allowNull = true;
+  if (destLength < 2) {
+    return false;
+  }
+  let page = dest[0];
+  if (!(typeof page === 'object' && typeof page.num === 'number' && (page.num | 0) === page.num && typeof page.gen === 'number' && (page.gen | 0) === page.gen) && !(typeof page === 'number' && (page | 0) === page && page >= 0)) {
+    return false;
+  }
+  let zoom = dest[1];
+  if (!(typeof zoom === 'object' && typeof zoom.name === 'string')) {
+    return false;
+  }
+  switch (zoom.name) {
+    case 'XYZ':
+      if (destLength !== 5) {
         return false;
       }
-    }
-    return true;
-  }
-  return PDFLinkService;
-}();
-var SimpleLinkService = function SimpleLinkServiceClosure() {
-  function SimpleLinkService() {}
-  SimpleLinkService.prototype = {
-    get page() {
-      return 0;
-    },
-    set page(value) {},
-    navigateTo(dest) {},
-    getDestinationHash(dest) {
-      return '#';
-    },
-    getAnchorUrl(hash) {
-      return '#';
-    },
-    setHash(hash) {},
-    executeNamedAction(action) {},
-    onFileAttachmentAnnotation(params) {},
-    cachePageRef(pageNum, pageRef) {}
-  };
-  return SimpleLinkService;
-}();
+      break;
+    case 'Fit':
+    case 'FitB':
+      return destLength === 2;
+    case 'FitH':
+    case 'FitBH':
+    case 'FitV':
+    case 'FitBV':
+      if (destLength !== 3) {
+        return false;
+      }
+      break;
+    case 'FitR':
+      if (destLength !== 6) {
+        return false;
+      }
+      allowNull = false;
+      break;
+    default:
+      return false;
+  }
+  for (let i = 2; i < destLength; i++) {
+    let param = dest[i];
+    if (!(typeof param === 'number' || allowNull && param === null)) {
+      return false;
+    }
+  }
+  return true;
+}
+class SimpleLinkService {
+  get page() {
+    return 0;
+  }
+  set page(value) {}
+  navigateTo(dest) {}
+  getDestinationHash(dest) {
+    return '#';
+  }
+  getAnchorUrl(hash) {
+    return '#';
+  }
+  setHash(hash) {}
+  executeNamedAction(action) {}
+  onFileAttachmentAnnotation({ id, filename, content }) {}
+  cachePageRef(pageNum, pageRef) {}
+}
 exports.PDFLinkService = PDFLinkService;
 exports.SimpleLinkService = SimpleLinkService;
 
 /***/ }),
 /* 6 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -4339,30 +4325,32 @@ class PDFFindBar {
     if (notFound) {
       this.findField.classList.add('notFound');
     } else {
       this.findField.classList.remove('notFound');
     }
     this.findField.setAttribute('data-status', status);
     Promise.resolve(findMsg).then(msg => {
       this.findMsg.textContent = msg;
+      this._adjustWidth();
     });
     this.updateResultsCount(matchCount);
-    this._adjustWidth();
   }
   updateResultsCount(matchCount) {
     if (!this.findResultsCount) {
       return;
     }
     if (!matchCount) {
       this.findResultsCount.classList.add('hidden');
-      return;
-    }
-    this.findResultsCount.textContent = matchCount.toLocaleString();
-    this.findResultsCount.classList.remove('hidden');
+      this.findResultsCount.textContent = '';
+    } else {
+      this.findResultsCount.textContent = matchCount.toLocaleString();
+      this.findResultsCount.classList.remove('hidden');
+    }
+    this._adjustWidth();
   }
   open() {
     if (!this.opened) {
       this.opened = true;
       this.toggleButton.classList.add('toggled');
       this.bar.classList.remove('hidden');
     }
     this.findField.select();
@@ -6390,56 +6378,56 @@ var _annotation_layer_builder = __webpac
 var _dom_events = __webpack_require__(2);
 
 var _pdf_page_view = __webpack_require__(20);
 
 var _pdf_link_service = __webpack_require__(5);
 
 var _text_layer_builder = __webpack_require__(28);
 
-var PresentationModeState = {
+const PresentationModeState = {
   UNKNOWN: 0,
   NORMAL: 1,
   CHANGING: 2,
   FULLSCREEN: 3
 };
-var DEFAULT_CACHE_SIZE = 10;
-var PDFViewer = function pdfViewer() {
-  function PDFPageViewBuffer(size) {
-    var data = [];
-    this.push = function cachePush(view) {
-      var i = data.indexOf(view);
-      if (i >= 0) {
-        data.splice(i, 1);
-      }
-      data.push(view);
-      if (data.length > size) {
-        data.shift().destroy();
-      }
-    };
-    this.resize = function (newSize) {
-      size = newSize;
-      while (data.length > size) {
-        data.shift().destroy();
-      }
-    };
-  }
-  function isSameScale(oldScale, newScale) {
-    if (newScale === oldScale) {
-      return true;
-    }
-    if (Math.abs(newScale - oldScale) < 1e-15) {
-      return true;
-    }
-    return false;
-  }
-  function isPortraitOrientation(size) {
-    return size.width <= size.height;
-  }
-  function PDFViewer(options) {
+const DEFAULT_CACHE_SIZE = 10;
+function PDFPageViewBuffer(size) {
+  let data = [];
+  this.push = function cachePush(view) {
+    let i = data.indexOf(view);
+    if (i >= 0) {
+      data.splice(i, 1);
+    }
+    data.push(view);
+    if (data.length > size) {
+      data.shift().destroy();
+    }
+  };
+  this.resize = function (newSize) {
+    size = newSize;
+    while (data.length > size) {
+      data.shift().destroy();
+    }
+  };
+}
+function isSameScale(oldScale, newScale) {
+  if (newScale === oldScale) {
+    return true;
+  }
+  if (Math.abs(newScale - oldScale) < 1e-15) {
+    return true;
+  }
+  return false;
+}
+function isPortraitOrientation(size) {
+  return size.width <= size.height;
+}
+class PDFViewer {
+  constructor(options) {
     this.container = options.container;
     this.viewer = options.viewer || options.container.firstElementChild;
     this.eventBus = options.eventBus || (0, _dom_events.getGlobalEventBus)();
     this.linkService = options.linkService || new _pdf_link_service.SimpleLinkService();
     this.downloadManager = options.downloadManager || null;
     this.removePageBorders = options.removePageBorders || false;
     this.enhanceTextSelection = options.enhanceTextSelection || false;
     this.renderInteractiveForms = options.renderInteractiveForms || false;
@@ -6455,597 +6443,605 @@ var PDFViewer = function pdfViewer() {
     }
     this.scroll = (0, _ui_utils.watchScroll)(this.container, this._scrollUpdate.bind(this));
     this.presentationModeState = PresentationModeState.UNKNOWN;
     this._resetView();
     if (this.removePageBorders) {
       this.viewer.classList.add('removePageBorders');
     }
   }
-  PDFViewer.prototype = {
-    get pagesCount() {
-      return this._pages.length;
-    },
-    getPageView(index) {
-      return this._pages[index];
-    },
-    get pageViewsReady() {
-      return this._pageViewsReady;
-    },
-    get currentPageNumber() {
-      return this._currentPageNumber;
-    },
-    set currentPageNumber(val) {
-      if ((val | 0) !== val) {
-        throw new Error('Invalid page number.');
-      }
-      if (!this.pdfDocument) {
-        return;
-      }
-      this._setCurrentPageNumber(val, true);
-    },
-    _setCurrentPageNumber: function PDFViewer_setCurrentPageNumber(val, resetCurrentPageView) {
-      if (this._currentPageNumber === val) {
-        if (resetCurrentPageView) {
-          this._resetCurrentPageView();
-        }
-        return;
-      }
-      if (!(0 < val && val <= this.pagesCount)) {
-        console.error('PDFViewer_setCurrentPageNumber: "' + val + '" is out of bounds.');
-        return;
-      }
-      var arg = {
-        source: this,
-        pageNumber: val,
-        pageLabel: this._pageLabels && this._pageLabels[val - 1]
-      };
-      this._currentPageNumber = val;
-      this.eventBus.dispatch('pagechanging', arg);
-      this.eventBus.dispatch('pagechange', arg);
+  get pagesCount() {
+    return this._pages.length;
+  }
+  getPageView(index) {
+    return this._pages[index];
+  }
+  get pageViewsReady() {
+    return this._pageViewsReady;
+  }
+  get currentPageNumber() {
+    return this._currentPageNumber;
+  }
+  set currentPageNumber(val) {
+    if ((val | 0) !== val) {
+      throw new Error('Invalid page number.');
+    }
+    if (!this.pdfDocument) {
+      return;
+    }
+    this._setCurrentPageNumber(val, true);
+  }
+  _setCurrentPageNumber(val, resetCurrentPageView = false) {
+    if (this._currentPageNumber === val) {
       if (resetCurrentPageView) {
         this._resetCurrentPageView();
       }
-    },
-    get currentPageLabel() {
-      return this._pageLabels && this._pageLabels[this._currentPageNumber - 1];
-    },
-    set currentPageLabel(val) {
-      let pageNumber = val | 0;
-      if (this._pageLabels) {
-        let i = this._pageLabels.indexOf(val);
-        if (i >= 0) {
-          pageNumber = i + 1;
-        }
-      }
-      this.currentPageNumber = pageNumber;
-    },
-    get currentScale() {
-      return this._currentScale !== _ui_utils.UNKNOWN_SCALE ? this._currentScale : _ui_utils.DEFAULT_SCALE;
-    },
-    set currentScale(val) {
-      if (isNaN(val)) {
-        throw new Error('Invalid numeric scale');
-      }
-      if (!this.pdfDocument) {
-        return;
-      }
-      this._setScale(val, false);
-    },
-    get currentScaleValue() {
-      return this._currentScaleValue;
-    },
-    set currentScaleValue(val) {
-      if (!this.pdfDocument) {
-        return;
-      }
-      this._setScale(val, false);
-    },
-    get pagesRotation() {
-      return this._pagesRotation;
-    },
-    set pagesRotation(rotation) {
-      if (!(typeof rotation === 'number' && rotation % 90 === 0)) {
-        throw new Error('Invalid pages rotation angle.');
-      }
-      if (!this.pdfDocument) {
-        return;
-      }
-      this._pagesRotation = rotation;
-      for (let i = 0, ii = this._pages.length; i < ii; i++) {
-        let pageView = this._pages[i];
-        pageView.update(pageView.scale, rotation);
-      }
-      this._setScale(this._currentScaleValue, true);
-      if (this.defaultRenderingQueue) {
-        this.update();
-      }
-    },
-    setDocument(pdfDocument) {
-      if (this.pdfDocument) {
-        this._cancelRendering();
-        this._resetView();
-      }
-      this.pdfDocument = pdfDocument;
-      if (!pdfDocument) {
-        return;
-      }
-      var pagesCount = pdfDocument.numPages;
-      var pagesCapability = (0, _pdfjsLib.createPromiseCapability)();
-      this.pagesPromise = pagesCapability.promise;
-      pagesCapability.promise.then(() => {
-        this._pageViewsReady = true;
-        this.eventBus.dispatch('pagesloaded', {
-          source: this,
-          pagesCount
-        });
+      return;
+    }
+    if (!(0 < val && val <= this.pagesCount)) {
+      console.error(`PDFViewer._setCurrentPageNumber: "${val}" is out of bounds.`);
+      return;
+    }
+    let arg = {
+      source: this,
+      pageNumber: val,
+      pageLabel: this._pageLabels && this._pageLabels[val - 1]
+    };
+    this._currentPageNumber = val;
+    this.eventBus.dispatch('pagechanging', arg);
+    this.eventBus.dispatch('pagechange', arg);
+    if (resetCurrentPageView) {
+      this._resetCurrentPageView();
+    }
+  }
+  get currentPageLabel() {
+    return this._pageLabels && this._pageLabels[this._currentPageNumber - 1];
+  }
+  set currentPageLabel(val) {
+    let pageNumber = val | 0;
+    if (this._pageLabels) {
+      let i = this._pageLabels.indexOf(val);
+      if (i >= 0) {
+        pageNumber = i + 1;
+      }
+    }
+    this.currentPageNumber = pageNumber;
+  }
+  get currentScale() {
+    return this._currentScale !== _ui_utils.UNKNOWN_SCALE ? this._currentScale : _ui_utils.DEFAULT_SCALE;
+  }
+  set currentScale(val) {
+    if (isNaN(val)) {
+      throw new Error('Invalid numeric scale');
+    }
+    if (!this.pdfDocument) {
+      return;
+    }
+    this._setScale(val, false);
+  }
+  get currentScaleValue() {
+    return this._currentScaleValue;
+  }
+  set currentScaleValue(val) {
+    if (!this.pdfDocument) {
+      return;
+    }
+    this._setScale(val, false);
+  }
+  get pagesRotation() {
+    return this._pagesRotation;
+  }
+  set pagesRotation(rotation) {
+    if (!(typeof rotation === 'number' && rotation % 90 === 0)) {
+      throw new Error('Invalid pages rotation angle.');
+    }
+    if (!this.pdfDocument) {
+      return;
+    }
+    this._pagesRotation = rotation;
+    for (let i = 0, ii = this._pages.length; i < ii; i++) {
+      let pageView = this._pages[i];
+      pageView.update(pageView.scale, rotation);
+    }
+    this._setScale(this._currentScaleValue, true);
+    if (this.defaultRenderingQueue) {
+      this.update();
+    }
+  }
+  setDocument(pdfDocument) {
+    if (this.pdfDocument) {
+      this._cancelRendering();
+      this._resetView();
+    }
+    this.pdfDocument = pdfDocument;
+    if (!pdfDocument) {
+      return;
+    }
+    let pagesCount = pdfDocument.numPages;
+    let pagesCapability = (0, _pdfjsLib.createPromiseCapability)();
+    this.pagesPromise = pagesCapability.promise;
+    pagesCapability.promise.then(() => {
+      this._pageViewsReady = true;
+      this.eventBus.dispatch('pagesloaded', {
+        source: this,
+        pagesCount
       });
-      var isOnePageRenderedResolved = false;
-      var onePageRenderedCapability = (0, _pdfjsLib.createPromiseCapability)();
-      this.onePageRendered = onePageRenderedCapability.promise;
-      var bindOnAfterAndBeforeDraw = pageView => {
-        pageView.onBeforeDraw = () => {
-          this._buffer.push(pageView);
-        };
-        pageView.onAfterDraw = () => {
-          if (!isOnePageRenderedResolved) {
-            isOnePageRenderedResolved = true;
-            onePageRenderedCapability.resolve();
-          }
-        };
+    });
+    let isOnePageRenderedResolved = false;
+    let onePageRenderedCapability = (0, _pdfjsLib.createPromiseCapability)();
+    this.onePageRendered = onePageRenderedCapability.promise;
+    let bindOnAfterAndBeforeDraw = pageView => {
+      pageView.onBeforeDraw = () => {
+        this._buffer.push(pageView);
       };
-      var firstPagePromise = pdfDocument.getPage(1);
-      this.firstPagePromise = firstPagePromise;
-      return firstPagePromise.then(pdfPage => {
-        var scale = this.currentScale;
-        var viewport = pdfPage.getViewport(scale * _ui_utils.CSS_UNITS);
-        for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
-          var textLayerFactory = null;
-          if (!_pdfjsLib.PDFJS.disableTextLayer) {
-            textLayerFactory = this;
-          }
-          var pageView = new _pdf_page_view.PDFPageView({
-            container: this.viewer,
-            eventBus: this.eventBus,
-            id: pageNum,
-            scale,
-            defaultViewport: viewport.clone(),
-            renderingQueue: this.renderingQueue,
-            textLayerFactory,
-            annotationLayerFactory: this,
-            enhanceTextSelection: this.enhanceTextSelection,
-            renderInteractiveForms: this.renderInteractiveForms,
-            renderer: this.renderer,
-            l10n: this.l10n
-          });
-          bindOnAfterAndBeforeDraw(pageView);
-          this._pages.push(pageView);
+      pageView.onAfterDraw = () => {
+        if (!isOnePageRenderedResolved) {
+          isOnePageRenderedResolved = true;
+          onePageRenderedCapability.resolve();
         }
-        onePageRenderedCapability.promise.then(() => {
-          if (_pdfjsLib.PDFJS.disableAutoFetch) {
-            pagesCapability.resolve();
-            return;
-          }
-          var getPagesLeft = pagesCount;
-          for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
-            pdfDocument.getPage(pageNum).then(pdfPage => {
-              var pageView = this._pages[pageNum - 1];
-              if (!pageView.pdfPage) {
-                pageView.setPdfPage(pdfPage);
-              }
-              this.linkService.cachePageRef(pageNum, pdfPage.ref);
-              if (--getPagesLeft === 0) {
-                pagesCapability.resolve();
-              }
-            });
-          }
-        });
-        this.eventBus.dispatch('pagesinit', { source: this });
-        if (this.defaultRenderingQueue) {
-          this.update();
-        }
-        if (this.findController) {
-          this.findController.resolveFirstPage();
+      };
+    };
+    let firstPagePromise = pdfDocument.getPage(1);
+    this.firstPagePromise = firstPagePromise;
+    return firstPagePromise.then(pdfPage => {
+      let scale = this.currentScale;
+      let viewport = pdfPage.getViewport(scale * _ui_utils.CSS_UNITS);
+      for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
+        let textLayerFactory = null;
+        if (!_pdfjsLib.PDFJS.disableTextLayer) {
+          textLayerFactory = this;
         }
-      });
-    },
-    setPageLabels: function PDFViewer_setPageLabels(labels) {
-      if (!this.pdfDocument) {
-        return;
-      }
-      if (!labels) {
-        this._pageLabels = null;
-      } else if (!(labels instanceof Array && this.pdfDocument.numPages === labels.length)) {
-        this._pageLabels = null;
-        console.error('PDFViewer_setPageLabels: Invalid page labels.');
-      } else {
-        this._pageLabels = labels;
-      }
-      for (var i = 0, ii = this._pages.length; i < ii; i++) {
-        var pageView = this._pages[i];
-        var label = this._pageLabels && this._pageLabels[i];
-        pageView.setPageLabel(label);
-      }
-    },
-    _resetView() {
-      this._pages = [];
-      this._currentPageNumber = 1;
-      this._currentScale = _ui_utils.UNKNOWN_SCALE;
-      this._currentScaleValue = null;
-      this._pageLabels = null;
-      this._buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE);
-      this._location = null;
-      this._pagesRotation = 0;
-      this._pagesRequests = [];
-      this._pageViewsReady = false;
-      this.viewer.textContent = '';
-    },
-    _scrollUpdate() {
-      if (this.pagesCount === 0) {
-        return;
-      }
-      this.update();
-    },
-    _setScaleDispatchEvent: function pdfViewer_setScaleDispatchEvent(newScale, newValue, preset) {
-      var arg = {
-        source: this,
-        scale: newScale,
-        presetValue: preset ? newValue : undefined
-      };
-      this.eventBus.dispatch('scalechanging', arg);
-      this.eventBus.dispatch('scalechange', arg);
-    },
-    _setScaleUpdatePages: function pdfViewer_setScaleUpdatePages(newScale, newValue, noScroll, preset) {
-      this._currentScaleValue = newValue.toString();
-      if (isSameScale(this._currentScale, newScale)) {
-        if (preset) {
-          this._setScaleDispatchEvent(newScale, newValue, true);
-        }
-        return;
-      }
-      for (var i = 0, ii = this._pages.length; i < ii; i++) {
-        this._pages[i].update(newScale);
-      }
-      this._currentScale = newScale;
-      if (!noScroll) {
-        var page = this._currentPageNumber,
-            dest;
-        if (this._location && !_pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom && !(this.isInPresentationMode || this.isChangingPresentationMode)) {
-          page = this._location.pageNumber;
-          dest = [null, { name: 'XYZ' }, this._location.left, this._location.top, null];
-        }
-        this.scrollPageIntoView({
-          pageNumber: page,
-          destArray: dest,
-          allowNegativeOffset: true
+        let pageView = new _pdf_page_view.PDFPageView({
+          container: this.viewer,
+          eventBus: this.eventBus,
+          id: pageNum,
+          scale,
+          defaultViewport: viewport.clone(),
+          renderingQueue: this.renderingQueue,
+          textLayerFactory,
+          annotationLayerFactory: this,
+          enhanceTextSelection: this.enhanceTextSelection,
+          renderInteractiveForms: this.renderInteractiveForms,
+          renderer: this.renderer,
+          l10n: this.l10n
         });
-      }
-      this._setScaleDispatchEvent(newScale, newValue, preset);
-      if (this.defaultRenderingQueue) {
-        this.update();
-      }
-    },
-    _setScale: function PDFViewer_setScale(value, noScroll) {
-      var scale = parseFloat(value);
-      if (scale > 0) {
-        this._setScaleUpdatePages(scale, value, noScroll, false);
-      } else {
-        var currentPage = this._pages[this._currentPageNumber - 1];
-        if (!currentPage) {
+        bindOnAfterAndBeforeDraw(pageView);
+        this._pages.push(pageView);
+      }
+      onePageRenderedCapability.promise.then(() => {
+        if (_pdfjsLib.PDFJS.disableAutoFetch) {
+          pagesCapability.resolve();
           return;
         }
-        var hPadding = this.isInPresentationMode || this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING;
-        var vPadding = this.isInPresentationMode || this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING;
-        var pageWidthScale = (this.container.clientWidth - hPadding) / currentPage.width * currentPage.scale;
-        var pageHeightScale = (this.container.clientHeight - vPadding) / currentPage.height * currentPage.scale;
-        switch (value) {
-          case 'page-actual':
-            scale = 1;
-            break;
-          case 'page-width':
-            scale = pageWidthScale;
-            break;
-          case 'page-height':
-            scale = pageHeightScale;
-            break;
-          case 'page-fit':
-            scale = Math.min(pageWidthScale, pageHeightScale);
-            break;
-          case 'auto':
-            var isLandscape = currentPage.width > currentPage.height;
-            var horizontalScale = isLandscape ? Math.min(pageHeightScale, pageWidthScale) : pageWidthScale;
-            scale = Math.min(_ui_utils.MAX_AUTO_SCALE, horizontalScale);
-            break;
-          default:
-            console.error('PDFViewer_setScale: "' + value + '" is an unknown zoom value.');
-            return;
+        let getPagesLeft = pagesCount;
+        for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
+          pdfDocument.getPage(pageNum).then(pdfPage => {
+            let pageView = this._pages[pageNum - 1];
+            if (!pageView.pdfPage) {
+              pageView.setPdfPage(pdfPage);
+            }
+            this.linkService.cachePageRef(pageNum, pdfPage.ref);
+            if (--getPagesLeft === 0) {
+              pagesCapability.resolve();
+            }
+          });
         }
-        this._setScaleUpdatePages(scale, value, noScroll, true);
-      }
-    },
-    _resetCurrentPageView() {
-      if (this.isInPresentationMode) {
-        this._setScale(this._currentScaleValue, true);
-      }
-      var pageView = this._pages[this._currentPageNumber - 1];
-      (0, _ui_utils.scrollIntoView)(pageView.div);
-    },
-    scrollPageIntoView: function PDFViewer_scrollPageIntoView(params) {
-      if (!this.pdfDocument) {
-        return;
-      }
-      var pageNumber = params.pageNumber || 0;
-      var dest = params.destArray || null;
-      var allowNegativeOffset = params.allowNegativeOffset || false;
-      if (this.isInPresentationMode || !dest) {
-        this._setCurrentPageNumber(pageNumber, true);
+      });
+      this.eventBus.dispatch('pagesinit', { source: this });
+      if (this.defaultRenderingQueue) {
+        this.update();
+      }
+      if (this.findController) {
+        this.findController.resolveFirstPage();
+      }
+    });
+  }
+  setPageLabels(labels) {
+    if (!this.pdfDocument) {
+      return;
+    }
+    if (!labels) {
+      this._pageLabels = null;
+    } else if (!(labels instanceof Array && this.pdfDocument.numPages === labels.length)) {
+      this._pageLabels = null;
+      console.error('PDFViewer.setPageLabels: Invalid page labels.');
+    } else {
+      this._pageLabels = labels;
+    }
+    for (let i = 0, ii = this._pages.length; i < ii; i++) {
+      let pageView = this._pages[i];
+      let label = this._pageLabels && this._pageLabels[i];
+      pageView.setPageLabel(label);
+    }
+  }
+  _resetView() {
+    this._pages = [];
+    this._currentPageNumber = 1;
+    this._currentScale = _ui_utils.UNKNOWN_SCALE;
+    this._currentScaleValue = null;
+    this._pageLabels = null;
+    this._buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE);
+    this._location = null;
+    this._pagesRotation = 0;
+    this._pagesRequests = [];
+    this._pageViewsReady = false;
+    this.viewer.textContent = '';
+  }
+  _scrollUpdate() {
+    if (this.pagesCount === 0) {
+      return;
+    }
+    this.update();
+  }
+  _setScaleDispatchEvent(newScale, newValue, preset = false) {
+    let arg = {
+      source: this,
+      scale: newScale,
+      presetValue: preset ? newValue : undefined
+    };
+    this.eventBus.dispatch('scalechanging', arg);
+    this.eventBus.dispatch('scalechange', arg);
+  }
+  _setScaleUpdatePages(newScale, newValue, noScroll = false, preset = false) {
+    this._currentScaleValue = newValue.toString();
+    if (isSameScale(this._currentScale, newScale)) {
+      if (preset) {
+        this._setScaleDispatchEvent(newScale, newValue, true);
+      }
+      return;
+    }
+    for (let i = 0, ii = this._pages.length; i < ii; i++) {
+      this._pages[i].update(newScale);
+    }
+    this._currentScale = newScale;
+    if (!noScroll) {
+      let page = this._currentPageNumber,
+          dest;
+      if (this._location && !_pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom && !(this.isInPresentationMode || this.isChangingPresentationMode)) {
+        page = this._location.pageNumber;
+        dest = [null, { name: 'XYZ' }, this._location.left, this._location.top, null];
+      }
+      this.scrollPageIntoView({
+        pageNumber: page,
+        destArray: dest,
+        allowNegativeOffset: true
+      });
+    }
+    this._setScaleDispatchEvent(newScale, newValue, preset);
+    if (this.defaultRenderingQueue) {
+      this.update();
+    }
+  }
+  _setScale(value, noScroll = false) {
+    let scale = parseFloat(value);
+    if (scale > 0) {
+      this._setScaleUpdatePages(scale, value, noScroll, false);
+    } else {
+      let currentPage = this._pages[this._currentPageNumber - 1];
+      if (!currentPage) {
         return;
       }
-      var pageView = this._pages[pageNumber - 1];
-      if (!pageView) {
-        console.error('PDFViewer_scrollPageIntoView: ' + 'Invalid "pageNumber" parameter.');
-        return;
-      }
-      var x = 0,
-          y = 0;
-      var width = 0,
-          height = 0,
-          widthScale,
-          heightScale;
-      var changeOrientation = pageView.rotation % 180 === 0 ? false : true;
-      var pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / _ui_utils.CSS_UNITS;
-      var pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / _ui_utils.CSS_UNITS;
-      var scale = 0;
-      switch (dest[1].name) {
-        case 'XYZ':
-          x = dest[2];
-          y = dest[3];
-          scale = dest[4];
-          x = x !== null ? x : 0;
-          y = y !== null ? y : pageHeight;
+      let hPadding = this.isInPresentationMode || this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING;
+      let vPadding = this.isInPresentationMode || this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING;
+      let pageWidthScale = (this.container.clientWidth - hPadding) / currentPage.width * currentPage.scale;
+      let pageHeightScale = (this.container.clientHeight - vPadding) / currentPage.height * currentPage.scale;
+      switch (value) {
+        case 'page-actual':
+          scale = 1;
           break;
-        case 'Fit':
-        case 'FitB':
-          scale = 'page-fit';
+        case 'page-width':
+          scale = pageWidthScale;
           break;
-        case 'FitH':
-        case 'FitBH':
-          y = dest[2];
-          scale = 'page-width';
-          if (y === null && this._location) {
-            x = this._location.left;
-            y = this._location.top;
-          }
+        case 'page-height':
+          scale = pageHeightScale;
           break;
-        case 'FitV':
-        case 'FitBV':
-          x = dest[2];
-          width = pageWidth;
-          height = pageHeight;
-          scale = 'page-height';
+        case 'page-fit':
+          scale = Math.min(pageWidthScale, pageHeightScale);
           break;
-        case 'FitR':
-          x = dest[2];
-          y = dest[3];
-          width = dest[4] - x;
-          height = dest[5] - y;
-          var hPadding = this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING;
-          var vPadding = this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING;
-          widthScale = (this.container.clientWidth - hPadding) / width / _ui_utils.CSS_UNITS;
-          heightScale = (this.container.clientHeight - vPadding) / height / _ui_utils.CSS_UNITS;
-          scale = Math.min(Math.abs(widthScale), Math.abs(heightScale));
+        case 'auto':
+          let isLandscape = currentPage.width > currentPage.height;
+          let horizontalScale = isLandscape ? Math.min(pageHeightScale, pageWidthScale) : pageWidthScale;
+          scale = Math.min(_ui_utils.MAX_AUTO_SCALE, horizontalScale);
           break;
         default:
-          console.error('PDFViewer_scrollPageIntoView: \'' + dest[1].name + '\' is not a valid destination type.');
+          console.error(`PDFViewer._setScale: "${value}" is an unknown zoom value.`);
           return;
       }
-      if (scale && scale !== this._currentScale) {
-        this.currentScaleValue = scale;
-      } else if (this._currentScale === _ui_utils.UNKNOWN_SCALE) {
-        this.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
-      }
-      if (scale === 'page-fit' && !dest[4]) {
-        (0, _ui_utils.scrollIntoView)(pageView.div);
-        return;
-      }
-      var boundingRect = [pageView.viewport.convertToViewportPoint(x, y), pageView.viewport.convertToViewportPoint(x + width, y + height)];
-      var left = Math.min(boundingRect[0][0], boundingRect[1][0]);
-      var top = Math.min(boundingRect[0][1], boundingRect[1][1]);
-      if (!allowNegativeOffset) {
-        left = Math.max(left, 0);
-        top = Math.max(top, 0);
-      }
-      (0, _ui_utils.scrollIntoView)(pageView.div, {
-        left,
-        top
-      });
-    },
-    _updateLocation(firstPage) {
-      var currentScale = this._currentScale;
-      var currentScaleValue = this._currentScaleValue;
-      var normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue;
-      var pageNumber = firstPage.id;
-      var pdfOpenParams = '#page=' + pageNumber;
-      pdfOpenParams += '&zoom=' + normalizedScaleValue;
-      var currentPageView = this._pages[pageNumber - 1];
-      var container = this.container;
-      var topLeft = currentPageView.getPagePoint(container.scrollLeft - firstPage.x, container.scrollTop - firstPage.y);
-      var intLeft = Math.round(topLeft[0]);
-      var intTop = Math.round(topLeft[1]);
-      pdfOpenParams += ',' + intLeft + ',' + intTop;
-      this._location = {
-        pageNumber,
-        scale: normalizedScaleValue,
-        top: intTop,
-        left: intLeft,
-        pdfOpenParams
-      };
-    },
-    update: function PDFViewer_update() {
-      var visible = this._getVisiblePages();
-      var visiblePages = visible.views;
-      if (visiblePages.length === 0) {
+      this._setScaleUpdatePages(scale, value, noScroll, true);
+    }
+  }
+  _resetCurrentPageView() {
+    if (this.isInPresentationMode) {
+      this._setScale(this._currentScaleValue, true);
+    }
+    let pageView = this._pages[this._currentPageNumber - 1];
+    (0, _ui_utils.scrollIntoView)(pageView.div);
+  }
+  scrollPageIntoView(params) {
+    if (!this.pdfDocument) {
+      return;
+    }
+    let pageNumber = params.pageNumber || 0;
+    let dest = params.destArray || null;
+    let allowNegativeOffset = params.allowNegativeOffset || false;
+    if (this.isInPresentationMode || !dest) {
+      this._setCurrentPageNumber(pageNumber, true);
+      return;
+    }
+    let pageView = this._pages[pageNumber - 1];
+    if (!pageView) {
+      console.error('PDFViewer.scrollPageIntoView: Invalid "pageNumber" parameter.');
+      return;
+    }
+    let x = 0,
+        y = 0;
+    let width = 0,
+        height = 0,
+        widthScale,
+        heightScale;
+    let changeOrientation = pageView.rotation % 180 === 0 ? false : true;
+    let pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / _ui_utils.CSS_UNITS;
+    let pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / _ui_utils.CSS_UNITS;
+    let scale = 0;
+    switch (dest[1].name) {
+      case 'XYZ':
+        x = dest[2];
+        y = dest[3];
+        scale = dest[4];
+        x = x !== null ? x : 0;
+        y = y !== null ? y : pageHeight;
+        break;
+      case 'Fit':
+      case 'FitB':
+        scale = 'page-fit';
+        break;
+      case 'FitH':
+      case 'FitBH':
+        y = dest[2];
+        scale = 'page-width';
+        if (y === null && this._location) {
+          x = this._location.left;
+          y = this._location.top;
+        }
+        break;
+      case 'FitV':
+      case 'FitBV':
+        x = dest[2];
+        width = pageWidth;
+        height = pageHeight;
+        scale = 'page-height';
+        break;
+      case 'FitR':
+        x = dest[2];
+        y = dest[3];
+        width = dest[4] - x;
+        height = dest[5] - y;
+        let hPadding = this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING;
+        let vPadding = this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING;
+        widthScale = (this.container.clientWidth - hPadding) / width / _ui_utils.CSS_UNITS;
+        heightScale = (this.container.clientHeight - vPadding) / height / _ui_utils.CSS_UNITS;
+        scale = Math.min(Math.abs(widthScale), Math.abs(heightScale));
+        break;
+      default:
+        console.error(`PDFViewer.scrollPageIntoView: "${dest[1].name}" ` + 'is not a valid destination type.');
         return;
-      }
-      var suggestedCacheSize = Math.max(DEFAULT_CACHE_SIZE, 2 * visiblePages.length + 1);
-      this._buffer.resize(suggestedCacheSize);
-      this.renderingQueue.renderHighestPriority(visible);
-      var currentId = this._currentPageNumber;
-      var firstPage = visible.first;
-      for (var i = 0, ii = visiblePages.length, stillFullyVisible = false; i < ii; ++i) {
-        var page = visiblePages[i];
-        if (page.percent < 100) {
-          break;
-        }
-        if (page.id === currentId) {
-          stillFullyVisible = true;
-          break;
-        }
-      }
-      if (!stillFullyVisible) {
-        currentId = visiblePages[0].id;
-      }
-      if (!this.isInPresentationMode) {
-        this._setCurrentPageNumber(currentId);
-      }
-      this._updateLocation(firstPage);
-      this.eventBus.dispatch('updateviewarea', {
-        source: this,
-        location: this._location
+    }
+    if (scale && scale !== this._currentScale) {
+      this.currentScaleValue = scale;
+    } else if (this._currentScale === _ui_utils.UNKNOWN_SCALE) {
+      this.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
+    }
+    if (scale === 'page-fit' && !dest[4]) {
+      (0, _ui_utils.scrollIntoView)(pageView.div);
+      return;
+    }
+    let boundingRect = [pageView.viewport.convertToViewportPoint(x, y), pageView.viewport.convertToViewportPoint(x + width, y + height)];
+    let left = Math.min(boundingRect[0][0], boundingRect[1][0]);
+    let top = Math.min(boundingRect[0][1], boundingRect[1][1]);
+    if (!allowNegativeOffset) {
+      left = Math.max(left, 0);
+      top = Math.max(top, 0);
+    }
+    (0, _ui_utils.scrollIntoView)(pageView.div, {
+      left,
+      top
+    });
+  }
+  _updateLocation(firstPage) {
+    let currentScale = this._currentScale;
+    let currentScaleValue = this._currentScaleValue;
+    let normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue;
+    let pageNumber = firstPage.id;
+    let pdfOpenParams = '#page=' + pageNumber;
+    pdfOpenParams += '&zoom=' + normalizedScaleValue;
+    let currentPageView = this._pages[pageNumber - 1];
+    let container = this.container;
+    let topLeft = currentPageView.getPagePoint(container.scrollLeft - firstPage.x, container.scrollTop - firstPage.y);
+    let intLeft = Math.round(topLeft[0]);
+    let intTop = Math.round(topLeft[1]);
+    pdfOpenParams += ',' + intLeft + ',' + intTop;
+    this._location = {
+      pageNumber,
+      scale: normalizedScaleValue,
+      top: intTop,
+      left: intLeft,
+      pdfOpenParams
+    };
+  }
+  update() {
+    let visible = this._getVisiblePages();
+    let visiblePages = visible.views;
+    if (visiblePages.length === 0) {
+      return;
+    }
+    let suggestedCacheSize = Math.max(DEFAULT_CACHE_SIZE, 2 * visiblePages.length + 1);
+    this._buffer.resize(suggestedCacheSize);
+    this.renderingQueue.renderHighestPriority(visible);
+    let currentId = this._currentPageNumber;
+    let firstPage = visible.first;
+    let stillFullyVisible = false;
+    for (let i = 0, ii = visiblePages.length; i < ii; ++i) {
+      let page = visiblePages[i];
+      if (page.percent < 100) {
+        break;
+      }
+      if (page.id === currentId) {
+        stillFullyVisible = true;
+        break;
+      }
+    }
+    if (!stillFullyVisible) {
+      currentId = visiblePages[0].id;
+    }
+    if (!this.isInPresentationMode) {
+      this._setCurrentPageNumber(currentId);
+    }
+    this._updateLocation(firstPage);
+    this.eventBus.dispatch('updateviewarea', {
+      source: this,
+      location: this._location
+    });
+  }
+  containsElement(element) {
+    return this.container.contains(element);
+  }
+  focus() {
+    this.container.focus();
+  }
+  get isInPresentationMode() {
+    return this.presentationModeState === PresentationModeState.FULLSCREEN;
+  }
+  get isChangingPresentationMode() {
+    return this.presentationModeState === PresentationModeState.CHANGING;
+  }
+  get isHorizontalScrollbarEnabled() {
+    return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth;
+  }
+  _getVisiblePages() {
+    if (!this.isInPresentationMode) {
+      return (0, _ui_utils.getVisibleElements)(this.container, this._pages, true);
+    }
+    let visible = [];
+    let currentPage = this._pages[this._currentPageNumber - 1];
+    visible.push({
+      id: currentPage.id,
+      view: currentPage
+    });
+    return {
+      first: currentPage,
+      last: currentPage,
+      views: visible
+    };
+  }
+  cleanup() {
+    for (let i = 0, ii = this._pages.length; i < ii; i++) {
+      if (this._pages[i] && this._pages[i].renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) {
+        this._pages[i].reset();
+      }
+    }
+  }
+  _cancelRendering() {
+    for (let i = 0, ii = this._pages.length; i < ii; i++) {
+      if (this._pages[i]) {
+        this._pages[i].cancelRendering();
+      }
+    }
+  }
+  _ensurePdfPageLoaded(pageView) {
+    if (pageView.pdfPage) {
+      return Promise.resolve(pageView.pdfPage);
+    }
+    let pageNumber = pageView.id;
+    if (this._pagesRequests[pageNumber]) {
+      return this._pagesRequests[pageNumber];
+    }
+    let promise = this.pdfDocument.getPage(pageNumber).then(pdfPage => {
+      if (!pageView.pdfPage) {
+        pageView.setPdfPage(pdfPage);
+      }
+      this._pagesRequests[pageNumber] = null;
+      return pdfPage;
+    });
+    this._pagesRequests[pageNumber] = promise;
+    return promise;
+  }
+  forceRendering(currentlyVisiblePages) {
+    let visiblePages = currentlyVisiblePages || this._getVisiblePages();
+    let pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, this.scroll.down);
+    if (pageView) {
+      this._ensurePdfPageLoaded(pageView).then(() => {
+        this.renderingQueue.renderView(pageView);
       });
-    },
-    containsElement(element) {
-      return this.container.contains(element);
-    },
-    focus() {
-      this.container.focus();
-    },
-    get isInPresentationMode() {
-      return this.presentationModeState === PresentationModeState.FULLSCREEN;
-    },
-    get isChangingPresentationMode() {
-      return this.presentationModeState === PresentationModeState.CHANGING;
-    },
-    get isHorizontalScrollbarEnabled() {
-      return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth;
-    },
-    _getVisiblePages() {
-      if (!this.isInPresentationMode) {
-        return (0, _ui_utils.getVisibleElements)(this.container, this._pages, true);
-      }
-      var visible = [];
-      var currentPage = this._pages[this._currentPageNumber - 1];
-      visible.push({
-        id: currentPage.id,
-        view: currentPage
-      });
+      return true;
+    }
+    return false;
+  }
+  getPageTextContent(pageIndex) {
+    return this.pdfDocument.getPage(pageIndex + 1).then(function (page) {
+      return page.getTextContent({ normalizeWhitespace: true });
+    });
+  }
+  createTextLayerBuilder(textLayerDiv, pageIndex, viewport, enhanceTextSelection = false) {
+    return new _text_layer_builder.TextLayerBuilder({
+      textLayerDiv,
+      eventBus: this.eventBus,
+      pageIndex,
+      viewport,
+      findController: this.isInPresentationMode ? null : this.findController,
+      enhanceTextSelection: this.isInPresentationMode ? false : enhanceTextSelection
+    });
+  }
+  createAnnotationLayerBuilder(pageDiv, pdfPage, renderInteractiveForms = false, l10n = _ui_utils.NullL10n) {
+    return new _annotation_layer_builder.AnnotationLayerBuilder({
+      pageDiv,
+      pdfPage,
+      renderInteractiveForms,
+      linkService: this.linkService,
+      downloadManager: this.downloadManager,
+      l10n
+    });
+  }
+  setFindController(findController) {
+    this.findController = findController;
+  }
+  get hasEqualPageSizes() {
+    let firstPageView = this._pages[0];
+    for (let i = 1, ii = this._pages.length; i < ii; ++i) {
+      let pageView = this._pages[i];
+      if (pageView.width !== firstPageView.width || pageView.height !== firstPageView.height) {
+        return false;
+      }
+    }
+    return true;
+  }
+  getPagesOverview() {
+    let pagesOverview = this._pages.map(function (pageView) {
+      let viewport = pageView.pdfPage.getViewport(1);
       return {
-        first: currentPage,
-        last: currentPage,
-        views: visible
+        width: viewport.width,
+        height: viewport.height,
+        rotation: viewport.rotation
       };
-    },
-    cleanup() {
-      for (var i = 0, ii = this._pages.length; i < ii; i++) {
-        if (this._pages[i] && this._pages[i].renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) {
-          this._pages[i].reset();
-        }
-      }
-    },
-    _cancelRendering: function PDFViewer_cancelRendering() {
-      for (var i = 0, ii = this._pages.length; i < ii; i++) {
-        if (this._pages[i]) {
-          this._pages[i].cancelRendering();
-        }
-      }
-    },
-    _ensurePdfPageLoaded(pageView) {
-      if (pageView.pdfPage) {
-        return Promise.resolve(pageView.pdfPage);
-      }
-      var pageNumber = pageView.id;
-      if (this._pagesRequests[pageNumber]) {
-        return this._pagesRequests[pageNumber];
-      }
-      var promise = this.pdfDocument.getPage(pageNumber).then(pdfPage => {
-        if (!pageView.pdfPage) {
-          pageView.setPdfPage(pdfPage);
-        }
-        this._pagesRequests[pageNumber] = null;
-        return pdfPage;
-      });
-      this._pagesRequests[pageNumber] = promise;
-      return promise;
-    },
-    forceRendering(currentlyVisiblePages) {
-      var visiblePages = currentlyVisiblePages || this._getVisiblePages();
-      var pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, this.scroll.down);
-      if (pageView) {
-        this._ensurePdfPageLoaded(pageView).then(() => {
-          this.renderingQueue.renderView(pageView);
-        });
-        return true;
-      }
-      return false;
-    },
-    getPageTextContent(pageIndex) {
-      return this.pdfDocument.getPage(pageIndex + 1).then(function (page) {
-        return page.getTextContent({ normalizeWhitespace: true });
-      });
-    },
-    createTextLayerBuilder(textLayerDiv, pageIndex, viewport, enhanceTextSelection = false) {
-      return new _text_layer_builder.TextLayerBuilder({
-        textLayerDiv,
-        eventBus: this.eventBus,
-        pageIndex,
-        viewport,
-        findController: this.isInPresentationMode ? null : this.findController,
-        enhanceTextSelection: this.isInPresentationMode ? false : enhanceTextSelection
-      });
-    },
-    createAnnotationLayerBuilder(pageDiv, pdfPage, renderInteractiveForms = false, l10n = _ui_utils.NullL10n) {
-      return new _annotation_layer_builder.AnnotationLayerBuilder({
-        pageDiv,
-        pdfPage,
-        renderInteractiveForms,
-        linkService: this.linkService,
-        downloadManager: this.downloadManager,
-        l10n
-      });
-    },
-    setFindController(findController) {
-      this.findController = findController;
-    },
-    getPagesOverview() {
-      var pagesOverview = this._pages.map(function (pageView) {
-        var viewport = pageView.pdfPage.getViewport(1);
-        return {
-          width: viewport.width,
-          height: viewport.height,
-          rotation: viewport.rotation
-        };
-      });
-      if (!this.enablePrintAutoRotate) {
-        return pagesOverview;
-      }
-      var isFirstPagePortrait = isPortraitOrientation(pagesOverview[0]);
-      return pagesOverview.map(function (size) {
-        if (isFirstPagePortrait === isPortraitOrientation(size)) {
-          return size;
-        }
-        return {
-          width: size.height,
-          height: size.width,
-          rotation: (size.rotation + 90) % 360
-        };
-      });
-    }
-  };
-  return PDFViewer;
-}();
+    });
+    if (!this.enablePrintAutoRotate) {
+      return pagesOverview;
+    }
+    let isFirstPagePortrait = isPortraitOrientation(pagesOverview[0]);
+    return pagesOverview.map(function (size) {
+      if (isFirstPagePortrait === isPortraitOrientation(size)) {
+        return size;
+      }
+      return {
+        width: size.height,
+        height: size.width,
+        rotation: (size.rotation + 90) % 360
+      };
+    });
+  }
+}
 exports.PresentationModeState = PresentationModeState;
 exports.PDFViewer = PDFViewer;
 
 /***/ }),
 /* 26 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
--- a/devtools/client/inspector/grids/components/GridDisplaySettings.js
+++ b/devtools/client/inspector/grids/components/GridDisplaySettings.js
@@ -68,56 +68,56 @@ module.exports = createClass({
         dom.li(
           {
             className: "grid-settings-item",
           },
           dom.label(
             {},
             dom.input(
               {
-                id: "grid-setting-extend-grid-lines",
-                type: "checkbox",
-                checked: highlighterSettings.showInfiniteLines,
-                onChange: this.onShowInfiniteLinesCheckboxClick,
-              }
-            ),
-            getStr("layout.extendGridLinesInfinitely")
-          )
-        ),
-        dom.li(
-          {
-            className: "grid-settings-item",
-          },
-          dom.label(
-            {},
-            dom.input(
-              {
                 id: "grid-setting-show-grid-line-numbers",
                 type: "checkbox",
                 checked: highlighterSettings.showGridLineNumbers,
                 onChange: this.onShowGridLineNumbersCheckboxClick,
               }
             ),
-            getStr("layout.displayNumbersOnLines2")
+            getStr("layout.displayLineNumbers")
           )
         ),
         dom.li(
           {
             className: "grid-settings-item",
           },
           dom.label(
            {},
            dom.input(
              {
                id: "grid-setting-show-grid-areas",
                type: "checkbox",
                checked: highlighterSettings.showGridAreasOverlay,
                onChange: this.onShowGridAreasCheckboxClick,
              }
            ),
-           getStr("layout.displayGridAreas")
+           getStr("layout.displayAreaNames")
+          )
+        ),
+        dom.li(
+          {
+            className: "grid-settings-item",
+          },
+          dom.label(
+            {},
+            dom.input(
+              {
+                id: "grid-setting-extend-grid-lines",
+                type: "checkbox",
+                checked: highlighterSettings.showInfiniteLines,
+                onChange: this.onShowInfiniteLinesCheckboxClick,
+              }
+            ),
+            getStr("layout.extendLinesInfinitely")
           )
         )
       )
     );
   },
 
 });
--- a/devtools/client/locales/en-US/layout.properties
+++ b/devtools/client/locales/en-US/layout.properties
@@ -5,27 +5,27 @@
 # LOCALIZATION NOTE This file contains the Layout Inspector strings.
 # The Layout Inspector is a panel accessible in the Inspector sidebar.
 
 # LOCALIZATION NOTE (layout.cannotShowGridOutline, layout.cannotSHowGridOutline.title):
 # In the case where the grid outline cannot be effectively displayed.
 layout.cannotShowGridOutline=Cannot show outline for this grid
 layout.cannotShowGridOutline.title=The selected grid’s outline cannot effectively fit inside the layout panel for it to be usable.
 
-# LOCALIZATION NOTE (layout.displayGridAreas): Label of the display grid areas setting
+# LOCALIZATION NOTE (layout.displayAreaNames): Label of the display area names setting
 # option in the CSS Grid pane.
-layout.displayGridAreas=Display grid areas
+layout.displayAreaNames=Display area names
 
-# LOCALIZATION NOTE (layout.displayNumbersOnLines2): Label of the display numbers on lines
+# LOCALIZATION NOTE (layout.displayLineNumbers): Label of the display line numbers
 # setting option in the CSS Grid pane.
-layout.displayNumbersOnLines2=Display line numbers
+layout.displayLineNumbers=Display line numbers
 
-# LOCALIZATION NOTE (layout.extendGridLinesInfinitely): Label of the extend grid lines
+# LOCALIZATION NOTE (layout.extendLinesInfinitely): Label of the extend lines
 # infinitely setting option in the CSS Grid pane.
-layout.extendGridLinesInfinitely=Extend grid lines infinitely
+layout.extendLinesInfinitely=Extend lines infinitely
 
 # LOCALIZATION NOTE (layout.header): The accordion header for the CSS Grid pane.
 layout.header=Grid
 
 # LOCALIZATION NOTE (layout.gridDisplaySettings): The header for the grid display
 # settings container in the CSS Grid pane.
 layout.gridDisplaySettings=Grid Display Settings
 
new file mode 100644
--- /dev/null
+++ b/docshell/test/navigation/file_bug1379762-1.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Bug 1379762</title>
+  </head>
+  <img srcset> <!-- This tries to add load blockers during bfcache restoration -->
+  <script>
+    onunload = null; // enable bfcache
+    opener.is(opener.testCount, 0,
+              "We should only run once; otherwise the loadCount variable makes no sense");
+    var loadCount = 0;
+    onpageshow = function() {
+      ++opener.testCount;
+      if (opener.testCount == 1) {
+        // Navigate forward and then back.
+        setTimeout(function() { location = "goback.html"; }, 0);
+      } else if (opener.testCount == 2) {
+        // Do this async so our load event gets a chance to fire if it plans to
+        // do it.
+        setTimeout(function() {
+          opener.nextTest();
+          window.close();
+        });
+      }
+    };
+    onload = function() {
+      ++loadCount;
+      opener.is(loadCount, 1, "Should only get one onload");
+    }
+  </script>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/navigation/file_bug1379762-2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Bug 1379762</title>
+  </head>
+  <script type="text/just-data">
+    onunload = null; // enable bfcache
+    ++opener.testCount;
+    onpageshow = function(e) {
+      opener.ok(!e.persisted, "Pageshow should not be coming from bfcache " + opener.testCount);
+    }
+    if (opener.testCount == 1) {
+      onload = function () {
+        setTimeout(function() {
+          document.write(testScript);
+        }, 0);
+      }
+    } else if (opener.testCount == 2) {
+      // Do this async, just in case.
+      setTimeout(function() {
+        history.back();
+      }, 0);
+    } else if (opener.testCount == 3) {
+      // Do this async, just in case.
+      setTimeout(function() {
+        history.forward();
+      }, 0);
+    } else if (opener.testCount == 4) {
+      onload = function() {
+        opener.nextTest();
+        window.close();
+      }
+    }
+  </script>
+  <script>
+    var data = document.querySelector("script[type='text/just-data']").textContent;
+    // Store the string that does all out work in a global variable, so we can
+    // get at it later.
+    var testScript = "<script>" + data + "</" + "script>";
+    document.write(testScript);
+  </script>
+</html>
--- a/docshell/test/navigation/mochitest.ini
+++ b/docshell/test/navigation/mochitest.ini
@@ -59,15 +59,16 @@ skip-if = (toolkit == 'android') || (!de
 [test_grandchild.html]
 [test_not-opener.html]
 [test_opener.html]
 [test_popup-navigates-children.html]
 [test_reserved.html]
 skip-if = (toolkit == 'android') || (debug && e10s) #too slow on Android 4.3 aws only; bug 1030403; bug 1263213 for debug e10s
 [test_sessionhistory.html]
 skip-if = toolkit == 'android' #RANDOM
+support-files = file_bug1379762-1.html file_bug1379762-2.html
 [test_sibling-matching-parent.html]
 [test_sibling-off-domain.html]
 [test_triggeringprincipal_frame_nav.html]
 [test_triggeringprincipal_window_open.html]
 [test_triggeringprincipal_parent_iframe_window_open.html]
 [test_triggeringprincipal_iframe_iframe_window_open.html]
 [test_contentpolicy_block_window.html]
--- a/docshell/test/navigation/test_sessionhistory.html
+++ b/docshell/test/navigation/test_sessionhistory.html
@@ -28,16 +28,18 @@ var testFiles =
     //"file_static_and_dynamic_1.html",// Static and dynamic frames and forward-back
     "file_bug534178.html",           // Session history transaction clean-up.
     "file_fragment_handling_during_load.html",
     "file_nested_frames.html",
     "file_shiftReload_and_pushState.html",
     "file_scrollRestoration.html",
     "file_bug1300461.html",
     "file_bug1326251.html",
+    "file_bug1379762-1.html",
+    "file_bug1379762-2.html",
   ];
 var testCount = 0; // Used by the test files.
 
 SimpleTest.waitForExplicitFinish();
 SimpleTest.requestFlakyTimeout("untriaged");
 
 var testWindow;
 function nextTest_() {
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -8799,18 +8799,21 @@ void
 nsDocument::BlockOnload()
 {
   if (mDisplayDocument) {
     mDisplayDocument->BlockOnload();
     return;
   }
 
   // If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup
-  // -- it's not ours.
-  if (mOnloadBlockCount == 0 && mScriptGlobalObject) {
+  // -- it's not ours.  Also, if we're already in the COMPLETE state, that means
+  // we already had our load event, conceptually, so there's no more need to
+  // mess about with the load blocker.
+  if (mOnloadBlockCount == 0 && mScriptGlobalObject &&
+      GetReadyStateEnum() != READYSTATE_COMPLETE) {
     if (!nsContentUtils::IsSafeToRunScript()) {
       // Because AddRequest may lead to OnStateChange calls in chrome,
       // block onload only when there are no script blockers.
       ++mAsyncOnloadBlockCount;
       if (mAsyncOnloadBlockCount == 1) {
         nsContentUtils::AddScriptRunner(NewRunnableMethod(
           "nsDocument::AsyncBlockOnload", this, &nsDocument::AsyncBlockOnload));
       }
--- a/dom/base/test/test_data_uri.html
+++ b/dom/base/test/test_data_uri.html
@@ -19,35 +19,42 @@ function imgListener(img) {
     img.addEventListener("error", () => reject());
   });
 }
 
 function runTests()
 {
   var iframe = document.getElementById("iframe");
   iframe.src="data:text/html,hello";
-  iframe.onload = function() {
-    ok(SpecialPowers.wrap(iframe).contentDocument.nodePrincipal.isNullPrincipal,
-       "iframe should have NullPrincipal.");
-  }
+  let p1 = new Promise((resolve, reject) => {
+    iframe.onload = function() {
+      ok(SpecialPowers.wrap(iframe).contentDocument.nodePrincipal.isNullPrincipal,
+         "iframe should have NullPrincipal.");
+      resolve();
+    }
+  });
+
   var iframe1 = document.getElementById("iframe1");
   iframe1.src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82";
-  iframe1.onload = function() {
-    ok(SpecialPowers.wrap(iframe1).contentDocument.nodePrincipal.isNullPrincipal,
-       "iframe1 should have NullPrincipal.");
-  }
+  let p2 = new Promise((resolve, reject) => {
+    iframe1.onload = function() {
+      ok(SpecialPowers.wrap(iframe1).contentDocument.nodePrincipal.isNullPrincipal,
+         "iframe1 should have NullPrincipal.");
+      resolve();
+    }
+  });
 
   var canvas = document.getElementById('canvas');
   var ctx = canvas.getContext('2d');
   ctx.fillRect(0, 0, canvas.height, canvas.width);
   ctx.fillStyle = '#000';
   var data = canvas.toDataURL('image/png');
   var img = new Image();
   img.src = data;
-  imgListener(img).then(() => {
+  let p3 = imgListener(img).then(() => {
     dump("img onload\n");
     ctx.drawImage(img, 0, 0);
     return new Promise((resolve, reject) => {
       try {
         ctx.getImageData(0, 0, 1, 1);
         ok(true, "data:image should be same origin.");
         resolve();
       } catch (e) {
@@ -74,16 +81,19 @@ function runTests()
         win.close();
         resolve();
       }});
   }).then(() => {
     document.fonts.add(new FontFace("test", "url(data:font/opentype;base64,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AC4AIABDAG8AcAB5AHIAaQBnAGgAdAAgAGkAbgBmAG8AIABwAGUAbgBkAGkAbgBnAC4AbABvAGEAZAB0AGUAcwB0AFIAZQBnAHUAbABhAHIAdwBlAGIAZgBvAG4AdABsAG8AYQBkAHQAZQBzAHQAIABSAGUAZwB1AGwAYQByAFYAZQByAHMAaQBvAG4AIAAwADAAMQAuADAAMAAxAEIAYQBzAGUAZAAgAG8AbgAgAEwAZQBhAGcAdQBlACAARwBvAHQAaABpAGMAIABiAHkAIABMAGUAYQBnAHUAZQAgAG8AZgAgAE0AbwB2AGUAYQBiAGwAZQAgAFQAeQBwAGUALAAgAG0AbwBkAGkAZgBpAGUAZAAgAGIAeQAgAEoAbwBoAG4AIABEAGEAZwBnAGUAdAB0AGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AGgAZQBsAGUAYQBnAHUAZQBvAGYAbQBvAHYAZQBhAGIAbABlAHQAeQBwAGUALgBjAG8AbQAvAGwAZQBhAGcAdQBlAC0AZwBvAHQAaABpAGMAQQBsAGwAIABmAG8AbgB0AHMAIABmAHIAbwBtACAAVABoAGUAIABMAGUAYQBnAHUAZQAgAG8AZgAgAE0AbwB2AGUAYQBiAGwAZQAgAFQAeQBwAGUAIABhAHIAZQAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAE8AcABlAG4AIABGAG8AbgB0ACAATABpAGMAZQBuAHMAZQBoAHQAdABwADoALwAvAHMAYwByAGkAcAB0AHMALgBzAGkAbAAuAG8AcgBnAC8ATwBGAEwAAgAAAAAAAP9nAGYAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQECAKMAhACFAJYAjgCLAQMAigDaAI0AwwDeAKIArQDJAMcArgBiAGMAkABkAMsAZQDIAMoAzwDMAM0AzgDpAGYA0wDQANEArwBnAJEA1gDUANUAaADrAO0AiQBqAGkAawBtAGwAbgCgAG8AcQBwAHIAcwB1AHQAdgB3AOoAeAB6AHkAewB9AHwAoQB/AH4AgACBAOwA7gC6ANcA4gDjALAAsQDkAOUAuwDmAOcA2ADhANsA3ADdAOAA2QDfAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQCyALMAtgC3AMQAtAC1AMUAhwCrARIBEwEUAIwA7wEVARYBFwd1bmkwMEEwB3VuaTAwQUQHdW5pMjAwMAd1bmkyMDAxB3VuaTIwMDIHdW5pMjAwMwd1bmkyMDA0B3VuaTIwMDUHdW5pMjAwNgd1bmkyMDA3B3VuaTIwMDgHdW5pMjAwOQd1bmkyMDBBB3VuaTIwMTAHdW5pMjAxMQpmaWd1cmVkYXNoB3VuaTIwMkYHdW5pMjA1RgRFdXJvB3VuaUUwMDAHdW5pRkIwMQd1bmlGQjAyAAAAAQAB//8ADwAAAAEAAAAAyYlvMQAAAADGp3m3AAAAAMrhKHcAAQAAAAwAAAAWAAAAAgABAAEA3wABAAQAAAABAAAAAAABAAAACgAuADwAAkRGTFQADmxhdG4AGAAEAAAAAP//AAAABAAAAAD//wABAAAAAVRTVDEACAAAAAEAAAABAAQAAQAAAAEACAACAA4ABABEADMANgBWAAEABAAkACkALAAvAAA=)"));
     return document.fonts.ready;
   }).then(() => {
     is(document.fonts.size, 1, "should load data:font");
+  });
+
+  Promise.all([p1, p2, p3]).then(() => {
     SimpleTest.finish();
   }).catch((e) => {
     ok(false, "throwing " + e);
     SimpleTest.finish();
   });
 }
 </script>
 
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -926,16 +926,18 @@ WebGLContext::SetDimensions(int32_t sign
             ForceLoseContext();
             return NS_OK;
         }
 
         // everything's good, we're done here
         mResetLayer = true;
         mBackbufferNeedsClear = true;
 
+        gl->ResetSyncCallCount("Existing WebGLContext resized.");
+
         return NS_OK;
     }
 
     nsCString failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_UNKOWN");
     auto autoTelemetry = mozilla::MakeScopeExit([&] {
         Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
                               failureId);
     });
@@ -1140,16 +1142,18 @@ WebGLContext::SetDimensions(int32_t sign
 
     mShouldPresent = true;
 
     //////
 
     reporter.SetSuccessful();
 
     failureId = NS_LITERAL_CSTRING("SUCCESS");
+
+    gl->ResetSyncCallCount("WebGLContext Initialization");
     return NS_OK;
 }
 
 void
 WebGLContext::ClearBackbufferIfNeeded()
 {
     if (!mBackbufferNeedsClear)
         return;
@@ -1592,16 +1596,17 @@ WebGLContext::ForceClearFramebufferWithD
 void
 WebGLContext::OnEndOfFrame() const
 {
    if (gfxPrefs::WebGLSpewFrameAllocs()) {
       GeneratePerfWarning("[webgl.perf.spew-frame-allocs] %" PRIu64 " data allocations this frame.",
                            mDataAllocGLCallCount);
    }
    mDataAllocGLCallCount = 0;
+   gl->ResetSyncCallCount("WebGLContext PresentScreenBuffer");
 }
 
 // For an overview of how WebGL compositing works, see:
 // https://wiki.mozilla.org/Platform/GFX/WebGL/Compositing
 bool
 WebGLContext::PresentScreenBuffer()
 {
     if (IsContextLost()) {
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -114,19 +114,19 @@ using namespace mozilla::plugins::parent
 
 // We should make this const...
 static NPNetscapeFuncs sBrowserFuncs = {
   sizeof(sBrowserFuncs),
   (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
   _geturl,
   _posturl,
   _requestread,
-  _newstream,
-  _write,
-  _destroystream,
+  nullptr,
+  nullptr,
+  nullptr,
   _status,
   _useragent,
   _memalloc,
   _memfree,
   _memflush,
   _reloadplugins,
   _getJavaEnv,
   _getJavaPeer,
@@ -771,137 +771,16 @@ NPError
 
   PluginDestructionGuard guard(npp);
 
   return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
                                     eNPPStreamTypeInternal_Post, false, nullptr,
                                     len, buf);
 }
 
-NPError
-_newstream(NPP npp, NPMIMEType type, const char* target, NPStream* *result)
-{
-  if (!NS_IsMainThread()) {
-    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_newstream called from the wrong thread\n"));
-    return NPERR_INVALID_PARAM;
-  }
-  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
-  ("NPN_NewStream: npp=%p, type=%s, target=%s\n", (void*)npp,
-   (const char *)type, target));
-
-  NPError err = NPERR_INVALID_INSTANCE_ERROR;
-  if (npp && npp->ndata) {
-    nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
-
-    PluginDestructionGuard guard(inst);
-
-    nsCOMPtr<nsIOutputStream> stream;
-    if (NS_SUCCEEDED(inst->NewStreamFromPlugin((const char*) type, target,
-                                               getter_AddRefs(stream)))) {
-      auto* wrapper = new nsNPAPIStreamWrapper(stream, nullptr);
-      if (wrapper) {
-        (*result) = &wrapper->mNPStream;
-        err = NPERR_NO_ERROR;
-      } else {
-        err = NPERR_OUT_OF_MEMORY_ERROR;
-      }
-    } else {
-      err = NPERR_GENERIC_ERROR;
-    }
-  }
-  return err;
-}
-
-int32_t
-_write(NPP npp, NPStream *pstream, int32_t len, void *buffer)
-{
-  if (!NS_IsMainThread()) {
-    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_write called from the wrong thread\n"));
-    return 0;
-  }
-  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
-                 ("NPN_Write: npp=%p, url=%s, len=%d, buffer=%s\n", (void*)npp,
-                  pstream->url, len, (char*)buffer));
-
-  // negative return indicates failure to the plugin
-  if (!npp)
-    return -1;
-
-  PluginDestructionGuard guard(npp);
-
-  nsNPAPIStreamWrapper* wrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
-  if (!wrapper) {
-    return -1;
-  }
-
-  nsIOutputStream* stream = wrapper->GetOutputStream();
-  if (!stream) {
-    return -1;
-  }
-
-  uint32_t count = 0;
-  nsresult rv = stream->Write((char *)buffer, len, &count);
-
-  if (NS_FAILED(rv)) {
-    return -1;
-  }
-
-  return (int32_t)count;
-}
-
-NPError
-_destroystream(NPP npp, NPStream *pstream, NPError reason)
-{
-  if (!NS_IsMainThread()) {
-    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_destroystream called from the wrong thread\n"));
-    return NPERR_INVALID_PARAM;
-  }
-  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
-                 ("NPN_DestroyStream: npp=%p, url=%s, reason=%d\n", (void*)npp,
-                  pstream->url, (int)reason));
-
-  if (!npp)
-    return NPERR_INVALID_INSTANCE_ERROR;
-
-  PluginDestructionGuard guard(npp);
-
-  nsNPAPIStreamWrapper *streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
-  if (!streamWrapper) {
-    return NPERR_INVALID_PARAM;
-  }
-
-  nsNPAPIPluginStreamListener *listener = streamWrapper->GetStreamListener();
-  if (listener) {
-    // This type of stream is going from the browser to the plugin. It's either the
-    // initial src/data stream or another stream resulting from NPN_GetURL* or
-    // NPN_PostURL*.
-    //
-    // Calling OnStopBinding on the listener may cause it to be deleted due to the
-    // releasing of its last references.
-    listener->OnStopBinding(nullptr, NS_BINDING_ABORTED);
-  } else {
-    // This type of stream (NPStream) was created via NPN_NewStream. The plugin holds
-    // the reference until it is to be deleted here. Deleting the wrapper will
-    // release the wrapped nsIOutputStream.
-    //
-    // The NPStream the plugin references should always be a sub-object of its own
-    // 'ndata', which is our nsNPAPIStramWrapper. See bug 548441.
-    NS_ASSERTION((char*)streamWrapper <= (char*)pstream &&
-                 ((char*)pstream) + sizeof(*pstream)
-                     <= ((char*)streamWrapper) + sizeof(*streamWrapper),
-                 "pstream is not a subobject of wrapper");
-    delete streamWrapper;
-  }
-
-  // 'listener' and/or 'streamWrapper' may be invalid (deleted) at this point. Don't
-  // touch them again!
-
-  return NPERR_NO_ERROR;
-}
-
 void
 _status(NPP npp, const char *message)
 {
   // NPN_Status is no longer supported.
 }
 
 void
 _memfree (void *ptr)
--- a/dom/plugins/base/nsNPAPIPlugin.h
+++ b/dom/plugins/base/nsNPAPIPlugin.h
@@ -266,25 +266,16 @@ NPError
 NPError
 _posturlnotify(NPP npp, const char* relativeURL, const char *target,
                uint32_t len, const char *buf, NPBool file, void* notifyData);
 
 NPError
 _posturl(NPP npp, const char* relativeURL, const char *target, uint32_t len,
             const char *buf, NPBool file);
 
-NPError
-_newstream(NPP npp, NPMIMEType type, const char* window, NPStream** pstream);
-
-int32_t
-_write(NPP npp, NPStream *pstream, int32_t len, void *buffer);
-
-NPError
-_destroystream(NPP npp, NPStream *pstream, NPError reason);
-
 void
 _status(NPP npp, const char *message);
 
 void
 _memfree (void *ptr);
 
 uint32_t
 _memflush(uint32_t size);
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -507,24 +507,16 @@ nsresult nsNPAPIPluginInstance::SetWindo
     ("NPP SetWindow called: this=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d], return=%d\n",
     this, window->x, window->y, window->width, window->height,
     window->clipRect.top, window->clipRect.bottom, window->clipRect.left, window->clipRect.right, error));
   }
   return NS_OK;
 }
 
 nsresult
-nsNPAPIPluginInstance::NewStreamFromPlugin(const char* type, const char* target,
-                                           nsIOutputStream* *result)
-{
-  nsPluginStreamToFile* stream = new nsPluginStreamToFile(target, mOwner);
-  return stream->QueryInterface(kIOutputStreamIID, (void**)result);
-}
-
-nsresult
 nsNPAPIPluginInstance::NewStreamListener(const char* aURL, void* notifyData,
                                          nsNPAPIPluginStreamListener** listener)
 {
   RefPtr<nsNPAPIPluginStreamListener> sl = new nsNPAPIPluginStreamListener(this, notifyData, aURL);
 
   mStreamListeners.AppendElement(sl);
 
   sl.forget(listener);
--- a/dom/plugins/base/nsNPAPIPluginStreamListener.cpp
+++ b/dom/plugins/base/nsNPAPIPluginStreamListener.cpp
@@ -29,108 +29,17 @@ nsNPAPIStreamWrapper::nsNPAPIStreamWrapp
 
 nsNPAPIStreamWrapper::~nsNPAPIStreamWrapper()
 {
   if (mOutputStream) {
     mOutputStream->Close();
   }
 }
 
-NS_IMPL_ISUPPORTS(nsPluginStreamToFile, nsIOutputStream)
-
-nsPluginStreamToFile::nsPluginStreamToFile(const char* target,
-                                           nsIPluginInstanceOwner* owner)
-: mTarget(PL_strdup(target)),
-mOwner(owner)
-{
-  nsresult rv;
-  nsCOMPtr<nsIFile> pluginTmp;
-  rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(pluginTmp));
-  if (NS_FAILED(rv)) return;
-
-  mTempFile = do_QueryInterface(pluginTmp, &rv);
-  if (NS_FAILED(rv)) return;
-
-  // need to create a file with a unique name - use target as the basis
-  rv = mTempFile->AppendNative(nsDependentCString(target));
-  if (NS_FAILED(rv)) return;
-
-  // Yes, make it unique.
-  rv = mTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0700);
-  if (NS_FAILED(rv)) return;
-
-  // create the file
-  rv = NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mTempFile, -1, 00600);
-  if (NS_FAILED(rv))
-    return;
-
-  // construct the URL we'll use later in calls to GetURL()
-  NS_GetURLSpecFromFile(mTempFile, mFileURL);
-
-#ifdef DEBUG
-  printf("File URL = %s\n", mFileURL.get());
-#endif
-}
-
-nsPluginStreamToFile::~nsPluginStreamToFile()
-{
-  // should we be deleting mTempFile here?
-  if (nullptr != mTarget)
-    PL_strfree(mTarget);
-}
-
-NS_IMETHODIMP
-nsPluginStreamToFile::Flush()
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginStreamToFile::Write(const char* aBuf, uint32_t aCount,
-                            uint32_t *aWriteCount)
-{
-  mOutputStream->Write(aBuf, aCount, aWriteCount);
-  mOutputStream->Flush();
-  mOwner->GetURL(mFileURL.get(), mTarget, nullptr, nullptr, 0, false);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginStreamToFile::WriteFrom(nsIInputStream *inStr, uint32_t count,
-                                uint32_t *_retval)
-{
-  NS_NOTREACHED("WriteFrom");
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsPluginStreamToFile::WriteSegments(nsReadSegmentFun reader, void * closure,
-                                    uint32_t count, uint32_t *_retval)
-{
-  NS_NOTREACHED("WriteSegments");
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsPluginStreamToFile::IsNonBlocking(bool *aNonBlocking)
-{
-  *aNonBlocking = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginStreamToFile::Close(void)
-{
-  mOutputStream->Close();
-  mOwner->GetURL(mFileURL.get(), mTarget, nullptr, nullptr, 0, false);
-  return NS_OK;
-}
-
 // nsNPAPIPluginStreamListener Methods
-
 NS_IMPL_ISUPPORTS(nsNPAPIPluginStreamListener,
                   nsITimerCallback, nsIHTTPHeaderListener)
 
 nsNPAPIPluginStreamListener::nsNPAPIPluginStreamListener(nsNPAPIPluginInstance* inst,
                                                          void* notifyData,
                                                          const char* aURL)
   : mStreamBuffer(nullptr)
   , mNotifyURL(aURL ? PL_strdup(aURL) : nullptr)
--- a/dom/plugins/base/nsNPAPIPluginStreamListener.h
+++ b/dom/plugins/base/nsNPAPIPluginStreamListener.h
@@ -35,35 +35,16 @@ public:
   nsNPAPIPluginStreamListener* GetStreamListener() { return mStreamListener; }
 
   NPStream                              mNPStream;
 protected:
   nsCOMPtr<nsIOutputStream>             mOutputStream; // only valid if not browser initiated
   nsNPAPIPluginStreamListener*          mStreamListener; // only valid if browser initiated
 };
 
-// Used to handle NPN_NewStream() - writes the stream as received by the plugin
-// to a file and at completion (NPN_DestroyStream), tells the browser to load it into
-// a plugin-specified target
-class nsPluginStreamToFile : public nsIOutputStream
-{
-public:
-  nsPluginStreamToFile(const char* target, nsIPluginInstanceOwner* owner);
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIOUTPUTSTREAM
-protected:
-  virtual ~nsPluginStreamToFile();
-  char* mTarget;
-  nsCString mFileURL;
-  nsCOMPtr<nsIFile> mTempFile;
-  nsCOMPtr<nsIOutputStream> mOutputStream;
-  nsIPluginInstanceOwner* mOwner;
-};
-
 class nsNPAPIPluginStreamListener : public nsITimerCallback,
                                     public nsIHTTPHeaderListener
 {
 private:
   typedef mozilla::PluginLibrary PluginLibrary;
 
 public:
   NS_DECL_ISUPPORTS
--- a/dom/plugins/ipc/BrowserStreamChild.cpp
+++ b/dom/plugins/ipc/BrowserStreamChild.cpp
@@ -173,26 +173,16 @@ BrowserStreamChild::NPN_RequestRead(NPBy
   }
 
   NPError result;
   CallNPN_RequestRead(ranges, &result);
   return result;
 }
 
 void
-BrowserStreamChild::NPN_DestroyStream(NPReason reason)
-{
-  mStreamStatus = reason;
-  if (ALIVE == mState)
-    SendNPN_DestroyStream(reason);
-
-  EnsureDeliveryPending();
-}
-
-void
 BrowserStreamChild::EnsureDeliveryPending()
 {
   MessageLoop::current()->PostTask(
     mDeliveryTracker.NewRunnableMethod(&BrowserStreamChild::Deliver));
 }
 
 void
 BrowserStreamChild::Deliver()
@@ -270,17 +260,20 @@ BrowserStreamChild::DeliverPendingData()
       mPendingData[0].offset + mPendingData[0].curpos, // offset
       mPendingData[0].data.Length() - mPendingData[0].curpos, // length
       const_cast<char*>(mPendingData[0].data.BeginReading() + mPendingData[0].curpos));
     if (kStreamOpen != mStreamStatus)
       return false;
     if (0 == r)
       return true;
     if (r < 0) { // error condition
-      NPN_DestroyStream(NPRES_NETWORK_ERR);
+      mStreamStatus = NPRES_NETWORK_ERR;
+
+      // Set up stream destruction
+      EnsureDeliveryPending();
       return false;
     }
     mPendingData[0].curpos += r;
   }
   mPendingData.RemoveElementAt(0);
   return false;
 }
 
--- a/dom/plugins/ipc/BrowserStreamChild.h
+++ b/dom/plugins/ipc/BrowserStreamChild.h
@@ -49,17 +49,16 @@ public:
   }
   void EnsureCorrectStream(NPStream* s)
   {
     if (s != &mStream)
       MOZ_CRASH("Incorrect stream data");
   }
 
   NPError NPN_RequestRead(NPByteRange* aRangeList);
-  void NPN_DestroyStream(NPReason reason);
 
   void NotifyPending() {
     NS_ASSERTION(!mNotifyPending, "Pending twice?");
     mNotifyPending = true;
     EnsureDeliveryPending();
   }
 
   /**
@@ -80,17 +79,16 @@ public:
     NS_ASSERTION(DELETING != mState, "InstanceDying didn't work?");
     mStreamStatus = NPRES_USER_BREAK;
     Deliver();
     NS_ASSERTION(!mStreamNotify, "Didn't deliver NPN_URLNotify?");
   }
 
 private:
   friend class StreamNotifyChild;
-  using PBrowserStreamChild::SendNPN_DestroyStream;
 
   /**
    * Post an event to ensure delivery of pending data/destroy/urlnotify events
    * outside of the current RPC stack.
    */
   void EnsureDeliveryPending();
 
   /**
@@ -111,17 +109,17 @@ private:
   PluginInstanceChild* mInstance;
   NPStream mStream;
 
   static const NPReason kStreamOpen = -1;
 
   /**
    * The plugin's notion of whether a stream has been "closed" (no more
    * data delivery) differs from the plugin host due to asynchronous delivery
-   * of data and NPN_DestroyStream. While the plugin-visible stream is open,
+   * of data and stream destruction. While the plugin-visible stream is open,
    * mStreamStatus should be kStreamOpen (-1). mStreamStatus will be a
    * failure code if either the parent or child indicates stream failure.
    */
   NPReason mStreamStatus;
 
   /**
    * Delivery of NPP_DestroyStream and NPP_URLNotify must be postponed until
    * all data has been delivered.
--- a/dom/plugins/ipc/BrowserStreamParent.cpp
+++ b/dom/plugins/ipc/BrowserStreamParent.cpp
@@ -80,35 +80,16 @@ BrowserStreamParent::AnswerNPN_RequestRe
     rp[i].next = &rp[i + 1];
   }
   rp[ranges.Length() - 1].next = nullptr;
 
   *result = mNPP->mNPNIface->requestread(mStream, rp.get());
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult
-BrowserStreamParent::RecvNPN_DestroyStream(const NPReason& reason)
-{
-  switch (mState) {
-  case ALIVE:
-    break;
-
-  case DYING:
-    return IPC_OK();
-
-  default:
-    NS_ERROR("Unexpected state");
-    return IPC_FAIL_NO_REASON(this);
-  }
-
-  mNPP->mNPNIface->destroystream(mNPP->mNPP, mStream, reason);
-  return IPC_OK();
-}
-
 void
 BrowserStreamParent::NPP_DestroyStream(NPReason reason)
 {
   NS_ASSERTION(ALIVE == mState || INITIALIZING == mState,
                "NPP_DestroyStream called twice?");
   bool stillInitializing = INITIALIZING == mState;
   if (stillInitializing) {
     mState = DEFERRING_DESTROY;
--- a/dom/plugins/ipc/BrowserStreamParent.h
+++ b/dom/plugins/ipc/BrowserStreamParent.h
@@ -28,18 +28,16 @@ public:
 
   virtual bool IsBrowserStream() override { return true; }
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual mozilla::ipc::IPCResult AnswerNPN_RequestRead(const IPCByteRanges& ranges,
                                                         NPError* result) override;
 
-  virtual mozilla::ipc::IPCResult RecvNPN_DestroyStream(const NPReason& reason) override;
-
   virtual mozilla::ipc::IPCResult RecvStreamDestroyed() override;
 
   int32_t WriteReady();
   int32_t Write(int32_t offset, int32_t len, void* buffer);
   void StreamAsFile(const char* fname);
 
   void NPP_DestroyStream(NPReason reason);
 
--- a/dom/plugins/ipc/PBrowserStream.ipdl
+++ b/dom/plugins/ipc/PBrowserStream.ipdl
@@ -33,17 +33,16 @@ child:
    * the message with StreamDestroyed before this actor is deleted.
    */
   async NPP_DestroyStream(NPReason reason);
   async __delete__();
 
 parent:
   intr NPN_RequestRead(IPCByteRanges ranges)
     returns (NPError result);
-  async NPN_DestroyStream(NPReason reason);
   async StreamDestroyed();
 
 /*
   TODO: turn on state machine.
 
   // need configurable start state: if the constructor
   // returns an error in result, start state should
   // be DELETING.
--- a/dom/plugins/ipc/PPluginInstance.ipdl
+++ b/dom/plugins/ipc/PPluginInstance.ipdl
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PPluginBackgroundDestroyer;
 include protocol PPluginModule;
 include protocol PPluginScriptableObject;
 include protocol PBrowserStream;
-include protocol PPluginStream;
 include protocol PStreamNotify;
 include protocol PPluginSurface;
 
 include "mozilla/GfxMessageUtils.h";
 include "mozilla/layers/LayersMessageUtils.h";
 
 using NPError from "npapi.h";
 using struct mozilla::plugins::NPRemoteWindow from "mozilla/plugins/PluginMessageUtils.h";
@@ -63,17 +62,16 @@ union OptionalShmem {
 
 intr protocol PPluginInstance
 {
   manager PPluginModule;
 
   manages PPluginBackgroundDestroyer;
   manages PPluginScriptableObject;
   manages PBrowserStream;
-  manages PPluginStream;
   manages PStreamNotify;
   manages PPluginSurface;
 
 child:
   intr __delete__();
 
   // This is only used on Windows and, for windowed plugins, must be called
   // before the first call to NPP_SetWindow.
@@ -286,22 +284,16 @@ child:
 
   // Implements the legacy (synchronous) version of NPP_NewStream for when
   // async plugin init is preffed off.
   intr NPP_NewStream(PBrowserStream actor, nsCString mimeType, bool seekable)
     returns (NPError rv,
              uint16_t stype);
 
 parent:
-  /* NPN_NewStream */
-  intr PPluginStream(nsCString mimeType,
-                    nsCString target)
-    returns (NPError result);
-
-parent:
   intr PluginFocusChange(bool gotFocus);
 
 child:
   intr SetPluginFocus();
   intr UpdateWindow();
 
   async PPluginBackgroundDestroyer();
 };
deleted file mode 100644
--- a/dom/plugins/ipc/PPluginStream.ipdl
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
-/* 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 protocol PPluginInstance;
-
-
-using mozilla::plugins::Buffer from "mozilla/plugins/PluginMessageUtils.h";
-using NPError from "npapi.h";
-using NPReason from "npapi.h";
-
-namespace mozilla {
-namespace plugins {
-
-/**
- * PPluginStream represents an NPStream sent from the plugin to the browser.
- */
-
-intr protocol PPluginStream
-{
-  manager PPluginInstance;
-
-parent:
-  intr NPN_Write(Buffer data) returns (int32_t written);
-
-both:
-  /**
-   * ~PPluginStream is for both NPN_DestroyStream and NPP_DestroyStream.
-   * @param artificial True when the stream is closed as a by-product of
-   *                        some other call (such as a failure in NPN_Write).
-   */
-  intr __delete__(NPReason reason, bool artificial);
-};
-
-} // namespace plugins
-} // namespace mozilla
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -3,17 +3,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PluginBackgroundDestroyer.h"
 #include "PluginInstanceChild.h"
 #include "PluginModuleChild.h"
 #include "BrowserStreamChild.h"
-#include "PluginStreamChild.h"
 #include "StreamNotifyChild.h"
 #include "PluginProcessChild.h"
 #include "gfxASurface.h"
 #include "gfxPlatform.h"
 #include "gfx2DGlue.h"
 #include "nsNPAPIPluginInstance.h"
 #include "mozilla/gfx/2D.h"
 #ifdef MOZ_X11
@@ -2524,32 +2523,16 @@ PluginInstanceChild::AllocPBrowserStream
 bool
 PluginInstanceChild::DeallocPBrowserStreamChild(PBrowserStreamChild* stream)
 {
     AssertPluginThread();
     delete stream;
     return true;
 }
 
-PPluginStreamChild*
-PluginInstanceChild::AllocPPluginStreamChild(const nsCString& mimeType,
-                                             const nsCString& target,
-                                             NPError* result)
-{
-    MOZ_CRASH("not callable");
-    return nullptr;
-}
-
-bool
-PluginInstanceChild::DeallocPPluginStreamChild(PPluginStreamChild* stream)
-{
-    AssertPluginThread();
-    delete stream;
-    return true;
-}
 
 PStreamNotifyChild*
 PluginInstanceChild::AllocPStreamNotifyChild(const nsCString& url,
                                              const nsCString& target,
                                              const bool& post,
                                              const nsCString& buffer,
                                              const bool& file,
                                              NPError* result)
@@ -2655,38 +2638,16 @@ PluginInstanceChild::GetActorForNPObject
         NS_ERROR("Failed to send constructor message!");
         return nullptr;
     }
 
     actor->InitializeLocal(aObject);
     return actor;
 }
 
-NPError
-PluginInstanceChild::NPN_NewStream(NPMIMEType aMIMEType, const char* aWindow,
-                                   NPStream** aStream)
-{
-    AssertPluginThread();
-    AutoStackHelper guard(this);
-
-    auto* ps = new PluginStreamChild();
-
-    NPError result;
-    CallPPluginStreamConstructor(ps, nsDependentCString(aMIMEType),
-                                 NullableString(aWindow), &result);
-    if (NPERR_NO_ERROR != result) {
-        *aStream = nullptr;
-        PPluginStreamChild::Call__delete__(ps, NPERR_GENERIC_ERROR, true);
-        return result;
-    }
-
-    *aStream = &ps->mStream;
-    return NPERR_NO_ERROR;
-}
-
 void
 PluginInstanceChild::NPN_URLRedirectResponse(void* notifyData, NPBool allow)
 {
     if (!notifyData) {
         return;
     }
 
     InfallibleTArray<PStreamNotifyChild*> notifyStreams;
--- a/dom/plugins/ipc/PluginInstanceChild.h
+++ b/dom/plugins/ipc/PluginInstanceChild.h
@@ -170,24 +170,16 @@ protected:
                              const uint32_t& length,
                              const uint32_t& lastmodified,
                              PStreamNotifyChild* notifyData,
                              const nsCString& headers) override;
 
     virtual bool
     DeallocPBrowserStreamChild(PBrowserStreamChild* stream) override;
 
-    virtual PPluginStreamChild*
-    AllocPPluginStreamChild(const nsCString& mimeType,
-                            const nsCString& target,
-                            NPError* result) override;
-
-    virtual bool
-    DeallocPPluginStreamChild(PPluginStreamChild* stream) override;
-
     virtual PStreamNotifyChild*
     AllocPStreamNotifyChild(const nsCString& url, const nsCString& target,
                             const bool& post, const nsCString& buffer,
                             const bool& file,
                             NPError* result) override;
 
     virtual bool
     DeallocPStreamNotifyChild(PStreamNotifyChild* notifyData) override;
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -9,17 +9,16 @@
 
 #include "mozilla/BasicEvents.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "PluginInstanceParent.h"
 #include "BrowserStreamParent.h"
 #include "PluginBackgroundDestroyer.h"
 #include "PluginModuleParent.h"
-#include "PluginStreamParent.h"
 #include "StreamNotifyParent.h"
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxSharedImageSurface.h"
 #include "nsNetUtil.h"
@@ -236,30 +235,16 @@ PluginInstanceParent::AllocPBrowserStrea
 
 bool
 PluginInstanceParent::DeallocPBrowserStreamParent(PBrowserStreamParent* stream)
 {
     delete stream;
     return true;
 }
 
-PPluginStreamParent*
-PluginInstanceParent::AllocPPluginStreamParent(const nsCString& mimeType,
-                                               const nsCString& target,
-                                               NPError* result)
-{
-    return new PluginStreamParent(this, mimeType, target, result);
-}
-
-bool
-PluginInstanceParent::DeallocPPluginStreamParent(PPluginStreamParent* stream)
-{
-    delete stream;
-    return true;
-}
 
 mozilla::ipc::IPCResult
 PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle* value,
                                                             NPError* result)
 {
 #ifdef XP_WIN
     HWND id;
 #elif defined(MOZ_X11)
@@ -1785,34 +1770,23 @@ PluginInstanceParent::NPP_DestroyStream(
 
     AStream* s = static_cast<AStream*>(stream->pdata);
     if (!s) {
         // The stream has already been deleted by other means.
         // With async plugin init this could happen if async NPP_NewStream
         // returns an error code.
         return NPERR_NO_ERROR;
     }
-    if (s->IsBrowserStream()) {
-        BrowserStreamParent* sp =
-            static_cast<BrowserStreamParent*>(s);
-        if (sp->mNPP != this)
-            MOZ_CRASH("Mismatched plugin data");
-
-        sp->NPP_DestroyStream(reason);
-        return NPERR_NO_ERROR;
-    }
-    else {
-        PluginStreamParent* sp =
-            static_cast<PluginStreamParent*>(s);
-        if (sp->mInstance != this)
-            MOZ_CRASH("Mismatched plugin data");
-
-        return PPluginStreamParent::Call__delete__(sp, reason, false) ?
-            NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
-    }
+    MOZ_ASSERT(s->IsBrowserStream());
+    BrowserStreamParent* sp =
+        static_cast<BrowserStreamParent*>(s);
+    if (sp->mNPP != this)
+        MOZ_CRASH("Mismatched plugin data");
+    sp->NPP_DestroyStream(reason);
+    return NPERR_NO_ERROR;
 }
 
 void
 PluginInstanceParent::NPP_Print(NPPrint* platformPrint)
 {
     // TODO: implement me
     NS_ERROR("Not implemented");
 }
--- a/dom/plugins/ipc/PluginInstanceParent.h
+++ b/dom/plugins/ipc/PluginInstanceParent.h
@@ -40,17 +40,16 @@ namespace plugins {
 class PBrowserStreamParent;
 class PluginModuleParent;
 class D3D11SurfaceHolder;
 
 class PluginInstanceParent : public PPluginInstanceParent
 {
     friend class PluginModuleParent;
     friend class BrowserStreamParent;
-    friend class PluginStreamParent;
     friend class StreamNotifyParent;
 
 #if defined(XP_WIN)
 public:
     /**
      * Helper method for looking up instances based on a supplied id.
      */
     static PluginInstanceParent*
@@ -85,23 +84,16 @@ public:
     AllocPBrowserStreamParent(const nsCString& url,
                               const uint32_t& length,
                               const uint32_t& lastmodified,
                               PStreamNotifyParent* notifyData,
                               const nsCString& headers) override;
     virtual bool
     DeallocPBrowserStreamParent(PBrowserStreamParent* stream) override;
 
-    virtual PPluginStreamParent*
-    AllocPPluginStreamParent(const nsCString& mimeType,
-                             const nsCString& target,
-                             NPError* result) override;
-    virtual bool
-    DeallocPPluginStreamParent(PPluginStreamParent* stream) override;
-
     virtual mozilla::ipc::IPCResult
     AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle* value,
                                           NPError* result) override;
     virtual mozilla::ipc::IPCResult
     AnswerNPN_GetValue_NPNVWindowNPObject(
                                        PPluginScriptableObjectParent** value,
                                        NPError* result) override;
     virtual mozilla::ipc::IPCResult
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -26,17 +26,16 @@
 #ifdef MOZ_X11
 # include "nsX11ErrorHandler.h"
 # include "mozilla/X11Util.h"
 #endif
 #include "mozilla/ipc/ProcessChild.h"
 #include "mozilla/plugins/PluginInstanceChild.h"
 #include "mozilla/plugins/StreamNotifyChild.h"
 #include "mozilla/plugins/BrowserStreamChild.h"
-#include "mozilla/plugins/PluginStreamChild.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Unused.h"
 
 #include "nsNPAPIPlugin.h"
 
 #ifdef XP_WIN
 #include "nsWindowsDllInterceptor.h"
 #include "mozilla/widget/AudioSession.h"
@@ -836,25 +835,16 @@ static NPError
 static NPError
 _posturlnotify(NPP aNPP, const char* relativeURL, const char *target,
                uint32_t len, const char *buf, NPBool file, void* notifyData);
 
 static NPError
 _posturl(NPP aNPP, const char* relativeURL, const char *target, uint32_t len,
          const char *buf, NPBool file);
 
-static NPError
-_newstream(NPP aNPP, NPMIMEType type, const char* window, NPStream** pstream);
-
-static int32_t
-_write(NPP aNPP, NPStream *pstream, int32_t len, void *buffer);
-
-static NPError
-_destroystream(NPP aNPP, NPStream *pstream, NPError reason);
-
 static void
 _status(NPP aNPP, const char *message);
 
 static void
 _memfree (void *ptr);
 
 static uint32_t
 _memflush(uint32_t size);
@@ -979,19 +969,19 @@ static void
 } /* namespace mozilla */
 
 const NPNetscapeFuncs PluginModuleChild::sBrowserFuncs = {
     sizeof(sBrowserFuncs),
     (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
     mozilla::plugins::child::_geturl,
     mozilla::plugins::child::_posturl,
     mozilla::plugins::child::_requestread,
-    mozilla::plugins::child::_newstream,
-    mozilla::plugins::child::_write,
-    mozilla::plugins::child::_destroystream,
+    nullptr,
+    nullptr,
+    nullptr,
     mozilla::plugins::child::_status,
     mozilla::plugins::child::_useragent,
     mozilla::plugins::child::_memalloc,
     mozilla::plugins::child::_memfree,
     mozilla::plugins::child::_memflush,
     mozilla::plugins::child::_reloadplugins,
     mozilla::plugins::child::_getjavaenv,
     mozilla::plugins::child::_getjavapeer,
@@ -1232,65 +1222,16 @@ NPError
     // FIXME what should happen when |aBuffer| is null?
     InstCast(aNPP)->CallNPN_PostURL(NullableString(aRelativeURL),
                                     NullableString(aTarget),
                                     nsDependentCString(aBuffer, aLength),
                                     aIsFile, &err);
     return err;
 }
 
-NPError
-_newstream(NPP aNPP,
-           NPMIMEType aMIMEType,
-           const char* aWindow,
-           NPStream** aStream)
-{
-    PLUGIN_LOG_DEBUG_FUNCTION;
-    ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
-    return InstCast(aNPP)->NPN_NewStream(aMIMEType, aWindow, aStream);
-}
-
-int32_t
-_write(NPP aNPP,
-       NPStream* aStream,
-       int32_t aLength,
-       void* aBuffer)
-{
-    PLUGIN_LOG_DEBUG_FUNCTION;
-    ENSURE_PLUGIN_THREAD(0);
-
-    PluginStreamChild* ps =
-        static_cast<PluginStreamChild*>(static_cast<AStream*>(aStream->ndata));
-    ps->EnsureCorrectInstance(InstCast(aNPP));
-    ps->EnsureCorrectStream(aStream);
-    return ps->NPN_Write(aLength, aBuffer);
-}
-
-NPError
-_destroystream(NPP aNPP,
-               NPStream* aStream,
-               NPError aReason)
-{
-    PLUGIN_LOG_DEBUG_FUNCTION;
-    ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
-
-    PluginInstanceChild* p = InstCast(aNPP);
-    AStream* s = static_cast<AStream*>(aStream->ndata);
-    if (s->IsBrowserStream()) {
-        BrowserStreamChild* bs = static_cast<BrowserStreamChild*>(s);
-        bs->EnsureCorrectInstance(p);
-        bs->NPN_DestroyStream(aReason);
-    }
-    else {
-        PluginStreamChild* ps = static_cast<PluginStreamChild*>(s);
-        ps->EnsureCorrectInstance(p);
-        PPluginStreamChild::Call__delete__(ps, aReason, false);
-    }
-    return NPERR_NO_ERROR;
-}
 
 void
 _status(NPP aNPP,
         const char* aMessage)
 {
     // NPN_Status is no longer supported.
 }
 
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -944,21 +944,16 @@ PluginModuleChromeParent::GetManagingIns
                 static_cast<PPluginScriptableObjectParent*>(aProtocol);
             return static_cast<PluginInstanceParent*>(actor->Manager());
         }
         case PBrowserStreamMsgStart: {
             PBrowserStreamParent* actor =
                 static_cast<PBrowserStreamParent*>(aProtocol);
             return static_cast<PluginInstanceParent*>(actor->Manager());
         }
-        case PPluginStreamMsgStart: {
-            PPluginStreamParent* actor =
-                static_cast<PPluginStreamParent*>(aProtocol);
-            return static_cast<PluginInstanceParent*>(actor->Manager());
-        }
         case PStreamNotifyMsgStart: {
             PStreamNotifyParent* actor =
                 static_cast<PStreamNotifyParent*>(aProtocol);
             return static_cast<PluginInstanceParent*>(actor->Manager());
         }
 #ifdef XP_WIN
         case PPluginSurfaceMsgStart: {
             PPluginSurfaceParent* actor =
deleted file mode 100644
--- a/dom/plugins/ipc/PluginStreamChild.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
-/* 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 "PluginStreamChild.h"
-#include "mozilla/plugins/PluginInstanceChild.h"
-
-namespace mozilla {
-namespace plugins {
-
-PluginStreamChild::PluginStreamChild()
-  : mClosed(false)
-{
-  memset(&mStream, 0, sizeof(mStream));
-  mStream.ndata = static_cast<AStream*>(this);
-}
-
-mozilla::ipc::IPCResult
-PluginStreamChild::Answer__delete__(const NPReason& reason,
-                                    const bool& artificial)
-{
-  AssertPluginThread();
-  if (!artificial)
-    NPP_DestroyStream(reason);
-  return IPC_OK();
-}
-
-int32_t
-PluginStreamChild::NPN_Write(int32_t length, void* buffer)
-{
-  AssertPluginThread();
-
-  int32_t written = 0;
-  CallNPN_Write(nsCString(static_cast<char*>(buffer), length),
-                &written);
-  if (written < 0)
-    PPluginStreamChild::Call__delete__(this, NPERR_GENERIC_ERROR, true);
-  // careful after here! |this| just got deleted
-
-  return written;
-}
-
-void
-PluginStreamChild::NPP_DestroyStream(NPError reason)
-{
-  AssertPluginThread();
-
-  if (mClosed)
-    return;
-
-  mClosed = true;
-  Instance()->mPluginIface->destroystream(
-    &Instance()->mData, &mStream, reason);
-}
-
-PluginInstanceChild*
-PluginStreamChild::Instance()
-{
-  return static_cast<PluginInstanceChild*>(Manager());
-}
-
-} // namespace plugins
-} // namespace mozilla
deleted file mode 100644
--- a/dom/plugins/ipc/PluginStreamChild.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_plugins_PluginStreamChild_h
-#define mozilla_plugins_PluginStreamChild_h
-
-#include "mozilla/plugins/PPluginStreamChild.h"
-#include "mozilla/plugins/AStream.h"
-
-namespace mozilla {
-namespace plugins {
-
-class PluginInstanceChild;
-
-class PluginStreamChild : public PPluginStreamChild, public AStream
-{
-  friend class PluginInstanceChild;
-
-public:
-  PluginStreamChild();
-  virtual ~PluginStreamChild() { }
-
-  virtual bool IsBrowserStream() override { return false; }
-
-  virtual mozilla::ipc::IPCResult Answer__delete__(const NPReason& reason,
-                                                   const bool& artificial) override;
-
-  int32_t NPN_Write(int32_t length, void* buffer);
-  void NPP_DestroyStream(NPError reason);
-
-  void EnsureCorrectInstance(PluginInstanceChild* i)
-  {
-    if (i != Instance())
-      MOZ_CRASH("Incorrect stream instance");
-  }
-  void EnsureCorrectStream(NPStream* s)
-  {
-    if (s != &mStream)
-      MOZ_CRASH("Incorrect stream data");
-  }
-
-private:
-  PluginInstanceChild* Instance();
-
-  NPStream mStream;
-  bool mClosed;
-};
-
-
-} // namespace plugins
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/plugins/ipc/PluginStreamParent.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
-/* 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 "PluginStreamParent.h"
-#include "PluginInstanceParent.h"
-
-namespace mozilla {
-namespace plugins {
-
-PluginStreamParent::PluginStreamParent(PluginInstanceParent* npp,
-                                       const nsCString& mimeType,
-                                       const nsCString& target,
-                                       NPError* result)
-  : mInstance(npp)
-  , mClosed(false)
-{
-  *result = mInstance->mNPNIface->newstream(mInstance->mNPP,
-                                            const_cast<char*>(mimeType.get()),
-                                            NullableStringGet(target),
-                                            &mStream);
-  if (*result == NPERR_NO_ERROR)
-    mStream->pdata = static_cast<AStream*>(this);
-  else
-    mStream = nullptr;
-}
-
-void
-PluginStreamParent::ActorDestroy(ActorDestroyReason aWhy)
-{
-  // Implement me! Bug 1005166
-}
-
-mozilla::ipc::IPCResult
-PluginStreamParent::AnswerNPN_Write(const Buffer& data, int32_t* written)
-{
-  if (mClosed) {
-    *written = -1;
-    return IPC_OK();
-  }
-
-  *written = mInstance->mNPNIface->write(mInstance->mNPP, mStream,
-                                         data.Length(),
-                                         const_cast<char*>(data.get()));
-  if (*written < 0)
-    mClosed = true;
-
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-PluginStreamParent::Answer__delete__(const NPError& reason,
-                                     const bool& artificial)
-{
-  if (!artificial)
-    this->NPN_DestroyStream(reason);
-  return IPC_OK();
-}
-
-void
-PluginStreamParent::NPN_DestroyStream(NPReason reason)
-{
-  if (mClosed)
-    return;
-
-  mInstance->mNPNIface->destroystream(mInstance->mNPP, mStream, reason);
-  mClosed = true;
-}
-
-} // namespace plugins
-} // namespace mozilla
deleted file mode 100644
--- a/dom/plugins/ipc/PluginStreamParent.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_plugins_PluginStreamParent_h
-#define mozilla_plugins_PluginStreamParent_h
-
-#include "mozilla/plugins/PPluginStreamParent.h"
-#include "mozilla/plugins/AStream.h"
-
-namespace mozilla {
-namespace plugins {
-
-class PluginInstanceParent;
-
-class PluginStreamParent : public PPluginStreamParent, public AStream
-{
-  friend class PluginModuleParent;
-  friend class PluginInstanceParent;
-
-public:
-  PluginStreamParent(PluginInstanceParent* npp, const nsCString& mimeType,
-                     const nsCString& target, NPError* result);
-  virtual ~PluginStreamParent() { }
-
-  virtual bool IsBrowserStream() override { return false; }
-
-  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
-
-  virtual mozilla::ipc::IPCResult AnswerNPN_Write(const Buffer& data, int32_t* written) override;
-
-  virtual mozilla::ipc::IPCResult Answer__delete__(const NPError& reason, const bool& artificial) override;
-
-private:
-  void NPN_DestroyStream(NPReason reason);
-
-  PluginInstanceParent* mInstance;
-  NPStream* mStream;
-  bool mClosed;
-};
-
-} // namespace plugins
-} // namespace mozilla
-
-#endif
--- a/dom/plugins/ipc/moz.build
+++ b/dom/plugins/ipc/moz.build
@@ -29,18 +29,16 @@ EXPORTS.mozilla.plugins += [
     'PluginModuleParent.h',
     'PluginProcessChild.h',
     'PluginProcessParent.h',
     'PluginQuirks.h',
     'PluginScriptableObjectChild.h',
     'PluginScriptableObjectParent.h',
     'PluginScriptableObjectUtils-inl.h',
     'PluginScriptableObjectUtils.h',
-    'PluginStreamChild.h',
-    'PluginStreamParent.h',
     'PluginUtilsOSX.h',
     'StreamNotifyChild.h',
     'StreamNotifyParent.h',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS.mozilla.plugins += [
         'PluginSurfaceParent.h',
@@ -72,18 +70,16 @@ UNIFIED_SOURCES += [
     'PluginInstanceParent.cpp',
     'PluginMessageUtils.cpp',
     'PluginModuleParent.cpp',
     'PluginProcessChild.cpp',
     'PluginProcessParent.cpp',
     'PluginQuirks.cpp',
     'PluginScriptableObjectChild.cpp',
     'PluginScriptableObjectParent.cpp',
-    'PluginStreamChild.cpp',
-    'PluginStreamParent.cpp',
 ]
 
 SOURCES += [
     'PluginInstanceChild.cpp', # 'PluginThreadCallback' : ambiguous symbol
     'PluginModuleChild.cpp',   # Redefinition of mozilla::WindowsDllInterceptor sUser32Intercept
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
@@ -108,17 +104,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
 
 IPDL_SOURCES += [
     'PBrowserStream.ipdl',
     'PluginTypes.ipdlh',
     'PPluginBackgroundDestroyer.ipdl',
     'PPluginInstance.ipdl',
     'PPluginModule.ipdl',
     'PPluginScriptableObject.ipdl',
-    'PPluginStream.ipdl',
     'PPluginSurface.ipdl',
     'PStreamNotify.ipdl',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
--- a/dom/plugins/test/testplugin/nptest.cpp
+++ b/dom/plugins/test/testplugin/nptest.cpp
@@ -473,78 +473,43 @@ static void sendBufferToFrame(NPP instan
   }
   else if (bufsize > 0) {
     outbuf.append(buf);
   }
   else {
     outbuf.append("Error: no data in buffer");
   }
 
-  if (instanceData->npnNewStream &&
-      instanceData->err.str().length() == 0) {
-    char typeHTML[] = "text/html";
-    NPStream* stream;
-    printf("calling NPN_NewStream...");
-    NPError err = NPN_NewStream(instance, typeHTML,
-        instanceData->frame.c_str(), &stream);
-    printf("return value %d\n", err);
-    if (err != NPERR_NO_ERROR) {
-      instanceData->err << "NPN_NewStream returned " << err;
-      return;
+  // Convert CRLF to LF, and escape most other non-alphanumeric chars.
+  for (size_t i = 0; i < outbuf.length(); i++) {
+    if (outbuf[i] == '\n') {
+      outbuf.replace(i, 1, "%0a");
+      i += 2;
+    }
+    else if (outbuf[i] == '\r') {
+      outbuf.replace(i, 1, "");
+      i -= 1;
     }
-
-    int32_t bytesToWrite = outbuf.length();
-    int32_t bytesWritten = 0;
-    while ((bytesToWrite - bytesWritten) > 0) {
-      int32_t numBytes = (bytesToWrite - bytesWritten) <
-          instanceData->streamChunkSize ?
-          bytesToWrite - bytesWritten : instanceData->streamChunkSize;
-      int32_t written = NPN_Write(instance, stream,
-          numBytes, (void*)(outbuf.c_str() + bytesWritten));
-      if (written <= 0) {
-        instanceData->err << "NPN_Write returned " << written;
-        break;
+    else {
+      int ascii = outbuf[i];
+      if (!((ascii >= ',' && ascii <= ';') ||
+            (ascii >= 'A' && ascii <= 'Z') ||
+            (ascii >= 'a' && ascii <= 'z'))) {
+        char hex[10];
+        sprintf(hex, "%%%x", ascii);
+        outbuf.replace(i, 1, hex);
+        i += 2;
       }
-      bytesWritten += numBytes;
-      printf("%d bytes written, total %d\n", written, bytesWritten);
-    }
-    err = NPN_DestroyStream(instance, stream, NPRES_DONE);
-    if (err != NPERR_NO_ERROR) {
-      instanceData->err << "NPN_DestroyStream returned " << err;
     }
   }
-  else {
-    // Convert CRLF to LF, and escape most other non-alphanumeric chars.
-    for (size_t i = 0; i < outbuf.length(); i++) {
-      if (outbuf[i] == '\n') {
-        outbuf.replace(i, 1, "%0a");
-        i += 2;
-      }
-      else if (outbuf[i] == '\r') {
-        outbuf.replace(i, 1, "");
-        i -= 1;
-      }
-      else {
-        int ascii = outbuf[i];
-        if (!((ascii >= ',' && ascii <= ';') ||
-              (ascii >= 'A' && ascii <= 'Z') ||
-              (ascii >= 'a' && ascii <= 'z'))) {
-          char hex[10];
-          sprintf(hex, "%%%x", ascii);
-          outbuf.replace(i, 1, hex);
-          i += 2;
-        }
-      }
-    }
-
-    NPError err = NPN_GetURL(instance, outbuf.c_str(),
-                             instanceData->frame.c_str());
-    if (err != NPERR_NO_ERROR) {
-      instanceData->err << "NPN_GetURL returned " << err;
-    }
+
+  NPError err = NPN_GetURL(instance, outbuf.c_str(),
+                           instanceData->frame.c_str());
+  if (err != NPERR_NO_ERROR) {
+    instanceData->err << "NPN_GetURL returned " << err;
   }
 }
 
 static void XPSleep(unsigned int seconds)
 {
 #ifdef XP_WIN
   Sleep(1000 * seconds);
 #else
@@ -847,17 +812,16 @@ NPP_New(NPMIMEType pluginType, NPP insta
   memset(&instanceData->window, 0, sizeof(instanceData->window));
   instanceData->crashOnDestroy = false;
   instanceData->cleanupWidget = true; // only used by nptest_gtk
   instanceData->topLevelWindowActivationState = ACTIVATION_STATE_UNKNOWN;
   instanceData->topLevelWindowActivationEventCount = 0;
   instanceData->focusState = ACTIVATION_STATE_UNKNOWN;
   instanceData->focusEventCount = 0;
   instanceData->eventModel = 0;
-  instanceData->closeStream = false;
   instanceData->wantsAllStreams = false;
   instanceData->mouseUpEventCount = 0;
   instanceData->bugMode = -1;
   instanceData->asyncDrawing = AD_NONE;
   instanceData->frontBuffer = nullptr;
   instanceData->backBuffer = nullptr;
   instanceData->placeholderWnd = nullptr;
   instanceData->cssZoomFactor = 1.0;
@@ -979,19 +943,16 @@ NPP_New(NPMIMEType pluginType, NPP insta
     // "cleanupwidget" is only used with nptest_gtk, defaulting to true.  It
     // indicates whether the plugin should destroy its window in response to
     // NPP_Destroy (or let the platform destroy the widget when the parent
     // window gets destroyed).
     if (strcmp(argn[i], "cleanupwidget") == 0 &&
         strcmp(argv[i], "false") == 0) {
       instanceData->cleanupWidget = false;
     }
-    if (!strcmp(argn[i], "closestream")) {
-      instanceData->closeStream = true;
-    }
     if (strcmp(argn[i], "bugmode") == 0) {
       instanceData->bugMode = atoi(argv[i]);
     }
     // Try to emulate java's codebase handling: Use the last seen codebase
     // value, regardless of whether it is in attributes or params.
     if (strcasecmp(argn[i], "codebase") == 0) {
       instanceData->javaCodebase = argv[i];
     }
@@ -1413,25 +1374,17 @@ NPP_Write(NPP instance, NPStream* stream
 
   if (nd && nd != &kNotifyData) {
     uint32_t newsize = nd->size + len;
     nd->data = (char*) realloc(nd->data, newsize);
     memcpy(nd->data + nd->size, buffer, len);
     nd->size = newsize;
     return len;
   }
-
-  if (instanceData->closeStream) {
-    instanceData->closeStream = false;
-    if (instanceData->testrange != nullptr) {
-      NPN_RequestRead(stream, instanceData->testrange);
-    }
-    NPN_DestroyStream(instance, stream, NPRES_USER_BREAK);
-  }
-  else if (instanceData->streamMode == NP_SEEK &&
+  if (instanceData->streamMode == NP_SEEK &&
       stream->end != 0 &&
       stream->end == ((uint32_t)instanceData->streamBufSize + len)) {
     // If the complete stream has been written, and we're doing a seek test,
     // then call NPN_RequestRead.
     // prevent recursion
     instanceData->streamMode = NP_NORMAL;
 
     if (instanceData->testrange != nullptr) {
@@ -1448,31 +1401,23 @@ NPP_Write(NPP instance, NPStream* stream
     if (memcmp(buffer, streamBuf + offset, len)) {
       instanceData->err <<
           "Error: data written from NPN_RequestRead doesn't match";
     }
     else {
       printf("data matches!\n");
     }
     TestRange* range = instanceData->testrange;
-    bool stillwaiting = false;
     while(range != nullptr) {
       if (offset == range->offset &&
         (uint32_t)len == range->length) {
         range->waiting = false;
       }
-      if (range->waiting) stillwaiting = true;
       range = reinterpret_cast<TestRange*>(range->next);
     }
-    if (!stillwaiting) {
-      NPError err = NPN_DestroyStream(instance, stream, NPRES_DONE);
-      if (err != NPERR_NO_ERROR) {
-        instanceData->err << "Error: NPN_DestroyStream returned " << err;
-      }
-    }
   }
   else {
     if (instanceData->streamBufSize == 0) {
       instanceData->streamBuf = malloc(len + 1);
       streamBuf = reinterpret_cast<char *>(instanceData->streamBuf);
     }
     else {
       instanceData->streamBuf =
@@ -1904,39 +1849,17 @@ NPN_PostURLNotify(NPP instance, const ch
 NPError
 NPN_PostURL(NPP instance, const char *url,
                     const char *target, uint32_t len,
                     const char *buf, NPBool file)
 {
   return sBrowserFuncs->posturl(instance, url, target, len, buf, file);
 }
 
-NPError
-NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
-{
-  return sBrowserFuncs->destroystream(instance, stream, reason);
-}
-
-NPError
-NPN_NewStream(NPP instance,
-              NPMIMEType  type,
-              const char* target,
-              NPStream**  stream)
-{
-  return sBrowserFuncs->newstream(instance, type, target, stream);
-}
-
-int32_t
-NPN_Write(NPP instance,
-          NPStream* stream,
-          int32_t len,
-          void* buf)
-{
-  return sBrowserFuncs->write(instance, stream, len, buf);
-}
+
 
 bool
 NPN_Enumerate(NPP instance,
               NPObject *npobj,
               NPIdentifier **identifiers,
               uint32_t *identifierCount)
 {
   return sBrowserFuncs->enumerate(instance, npobj, identifiers,
--- a/dom/quota/test/browser_permissionsPromptUnknown.js
+++ b/dom/quota/test/browser_permissionsPromptUnknown.js
@@ -29,10 +29,11 @@ add_task(async function testPermissionUn
   await waitForMessage(false, win.gBrowser);
 
   is(getPermission(testPageURL, "persistent-storage"),
      Components.interfaces.nsIPermissionManager.UNKNOWN_ACTION,
      "Correct permission set");
   unregisterAllPopupEventHandlers(win);
   win.gBrowser.removeCurrentTab();
   await BrowserTestUtils.closeWindow(win);
+  win = null;
   removePermission(testPageURL, "persistent-storage");
 });
--- a/dom/webidl/DOMException.webidl
+++ b/dom/webidl/DOMException.webidl
@@ -14,28 +14,21 @@
 // This is the WebIDL version of nsIException.  This is mostly legacy stuff.
 
 interface StackFrame;
 
 [NoInterfaceObject,
  Exposed=(Window,Worker)]
 interface ExceptionMembers
 {
-  // A custom message set by the thrower.  LenientThis so it can be
-  // gotten on the prototype, which Error.prototype.toString will do
-  // if someone tries to stringify DOMException.prototype.
-  [LenientThis]
+  // A custom message set by the thrower.
   readonly attribute DOMString               message;
   // The nsresult associated with this exception.
   readonly attribute unsigned long           result;
   // The name of the error code (ie, a string repr of |result|).
-  // LenientThis so it can be gotten on the prototype, which
-  // Error.prototype.toString will do if someone tries to stringify
-  // DOMException.prototype.
-  [LenientThis]
   readonly attribute DOMString               name;
 
   // Filename location.  This is the location that caused the
   // error, which may or may not be a source file location.
   // For example, standard language errors would generally have
   // the same location as their top stack entry.  File
   // parsers may put the location of the file they were parsing,
   // etc.
--- a/gfx/2d/InlineTranslator.cpp
+++ b/gfx/2d/InlineTranslator.cpp
@@ -25,17 +25,17 @@ InlineTranslator::InlineTranslator(DrawT
 }
 
 bool
 InlineTranslator::TranslateRecording(char *aData, size_t aLen)
 {
   // an istream like class for reading from memory
   struct MemReader {
     MemReader(char *aData, size_t aLen) : mData(aData), mEnd(aData + aLen) {}
-    void read(char* s, streamsize n) {
+    void read(char* s, std::streamsize n) {
       if (n <= (mEnd - mData)) {
         memcpy(s, mData, n);
         mData += n;
       } else {
         // We've requested more data than is available
         // set the Reader into an eof state
         mData = mEnd + 1;
       }
--- a/gfx/2d/RecordedEventImpl.h
+++ b/gfx/2d/RecordedEventImpl.h
@@ -1199,19 +1199,16 @@ private:
   uint32_t mIndex;
   ReferencePtr mInputFilter;
   ReferencePtr mInputSurface;
 
   template<class S>
   MOZ_IMPLICIT RecordedFilterNodeSetInput(S &aStream);
 };
 
-
-using namespace std;
-
 static std::string NameFromBackend(BackendType aType)
 {
   switch (aType) {
   case BackendType::NONE:
     return "None";
   case BackendType::DIRECT2D:
     return "Direct2D";
   default:
@@ -1511,17 +1508,17 @@ RecordedDrawTargetCreation::RecordedDraw
       aStream.read((char*)dataSurf->GetData() + y * dataSurf->Stride(),
                     BytesPerPixel(mFormat) * mSize.width);
     }
     mExistingData = dataSurf;
   }
 }
 
 inline void
-RecordedDrawTargetCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedDrawTargetCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: " << NameFromBackend(mBackendType) << ", Size: " << mSize.width << "x" << mSize.height << ")";
 }
 
 
 inline bool
 RecordedDrawTargetDestruction::PlayEvent(Translator *aTranslator) const
 {
@@ -1539,17 +1536,17 @@ RecordedDrawTargetDestruction::Record(S 
 template<class S>
 RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(S &aStream)
   : RecordedEventDerived(DRAWTARGETDESTRUCTION)
 {
   ReadElement(aStream, mRefPtr);
 }
 
 inline void
-RecordedDrawTargetDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedDrawTargetDestruction::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
 }
 
 inline bool
 RecordedCreateSimilarDrawTarget::PlayEvent(Translator *aTranslator) const
 {
   RefPtr<DrawTarget> newDT =
@@ -1579,17 +1576,17 @@ RecordedCreateSimilarDrawTarget::Recorde
   : RecordedEventDerived(CREATESIMILARDRAWTARGET)
 {
   ReadElement(aStream, mRefPtr);
   ReadElement(aStream, mSize);
   ReadElement(aStream, mFormat);
 }
 
 inline void
-RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x" << mSize.height << ")";
 }
 
 struct GenericPattern
 {
   GenericPattern(const PatternStorage &aStorage, Translator *aTranslator)
     : mPattern(nullptr), mTranslator(aTranslator)
@@ -1678,17 +1675,17 @@ RecordedFillRect::RecordedFillRect(S &aS
   : RecordedDrawingEvent(FILLRECT, aStream)
 {
   ReadElement(aStream, mRect);
   ReadElement(aStream, mOptions);
   ReadPatternData(aStream, mPattern);
 }
 
 inline void
-RecordedFillRect::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFillRect::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] FillRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
   OutputSimplePatternInfo(mPattern, aStringStream);
 }
 
 inline bool
 RecordedStrokeRect::PlayEvent(Translator *aTranslator) const
 {
@@ -1713,17 +1710,17 @@ RecordedStrokeRect::RecordedStrokeRect(S
 {
   ReadElement(aStream, mRect);
   ReadElement(aStream, mOptions);
   ReadPatternData(aStream, mPattern);
   ReadStrokeOptions(aStream, mStrokeOptions);
 }
 
 inline void
-RecordedStrokeRect::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedStrokeRect::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] StrokeRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height
                 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
   OutputSimplePatternInfo(mPattern, aStringStream);
 }
 
 inline bool
 RecordedStrokeLine::PlayEvent(Translator *aTranslator) const
@@ -1751,17 +1748,17 @@ RecordedStrokeLine::RecordedStrokeLine(S
   ReadElement(aStream, mBegin);
   ReadElement(aStream, mEnd);
   ReadElement(aStream, mOptions);
   ReadPatternData(aStream, mPattern);
   ReadStrokeOptions(aStream, mStrokeOptions);
 }
 
 inline void
-RecordedStrokeLine::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedStrokeLine::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] StrokeLine (" << mBegin.x << ", " << mBegin.y << " - " << mEnd.x << ", " << mEnd.y
                 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
   OutputSimplePatternInfo(mPattern, aStringStream);
 }
 
 inline bool
 RecordedFill::PlayEvent(Translator *aTranslator) const
@@ -1785,17 +1782,17 @@ RecordedFill::Record(S &aStream) const
 {
   RecordedDrawingEvent::Record(aStream);
   WriteElement(aStream, mPath);
   WriteElement(aStream, mOptions);
   RecordPatternData(aStream, mPattern);
 }
 
 inline void
-RecordedFill::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFill::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] Fill (" << mPath << ") ";
   OutputSimplePatternInfo(mPattern, aStringStream);
 }
 
 inline
 RecordedFillGlyphs::~RecordedFillGlyphs()
 {
@@ -1832,17 +1829,17 @@ RecordedFillGlyphs::Record(S &aStream) c
   WriteElement(aStream, mScaledFont);
   WriteElement(aStream, mOptions);
   RecordPatternData(aStream, mPattern);
   WriteElement(aStream, mNumGlyphs);
   aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
 }
 
 inline void
-RecordedFillGlyphs::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFillGlyphs::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] FillGlyphs (" << mScaledFont << ") ";
   OutputSimplePatternInfo(mPattern, aStringStream);
 }
 
 inline bool
 RecordedMask::PlayEvent(Translator *aTranslator) const
 {
@@ -1865,17 +1862,17 @@ RecordedMask::Record(S &aStream) const
 {
   RecordedDrawingEvent::Record(aStream);
   WriteElement(aStream, mOptions);
   RecordPatternData(aStream, mSource);
   RecordPatternData(aStream, mMask);
 }
 
 inline void
-RecordedMask::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedMask::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] Mask (Source: ";
   OutputSimplePatternInfo(mSource, aStringStream);
   aStringStream << " Mask: ";
   OutputSimplePatternInfo(mMask, aStringStream);
 }
 
 inline bool
@@ -1902,17 +1899,17 @@ RecordedStroke::RecordedStroke(S &aStrea
 {
   ReadElement(aStream, mPath);
   ReadElement(aStream, mOptions);
   ReadPatternData(aStream, mPattern);
   ReadStrokeOptions(aStream, mStrokeOptions);
 }
 
 inline void
-RecordedStroke::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedStroke::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] Stroke ("<< mPath << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
   OutputSimplePatternInfo(mPattern, aStringStream);
 }
 
 inline bool
 RecordedClearRect::PlayEvent(Translator *aTranslator) const
 {
@@ -1931,17 +1928,17 @@ RecordedClearRect::Record(S &aStream) co
 template<class S>
 RecordedClearRect::RecordedClearRect(S &aStream)
   : RecordedDrawingEvent(CLEARRECT, aStream)
 {
     ReadElement(aStream, mRect);
 }
 
 inline void
-RecordedClearRect::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedClearRect::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT<< "] ClearRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
 }
 
 inline bool
 RecordedCopySurface::PlayEvent(Translator *aTranslator) const
 {
 	aTranslator->LookupDrawTarget(mDT)->CopySurface(aTranslator->LookupSourceSurface(mSourceSurface),
@@ -1964,17 +1961,17 @@ RecordedCopySurface::RecordedCopySurface
   : RecordedDrawingEvent(COPYSURFACE, aStream)
 {
   ReadElement(aStream, mSourceSurface);
   ReadElement(aStream, mSourceRect);
   ReadElement(aStream, mDest);
 }
 
 inline void
-RecordedCopySurface::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedCopySurface::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT<< "] CopySurface (" << mSourceSurface << ")";
 }
 
 inline bool
 RecordedPushClip::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->LookupDrawTarget(mDT)->PushClip(aTranslator->LookupPath(mPath));
@@ -1992,17 +1989,17 @@ RecordedPushClip::Record(S &aStream) con
 template<class S>
 RecordedPushClip::RecordedPushClip(S &aStream)
   : RecordedDrawingEvent(PUSHCLIP, aStream)
 {
   ReadElement(aStream, mPath);
 }
 
 inline void
-RecordedPushClip::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedPushClip::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] PushClip (" << mPath << ") ";
 }
 
 inline bool
 RecordedPushClipRect::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->LookupDrawTarget(mDT)->PushClipRect(mRect);
@@ -2020,17 +2017,17 @@ RecordedPushClipRect::Record(S &aStream)
 template<class S>
 RecordedPushClipRect::RecordedPushClipRect(S &aStream)
   : RecordedDrawingEvent(PUSHCLIPRECT, aStream)
 {
   ReadElement(aStream, mRect);
 }
 
 inline void
-RecordedPushClipRect::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedPushClipRect::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] PushClipRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
 }
 
 inline bool
 RecordedPopClip::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->LookupDrawTarget(mDT)->PopClip();
@@ -2046,17 +2043,17 @@ RecordedPopClip::Record(S &aStream) cons
 
 template<class S>
 RecordedPopClip::RecordedPopClip(S &aStream)
   : RecordedDrawingEvent(POPCLIP, aStream)
 {
 }
 
 inline void
-RecordedPopClip::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedPopClip::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] PopClip";
 }
 
 inline bool
 RecordedPushLayer::PlayEvent(Translator *aTranslator) const
 {
   SourceSurface* mask = mMask ? aTranslator->LookupSourceSurface(mMask)
@@ -2087,17 +2084,17 @@ RecordedPushLayer::RecordedPushLayer(S &
   ReadElement(aStream, mOpacity);
   ReadElement(aStream, mMask);
   ReadElement(aStream, mMaskTransform);
   ReadElement(aStream, mBounds);
   ReadElement(aStream, mCopyBackground);
 }
 
 inline void
-RecordedPushLayer::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedPushLayer::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] PushPLayer (Opaque=" << mOpaque <<
     ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
 }
 
 inline bool
 RecordedPopLayer::PlayEvent(Translator *aTranslator) const
 {
@@ -2114,17 +2111,17 @@ RecordedPopLayer::Record(S &aStream) con
 
 template<class S>
 RecordedPopLayer::RecordedPopLayer(S &aStream)
   : RecordedDrawingEvent(POPLAYER, aStream)
 {
 }
 
 inline void
-RecordedPopLayer::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedPopLayer::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] PopLayer";
 }
 
 inline bool
 RecordedSetTransform::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->LookupDrawTarget(mDT)->SetTransform(mTransform);
@@ -2142,17 +2139,17 @@ RecordedSetTransform::Record(S &aStream)
 template<class S>
 RecordedSetTransform::RecordedSetTransform(S &aStream)
   : RecordedDrawingEvent(SETTRANSFORM, aStream)
 {
   ReadElement(aStream, mTransform);
 }
 
 inline void
-RecordedSetTransform::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedSetTransform::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] SetTransform [ " << mTransform._11 << " " << mTransform._12 << " ; " <<
     mTransform._21 << " " << mTransform._22 << " ; " << mTransform._31 << " " << mTransform._32 << " ]";
 }
 
 inline bool
 RecordedDrawSurface::PlayEvent(Translator *aTranslator) const
 {
@@ -2181,17 +2178,17 @@ RecordedDrawSurface::RecordedDrawSurface
   ReadElement(aStream, mRefSource);
   ReadElement(aStream, mDest);
   ReadElement(aStream, mSource);
   ReadElement(aStream, mDSOptions);
   ReadElement(aStream, mOptions);
 }
 
 inline void
-RecordedDrawSurface::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedDrawSurface::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] DrawSurface (" << mRefSource << ")";
 }
 
 inline bool
 RecordedDrawFilter::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->LookupDrawTarget(mDT)->
@@ -2217,17 +2214,17 @@ RecordedDrawFilter::RecordedDrawFilter(S
 {
   ReadElement(aStream, mNode);
   ReadElement(aStream, mSourceRect);
   ReadElement(aStream, mDestPoint);
   ReadElement(aStream, mOptions);
 }
 
 inline void
-RecordedDrawFilter::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedDrawFilter::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] DrawFilter (" << mNode << ")";
 }
 
 inline bool
 RecordedDrawSurfaceWithShadow::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->LookupDrawTarget(mDT)->
@@ -2257,17 +2254,17 @@ RecordedDrawSurfaceWithShadow::RecordedD
   ReadElement(aStream, mDest);
   ReadElement(aStream, mColor);
   ReadElement(aStream, mOffset);
   ReadElement(aStream, mSigma);
   ReadElement(aStream, mOp);
 }
 
 inline void
-RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] DrawSurfaceWithShadow (" << mRefSource << ") Color: (" <<
     mColor.r << ", " << mColor.g << ", " << mColor.b << ", " << mColor.a << ")";
 }
 
 inline
 RecordedPathCreation::RecordedPathCreation(PathRecording *aPath)
   : RecordedEventDerived(PATHCREATION), mRefPtr(aPath), mFillRule(aPath->mFillRule), mPathOps(aPath->mPathOps)
@@ -2358,17 +2355,17 @@ RecordedPathCreation::RecordedPathCreati
     }
 
     mPathOps.push_back(newPathOp);
   }
 
 }
 
 inline void
-RecordedPathCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedPathCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << mPathOps.size() << ")";
 }
 inline bool
 RecordedPathDestruction::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->RemovePath(mRefPtr);
   return true;
@@ -2384,17 +2381,17 @@ RecordedPathDestruction::Record(S &aStre
 template<class S>
 RecordedPathDestruction::RecordedPathDestruction(S &aStream)
   : RecordedEventDerived(PATHDESTRUCTION)
 {
   ReadElement(aStream, mRefPtr);
 }
 
 inline void
-RecordedPathDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedPathDestruction::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] Path Destroyed";
 }
 
 inline
 RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation()
 {
   if (mDataOwned) {
@@ -2439,17 +2436,17 @@ RecordedSourceSurfaceCreation::RecordedS
   if (!mData) {
     gfxWarning() << "RecordedSourceSurfaceCreation failed to allocate data";
   } else {
     aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat));
   }
 }
 
 inline void
-RecordedSourceSurfaceCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedSourceSurfaceCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] SourceSurface created (Size: " << mSize.width << "x" << mSize.height << ")";
 }
 
 inline bool
 RecordedSourceSurfaceDestruction::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->RemoveSourceSurface(mRefPtr);
@@ -2466,17 +2463,17 @@ RecordedSourceSurfaceDestruction::Record
 template<class S>
 RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(S &aStream)
   : RecordedEventDerived(SOURCESURFACEDESTRUCTION)
 {
   ReadElement(aStream, mRefPtr);
 }
 
 inline void
-RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
 }
 
 inline
 RecordedFilterNodeCreation::~RecordedFilterNodeCreation()
 {
 }
@@ -2502,17 +2499,17 @@ template<class S>
 RecordedFilterNodeCreation::RecordedFilterNodeCreation(S &aStream)
   : RecordedEventDerived(FILTERNODECREATION)
 {
   ReadElement(aStream, mRefPtr);
   ReadElement(aStream, mType);
 }
 
 inline void
-RecordedFilterNodeCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFilterNodeCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] FilterNode created (Type: " << int(mType) << ")";
 }
 
 inline bool
 RecordedFilterNodeDestruction::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->RemoveFilterNode(mRefPtr);
@@ -2529,17 +2526,17 @@ RecordedFilterNodeDestruction::Record(S 
 template<class S>
 RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(S &aStream)
   : RecordedEventDerived(FILTERNODEDESTRUCTION)
 {
   ReadElement(aStream, mRefPtr);
 }
 
 inline void
-RecordedFilterNodeDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFilterNodeDestruction::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
 }
 
 inline
 RecordedGradientStopsCreation::~RecordedGradientStopsCreation()
 {
   if (mDataOwned) {
@@ -2574,17 +2571,17 @@ RecordedGradientStopsCreation::RecordedG
   ReadElement(aStream, mExtendMode);
   ReadElement(aStream, mNumStops);
   mStops = new GradientStop[mNumStops];
 
   aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
 }
 
 inline void
-RecordedGradientStopsCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedGradientStopsCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] GradientStops created (Stops: " << mNumStops << ")";
 }
 
 inline bool
 RecordedGradientStopsDestruction::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->RemoveGradientStops(mRefPtr);
@@ -2601,17 +2598,17 @@ RecordedGradientStopsDestruction::Record
 template<class S>
 RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(S &aStream)
   : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION)
 {
   ReadElement(aStream, mRefPtr);
 }
 
 inline void
-RecordedGradientStopsDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedGradientStopsDestruction::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
 }
 
 inline bool
 RecordedIntoLuminanceSource::PlayEvent(Translator *aTranslator) const
 {
   RefPtr<SourceSurface> src = aTranslator->LookupDrawTarget(mDT)->IntoLuminanceSource(mLuminanceType, mOpacity);
@@ -2635,17 +2632,17 @@ RecordedIntoLuminanceSource::RecordedInt
 {
   ReadElement(aStream, mRefPtr);
   ReadElement(aStream, mDT);
   ReadElement(aStream, mLuminanceType);
   ReadElement(aStream, mOpacity);
 }
 
 inline void
-RecordedIntoLuminanceSource::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedIntoLuminanceSource::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] Into Luminance Source (DT: " << mDT << ")";
 }
 
 inline bool
 RecordedSnapshot::PlayEvent(Translator *aTranslator) const
 {
   RefPtr<SourceSurface> src = aTranslator->LookupDrawTarget(mDT)->Snapshot();
@@ -2665,17 +2662,17 @@ template<class S>
 RecordedSnapshot::RecordedSnapshot(S &aStream)
   : RecordedEventDerived(SNAPSHOT)
 {
   ReadElement(aStream, mRefPtr);
   ReadElement(aStream, mDT);
 }
 
 inline void
-RecordedSnapshot::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedSnapshot::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] Snapshot Created (DT: " << mDT << ")";
 }
 
 inline
 RecordedFontData::~RecordedFontData()
 {
   delete[] mData;
@@ -2704,17 +2701,17 @@ RecordedFontData::Record(S &aStream) con
 
   WriteElement(aStream, mType);
   WriteElement(aStream, mFontDetails.fontDataKey);
   WriteElement(aStream, mFontDetails.size);
   aStream.write((const char*)mData, mFontDetails.size);
 }
 
 inline void
-RecordedFontData::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFontData::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "Font Data of size " << mFontDetails.size;
 }
 
 inline void
 RecordedFontData::SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex)
 {
   mData = new uint8_t[aSize];
@@ -2778,17 +2775,17 @@ RecordedFontDescriptor::Record(S &aStrea
   MOZ_ASSERT(mHasDesc);
   WriteElement(aStream, mType);
   WriteElement(aStream, mRefPtr);
   WriteElement(aStream, (size_t)mData.size());
   aStream.write((char*)mData.data(), mData.size());
 }
 
 inline void
-RecordedFontDescriptor::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFontDescriptor::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] Font Descriptor";
 }
 
 inline void
 RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData, uint32_t aSize)
 {
   mData.assign(aData, aData + aSize);
@@ -2830,17 +2827,17 @@ RecordedUnscaledFontCreation::Record(S &
   WriteElement(aStream, mRefPtr);
   WriteElement(aStream, mFontDataKey);
   WriteElement(aStream, mIndex);
   WriteElement(aStream, (size_t)mInstanceData.size());
   aStream.write((char*)mInstanceData.data(), mInstanceData.size());
 }
 
 inline void
-RecordedUnscaledFontCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedUnscaledFontCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
 }
 
 inline void
 RecordedUnscaledFontCreation::SetFontInstanceData(const uint8_t *aData, uint32_t aSize)
 {
   mInstanceData.assign(aData, aData + aSize);
@@ -2877,17 +2874,17 @@ RecordedUnscaledFontDestruction::Record(
 template<class S>
 RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(S &aStream)
   : RecordedEventDerived(UNSCALEDFONTDESTRUCTION)
 {
   ReadElement(aStream, mRefPtr);
 }
 
 inline void
-RecordedUnscaledFontDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedUnscaledFontDestruction::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
 }
 
 inline bool
 RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const
 {
   UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
@@ -2910,17 +2907,17 @@ RecordedScaledFontCreation::Record(S &aS
   WriteElement(aStream, mRefPtr);
   WriteElement(aStream, mUnscaledFont);
   WriteElement(aStream, mGlyphSize);
   WriteElement(aStream, (size_t)mInstanceData.size());
   aStream.write((char*)mInstanceData.data(), mInstanceData.size());
 }
 
 inline void
-RecordedScaledFontCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedScaledFontCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] ScaledFont Created";
 }
 
 inline void
 RecordedScaledFontCreation::SetFontInstanceData(const uint8_t *aData, uint32_t aSize)
 {
   mInstanceData.assign(aData, aData + aSize);
@@ -2957,17 +2954,17 @@ RecordedScaledFontDestruction::Record(S 
 template<class S>
 RecordedScaledFontDestruction::RecordedScaledFontDestruction(S &aStream)
   : RecordedEventDerived(SCALEDFONTDESTRUCTION)
 {
   ReadElement(aStream, mRefPtr);
 }
 
 inline void
-RecordedScaledFontDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedScaledFontDestruction::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
 }
 
 inline bool
 RecordedMaskSurface::PlayEvent(Translator *aTranslator) const
 {
   aTranslator->LookupDrawTarget(mDT)->
@@ -2994,17 +2991,17 @@ RecordedMaskSurface::RecordedMaskSurface
 {
   ReadPatternData(aStream, mPattern);
   ReadElement(aStream, mRefMask);
   ReadElement(aStream, mOffset);
   ReadElement(aStream, mOptions);
 }
 
 inline void
-RecordedMaskSurface::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedMaskSurface::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mDT << "] MaskSurface (" << mRefMask << ")  Offset: (" << mOffset.x << "x" << mOffset.y << ") Pattern: ";
   OutputSimplePatternInfo(mPattern, aStringStream);
 }
 
 template<typename T>
 void
 ReplaySetAttribute(FilterNode *aNode, uint32_t aIndex, T aValue)
@@ -3065,17 +3062,17 @@ RecordedFilterNodeSetAttribute::Recorded
   ReadElement(aStream, mArgType);
   uint64_t size;
   ReadElement(aStream, size);
   mPayload.resize(size_t(size));
   aStream.read((char*)&mPayload.front(), size);
 }
 
 inline void
-RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
 }
 
 inline bool
 RecordedFilterNodeSetInput::PlayEvent(Translator *aTranslator) const
 {
   if (mInputFilter) {
@@ -3105,17 +3102,17 @@ RecordedFilterNodeSetInput::RecordedFilt
 {
   ReadElement(aStream, mNode);
   ReadElement(aStream, mIndex);
   ReadElement(aStream, mInputFilter);
   ReadElement(aStream, mInputSurface);
 }
 
 inline void
-RecordedFilterNodeSetInput::OutputSimpleEventInfo(stringstream &aStringStream) const
+RecordedFilterNodeSetInput::OutputSimpleEventInfo(std::stringstream &aStringStream) const
 {
   aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
 
   if (mInputFilter) {
     aStringStream << "Filter: " << mInputFilter;
   } else {
     aStringStream << "Surface: " << mInputSurface;
   }
--- a/gfx/angle/src/libANGLE/Framebuffer.cpp
+++ b/gfx/angle/src/libANGLE/Framebuffer.cpp
@@ -175,17 +175,19 @@ bool FramebufferState::attachmentsHaveSa
         }
 
         if (!attachmentSize.valid())
         {
             attachmentSize = attachment.getSize();
             return false;
         }
 
-        return (attachment.getSize() != attachmentSize.value());
+        const Extents &size = attachment.getSize();
+        return size.width != attachmentSize.value().width ||
+               size.height != attachmentSize.value().height;
     };
 
     for (const auto &attachment : mColorAttachments)
     {
         if (hasMismatchedSize(attachment))
         {
             return false;
         }
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -285,16 +285,17 @@ GLContext::GLContext(CreateContextFlags 
     mMaxTextureImageSize(0),
     mMaxRenderbufferSize(0),
     mMaxSamples(0),
     mNeedsTextureSizeChecks(false),
     mNeedsFlushBeforeDeleteFB(false),
     mTextureAllocCrashesOnMapFailure(false),
     mNeedsCheckAfterAttachTextureToFb(false),
     mWorkAroundDriverBugs(true),
+    mSyncGLCallCount(0),
     mHeavyGLCallsSinceLastFlush(false)
 {
     mMaxViewportDims[0] = 0;
     mMaxViewportDims[1] = 0;
     mOwningThreadId = PlatformThread::CurrentId();
     MOZ_ALWAYS_TRUE( sCurrentContext.init() );
     sCurrentContext.set(nullptr);
 }
@@ -3041,11 +3042,21 @@ bool GLContext::MakeCurrent(bool aForce)
 
     if (mUseTLSIsCurrent) {
         sCurrentContext.set(this);
     }
 
     return true;
 }
 
+void
+GLContext::ResetSyncCallCount(const char* resetReason) const
+{
+    if (ShouldSpew()) {
+        printf_stderr("On %s, mSyncGLCallCount = %" PRIu64 "\n",
+                       resetReason, mSyncGLCallCount);
+    }
+
+    mSyncGLCallCount = 0;
+}
 
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -783,16 +783,26 @@ private:
     // Do whatever setup is necessary to read from our offscreen FBO, if it's
     // bound.
     void BeforeGLReadCall();
 
     // Do whatever tear-down is necessary after reading from our offscreen FBO,
     // if it's bound.
     void AfterGLReadCall() { }
 
+public:
+    void OnSyncCall() const {
+        mSyncGLCallCount++;
+    }
+
+    uint64_t GetSyncCallCount() const {
+        return mSyncGLCallCount;
+    }
+
+    void ResetSyncCallCount(const char* resetReason) const;
 
 // -----------------------------------------------------------------------------
 // GL official entry points
 public:
 
     void fActiveTexture(GLenum texture) {
         BEFORE_GL_CALL;
         mSymbols.fActiveTexture(texture);
@@ -880,16 +890,17 @@ public:
         AFTER_GL_CALL;
     }
 
 private:
     void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
         ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
         BEFORE_GL_CALL;
         mSymbols.fBufferData(target, size, data, usage);
+        OnSyncCall();
         AFTER_GL_CALL;
         mHeavyGLCallsSinceLastFlush = true;
     }
 
 public:
     void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
         raw_fBufferData(target, size, data, usage);
 
@@ -1126,16 +1137,17 @@ public:
         ASSERT_SYMBOL_PRESENT(fEndQuery);
         mSymbols.fEndQuery(target);
         AFTER_GL_CALL;
     }
 
     void fFinish() {
         BEFORE_GL_CALL;
         mSymbols.fFinish();
+        OnSyncCall();
         AFTER_GL_CALL;
         mHeavyGLCallsSinceLastFlush = false;
     }
 
     void fFlush() {
         BEFORE_GL_CALL;
         mSymbols.fFlush();
         AFTER_GL_CALL;
@@ -1146,42 +1158,47 @@ public:
         BEFORE_GL_CALL;
         mSymbols.fFrontFace(face);
         AFTER_GL_CALL;
     }
 
     void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
         BEFORE_GL_CALL;
         mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type, name);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
         BEFORE_GL_CALL;
         mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type, name);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
         BEFORE_GL_CALL;
         mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     GLint fGetAttribLocation(GLuint program, const GLchar* name) {
         BEFORE_GL_CALL;
         GLint retval = mSymbols.fGetAttribLocation(program, name);
+        OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
 private:
     void raw_fGetIntegerv(GLenum pname, GLint* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetIntegerv(pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 public:
 
     void fGetIntegerv(GLenum pname, GLint* params);
 
     void GetUIntegerv(GLenum pname, GLuint* params) {
@@ -1194,75 +1211,84 @@ public:
         T ret = 0;
         fGetIntegerv(pname, (GLint*)&ret);
         return ret;
     }
 
     void fGetFloatv(GLenum pname, GLfloat* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetFloatv(pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetBooleanv(GLenum pname, realGLboolean* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetBooleanv(pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetBufferParameteriv(target, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
         GLuint ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fGetPointerv(GLenum pname, GLvoid** params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetPointerv);
         mSymbols.fGetPointerv(pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetObjectLabel);
         mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel);
         mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGenerateMipmap(GLenum target) {
         BEFORE_GL_CALL;
         mSymbols.fGenerateMipmap(target);
         AFTER_GL_CALL;
     }
 
     void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
         BEFORE_GL_CALL;
         mSymbols.fGetProgramiv(program, pname, param);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
         BEFORE_GL_CALL;
         mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fTexParameteri(GLenum target, GLenum pname, GLint param) {
         BEFORE_GL_CALL;
         mSymbols.fTexParameteri(target, pname, param);
         AFTER_GL_CALL;
     }
@@ -1277,100 +1303,113 @@ public:
         BEFORE_GL_CALL;
         mSymbols.fTexParameterf(target, pname, param);
         AFTER_GL_CALL;
     }
 
     const GLubyte* fGetString(GLenum name) {
         BEFORE_GL_CALL;
         const GLubyte* result = mSymbols.fGetString(name);
+        OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
     void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* img) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetTexImage);
         mSymbols.fGetTexImage(target, level, format, type, img);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv);
         mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetTexParameterfv(target, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetTexParameteriv(target, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetUniformfv(program, location, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetUniformiv(GLuint program, GLint location, GLint* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetUniformiv(program, location, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetUniformuiv(GLuint program, GLint location, GLuint* params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetUniformuiv);
         mSymbols.fGetUniformuiv(program, location, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     GLint fGetUniformLocation (GLint programObj, const GLchar* name) {
         BEFORE_GL_CALL;
         GLint retval = mSymbols.fGetUniformLocation(programObj, name);
+        OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
     void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
         BEFORE_GL_CALL;
         mSymbols.fGetVertexAttribfv(index, pname, retval);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
         BEFORE_GL_CALL;
         mSymbols.fGetVertexAttribiv(index, pname, retval);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) {
         BEFORE_GL_CALL;
         mSymbols.fGetVertexAttribPointerv(index, pname, retval);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fHint(GLenum target, GLenum mode) {
         BEFORE_GL_CALL;
         mSymbols.fHint(target, mode);
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsBuffer(GLuint buffer) {
         BEFORE_GL_CALL;
         realGLboolean retval = mSymbols.fIsBuffer(buffer);
+        OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
     realGLboolean fIsEnabled(GLenum capability) {
         BEFORE_GL_CALL;
         realGLboolean retval = mSymbols.fIsEnabled(capability);
         AFTER_GL_CALL;
@@ -1492,16 +1531,17 @@ public:
         mSymbols.fReadBuffer(mode);
         AFTER_GL_CALL;
     }
 
     void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
         ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
         BEFORE_GL_CALL;
         mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
+        OnSyncCall();
         AFTER_GL_CALL;
         mHeavyGLCallsSinceLastFlush = true;
     }
 
     void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
                      GLenum type, GLvoid* pixels);
 
 public:
@@ -1855,48 +1895,52 @@ private:
         mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
         AFTER_GL_CALL;
     }
 
 public:
     void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
         BEFORE_GL_CALL;
         mSymbols.fGetShaderiv(shader, pname, param);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
         BEFORE_GL_CALL;
         mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 private:
     void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
         MOZ_ASSERT(IsGLES());
 
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat);
         mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 public:
     void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
         if (IsGLES()) {
             raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
         } else {
             // Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions.
             GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision);
         }
     }
 
     void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) {
         BEFORE_GL_CALL;
         mSymbols.fGetShaderSource(obj, maxLength, length, source);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fShaderSource(GLuint shader, GLsizei count, const GLchar* const* strings, const GLint* lengths) {
         BEFORE_GL_CALL;
         mSymbols.fShaderSource(shader, count, strings, lengths);
         AFTER_GL_CALL;
     }
@@ -1915,16 +1959,17 @@ public:
         BEFORE_GL_CALL;
         mSymbols.fBindRenderbuffer(target, renderbuffer);
         AFTER_GL_CALL;
     }
 
     GLenum fCheckFramebufferStatus(GLenum target) {
         BEFORE_GL_CALL;
         GLenum retval = mSymbols.fCheckFramebufferStatus(target);
+        OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
     void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
         BEFORE_GL_CALL;
         mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
         AFTER_GL_CALL;
@@ -1944,36 +1989,40 @@ public:
         ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer);
         mSymbols.fFramebufferTextureLayer(target, attachment, texture, level, layer);
         AFTER_GL_CALL;
     }
 
     void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* value) {
         BEFORE_GL_CALL;
         mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
         BEFORE_GL_CALL;
         mSymbols.fGetRenderbufferParameteriv(target, pname, value);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsFramebuffer (GLuint framebuffer) {
         BEFORE_GL_CALL;
         realGLboolean retval = mSymbols.fIsFramebuffer(framebuffer);
+        OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
 public:
     realGLboolean fIsRenderbuffer (GLuint renderbuffer) {
         BEFORE_GL_CALL;
         realGLboolean retval = mSymbols.fIsRenderbuffer(renderbuffer);
+        OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
     void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) {
         BEFORE_GL_CALL;
         mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
         AFTER_GL_CALL;
@@ -2032,16 +2081,17 @@ public:
             raw_fClearDepth(v);
         }
     }
 
     void* fMapBuffer(GLenum target, GLenum access) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fMapBuffer);
         void* ret = mSymbols.fMapBuffer(target, access);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     realGLboolean fUnmapBuffer(GLenum target) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
         realGLboolean ret = mSymbols.fUnmapBuffer(target);
@@ -2063,34 +2113,38 @@ private:
         GLuint ret = mSymbols.fCreateShader(t);
         AFTER_GL_CALL;
         return ret;
     }
 
     void raw_fGenBuffers(GLsizei n, GLuint* names) {
         BEFORE_GL_CALL;
         mSymbols.fGenBuffers(n, names);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void raw_fGenFramebuffers(GLsizei n, GLuint* names) {
         BEFORE_GL_CALL;
         mSymbols.fGenFramebuffers(n, names);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
         BEFORE_GL_CALL;
         mSymbols.fGenRenderbuffers(n, names);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void raw_fGenTextures(GLsizei n, GLuint* names) {
         BEFORE_GL_CALL;
         mSymbols.fGenTextures(n, names);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 public:
     GLuint fCreateProgram() {
         GLuint ret = raw_fCreateProgram();
         TRACKING_CONTEXT(CreatedProgram(this, ret));
         return ret;
@@ -2187,51 +2241,55 @@ public:
         raw_fDeleteTextures(n, names);
         TRACKING_CONTEXT(DeletedTextures(this, n, names));
     }
 
     GLenum fGetGraphicsResetStatus() {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus);
         GLenum ret = mSymbols.fGetGraphicsResetStatus();
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
 
 // -----------------------------------------------------------------------------
 // Extension ARB_sync (GL)
 public:
     GLsync fFenceSync(GLenum condition, GLbitfield flags) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fFenceSync);
         GLsync ret = mSymbols.fFenceSync(condition, flags);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     realGLboolean fIsSync(GLsync sync) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsSync);
         realGLboolean ret = mSymbols.fIsSync(sync);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fDeleteSync(GLsync sync) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fDeleteSync);
         mSymbols.fDeleteSync(sync);
         AFTER_GL_CALL;
     }
 
     GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fClientWaitSync);
         GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fWaitSync);
         mSymbols.fWaitSync(sync, flags, timeout);
@@ -2244,16 +2302,17 @@ public:
         mSymbols.fGetInteger64v(pname, params);
         AFTER_GL_CALL;
     }
 
     void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetSynciv);
         mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 
 // -----------------------------------------------------------------------------
 // Extension OES_EGL_image (GLES)
 public:
     void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
@@ -2386,24 +2445,26 @@ public:
 // -----------------------------------------------------------------------------
 //  GL 3.0, GL ES 3.0 & EXT_gpu_shader4
 public:
     void fGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
     {
         ASSERT_SYMBOL_PRESENT(fGetVertexAttribIiv);
         BEFORE_GL_CALL;
         mSymbols.fGetVertexAttribIiv(index, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
     {
         ASSERT_SYMBOL_PRESENT(fGetVertexAttribIuiv);
         BEFORE_GL_CALL;
         mSymbols.fGetVertexAttribIuiv(index, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fVertexAttribI4i);
         mSymbols.fVertexAttribI4i(index, x, y, z, w);
@@ -2498,16 +2559,17 @@ public:
         AFTER_GL_CALL;
     }
 
     GLint fGetFragDataLocation(GLuint program, const GLchar* name)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetFragDataLocation);
         GLint result = mSymbols.fGetFragDataLocation(program, name);
+        OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
 
 // -----------------------------------------------------------------------------
 // Package XXX_instanced_arrays
 public:
@@ -2521,16 +2583,17 @@ public:
 
 // -----------------------------------------------------------------------------
 // Feature internalformat_query
 public:
     void fGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetInternalformativ);
         mSymbols.fGetInternalformativ(target, internalformat, pname, bufSize, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 
 // -----------------------------------------------------------------------------
 // Package XXX_query_counter
 /**
  * XXX_query_counter:
@@ -2577,53 +2640,58 @@ public:
         AFTER_GL_CALL;
         TRACKING_CONTEXT(CreatedQueries(this, n, names));
     }
 
     void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetQueryiv);
         mSymbols.fGetQueryiv(target, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
         mSymbols.fGetQueryObjectuiv(id, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsQuery(GLuint query) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsQuery);
         realGLboolean retval = mSymbols.fIsQuery(query);
+        OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
 // -----------------------------------------------------------------------------
 // Package XXX_get_query_object_i64v
 /**
  * XXX_get_query_object_i64v:
  *  - depends on XXX_query_objects
  *  - provide the followed entry point
  */
 public:
     void fGetQueryObjecti64v(GLuint id, GLenum pname, GLint64* params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetQueryObjecti64v);
         mSymbols.fGetQueryObjecti64v(id, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetQueryObjectui64v);
         mSymbols.fGetQueryObjectui64v(id, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 
 // -----------------------------------------------------------------------------
 // Package XXX_get_query_object_iv
 /**
  * XXX_get_query_object_iv:
@@ -2634,16 +2702,17 @@ public:
  *  - depends on XXX_get_query_object_iv
  *  - provide LOCAL_GL_SAMPLES_PASSED
  */
 public:
     void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
         mSymbols.fGetQueryObjectiv(id, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 
 // -----------------------------------------------------------------------------
 // GL 4.0, GL ES 3.0, ARB_transform_feedback2, NV_transform_feedback2
 public:
     void fBindBufferBase(GLenum target, GLuint index, GLuint buffer)
@@ -2662,32 +2731,34 @@ public:
         AFTER_GL_CALL;
     }
 
     void fGenTransformFeedbacks(GLsizei n, GLuint* ids)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGenTransformFeedbacks);
         mSymbols.fGenTransformFeedbacks(n, ids);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks);
         mSymbols.fDeleteTransformFeedbacks(n, ids);
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsTransformFeedback(GLuint id)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsTransformFeedback);
         realGLboolean result = mSymbols.fIsTransformFeedback(id);
+        OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
     void fBindTransformFeedback(GLenum target, GLuint id)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fBindTransformFeedback);
@@ -2719,16 +2790,17 @@ public:
         AFTER_GL_CALL;
     }
 
     void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
         mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fPauseTransformFeedback()
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fPauseTransformFeedback);
         mSymbols.fPauseTransformFeedback();
@@ -2743,23 +2815,25 @@ public:
         AFTER_GL_CALL;
     }
 
     void fGetIntegeri_v(GLenum param, GLuint index, GLint* values)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
         mSymbols.fGetIntegeri_v(param, index, values);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetInteger64i_v(GLenum target, GLuint index, GLint64* data) {
         ASSERT_SYMBOL_PRESENT(fGetInteger64i_v);
         BEFORE_GL_CALL;
         mSymbols.fGetInteger64i_v(target, index, data);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 // -----------------------------------------------------------------------------
 // Package XXX_vertex_array_object
 public:
     void fBindVertexArray(GLuint array)
     {
@@ -2785,16 +2859,17 @@ public:
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsVertexArray(GLuint array)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsVertexArray);
         realGLboolean ret = mSymbols.fIsVertexArray(array);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
 // -----------------------------------------------------------------------------
 // Extension NV_fence
 public:
     void fGenFences(GLsizei n, GLuint* fences)
@@ -2821,42 +2896,46 @@ public:
         AFTER_GL_CALL;
     }
 
     realGLboolean fTestFence(GLuint fence)
     {
         ASSERT_SYMBOL_PRESENT(fTestFence);
         BEFORE_GL_CALL;
         realGLboolean ret = mSymbols.fTestFence(fence);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fFinishFence(GLuint fence)
     {
         ASSERT_SYMBOL_PRESENT(fFinishFence);
         BEFORE_GL_CALL;
         mSymbols.fFinishFence(fence);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsFence(GLuint fence)
     {
         ASSERT_SYMBOL_PRESENT(fIsFence);
         BEFORE_GL_CALL;
         realGLboolean ret = mSymbols.fIsFence(fence);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fGetFenceiv(GLuint fence, GLenum pname, GLint* params)
     {
         ASSERT_SYMBOL_PRESENT(fGetFenceiv);
         BEFORE_GL_CALL;
         mSymbols.fGetFenceiv(fence, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 // -----------------------------------------------------------------------------
 // Extension NV_texture_barrier
 public:
     void fTextureBarrier()
     {
@@ -2883,16 +2962,17 @@ public:
 // Core GL & Extension ARB_map_buffer_range
 public:
     void* fMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
                           GLbitfield access)
     {
         ASSERT_SYMBOL_PRESENT(fMapBufferRange);
         BEFORE_GL_CALL;
         void* data = mSymbols.fMapBufferRange(target, offset, length, access);
+        OnSyncCall();
         AFTER_GL_CALL;
         return data;
     }
 
     void fFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) {
         ASSERT_SYMBOL_PRESENT(fFlushMappedBufferRange);
         BEFORE_GL_CALL;
         mSymbols.fFlushMappedBufferRange(target, offset, length);
@@ -2919,16 +2999,17 @@ public:
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsSampler(GLuint sampler)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsSampler);
         realGLboolean result = mSymbols.fIsSampler(sampler);
+        OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
     void fBindSampler(GLuint unit, GLuint sampler)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fBindSampler);
@@ -2989,51 +3070,56 @@ public:
 // Core GL & Extension ARB_uniform_buffer_object
 public:
     void fGetUniformIndices(GLuint program, GLsizei uniformCount,
                             const GLchar* const* uniformNames, GLuint* uniformIndices)
     {
         ASSERT_SYMBOL_PRESENT(fGetUniformIndices);
         BEFORE_GL_CALL;
         mSymbols.fGetUniformIndices(program, uniformCount, uniformNames, uniformIndices);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices,
                               GLenum pname, GLint* params)
     {
         ASSERT_SYMBOL_PRESENT(fGetActiveUniformsiv);
         BEFORE_GL_CALL;
         mSymbols.fGetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     GLuint fGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) {
         ASSERT_SYMBOL_PRESENT(fGetUniformBlockIndex);
         BEFORE_GL_CALL;
         GLuint result = mSymbols.fGetUniformBlockIndex(program, uniformBlockName);
+        OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
     void fGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex,
                                   GLenum pname, GLint* params)
     {
         ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockiv);
         BEFORE_GL_CALL;
         mSymbols.fGetActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize,
                                     GLsizei* length, GLchar* uniformBlockName)
     {
         ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockName);
         BEFORE_GL_CALL;
         mSymbols.fGetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
         ASSERT_SYMBOL_PRESENT(fUniformBlockBinding);
         BEFORE_GL_CALL;
         mSymbols.fUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
         AFTER_GL_CALL;
@@ -3041,24 +3127,26 @@ public:
 
 // -----------------------------------------------------------------------------
 // Core GL 4.2, GL ES 3.0 & Extension ARB_texture_storage/EXT_texture_storage
     void fTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fTexStorage2D);
         mSymbols.fTexStorage2D(target, levels, internalformat, width, height);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fTexStorage3D);
         mSymbols.fTexStorage3D(target, levels, internalformat, width, height, depth);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
 // -----------------------------------------------------------------------------
 // 3D Textures
     void fTexImage3D(GLenum target, GLint level,
                      GLint internalFormat,
                      GLsizei width, GLsizei height, GLsizei depth,
@@ -3066,28 +3154,30 @@ public:
                      const GLvoid * data)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fTexImage3D);
         mSymbols.fTexImage3D(target, level, internalFormat,
                              width, height, depth,
                              border, format, type,
                              data);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                         GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
                         GLenum format, GLenum type, const GLvoid* pixels)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fTexSubImage3D);
         mSymbols.fTexSubImage3D(target, level, xoffset, yoffset, zoffset,
                                 width, height, depth, format, type,
                                 pixels);
+        OnSyncCall();
         AFTER_GL_CALL;
     }
 
     void fCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset,
                             GLint yoffset, GLint zoffset, GLint x,
                             GLint y, GLsizei width, GLsizei height)
     {
         BeforeGLReadCall();
@@ -3127,16 +3217,17 @@ public:
 
 // -----------------------------------------------------------------------------
 // GL3+, ES3+
 
     const GLubyte* fGetStringi(GLenum name, GLuint index) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetStringi);
         const GLubyte* ret = mSymbols.fGetStringi(name, index);
+        OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
 // -----------------------------------------------------------------------------
 // APPLE_framebuffer_multisample
 
     void fResolveMultisampleFramebufferAPPLE() {
@@ -3470,16 +3561,17 @@ protected:
     GLint mMaxRenderbufferSize;
     GLint mMaxViewportDims[2];
     GLsizei mMaxSamples;
     bool mNeedsTextureSizeChecks;
     bool mNeedsFlushBeforeDeleteFB;
     bool mTextureAllocCrashesOnMapFailure;
     bool mNeedsCheckAfterAttachTextureToFb;
     bool mWorkAroundDriverBugs;
+    mutable uint64_t mSyncGLCallCount;
 
     bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
         if (mNeedsTextureSizeChecks) {
             // some drivers incorrectly handle some large texture sizes that are below the
             // max texture size that they report. So we check ourselves against our own values
             // (mMax[CubeMap]TextureSize).
             // see bug 737182 for Mac Intel 2D textures
             // see bug 684882 for Mac Intel cube map textures
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -333,16 +333,21 @@ typedef GenericFlingAnimation FlingAnima
  * Units: screen pixels (for distance)
  *        screen pixels per millisecond (for velocity)
  *
  * \li\b apz.paint_skipping.enabled
  * When APZ is scrolling and sending repaint requests to the main thread, often
  * the main thread doesn't actually need to do a repaint. This pref allows the
  * main thread to skip doing those repaints in cases where it doesn't need to.
  *
+ * \li\b apz.popups.enabled
+ * Determines whether APZ is used for XUL popup widgets with remote content.
+ * Ideally, this should always be true, but it is currently not well tested, and
+ * has known issues, so needs to be prefable.
+ *
  * \li\b apz.record_checkerboarding
  * Whether or not to record detailed info on checkerboarding events.
  *
  * \li\b apz.test.logging_enabled
  * Enable logging of APZ test data (see bug 961289).
  *
  * \li\b apz.touch_move_tolerance
  * See the description for apz.touch_start_tolerance below. This is a similar
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -324,16 +324,17 @@ private:
   DECL_GFX_PREF(Live, "apz.overscroll.min_pan_distance_ratio", APZMinPanDistanceRatio, float, 1.0f);
   DECL_GFX_PREF(Live, "apz.overscroll.spring_friction",        APZOverscrollSpringFriction, float, 0.015f);
   DECL_GFX_PREF(Live, "apz.overscroll.spring_stiffness",       APZOverscrollSpringStiffness, float, 0.001f);
   DECL_GFX_PREF(Live, "apz.overscroll.stop_distance_threshold", APZOverscrollStopDistanceThreshold, float, 5.0f);
   DECL_GFX_PREF(Live, "apz.overscroll.stop_velocity_threshold", APZOverscrollStopVelocityThreshold, float, 0.01f);
   DECL_GFX_PREF(Live, "apz.overscroll.stretch_factor",         APZOverscrollStretchFactor, float, 0.5f);
   DECL_GFX_PREF(Live, "apz.paint_skipping.enabled",            APZPaintSkipping, bool, true);
   DECL_GFX_PREF(Live, "apz.peek_messages.enabled",             APZPeekMessages, bool, true);
+  DECL_GFX_PREF(Live, "apz.popups.enabled",                    APZPopupsEnabled, bool, false);
   DECL_GFX_PREF(Live, "apz.printtree",                         APZPrintTree, bool, false);
   DECL_GFX_PREF(Live, "apz.record_checkerboarding",            APZRecordCheckerboarding, bool, false);
   DECL_GFX_PREF(Live, "apz.test.fails_with_native_injection",  APZTestFailsWithNativeInjection, bool, false);
   DECL_GFX_PREF(Live, "apz.test.logging_enabled",              APZTestLoggingEnabled, bool, false);
   DECL_GFX_PREF(Live, "apz.touch_move_tolerance",              APZTouchMoveTolerance, float, 0.0);
   DECL_GFX_PREF(Live, "apz.touch_start_tolerance",             APZTouchStartTolerance, float, 1.0f/4.5f);
   DECL_GFX_PREF(Live, "apz.velocity_bias",                     APZVelocityBias, float, 0.0f);
   DECL_GFX_PREF(Live, "apz.velocity_relevance_time_ms",        APZVelocityRelevanceTime, uint32_t, 150);
--- a/intl/strres/nsStringBundle.cpp
+++ b/intl/strres/nsStringBundle.cpp
@@ -31,30 +31,32 @@
 #include "nsIBinaryInputStream.h"
 #include "nsIStringStream.h"
 #endif
 
 using namespace mozilla;
 
 static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID);
 
-nsStringBundle::~nsStringBundle()
-{
-}
+NS_IMPL_ISUPPORTS(nsStringBundle, nsIStringBundle)
 
 nsStringBundle::nsStringBundle(const char* aURLSpec,
                                nsIStringBundleOverride* aOverrideStrings) :
   mPropertiesURL(aURLSpec),
   mOverrideStrings(aOverrideStrings),
   mReentrantMonitor("nsStringBundle.mReentrantMonitor"),
   mAttemptedLoad(false),
   mLoaded(false)
 {
 }
 
+nsStringBundle::~nsStringBundle()
+{
+}
+
 nsresult
 nsStringBundle::LoadProperties()
 {
   // this is different than mLoaded, because we only want to attempt
   // to load once
   // we only want to load once, but if we've tried once and failed,
   // continue to throw an error!
   if (mAttemptedLoad) {
@@ -108,65 +110,78 @@ nsStringBundle::LoadProperties()
   mAttemptedLoad = mLoaded = true;
   rv = mProps->Load(in);
 
   mLoaded = NS_SUCCEEDED(rv);
 
   return rv;
 }
 
-
 nsresult
-nsStringBundle::GetStringFromID(int32_t aID, nsAString& aResult)
+nsStringBundle::GetStringFromNameHelper(const char* aName, nsAString& aResult)
 {
-  ReentrantMonitorAutoEnter automon(mReentrantMonitor);
-  nsAutoCString name;
-  name.AppendInt(aID, 10);
-
-  nsresult rv;
+  NS_ENSURE_ARG_POINTER(aName);
 
-  // try override first
-  if (mOverrideStrings) {
-    rv = mOverrideStrings->GetStringFromName(mPropertiesURL,
-                                             name,
-                                             aResult);
-    if (NS_SUCCEEDED(rv)) return rv;
-  }
+  nsresult rv = LoadProperties();
+  if (NS_FAILED(rv)) return rv;
 
-  rv = mProps->GetStringProperty(name, aResult);
-
-  return rv;
-}
-
-nsresult
-nsStringBundle::GetStringFromName(const char* aName, nsAString& aResult)
-{
-  nsresult rv;
+  ReentrantMonitorAutoEnter automon(mReentrantMonitor);
 
   // try override first
   if (mOverrideStrings) {
     rv = mOverrideStrings->GetStringFromName(mPropertiesURL,
                                              nsDependentCString(aName),
                                              aResult);
     if (NS_SUCCEEDED(rv)) return rv;
   }
 
   rv = mProps->GetStringProperty(nsDependentCString(aName), aResult);
   return rv;
 }
 
 NS_IMETHODIMP
+nsStringBundle::GetStringFromID(int32_t aID, char16_t **aResult)
+{
+  nsAutoCString idStr;
+  idStr.AppendInt(aID, 10);
+  return GetStringFromName(idStr.get(), aResult);
+}
+
+NS_IMETHODIMP
+nsStringBundle::GetStringFromAUTF8Name(const nsACString& aName,
+                                       char16_t **aResult)
+{
+  return GetStringFromName(PromiseFlatCString(aName).get(), aResult);
+}
+
+NS_IMETHODIMP
+nsStringBundle::GetStringFromName(const char* aName, char16_t** aResult)
+{
+  NS_ENSURE_ARG_POINTER(aResult);
+
+  *aResult = nullptr;
+
+  nsAutoString tmpstr;
+  nsresult rv = GetStringFromNameHelper(aName, tmpstr);
+  if (NS_FAILED(rv)) return rv;
+
+  *aResult = ToNewUnicode(tmpstr);
+  NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsStringBundle::FormatStringFromID(int32_t aID,
                                    const char16_t **aParams,
                                    uint32_t aLength,
                                    char16_t ** aResult)
 {
   nsAutoCString idStr;
   idStr.AppendInt(aID, 10);
-
   return FormatStringFromName(idStr.get(), aParams, aLength, aResult);
 }
 
 // this function supports at most 10 parameters.. see below for why
 NS_IMETHODIMP
 nsStringBundle::FormatStringFromAUTF8Name(const nsACString& aName,
                                           const char16_t **aParams,
                                           uint32_t aLength,
@@ -178,81 +193,28 @@ nsStringBundle::FormatStringFromAUTF8Nam
 
 // this function supports at most 10 parameters.. see below for why
 NS_IMETHODIMP
 nsStringBundle::FormatStringFromName(const char* aName,
                                      const char16_t** aParams,
                                      uint32_t aLength,
                                      char16_t** aResult)
 {
-  NS_ENSURE_ARG_POINTER(aName);
+  NS_ENSURE_ARG_POINTER(aResult);
   NS_ASSERTION(aParams && aLength, "FormatStringFromName() without format parameters: use GetStringFromName() instead");
-  NS_ENSURE_ARG_POINTER(aResult);
 
-  nsresult rv;
-  rv = LoadProperties();
-  if (NS_FAILED(rv)) return rv;
+  *aResult = nullptr;
 
   nsAutoString formatStr;
-  rv = GetStringFromName(aName, formatStr);
+  nsresult rv = GetStringFromNameHelper(aName, formatStr);
   if (NS_FAILED(rv)) return rv;
 
   return FormatString(formatStr.get(), aParams, aLength, aResult);
 }
 
-NS_IMPL_ISUPPORTS(nsStringBundle, nsIStringBundle)
-
-NS_IMETHODIMP
-nsStringBundle::GetStringFromID(int32_t aID, char16_t **aResult)
-{
-  nsresult rv;
-  rv = LoadProperties();
-  if (NS_FAILED(rv)) return rv;
-
-  *aResult = nullptr;
-  nsAutoString tmpstr;
-
-  rv = GetStringFromID(aID, tmpstr);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aResult = ToNewUnicode(tmpstr);
-  NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsStringBundle::GetStringFromAUTF8Name(const nsACString& aName,
-                                       char16_t **aResult)
-{
-  return GetStringFromName(PromiseFlatCString(aName).get(), aResult);
-}
-
-NS_IMETHODIMP
-nsStringBundle::GetStringFromName(const char* aName, char16_t** aResult)
-{
-  NS_ENSURE_ARG_POINTER(aName);
-  NS_ENSURE_ARG_POINTER(aResult);
-
-  nsresult rv;
-  rv = LoadProperties();
-  if (NS_FAILED(rv)) return rv;
-
-  ReentrantMonitorAutoEnter automon(mReentrantMonitor);
-  *aResult = nullptr;
-  nsAutoString tmpstr;
-  rv = GetStringFromName(aName, tmpstr);
-  if (NS_FAILED(rv)) return rv;
-
-  *aResult = ToNewUnicode(tmpstr);
-  NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-
-  return NS_OK;
-}
-
 nsresult
 nsStringBundle::GetCombinedEnumeration(nsIStringBundleOverride* aOverrideStrings,
                                        nsISimpleEnumerator** aResult)
 {
   nsCOMPtr<nsISupports> supports;
   nsCOMPtr<nsIPropertyElement> propElement;
 
   nsresult rv;
@@ -338,42 +300,29 @@ nsStringBundle::FormatString(const char1
   NS_ENSURE_ARG(aLength <= 10); // enforce 10-parameter limit
 
   // implementation note: you would think you could use vsmprintf
   // to build up an arbitrary length array.. except that there
   // is no way to build up a va_list at runtime!
   // Don't believe me? See:
   //   http://www.eskimo.com/~scs/C-faq/q15.13.html
   // -alecf
-  char16_t *text =
+  *aResult =
     nsTextFormatter::smprintf(aFormatStr,
                               aLength >= 1 ? aParams[0] : nullptr,
                               aLength >= 2 ? aParams[1] : nullptr,
                               aLength >= 3 ? aParams[2] : nullptr,
                               aLength >= 4 ? aParams[3] : nullptr,
                               aLength >= 5 ? aParams[4] : nullptr,
                               aLength >= 6 ? aParams[5] : nullptr,
                               aLength >= 7 ? aParams[6] : nullptr,
                               aLength >= 8 ? aParams[7] : nullptr,
                               aLength >= 9 ? aParams[8] : nullptr,
                               aLength >= 10 ? aParams[9] : nullptr);
 
-  if (!text) {
-    *aResult = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  // nsTextFormatter does not use the shared nsMemory allocator.
-  // Instead it is required to free the memory it allocates using
-  // nsTextFormatter::smprintf_free.  Let's instead use nsMemory based
-  // allocation for the result that we give out and free the string
-  // returned by smprintf ourselves!
-  *aResult = NS_strdup(text);
-  nsTextFormatter::smprintf_free(text);
-
   return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMPL_ISUPPORTS(nsExtensibleStringBundle, nsIStringBundle)
 
 nsExtensibleStringBundle::nsExtensibleStringBundle()
 {
   mLoaded = false;
@@ -421,28 +370,19 @@ nsExtensibleStringBundle::Init(const cha
 }
 
 nsExtensibleStringBundle::~nsExtensibleStringBundle()
 {
 }
 
 nsresult nsExtensibleStringBundle::GetStringFromID(int32_t aID, char16_t ** aResult)
 {
-  nsresult rv;
-  const uint32_t size = mBundles.Count();
-  for (uint32_t i = 0; i < size; ++i) {
-    nsIStringBundle *bundle = mBundles[i];
-    if (bundle) {
-      rv = bundle->GetStringFromID(aID, aResult);
-      if (NS_SUCCEEDED(rv))
-        return NS_OK;
-    }
-  }
-
-  return NS_ERROR_FAILURE;
+  nsAutoCString idStr;
+  idStr.AppendInt(aID, 10);
+  return GetStringFromName(idStr.get(), aResult);
 }
 
 nsresult nsExtensibleStringBundle::GetStringFromAUTF8Name(
   const nsACString& aName, char16_t ** aResult)
 {
   return GetStringFromName(PromiseFlatCString(aName).get(), aResult);
 }
 
--- a/intl/strres/nsStringBundle.h
+++ b/intl/strres/nsStringBundle.h
@@ -25,19 +25,17 @@ public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSISTRINGBUNDLE
 
     nsCOMPtr<nsIPersistentProperties> mProps;
 
 protected:
     virtual ~nsStringBundle();
 
-    // Functional decomposition of the functions repeatedly called.
-    nsresult GetStringFromID(int32_t aID, nsAString& aResult);
-    nsresult GetStringFromName(const char* aName, nsAString& aResult);
+    nsresult GetStringFromNameHelper(const char* aName, nsAString& aResult);
 
     nsresult GetCombinedEnumeration(nsIStringBundleOverride* aOverrideString,
                                     nsISimpleEnumerator** aResult);
 private:
     nsCString              mPropertiesURL;
     nsCOMPtr<nsIStringBundleOverride> mOverrideStrings;
     mozilla::ReentrantMonitor    mReentrantMonitor;
     bool                         mAttemptedLoad;
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -742,18 +742,16 @@ description =
 [PPluginInstance::NPN_SetValueForURL]
 description =
 [PPluginInstance::NPN_ConvertPoint]
 description =
 [PPluginInstance::GetCompositionString]
 description =
 [PPluginInstance::NPP_NewStream]
 description =
-[PPluginInstance::PPluginStream]
-description =
 [PPluginInstance::PluginFocusChange]
 description =
 [PPluginInstance::SetPluginFocus]
 description =
 [PPluginInstance::UpdateWindow]
 description =
 [PPluginModule::ModuleSupportsAsyncRender]
 description =
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -687,17 +687,17 @@ static MOZ_MUST_USE bool
 NewPromiseCapability(JSContext* cx, HandleObject C, MutableHandleObject promise,
                      MutableHandleObject resolve, MutableHandleObject reject,
                      bool canOmitResolutionFunctions)
 {
     RootedValue cVal(cx, ObjectValue(*C));
 
     // Steps 1-2.
     if (!IsConstructor(C)) {
-        ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, -1, cVal, nullptr);
+        ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_SEARCH_STACK, cVal, nullptr);
         return false;
     }
 
     // If we'd call the original Promise constructor and know that the
     // resolve/reject functions won't ever escape to content, we can skip
     // creating and calling the executor function and instead return a Promise
     // marked as having default resolve/reject functions.
     //
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -640,21 +640,21 @@ frontend::CompileModule(JSContext* cx, c
     return module;
 }
 
 bool
 frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const char16_t* chars, size_t length)
 {
     MOZ_ASSERT(cx->compartment() == lazy->functionNonDelazifying()->compartment());
 
-    uint32_t sourceStartColumn = lazy->scriptSource()->startColumn();
     CompileOptions options(cx, lazy->version());
     options.setMutedErrors(lazy->mutedErrors())
            .setFileAndLine(lazy->filename(), lazy->lineno())
-           .setColumn(lazy->column(), sourceStartColumn)
+           .setColumn(lazy->column())
+           .setScriptSourceOffset(lazy->begin())
            .setNoScriptRval(false)
            .setSelfHostingMode(false);
 
     // Update statistics to find out if we are delazifying just after having
     // lazified. Note that we are interested in the delta between end of
     // syntax parsing and start of full parsing, so we do this now rather than
     // after parsing below.
     if (!lazy->scriptSource()->parseEnded().IsNull()) {
@@ -677,18 +677,19 @@ frontend::CompileLazyFunction(JSContext*
     Parser<FullParseHandler, char16_t> parser(cx, cx->tempLifoAlloc(), options, chars, length,
                                               /* foldConstants = */ true, usedNames, nullptr,
                                               lazy);
     if (!parser.checkOptions())
         return false;
 
     Rooted<JSFunction*> fun(cx, lazy->functionNonDelazifying());
     MOZ_ASSERT(!lazy->isLegacyGenerator());
-    ParseNode* pn = parser.standaloneLazyFunction(fun, lazy->toStringStart() + sourceStartColumn,
-                                                  lazy->strict(), lazy->generatorKind(), lazy->asyncKind());
+    ParseNode* pn = parser.standaloneLazyFunction(fun, lazy->toStringStart(),
+                                                  lazy->strict(), lazy->generatorKind(),
+                                                  lazy->asyncKind());
     if (!pn)
         return false;
 
     RootedScriptSource sourceObject(cx, lazy->sourceObject());
     MOZ_ASSERT(sourceObject);
 
     Rooted<JSScript*> script(cx, JSScript::Create(cx, options, sourceObject,
                                                   lazy->begin(), lazy->end(),
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -10775,24 +10775,18 @@ BytecodeEmitter::emitClass(ParseNode* pn
             if (!emit2(JSOP_INITHOMEOBJECT, 0))                 // ... HOMEOBJ CONSTRUCTOR
                 return false;
         }
     } else {
         // In the case of default class constructors, emit the start and end
         // offsets in the source buffer as source notes so that when we
         // actually make the constructor during execution, we can give it the
         // correct toString output.
-        //
-        // Token positions are already offset from the start column. Since
-        // toString offsets are absolute offsets into the ScriptSource,
-        // de-offset from the starting column.
-        ptrdiff_t classStart = ptrdiff_t(pn->pn_pos.begin) -
-                               tokenStream().options().sourceStartColumn;
-        ptrdiff_t classEnd = ptrdiff_t(pn->pn_pos.end) -
-                             tokenStream().options().sourceStartColumn;
+        ptrdiff_t classStart = ptrdiff_t(pn->pn_pos.begin);
+        ptrdiff_t classEnd = ptrdiff_t(pn->pn_pos.end);
         if (!newSrcNote3(SRC_CLASS_SPAN, classStart, classEnd))
             return false;
 
         JSAtom *name = names ? names->innerBinding()->pn_atom : cx->names().empty;
         if (heritageExpression) {
             if (!emitAtomOp(name, JSOP_DERIVEDCONSTRUCTOR))     // ... HOMEOBJ CONSTRUCTOR
                 return false;
         } else {
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -3049,31 +3049,40 @@ Parser<ParseHandler, CharT>::functionArg
         firstTokenModifier = funbox->isAsync() ? TokenStream::None : TokenStream::Operand;
         if (!tokenStream.peekToken(&tt, firstTokenModifier))
             return false;
         if (TokenKindIsPossibleIdentifier(tt)) {
             parenFreeArrow = true;
             argModifier = firstTokenModifier;
         }
     }
+
+    TokenPos firstTokenPos;
     if (!parenFreeArrow) {
         TokenKind tt;
         if (!tokenStream.getToken(&tt, firstTokenModifier))
             return false;
         if (tt != TOK_LP) {
             error(kind == Arrow ? JSMSG_BAD_ARROW_ARGS : JSMSG_PAREN_BEFORE_FORMAL);
             return false;
         }
 
+        firstTokenPos = pos();
+
         // Record the start of function source (for FunctionToString). If we
         // are parenFreeArrow, we will set this below, after consuming the NAME.
         funbox->setStart(tokenStream);
-    }
-
-    Node argsbody = handler.newList(PNK_PARAMSBODY, pos());
+    } else {
+        // When delazifying, we may not have a current token and pos() is
+        // garbage. In that case, substitute the first token's position.
+        if (!tokenStream.peekTokenPos(&firstTokenPos, firstTokenModifier))
+            return false;
+    }
+
+    Node argsbody = handler.newList(PNK_PARAMSBODY, firstTokenPos);
     if (!argsbody)
         return false;
     handler.setFunctionFormalParametersAndBody(funcpn, argsbody);
 
     bool hasArguments = false;
     if (parenFreeArrow) {
         hasArguments = true;
     } else {
@@ -3290,23 +3299,17 @@ Parser<FullParseHandler, char16_t>::skip
     LazyScript* lazy = fun->lazyScript();
     if (lazy->needsHomeObject())
         funbox->setNeedsHomeObject();
     if (lazy->isExprBody())
         funbox->setIsExprBody();
 
     PropagateTransitiveParseFlags(lazy, pc->sc());
 
-    // The position passed to tokenStream.advance() is an offset of the sort
-    // returned by userbuf.offset() and expected by userbuf.rawCharPtrAt(),
-    // while LazyScript::{begin,end} offsets are relative to the outermost
-    // script source.
-    Rooted<LazyScript*> lazyOuter(context, handler.lazyOuterFunction());
-    uint32_t userbufBase = lazyOuter->begin() - lazyOuter->column();
-    if (!tokenStream.advance(fun->lazyScript()->end() - userbufBase))
+    if (!tokenStream.advance(fun->lazyScript()->end()))
         return false;
 
 #if JS_HAS_EXPR_CLOSURES
     // Only expression closure can be Statement kind.
     // If we remove expression closure, we can remove isExprBody flag from
     // LazyScript and JSScript.
     if (kind == Statement && funbox->isExprBody()) {
         if (!matchOrInsertSemicolonAfterExpression())
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -556,42 +556,28 @@ class FunctionBox : public ObjectBox, pu
     // while the function is being reparsed. This flag can be used to disable
     // certain parsing features that are necessary in general, but unnecessary
     // for validated asm.js.
     bool useAsmOrInsideUseAsm() const {
         return useAsm || insideUseAsm;
     }
 
     void setStart(const TokenStream& tokenStream) {
-        // Token positions are already offset from the start column in
-        // CompileOptions. bufStart and toStringStart, however, refer to
-        // absolute positions within the ScriptSource buffer, and need to
-        // de-offset from the starting column.
         uint32_t offset = tokenStream.currentToken().pos.begin;
-        uint32_t sourceStartColumn = tokenStream.options().sourceStartColumn;
-
-        MOZ_ASSERT(offset >= sourceStartColumn);
-        MOZ_ASSERT(toStringStart >= sourceStartColumn);
-        toStringStart -= sourceStartColumn;
-        bufStart = offset - sourceStartColumn;
+        bufStart = offset;
         tokenStream.srcCoords.lineNumAndColumnIndex(offset, &startLine, &startColumn);
     }
 
     void setEnd(const TokenStream& tokenStream) {
         // For all functions except class constructors, the buffer and
         // toString ending positions are the same. Class constructors override
         // the toString ending position with the end of the class definition.
-        //
-        // Offsets are de-offset for the same reason as in setStart above.
         uint32_t offset = tokenStream.currentToken().pos.end;
-        uint32_t sourceStartColumn = tokenStream.options().sourceStartColumn;
-
-        MOZ_ASSERT(offset >= sourceStartColumn);
-        bufEnd = offset - sourceStartColumn;
-        toStringEnd = bufEnd;
+        bufEnd = offset;
+        toStringEnd = offset;
     }
 
     void trace(JSTracer* trc) override;
 };
 
 inline FunctionBox*
 SharedContext::asFunctionBox()
 {
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -243,44 +243,46 @@ TokenStreamAnyChars::reservedWordToPrope
       FOR_EACH_JAVASCRIPT_RESERVED_WORD(EMIT_CASE)
 #undef EMIT_CASE
       default:
         MOZ_ASSERT_UNREACHABLE("Not a reserved word TokenKind.");
     }
     return nullptr;
 }
 
-TokenStream::SourceCoords::SourceCoords(JSContext* cx, uint32_t ln)
-  : lineStartOffsets_(cx), initialLineNum_(ln), lastLineIndex_(0)
+TokenStream::SourceCoords::SourceCoords(JSContext* cx, uint32_t ln, uint32_t col,
+                                        uint32_t initialLineOffset)
+  : lineStartOffsets_(cx), initialLineNum_(ln), initialColumn_(col), lastLineIndex_(0)
 {
     // This is actually necessary!  Removing it causes compile errors on
     // GCC and clang.  You could try declaring this:
     //
     //   const uint32_t TokenStream::SourceCoords::MAX_PTR;
     //
     // which fixes the GCC/clang error, but causes bustage on Windows.  Sigh.
     //
     uint32_t maxPtr = MAX_PTR;
 
-    // The first line begins at buffer offset 0.  MAX_PTR is the sentinel.  The
-    // appends cannot fail because |lineStartOffsets_| has statically-allocated
-    // elements.
+    // The first line begins at buffer offset |initialLineOffset|.  MAX_PTR is
+    // the sentinel.  The appends cannot fail because |lineStartOffsets_| has
+    // statically-allocated elements.
     MOZ_ASSERT(lineStartOffsets_.capacity() >= 2);
     MOZ_ALWAYS_TRUE(lineStartOffsets_.reserve(2));
-    lineStartOffsets_.infallibleAppend(0);
+    lineStartOffsets_.infallibleAppend(initialLineOffset);
     lineStartOffsets_.infallibleAppend(maxPtr);
 }
 
 MOZ_ALWAYS_INLINE bool
 TokenStream::SourceCoords::add(uint32_t lineNum, uint32_t lineStartOffset)
 {
     uint32_t lineIndex = lineNumToIndex(lineNum);
     uint32_t sentinelIndex = lineStartOffsets_.length() - 1;
 
-    MOZ_ASSERT(lineStartOffsets_[0] == 0 && lineStartOffsets_[sentinelIndex] == MAX_PTR);
+    MOZ_ASSERT(lineStartOffsets_[0] <= lineStartOffset &&
+               lineStartOffsets_[sentinelIndex] == MAX_PTR);
 
     if (lineIndex == sentinelIndex) {
         // We haven't seen this newline before.  Update lineStartOffsets_
         // only if lineStartOffsets_.append succeeds, to keep sentinel.
         // Otherwise return false to tell TokenStream about OOM.
         uint32_t maxPtr = MAX_PTR;
         if (!lineStartOffsets_.append(maxPtr)) {
             static_assert(mozilla::IsSame<decltype(lineStartOffsets_.allocPolicy()),
@@ -298,16 +300,17 @@ TokenStream::SourceCoords::add(uint32_t 
         MOZ_ASSERT_IF(lineIndex < sentinelIndex, lineStartOffsets_[lineIndex] == lineStartOffset);
     }
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
 TokenStreamAnyChars::SourceCoords::fill(const TokenStreamAnyChars::SourceCoords& other)
 {
+    MOZ_ASSERT(lineStartOffsets_[0] == other.lineStartOffsets_[0]);
     MOZ_ASSERT(lineStartOffsets_.back() == MAX_PTR);
     MOZ_ASSERT(other.lineStartOffsets_.back() == MAX_PTR);
 
     if (lineStartOffsets_.length() >= other.lineStartOffsets_.length())
         return true;
 
     uint32_t sentinelIndex = lineStartOffsets_.length() - 1;
     lineStartOffsets_[sentinelIndex] = other.lineStartOffsets_[sentinelIndex];
@@ -375,41 +378,36 @@ TokenStreamAnyChars::SourceCoords::lineN
 {
     uint32_t lineIndex = lineIndexOf(offset);
     return lineIndexToNum(lineIndex);
 }
 
 uint32_t
 TokenStreamAnyChars::SourceCoords::columnIndex(uint32_t offset) const
 {
-    uint32_t lineIndex = lineIndexOf(offset);
-    uint32_t lineStartOffset = lineStartOffsets_[lineIndex];
-    MOZ_ASSERT(offset >= lineStartOffset);
-    return offset - lineStartOffset;
+    return lineIndexAndOffsetToColumn(lineIndexOf(offset), offset);
 }
 
 void
 TokenStreamAnyChars::SourceCoords::lineNumAndColumnIndex(uint32_t offset, uint32_t* lineNum,
-                                                         uint32_t* columnIndex) const
+                                                         uint32_t* column) const
 {
     uint32_t lineIndex = lineIndexOf(offset);
     *lineNum = lineIndexToNum(lineIndex);
-    uint32_t lineStartOffset = lineStartOffsets_[lineIndex];
-    MOZ_ASSERT(offset >= lineStartOffset);
-    *columnIndex = offset - lineStartOffset;
+    *column = lineIndexAndOffsetToColumn(lineIndex, offset);
 }
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4351)
 #endif
 
 TokenStreamAnyChars::TokenStreamAnyChars(JSContext* cx, const ReadOnlyCompileOptions& options,
                                          StrictModeGetter* smg)
-  : srcCoords(cx, options.lineno),
+  : srcCoords(cx, options.lineno, options.column, options.scriptSourceOffset),
     options_(options),
     tokens(),
     cursor(),
     lookahead(),
     lineno(options.lineno),
     flags(),
     linebase(0),
     prevLinebase(size_t(-1)),
@@ -420,17 +418,17 @@ TokenStreamAnyChars::TokenStreamAnyChars
     mutedErrors(options.mutedErrors()),
     strictModeGetter(smg)
 {
 }
 
 TokenStream::TokenStream(JSContext* cx, const ReadOnlyCompileOptions& options,
                          const CharT* base, size_t length, StrictModeGetter* smg)
   : TokenStreamAnyChars(cx, options, smg),
-    userbuf(cx, base, length, options.column),
+    userbuf(cx, base, length, options.scriptSourceOffset),
     tokenbuf(cx)
 {
     // Nb: the following tables could be static, but initializing them here is
     // much easier.  Don't worry, the time to initialize them for each
     // TokenStream is trivial.  See bug 639420.
 
     // See Parser::assignExpr() for an explanation of isExprEnding[].
     memset(isExprEnding, 0, sizeof(isExprEnding));
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -461,17 +461,18 @@ class TokenStreamAnyChars
 
     // This class maps a userbuf offset (which is 0-indexed) to a line number
     // (which is 1-indexed) and a column index (which is 0-indexed).
     class SourceCoords
     {
         // For a given buffer holding source code, |lineStartOffsets_| has one
         // element per line of source code, plus one sentinel element.  Each
         // non-sentinel element holds the buffer offset for the start of the
-        // corresponding line of source code.  For this example script:
+        // corresponding line of source code.  For this example script,
+        // assuming an initialLineOffset of 0:
         //
         // 1  // xyz            [line starts at offset 0]
         // 2  var x;            [line starts at offset 7]
         // 3                    [line starts at offset 14]
         // 4  var y;            [line starts at offset 15]
         //
         // |lineStartOffsets_| is:
         //
@@ -479,59 +480,68 @@ class TokenStreamAnyChars
         //
         // To convert a "line number" to a "line index" (i.e. an index into
         // |lineStartOffsets_|), subtract |initialLineNum_|.  E.g. line 3's
         // line index is (3 - initialLineNum_), which is 2.  Therefore
         // lineStartOffsets_[2] holds the buffer offset for the start of line 3,
         // which is 14.  (Note that |initialLineNum_| is often 1, but not
         // always.)
         //
-        // The first element is always 0, and the last element is always the
-        // MAX_PTR sentinel.
+        // The first element is always initialLineOffset, passed to the
+        // constructor, and the last element is always the MAX_PTR sentinel.
         //
         // offset-to-line/column lookups are O(log n) in the worst case (binary
         // search), but in practice they're heavily clustered and we do better
         // than that by using the previous lookup's result (lastLineIndex_) as
         // a starting point.
         //
         // Checking if an offset lies within a particular line number
         // (isOnThisLine()) is O(1).
         //
         Vector<uint32_t, 128> lineStartOffsets_;
         uint32_t            initialLineNum_;
+        uint32_t            initialColumn_;
 
         // This is mutable because it's modified on every search, but that fact
         // isn't visible outside this class.
         mutable uint32_t    lastLineIndex_;
 
         uint32_t lineIndexOf(uint32_t offset) const;
 
         static const uint32_t MAX_PTR = UINT32_MAX;
 
         uint32_t lineIndexToNum(uint32_t lineIndex) const { return lineIndex + initialLineNum_; }
         uint32_t lineNumToIndex(uint32_t lineNum)   const { return lineNum   - initialLineNum_; }
+        uint32_t lineIndexAndOffsetToColumn(uint32_t lineIndex, uint32_t offset) const {
+            uint32_t lineStartOffset = lineStartOffsets_[lineIndex];
+            MOZ_RELEASE_ASSERT(offset >= lineStartOffset);
+            uint32_t column = offset - lineStartOffset;
+            if (lineIndex == 0)
+                return column + initialColumn_;
+            return column;
+        }
 
       public:
-        SourceCoords(JSContext* cx, uint32_t ln);
+        SourceCoords(JSContext* cx, uint32_t ln, uint32_t col, uint32_t initialLineOffset);
 
         MOZ_MUST_USE bool add(uint32_t lineNum, uint32_t lineStartOffset);
         MOZ_MUST_USE bool fill(const SourceCoords& other);
 
         bool isOnThisLine(uint32_t offset, uint32_t lineNum, bool* onThisLine) const {
             uint32_t lineIndex = lineNumToIndex(lineNum);
             if (lineIndex + 1 >= lineStartOffsets_.length()) // +1 due to sentinel
                 return false;
             *onThisLine = lineStartOffsets_[lineIndex] <= offset &&
                           offset < lineStartOffsets_[lineIndex + 1];
             return true;
         }
 
         uint32_t lineNum(uint32_t offset) const;
         uint32_t columnIndex(uint32_t offset) const;
-        void lineNumAndColumnIndex(uint32_t offset, uint32_t* lineNum, uint32_t* columnIndex) const;
+        void lineNumAndColumnIndex(uint32_t offset, uint32_t* lineNum, uint32_t* column) const;
     };
 
     SourceCoords srcCoords;
 
     JSAtomState& names() const {
         return cx->names();
     }
 
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -472,16 +472,27 @@ js::Nursery::renderProfileJSON(JSONPrint
 {
     if (!isEnabled()) {
         json.beginObject();
         json.property("status", "nursery disabled");
         json.endObject();
         return;
     }
 
+    if (previousGC.reason == JS::gcreason::NO_REASON) {
+        // If the nursery was empty when the last minorGC was requested, then
+        // no nursery collection will have been performed but JSON may still be
+        // requested. (And as a public API, this function should not crash in
+        // such a case.)
+        json.beginObject();
+        json.property("status", "no collection");
+        json.endObject();
+        return;
+    }
+
     json.beginObject();
 
     json.property("reason", JS::gcreason::ExplainReason(previousGC.reason));
     json.property("bytes_tenured", previousGC.tenuredBytes);
     json.floatProperty("promotion_rate",
                        100.0 * previousGC.tenuredBytes / double(previousGC.nurseryUsedBytes), 2);
     json.property("nursery_bytes", previousGC.nurseryUsedBytes);
     json.property("new_nursery_bytes", numChunks() * ChunkSize);
@@ -596,16 +607,17 @@ js::Nursery::collect(JS::gcreason::Reaso
     startProfile(ProfileKey::Total);
 
     // The hazard analysis thinks doCollection can invalidate pointers in
     // tenureCounts below.
     JS::AutoSuppressGCAnalysis nogc;
 
     TenureCountCache tenureCounts;
     double promotionRate = 0;
+    previousGC.reason = JS::gcreason::NO_REASON;
     if (!isEmpty())
         promotionRate = doCollection(reason, tenureCounts);
 
     // Resize the nursery.
     startProfile(ProfileKey::Resize);
     maybeResizeNursery(reason, promotionRate);
     endProfile(ProfileKey::Resize);
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-eval-33.js
@@ -0,0 +1,38 @@
+load(libdir + "evalInFrame.js");
+
+// Test that computing the implicit 'this' in calls for D.F.eval is as if it
+// were a pasted-in eval.
+
+var G = this;
+
+function globalFun(check, expectedThis) {
+  if (check)
+    assertEq(this, expectedThis);
+  return this;
+}
+var expectedGlobalFunThis = globalFun(false);
+evalInFrame(0, "globalFun(true, expectedGlobalFunThis)");
+
+(function testInnerFun() {
+  function innerFun(check, expectedThis) {
+    if (check)
+      assertEq(this, expectedThis);
+    return this;
+  }
+  var expectedInnerFunThis = innerFun(false);
+  evalInFrame(0, "innerFun(true, expectedInnerFunThis)");
+})();
+
+(function testWith() {
+  var o = {
+    withFun: function withFun(check, expectedThis) {
+      if (check)
+        assertEq(this, expectedThis);
+      return this;
+    }
+  };
+  with (o) {
+    var expectedWithFunThis = withFun(false);
+    evalInFrame(0, "withFun(true, expectedWithFunThis)");
+  }
+})();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/parser/bug-1366927.js
@@ -0,0 +1,1 @@
+evaluate("\n(y => 1)()", { columnNumber: 1729 })
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/promise/newpromisecapability-error-message.js
@@ -0,0 +1,20 @@
+load(libdir + "asserts.js");
+
+let foo = {};
+for (let method of ["resolve", "reject", "race"]) {
+  assertErrorMessage(
+    () => Promise[method].call(foo),
+    TypeError,
+    "foo is not a constructor"
+  );
+  assertErrorMessage(
+    () => Promise[method].call(foo, []),
+    TypeError,
+    "foo is not a constructor"
+  );
+  assertErrorMessage(
+    () => Promise[method].call({}, [], foo),
+    TypeError,
+    "({}) is not a constructor"
+  );
+}
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -6450,28 +6450,41 @@ IonBuilder::jsop_initprop(PropertyName* 
         } else {
             useSlowPath = true;
         }
     } else {
         MOZ_ASSERT(obj->isUnbox() && obj->getOperand(0)->isNullarySharedStub());
         useSlowPath = true;
     }
 
-    if (useSlowPath) {
-        current->pop();
-        MInitProp* init = MInitProp::New(alloc(), obj, name, value);
-        current->add(init);
-        return resumeAfter(init);
-    }
-
     MInstruction* last = *current->rbegin();
 
-    // This is definitely initializing an 'own' property of the object, treat
-    // it as an assignment.
-    MOZ_TRY(jsop_setprop(name));
+    if (!useSlowPath && !forceInlineCaches()) {
+        // This is definitely initializing an 'own' property of the object, treat
+        // it as an assignment.
+        MOZ_TRY(jsop_setprop(name));
+    } else {
+        if (*pc != JSOP_INITPROP) {
+            current->pop();
+            MInitProp* init = MInitProp::New(alloc(), obj, name, value);
+            current->add(init);
+            return resumeAfter(init);
+        }
+
+        MDefinition* value = current->pop();
+        MDefinition* obj = current->pop();
+
+        TemporaryTypeSet* objTypes = obj->resultTypeSet();
+        bool barrier = PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, name, &value,
+                                                 /* canModify = */ true);
+
+        bool emitted = false;
+        MOZ_TRY(setPropTryCache(&emitted, obj, name, value, barrier, objTypes));
+        MOZ_ASSERT(emitted == true);
+    }
 
     // SETPROP pushed the value, instead of the object. Fix this on the stack,
     // and check the most recent resume point to see if it needs updating too.
     current->pop();
     current->push(obj);
     for (MInstructionReverseIterator riter = current->rbegin(); *riter != last; riter++) {
         if (MResumePoint* resumePoint = riter->resumePoint()) {
             MOZ_ASSERT(resumePoint->pc() == pc);
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -6182,46 +6182,43 @@ jit::PropertyReadNeedsTypeBarrier(JSCont
                                   TemporaryTypeSet* observed, bool updateObserved)
 {
     if (!updateObserved)
         return PropertyReadNeedsTypeBarrier(constraints, key, name, observed);
 
     // If this access has never executed, try to add types to the observed set
     // according to any property which exists on the object or its prototype.
     if (observed->empty() && name) {
-        JSObject* obj;
-        if (key->isSingleton())
-            obj = key->singleton();
-        else
-            obj = key->proto().isDynamic() ? nullptr : key->proto().toObjectOrNull();
-
-        while (obj) {
-            if (!obj->getClass()->isNative())
+        TypeSet::ObjectKey* obj = key;
+        do {
+            if (!obj->clasp()->isNative())
                 break;
 
-            TypeSet::ObjectKey* key = TypeSet::ObjectKey::get(obj);
             if (propertycx)
-                key->ensureTrackedProperty(propertycx, NameToId(name));
-
-            if (!key->unknownProperties()) {
-                HeapTypeSetKey property = key->property(NameToId(name));
-                if (property.maybeTypes()) {
-                    TypeSet::TypeList types;
-                    if (!property.maybeTypes()->enumerateTypes(&types))
-                        break;
-                    if (types.length() == 1) {
-                        // Note: the return value here is ignored.
-                        observed->addType(types[0], GetJitContext()->temp->lifoAlloc());
-                        break;
-                    }
+                obj->ensureTrackedProperty(propertycx, NameToId(name));
+
+            if (obj->unknownProperties())
+                break;
+
+            HeapTypeSetKey property = obj->property(NameToId(name));
+            if (property.maybeTypes()) {
+                TypeSet::TypeList types;
+                if (!property.maybeTypes()->enumerateTypes(&types))
+                    break;
+                if (types.length() == 1) {
+                    // Note: the return value here is ignored.
+                    observed->addType(types[0], GetJitContext()->temp->lifoAlloc());
                 }
+                break;
             }
 
-            obj = obj->staticPrototype();
-        }
+            if (!obj->proto().isObject())
+                break;
+            obj = TypeSet::ObjectKey::get(obj->proto().toObject());
+        } while (obj);
     }
 
     // If any objects which could be observed are similar to ones that have
     // already been observed, add them to the observed type set.
     if (!key->unknownProperties()) {
         HeapTypeSetKey property = key->property(name ? NameToId(name) : JSID_VOID);
 
         if (property.maybeTypes() && !property.maybeTypes()->unknownObject()) {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3937,17 +3937,17 @@ JS::TransitiveCompileOptions::copyPODTra
 };
 
 void
 JS::ReadOnlyCompileOptions::copyPODOptions(const ReadOnlyCompileOptions& rhs)
 {
     copyPODTransitiveOptions(rhs);
     lineno = rhs.lineno;
     column = rhs.column;
-    sourceStartColumn = rhs.sourceStartColumn;
+    scriptSourceOffset = rhs.scriptSourceOffset;
     isRunOnce = rhs.isRunOnce;
     noScriptRval = rhs.noScriptRval;
 }
 
 JS::OwningCompileOptions::OwningCompileOptions(JSContext* cx)
     : ReadOnlyCompileOptions(),
       elementRoot(cx),
       elementAttributeNameRoot(cx),
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3973,17 +3973,17 @@ class JS_FRIEND_API(ReadOnlyCompileOptio
 {
     friend class CompileOptions;
 
   protected:
     ReadOnlyCompileOptions()
       : TransitiveCompileOptions(),
         lineno(1),
         column(0),
-        sourceStartColumn(0),
+        scriptSourceOffset(0),
         isRunOnce(false),
         noScriptRval(false)
     { }
 
     // Set all POD options (those not requiring reference counts, copies,
     // rooting, or other hand-holding) to their values in |rhs|.
     void copyPODOptions(const ReadOnlyCompileOptions& rhs);
 
@@ -3996,17 +3996,28 @@ class JS_FRIEND_API(ReadOnlyCompileOptio
     const char16_t* sourceMapURL() const { return sourceMapURL_; }
     virtual JSObject* element() const = 0;
     virtual JSString* elementAttributeName() const = 0;
     virtual JSScript* introductionScript() const = 0;
 
     // POD options.
     unsigned lineno;
     unsigned column;
-    unsigned sourceStartColumn;
+    // The offset within the ScriptSource's full uncompressed text of the first
+    // character we're presenting for compilation with this CompileOptions.
+    //
+    // When we compile a LazyScript, we pass the compiler only the substring of
+    // the source the lazy function occupies. With chunked decompression, we
+    // may not even have the complete uncompressed source present in memory. But
+    // parse node positions are offsets within the ScriptSource's full text,
+    // and LazyScripts indicate their substring of the full source by its
+    // starting and ending offsets within the full text. This
+    // scriptSourceOffset field lets the frontend convert between these
+    // offsets and offsets within the substring presented for compilation.
+    unsigned scriptSourceOffset;
     // isRunOnce only applies to non-function scripts.
     bool isRunOnce;
     bool noScriptRval;
 
   private:
     void operator=(const ReadOnlyCompileOptions&) = delete;
 };
 
@@ -4069,22 +4080,18 @@ class JS_FRIEND_API(OwningCompileOptions
         return *this;
     }
     OwningCompileOptions& setVersion(JSVersion v) {
         version = v;
         versionSet = true;
         return *this;
     }
     OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
-    OwningCompileOptions& setColumn(unsigned c, unsigned ssc) {
-        MOZ_ASSERT(ssc <= c);
-        column = c;
-        sourceStartColumn = ssc;
-        return *this;
-    }
+    OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; }
+    OwningCompileOptions& setScriptSourceOffset(unsigned o) { scriptSourceOffset = o; return *this; }
     OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
     OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
     OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
     OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
     OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
     OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
     bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro,
                              unsigned line, JSScript* script, uint32_t offset)
@@ -4170,22 +4177,18 @@ class MOZ_STACK_CLASS JS_FRIEND_API(Comp
         return *this;
     }
     CompileOptions& setVersion(JSVersion v) {
         version = v;
         versionSet = true;
         return *this;
     }
     CompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
-    CompileOptions& setColumn(unsigned c, unsigned ssc) {
-        MOZ_ASSERT(ssc <= c);
-        column = c;
-        sourceStartColumn = ssc;
-        return *this;
-    }
+    CompileOptions& setColumn(unsigned c) { column = c; return *this; }
+    CompileOptions& setScriptSourceOffset(unsigned o) { scriptSourceOffset = o; return *this; }
     CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
     CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
     CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
     CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
     CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
     CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
     CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro,
                                         unsigned line, JSScript* script, uint32_t offset)
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -2321,17 +2321,16 @@ ScriptSource::initFromOptions(JSContext*
 {
     MOZ_ASSERT(!filename_);
     MOZ_ASSERT(!introducerFilename_);
 
     mutedErrors_ = options.mutedErrors();
 
     introductionType_ = options.introductionType;
     setIntroductionOffset(options.introductionOffset);
-    startColumn_ = options.sourceStartColumn;
     parameterListEnd_ = parameterListEnd.isSome() ? parameterListEnd.value() : 0;
 
     if (options.hasIntroductionInfo) {
         MOZ_ASSERT(options.introductionType != nullptr);
         const char* filename = options.filename() ? options.filename() : "<unknown>";
         char* formatted = FormatIntroducedFilename(cx, filename, options.introductionLineno,
                                                    options.introductionType);
         if (!formatted)
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -429,22 +429,16 @@ class ScriptSource
 
     // The filename of this script.
     UniqueChars filename_;
 
     UniqueTwoByteChars displayURL_;
     UniqueTwoByteChars sourceMapURL_;
     bool mutedErrors_;
 
-    // The start column of the source. Offsets kept for toString and the
-    // function source in LazyScripts are absolute positions within a
-    // ScriptSource buffer. To get their positions, they need to be offset
-    // with the starting column.
-    uint32_t startColumn_;
-
     // bytecode offset in caller script that generated this code.
     // This is present for eval-ed code, as well as "new Function(...)"-introduced
     // scripts.
     uint32_t introductionOffset_;
 
     // If this source is for Function constructor, the position of ")" after
     // parameter list in the source.  This is used to get function body.
     // 0 for other cases.
@@ -511,17 +505,16 @@ class ScriptSource
     explicit ScriptSource()
       : refs(0),
         data(SourceType(Missing())),
         pinnedCharsStack_(nullptr),
         filename_(nullptr),
         displayURL_(nullptr),
         sourceMapURL_(nullptr),
         mutedErrors_(false),
-        startColumn_(0),
         introductionOffset_(0),
         parameterListEnd_(0),
         introducerFilename_(nullptr),
         introductionType_(nullptr),
         xdrEncoder_(nullptr),
         sourceRetrievable_(false),
         hasIntroductionOffset_(false)
     {
@@ -626,18 +619,16 @@ class ScriptSource
     bool hasSourceMapURL() const { return sourceMapURL_ != nullptr; }
     const char16_t * sourceMapURL() {
         MOZ_ASSERT(hasSourceMapURL());
         return sourceMapURL_.get();
     }
 
     bool mutedErrors() const { return mutedErrors_; }
 
-    uint32_t startColumn() const { return startColumn_; }
-
     bool hasIntroductionOffset() const { return hasIntroductionOffset_; }
     uint32_t introductionOffset() const {
         MOZ_ASSERT(hasIntroductionOffset());
         return introductionOffset_;
     }
     void setIntroductionOffset(uint32_t offset) {
         MOZ_ASSERT(!hasIntroductionOffset());
         MOZ_ASSERT(offset <= (uint32_t)INT32_MAX);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1300,17 +1300,17 @@ ParseCompileOptions(JSContext* cx, Compi
     }
 
     if (!JS_GetProperty(cx, opts, "columnNumber", &v))
         return false;
     if (!v.isUndefined()) {
         int32_t c;
         if (!ToInt32(cx, v, &c))
             return false;
-        options.setColumn(c, c);
+        options.setColumn(c);
     }
 
     if (!JS_GetProperty(cx, opts, "sourceIsLazy", &v))
         return false;
     if (v.isBoolean())
         options.setSourceIsLazy(v.toBoolean());
 
     return true;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1465,16 +1465,22 @@ static inline Value
 ComputeImplicitThis(JSObject* obj)
 {
     if (obj->is<GlobalObject>())
         return UndefinedValue();
 
     if (IsCacheableEnvironment(obj))
         return UndefinedValue();
 
+    // Debugger environments need special casing, as despite being
+    // non-syntactic, they wrap syntactic environments and should not be
+    // treated like other embedding-specific non-syntactic environments.
+    if (obj->is<DebugEnvironmentProxy>())
+        return ComputeImplicitThis(&obj->as<DebugEnvironmentProxy>().environment());
+
     return GetThisValue(obj);
 }
 
 static MOZ_ALWAYS_INLINE bool
 AddOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
 {
     if (lhs.isInt32() && rhs.isInt32()) {
         int32_t l = lhs.toInt32(), r = rhs.toInt32();
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -1058,27 +1058,40 @@ nsDocumentViewer::LoadComplete(nsresult 
 
     // If the document presentation is being restored, we don't want to fire
     // onload to the document content since that would likely confuse scripts
     // on the page.
 
     nsIDocShell *docShell = window->GetDocShell();
     NS_ENSURE_TRUE(docShell, NS_ERROR_UNEXPECTED);
 
-    docShell->GetRestoringDocument(&restoring);
+    // Unfortunately, docShell->GetRestoringDocument() might no longer be set
+    // correctly.  In particular, it can be false by now if someone took it upon
+    // themselves to block onload from inside restoration and unblock it later.
+    // But we can detect the restoring case very simply: by whether our
+    // document's readyState is COMPLETE.
+    restoring = (mDocument->GetReadyStateEnum() ==
+                 nsIDocument::READYSTATE_COMPLETE);
     if (!restoring) {
       NS_ASSERTION(mDocument->IsXULDocument() || // readyState for XUL is bogus
                    mDocument->GetReadyStateEnum() ==
                      nsIDocument::READYSTATE_INTERACTIVE ||
                    // test_stricttransportsecurity.html has old-style
                    // docshell-generated about:blank docs reach this code!
                    (mDocument->GetReadyStateEnum() ==
                       nsIDocument::READYSTATE_UNINITIALIZED &&
                     NS_IsAboutBlank(mDocument->GetDocumentURI())),
                    "Bad readystate");
+#ifdef DEBUG
+      bool docShellThinksWeAreRestoring;
+      docShell->GetRestoringDocument(&docShellThinksWeAreRestoring);
+      MOZ_ASSERT(!docShellThinksWeAreRestoring,
+                 "How can docshell think we are restoring if we don't have a "
+                 "READYSTATE_COMPLETE document?");
+#endif // DEBUG
       nsCOMPtr<nsIDocument> d = mDocument;
       mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
 
       RefPtr<nsDOMNavigationTiming> timing(d->GetNavigationTiming());
       if (timing) {
         timing->NotifyLoadEventStart();
       }
 
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1408,20 +1408,25 @@ nsPresContext::SetFullZoom(float aZoom)
   AppUnitsPerDevPixelChanged();
 
   mSuppressResizeReflow = false;
 }
 
 void
 nsPresContext::SetOverrideDPPX(float aDPPX)
 {
-  mOverrideDPPX = aDPPX;
-
-  if (HasCachedStyleData()) {
-    MediaFeatureValuesChanged(nsRestyleHint(0), nsChangeHint(0));
+  // SetOverrideDPPX is called during navigations, including history
+  // traversals.  In that case, it's typically called with our current value,
+  // and we don't need to actually do anything.
+  if (aDPPX != mOverrideDPPX) {
+    mOverrideDPPX = aDPPX;
+
+    if (HasCachedStyleData()) {
+      MediaFeatureValuesChanged(nsRestyleHint(0), nsChangeHint(0));
+    }
   }
 }
 
 gfxSize
 nsPresContext::ScreenSizeInchesForFontInflation(bool* aChanged)
 {
   if (aChanged) {
     *aChanged = false;
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/chrome/bug1041200_frame.html
@@ -0,0 +1,2 @@
+<body onload='parent.childLoaded()' style='background:lime'>
+<p>Hello<p>Hello<p>Hello<p>Hello<p>Hello<p>
--- a/layout/base/tests/chrome/bug1041200_window.html
+++ b/layout/base/tests/chrome/bug1041200_window.html
@@ -22,17 +22,17 @@ var viewer =
                .contentViewer;
 viewer.fullZoom = 2;
 
 SimpleTest.waitForExplicitFinish();
 
 window.onload = function() {
   window.waitForAllPaintsFlushed(function () {
     // Supply random key to ensure load actually happens
-    ourFrame.src = "data:text/html,<body onload='parent.childLoaded()' style='background:lime'><p>Hello<p>Hello<p>Hello<p>Hello<p>Hello<p>" + Math.random();
+    ourFrame.src = "bug1041200_frame.html?" + Math.random();
   }, document.getElementById("ourFrame").contentDocument);
 };
 
 window.childLoaded = function() {
   setTimeout(function() {
     window.waitForAllPaintsFlushed(function(x1, y1, x2, y2) {
       ok(x2 - x1 >= 700 && y2 - y1 >= 500,
          "expected to see invalidate of entire frame, got " + [x1,y1,x2,y2].join(','));
--- a/layout/base/tests/chrome/chrome.ini
+++ b/layout/base/tests/chrome/chrome.ini
@@ -3,16 +3,17 @@ skip-if = os == 'android'
 support-files =
   animated.gif
   blue-32x32.png
   bug495648.rdf
   bug551434_childframe.html
   chrome_content_integration_window.xul
   default_background_window.xul
   dialog_with_positioning_window.xul
+  file_bug458898.html
   no_clip_iframe_subdoc.html
   no_clip_iframe_window.xul
   printpreview_bug396024_helper.xul
   printpreview_bug482976_helper.xul
   printpreview_helper.xul
   file_bug1018265.xul
 
 [test_bug396367-1.html]
@@ -25,17 +26,19 @@ support-files =
 [test_bug533845.xul]
 skip-if = os == 'linux' && !debug # Bug 1208197
 [test_bug551434.html]
 [test_bug708062.html]
 [test_bug812817.xul]
 [test_bug847890_paintFlashing.html]
 [test_bug1018265.xul]
 [test_bug1041200.xul]
-support-files=bug1041200_window.html
+support-files =
+  bug1041200_frame.html
+  bug1041200_window.html
 [test_chrome_content_integration.xul]
 [test_chrome_over_plugin.xul]
 support-files =
   chrome_over_plugin_window.xul
   chrome_over_plugin_window_frame.html
 [test_default_background.xul]
 [test_dialog_with_positioning.html]
 tags = openwindow
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/chrome/file_bug458898.html
@@ -0,0 +1,1 @@
+<div style='height:200px; width:100px;'>
--- a/layout/base/tests/chrome/test_bug458898.html
+++ b/layout/base/tests/chrome/test_bug458898.html
@@ -13,17 +13,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=458898">Mozilla Bug 458898</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-var win = window.openDialog("data:text/html,<div style='height:200px; width:100px;'>");
+var win = window.openDialog("file_bug458898.html");
 
 function loaded() {
   var disableWindowResizePref = "dom.disable_window_move_resize";
   SpecialPowers.pushPrefEnv({"set":[[disableWindowResizePref, false]]}, function() {
     win.sizeToContent();
     ok(win.innerWidth >= 100, "innerWidth: " + win.innerWidth + " >= 100 ?");
     ok(win.innerHeight >= 200, "innerHeight: " + win.innerHeight + " >= 200 ?");
     win.close();
--- a/layout/generic/test/test_bug391747.html
+++ b/layout/generic/test/test_bug391747.html
@@ -8,17 +8,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Test for bug 391747</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=391747">Mozilla Bug 391747</a>
 <p id="display"></p>
 <div id="content" style="display: block">
-<iframe id="iframe_391747" src="data:text/html,<table><tr><td style='width:500px;height:500px;border:1px solid blue'>x</td>"></iframe>
+<iframe id="iframe_391747" srcdoc="<table><tr><td style='width:500px;height:500px;border:1px solid blue'>x</td>"></iframe>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 function ctrlclick_391747(doc,x,y){
   var wu =  SpecialPowers.getDOMWindowUtils(doc.defaultView);
   wu.sendMouseEvent('mousedown',  x, y, 0, 1, 2);
   wu.sendMouseEvent('mouseup',  x, y, 0, 1, 2);
--- a/layout/generic/test/test_bug748961.html
+++ b/layout/generic/test/test_bug748961.html
@@ -20,26 +20,26 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 /** Test for Bug 748961 **/
 
 SimpleTest.waitForExplicitFinish();
 
 var f = document.createElement('iframe');
 document.body.appendChild(f);
 
-src = "data:text/html,<meta charset='utf-8'><body><p id='sel'>Selection</p><scr" + "ipt>"
+src = "<meta charset='utf-8'><body><p id='sel'>Selection</p><scr" + "ipt>"
 src += "try {"
 src += "var range = document.createRange();"
 src += "range.selectNode(document.getElementById('sel'));"
 src += "var sel = window.getSelection();"
 src += "sel.addRange(range);"
 src += "parent.is(sel.toString(), 'Selection', 'Selection.toString()');"
 src += "document.body.offsetHeight;"
 src += "parent.is(sel.toString(), 'Selection', 'Selection.toString() after explicit flush');"
 src += "} finally { parent.ok(true,'silence no test run warning'); parent.SimpleTest.finish(); }"
 src += "</scr"+"ipt>";
 
-f.src = src;
+f.srcdoc = src;
 
 </script>
 </pre>
 </body>
 </html>
--- a/layout/generic/test/test_bug938772.html
+++ b/layout/generic/test/test_bug938772.html
@@ -13,11 +13,11 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script>
 SimpleTest.waitForExplicitFinish();
 
 i.onload = function() {
   ok(!i.contentDocument.getElementById("v").failed,
      "Check whether an error was reported");
   SimpleTest.finish();
 };
-i.src = "data:text/html,<base href='http://basetag/basetag'><video id='v' onerror='v.failed=true'></video>";
+i.srcdoc = "<base href='http://basetag/basetag'><video id='v' onerror='v.failed=true'></video>";
 </script>
 
--- a/layout/generic/test/test_plugin_mouse_coords.html
+++ b/layout/generic/test/test_plugin_mouse_coords.html
@@ -15,17 +15,17 @@
   </style>
 </head>
 <body>
 <p id="display"></p>
 <div id="content" style="display: block">
   <embed id="p1" type="application/x-test"
          style="position:absolute; left:300px; top:10px;"></embed>
   <iframe id="f1" style="position:absolute; left:0; top:250px;"
-          src="data:text/html,&lt;embed id='p2' type='application/x-test' style='position:absolute; left:10px; top:10px'&gt;"></iframe>
+          srcdoc="&lt;embed id='p2' type='application/x-test' style='position:absolute; left:10px; top:10px'&gt;"></iframe>
   <embed id="p3" type="application/x-test"
          style="position:absolute; left:320px; top:250px;
                 outline:5px solid blue;
                 border:solid black; border-width:4px 8px 4px 8px;
                 padding:3px 1px;"></embed>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
--- a/layout/generic/test/test_scroll_position_iframe.html
+++ b/layout/generic/test/test_scroll_position_iframe.html
@@ -27,11 +27,11 @@ function runtest() {
   iframe.classList.toggle("off");
   waitForAllPaintsFlushed(function() {
     iframe.classList.toggle("off");
     is(iframe.contentDocument.scrollingElement.scrollTop, 50, "scroll position restored");
     SimpleTest.finish();
   });
 }
 </script>
-<iframe onload="runtest()" id="iframe" class="" src="data:text/html,<p>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br></p>"></iframe><br>
+<iframe onload="runtest()" id="iframe" class="" srcdoc="<p>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br>bla<br></p>"></iframe><br>
 </body>
 </html>
--- a/layout/generic/test/test_selection_expanding.html
+++ b/layout/generic/test/test_selection_expanding.html
@@ -36,17 +36,17 @@
     -moz-binding: url(selection_expanding_xbl.xml#binding);
   }
 </style>
 
 </head>
 <body>
 <div id="div1" class="testingDiv">
   aaaaaaa
-  <iframe id="iframe" src="data:text/html,<style type='text/css'>*{margin: 0; padding: 0; font-size: 16px;}</style><div>ffffff ffffff ffffff ffffff</div>"></iframe>
+  <iframe id="iframe" srcdoc="<style type='text/css'>*{margin: 0; padding: 0; font-size: 16px;}</style><div>ffffff ffffff ffffff ffffff</div>"></iframe>
   aaaaaaa aaaaaaa<br>aaaaaaa aaaaaaa aaaaaaa aaaaaaa<br>aaaaaaa
 </div>
 <div id="div2" class="testingDiv">
   bbbbbbb
   <input id="input" type="text" value="iiiiiiiii iiiiiiiii iiiiiiiii">
   bbbbbbb bbbbbbb<br>bbbbbbb bbbbbbb bbbbbbb<br>bbbbbbb
 </div>
 <div id="div3" class="testingDiv">
--- a/layout/inspector/tests/test_bug462789.html
+++ b/layout/inspector/tests/test_bug462789.html
@@ -5,17 +5,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 -->
 <head>
   <title>Test for Bug 462789</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462789">Mozilla Bug 462789</a>
-<p id="display"><iframe id="bug462789_iframe" src="data:text/html,<html><head><style>*{color:black;}</style></head><body>xxx" style="display: none;"></iframe></p>
+<p id="display"><iframe id="bug462789_iframe" srcdoc="<html><head><style>*{color:black;}</style></head><body>xxx" style="display: none;"></iframe></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 462789 **/
 
new file mode 100644
--- /dev/null
+++ b/layout/style/test/file_computed_style_bfcache_display_none.html
@@ -0,0 +1,6 @@
+<div id=div style="display:none">Page 1</div>
+<script>
+  window.onload = function() {
+    opener.postMessage("loaded", "*");
+  }
+</script>
new file mode 100644
--- /dev/null
+++ b/layout/style/test/file_computed_style_bfcache_display_none2.html
@@ -0,0 +1,6 @@
+<div>Page 2</div>
+<script>
+  window.onload = function() {
+    opener.postMessage("loaded", "*");
+  }
+</script>;
--- a/layout/style/test/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -5,16 +5,18 @@ support-files =
   ccd.sjs
   ccd-standards.html
   chrome/bug418986-2.js
   chrome/match.png
   chrome/mismatch.png
   descriptor_database.js
   display_mode_reflow_iframe.html
   empty.html
+  file_computed_style_bfcache_display_none.html
+  file_computed_style_bfcache_display_none2.html
   media_queries_dynamic_xbl_binding.xml
   media_queries_dynamic_xbl_iframe.html
   media_queries_dynamic_xbl_style.css
   media_queries_iframe.html
   neverending_font_load.sjs
   neverending_stylesheet_load.sjs
   post-redirect-1.css
   post-redirect-2.css
--- a/layout/style/test/test_computed_style_bfcache_display_none.html
+++ b/layout/style/test/test_computed_style_bfcache_display_none.html
@@ -5,30 +5,29 @@
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1377010">Mozilla Bug 1377010</a>
 <p id="display"></p>
 <script>
 SimpleTest.waitForExplicitFinish();
 
 let testDiv;
 let loadedPromiseResolve;
 
+const TEST_PATH = "http://mochi.test:8888/tests/layout/style/test/";
+const TEST_FILE1 = TEST_PATH + "file_computed_style_bfcache_display_none.html";
+const TEST_FILE2 = TEST_PATH + "file_computed_style_bfcache_display_none2.html";
+
 // Open a new window.
-const w = window.open('data:text/html,'
-                      + '<div id=div style="display:none">Page 1</div>'
-                      + '<script>window.onload = function() { '
-                      + 'opener.postMessage("loaded", "*"); }</' + 'script>');
+const w = window.open(TEST_FILE1);
 waitForLoadMessage().then(() => {
   // Take a reference to a node in the new window.
   testDiv = w.document.getElementById('div');
 
   // Open a new document so that the test div now refers to a node in a
   // document in the bfcache.
-  w.location = 'data:text/html,<div>Page 2</div>'
-               + '<script>window.onload = function() { '
-               + 'opener.postMessage("loaded", "*"); }</' + 'script>';
+  w.location = TEST_FILE2;
   return waitForLoadMessage();
 }).then(() => {
   // Compute styles for the node in the bfcache document.
   is(w.getComputedStyle(testDiv).opacity, '1');
 
   // Restore the bfcache document.
   return goBack(w);
 }).then(() => {
new file mode 100644
--- /dev/null
+++ b/layout/xul/test/file_bug386386.sjs
@@ -0,0 +1,8 @@
+// SJS file for test_bug386386.html
+"use strict";
+
+function handleRequest(request, response) {
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Content-Type", "application/vnd.mozilla.xul+xml;charset=utf-8", false);
+  response.write("%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cwindow%3E%3C/window%3E");
+}
--- a/layout/xul/test/mochitest.ini
+++ b/layout/xul/test/mochitest.ini
@@ -1,10 +1,11 @@
 [DEFAULT]
-
+support-files =
+  file_bug386386.sjs
 [test_bug386386.html]
 [test_bug394800.xhtml]
 [test_bug511075.html]
 skip-if = toolkit == 'android' #bug 798806
 [test_bug563416.html]
 [test_bug1197913.xul]
 skip-if = toolkit == 'android'
 [test_resizer_incontent.xul]
--- a/layout/xul/test/test_bug386386.html
+++ b/layout/xul/test/test_bug386386.html
@@ -2,17 +2,17 @@
 <head><title>Testcase for bug 386386</title>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=386386
 -->
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
 </head>
 <body>
 
-<iframe id="test386386" src="data:application/vnd.mozilla.xul+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cwindow%3E%3C/window%3E"></iframe>
+<iframe id="test386386" src="file_bug386386.sjs"></iframe>
 
 <script class="testbody" type="application/javascript">
 
 function boom()
 {
   var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
   var doc = document.getElementById("test386386").contentDocument;
   var observes = doc.createElementNS(XUL_NS, 'observes');
--- a/layout/xul/test/test_bug563416.html
+++ b/layout/xul/test/test_bug563416.html
@@ -5,17 +5,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 -->
 <head>
   <title>Test for Bug 563416</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=563416">Mozilla Bug 563416</a>
-<p id="display"><iframe id="test" src='data:text/html,<textarea style="box-sizing:content-box; -moz-appearance:none; height: 0px; padding: 0px;" cols="20" rows="10">hsldkjvmshlkkajskdlfksdjflskdjflskdjflskdjflskdjfddddddddd</textarea>'></iframe></p>
+<p id="display"><iframe id="test" srcdoc='<textarea style="box-sizing:content-box; -moz-appearance:none; height: 0px; padding: 0px;" cols="20" rows="10">hsldkjvmshlkkajskdlfksdjflskdjflskdjflskdjflskdjfddddddddd</textarea>'></iframe></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 563416 **/
 
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -100,16 +100,26 @@ Preferences::DirtyCallback()
     // ignore it for now.
     return;
   }
   if (gHashTable && sPreferences && !sPreferences->mDirty) {
     sPreferences->mDirty = true;
 
     NS_WARNING_ASSERTION(!sPreferences->mProfileShutdown,
                          "Setting user pref after profile shutdown.");
+
+    if (sPreferences->AllowOffMainThreadSave() && !sPreferences->mSavePending) {
+      sPreferences->mSavePending = true;
+      static const int PREF_DELAY_MS = 500;
+      NS_DelayedDispatchToCurrentThread(
+        mozilla::NewRunnableMethod("Preferences::SavePrefFileAsynchronous",
+                                   sPreferences,
+                                   &Preferences::SavePrefFileAsynchronous),
+        PREF_DELAY_MS);
+    }
   }
 }
 
 // Prototypes
 static nsresult openPrefFile(nsIFile* aFile);
 static nsresult pref_InitInitialObjects(void);
 static nsresult pref_LoadPrefsInDirList(const char *listId);
 static nsresult ReadExtensionPrefs(nsIFile *aFile);
@@ -1153,16 +1163,18 @@ Preferences::SavePrefFileInternal(nsIFil
   }
 
   // We allow different behavior here when aFile argument is not null,
   // but it happens to be the same as the current file.  It is not
   // clear that we should, but it does give us a "force" save on the
   // unmodified pref file (see the original bug 160377 when we added this.)
 
   if (nullptr == aFile) {
+    mSavePending = false;
+
     // Off main thread writing only if allowed
     if (!AllowOffMainThreadSave()) {
       aSaveMethod = SaveMethod::Blocking;
     }
 
     // the mDirty flag tells us if we should write to mCurrentFile
     // we only check this flag when the caller wants to write to the default
     if (!mDirty) {
--- a/modules/libpref/Preferences.h
+++ b/modules/libpref/Preferences.h
@@ -482,16 +482,19 @@ protected:
                                           const char* aPref,
                                           void* aClosure,
                                           MatchKind aMatchKind);
 
 private:
   nsCOMPtr<nsIFile>        mCurrentFile;
   bool                     mDirty = false;
   bool                     mProfileShutdown = false;
+  // we wait a bit after prefs are dirty before writing them. In this
+  // period, mDirty and mSavePending will both be true.
+  bool                     mSavePending = false;
 
   static Preferences*      sPreferences;
   static nsIPrefBranch*    sRootBranch;
   static nsIPrefBranch*    sDefaultRootBranch;
   static bool              sShutdown;
 
   /**
    * Init static members.  TRUE if it succeeded.  Otherwise, FALSE.
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -715,16 +715,17 @@ pref("apz.overscroll.min_pan_distance_ra
 pref("apz.overscroll.spring_friction", "0.015");
 pref("apz.overscroll.spring_stiffness", "0.0018");
 pref("apz.overscroll.stop_distance_threshold", "5.0");
 pref("apz.overscroll.stop_velocity_threshold", "0.01");
 pref("apz.overscroll.stretch_factor", "0.35");
 pref("apz.paint_skipping.enabled", true);
 // Fetch displayport updates early from the message queue
 pref("apz.peek_messages.enabled", true);
+pref("apz.popups.enabled", false);
 
 // Whether to print the APZC tree for debugging
 pref("apz.printtree", false);
 
 #ifdef NIGHTLY_BUILD
 pref("apz.record_checkerboarding", true);
 #else
 pref("apz.record_checkerboarding", false);
@@ -4732,17 +4733,17 @@ pref("network.tcp.keepalive.idle_time", 
 pref("network.tcp.keepalive.retry_interval", 1); // seconds
 #endif
 // Default maximum probe retransmissions.
 // Linux only; not configurable on Win and Mac; fixed at 10 and 8 respectively.
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
 pref("network.tcp.keepalive.probe_count", 4);
 #endif
 
-pref("network.tcp.tcp_fastopen_enable", false);
+pref("network.tcp.tcp_fastopen_enable", true);
 pref("network.tcp.tcp_fastopen_consecutive_failure_limit", 5);
 
 // Whether to disable acceleration for all widgets.
 pref("layers.acceleration.disabled", false);
 // Preference that when switched at runtime will run a series of benchmarks
 // and output the result to stderr.
 pref("layers.bench.enabled", false);
 
--- a/netwerk/base/TCPFastOpenLayer.cpp
+++ b/netwerk/base/TCPFastOpenLayer.cpp
@@ -373,17 +373,17 @@ TCPFastOpenFinish(PRFileDesc *fd, PRErro
   tfoStatus = TFO_NOT_TRIED;
   PRErrorCode result = 0;
 
   // If we do not have data to send with syn packet or nspr version does not
   // have sendto implemented we will call normal connect.
   // If sendto is not implemented it points to _PR_InvalidInt, therefore we
   // check if sendto != _PR_InvalidInt. _PR_InvalidInt is exposed so we use
   // reserved_fn_0 which also points to _PR_InvalidInt.
-  if (!secret->mFirstPacketBufLen ||
+  if ((secret->mFirstPacketBufLen < 10) ||
       (tfoFd->lower->methods->sendto == (PRSendtoFN)tfoFd->lower->methods->reserved_fn_0)) {
     // Because of the way our nsHttpTransaction dispatch work, it can happened
     // that data has not been written into the socket.
     // In this case we can just call connect.
     PRInt32 rv = (tfoFd->lower->methods->connect)(tfoFd->lower, &secret->mAddr,
                                                   PR_INTERVAL_NO_WAIT);
     if (rv == PR_SUCCESS) {
       result = PR_IS_CONNECTED_ERROR;
@@ -394,25 +394,27 @@ TCPFastOpenFinish(PRFileDesc *fd, PRErro
         // sendto is not implemented, it is equal to _PR_InvalidInt!
         // We will disable Fast Open.
         SOCKET_LOG(("TCPFastOpenFinish - sendto not implemented.\n"));
         fastOpenNotSupported = true;
     }
   } else {
     // We have some data ready in the buffer we will send it with the syn
     // packet.
+    MOZ_ASSERT(secret->mFirstPacketBufLen >= 10);
     PRInt32 rv = (tfoFd->lower->methods->sendto)(tfoFd->lower,
                                                  secret->mFirstPacketBuf,
-                                                 secret->mFirstPacketBufLen,
+                                                 10,
                                                  0, //flags
                                                  &secret->mAddr,
                                                  PR_INTERVAL_NO_WAIT);
 
     SOCKET_LOG(("TCPFastOpenFinish - sendto result=%d.\n", rv));
     if (rv > 0) {
+      MOZ_DIAGNOSTIC_ASSERT(rv <= 10);
       result = PR_IN_PROGRESS_ERROR;
       secret->mFirstPacketBufLen -= rv;
       if (secret->mFirstPacketBufLen) {
         memmove(secret->mFirstPacketBuf,
                 secret->mFirstPacketBuf + rv,
                 secret->mFirstPacketBufLen);
       }
       tfoStatus = TFO_DATA_SENT;
--- a/netwerk/cache2/CacheFile.cpp
+++ b/netwerk/cache2/CacheFile.cpp
@@ -1248,18 +1248,16 @@ nsresult CacheFile::SetNetworkTimes(uint
 {
   CacheFileAutoLock lock(this);
 
   LOG(("CacheFile::SetNetworkTimes() this=%p, aOnStartTime=%" PRIu64
        ", aOnStopTime=%" PRIu64 "", this, aOnStartTime, aOnStopTime));
 
   MOZ_ASSERT(mMetadata);
   NS_ENSURE_TRUE(mMetadata, NS_ERROR_UNEXPECTED);
-  MOZ_ASSERT(aOnStartTime != kIndexTimeNotAvailable);
-  MOZ_ASSERT(aOnStopTime != kIndexTimeNotAvailable);
 
   PostWriteTimer();
 
   nsAutoCString onStartTime;
   onStartTime.AppendInt(aOnStartTime);
   nsresult rv = mMetadata->SetElement("net-response-time-onstart", onStartTime.get());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
--- a/netwerk/protocol/http/ConnectionDiagnostics.cpp
+++ b/netwerk/protocol/http/ConnectionDiagnostics.cpp
@@ -44,17 +44,17 @@ nsHttpConnectionMgr::OnMsgPrintDiagnosti
 
   mLogData.AppendPrintf("HTTP Connection Diagnostics\n---------------------\n");
   mLogData.AppendPrintf("IsSpdyEnabled() = %d\n", gHttpHandler->IsSpdyEnabled());
   mLogData.AppendPrintf("MaxSocketCount() = %d\n", gHttpHandler->MaxSocketCount());
   mLogData.AppendPrintf("mNumActiveConns = %d\n", mNumActiveConns);
   mLogData.AppendPrintf("mNumIdleConns = %d\n", mNumIdleConns);
 
   for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-    nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
+    RefPtr<nsConnectionEntry> ent = iter.Data();
 
     mLogData.AppendPrintf(" ent host = %s hashkey = %s\n",
                           ent->mConnInfo->Origin(), ent->mConnInfo->HashKey().get());
     mLogData.AppendPrintf("   AtActiveConnectionLimit = %d\n",
                           AtActiveConnectionLimit(ent, NS_HTTP_ALLOW_KEEPALIVE));
     mLogData.AppendPrintf("   RestrictConnections = %d\n",
                           RestrictConnections(ent));
     mLogData.AppendPrintf("   Pending Q Length = %" PRIuSIZE "\n",
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -139,16 +139,17 @@ nsHttpConnection::Init(nsHttpConnectionI
                        PRIntervalTime rtt)
 {
     LOG(("nsHttpConnection::Init this=%p", this));
     NS_ENSURE_ARG_POINTER(info);
     NS_ENSURE_TRUE(!mConnInfo, NS_ERROR_ALREADY_INITIALIZED);
 
     mConnectedTransport = connectedTransport;
     mConnInfo = info;
+    MOZ_DIAGNOSTIC_ASSERT(mConnInfo);
     mLastWriteTime = mLastReadTime = PR_IntervalNow();
     mRtt = rtt;
     mMaxHangTime = PR_SecondsToInterval(maxHangTime);
 
     mSocketTransport = transport;
     mSocketIn = instream;
     mSocketOut = outstream;
 
@@ -308,16 +309,17 @@ nsHttpConnection::StartSpdy(uint8_t spdy
     bool spdyProxy = mConnInfo->UsingHttpsProxy() && !mTLSFilter;
     if (spdyProxy) {
         RefPtr<nsHttpConnectionInfo> wildCardProxyCi;
         rv = mConnInfo->CreateWildCard(getter_AddRefs(wildCardProxyCi));
         MOZ_ASSERT(NS_SUCCEEDED(rv));
         gHttpHandler->ConnMgr()->MoveToWildCardConnEntry(mConnInfo,
                                                          wildCardProxyCi, this);
         mConnInfo = wildCardProxyCi;
+        MOZ_DIAGNOSTIC_ASSERT(mConnInfo);
     }
 
     if (!mDid0RTTSpdy) {
         rv = MoveTransactionsToSpdy(rv, list);
         if (NS_FAILED(rv)) {
             return;
         }
     }
@@ -1920,17 +1922,17 @@ nsHttpConnection::SetupSecondaryTLS()
 
     nsHttpConnectionInfo *ci = nullptr;
     if (mTransaction) {
         ci = mTransaction->ConnectionInfo();
     }
     if (!ci) {
         ci = mConnInfo;
     }
-    MOZ_ASSERT(ci);
+    MOZ_DIAGNOSTIC_ASSERT(ci);
 
     mTLSFilter = new TLSFilterTransaction(mTransaction,
                                           ci->Origin(), ci->OriginPort(), this, this);
 
     if (mTransaction) {
         mTransaction = mTLSFilter;
     }
 }
--- a/netwerk/protocol/http/nsHttpConnection.h
+++ b/netwerk/protocol/http/nsHttpConnection.h
@@ -218,17 +218,18 @@ public:
     // ping, ordinary HTTP connections get some time to get traffic to be
     // considered alive.
     void CheckForTraffic(bool check);
 
     // NoTraffic() returns true if there's been no traffic on the (non-spdy)
     // connection since CheckForTraffic() was called.
     bool NoTraffic() {
         return mTrafficStamp &&
-            (mTrafficCount == (mTotalBytesWritten + mTotalBytesRead));
+            (mTrafficCount == (mTotalBytesWritten + mTotalBytesRead)) &&
+            !mFastOpen;
     }
     // override of nsAHttpConnection
     virtual uint32_t Version();
 
     bool TestJoinConnection(const nsACString &hostname, int32_t port);
     bool JoinConnection(const nsACString &hostname, int32_t port);
 
     void SetFastOpenStatus(uint8_t tfoStatus) {
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -607,24 +607,25 @@ nsHttpConnectionMgr::UpdateRequestTokenB
 }
 
 nsresult
 nsHttpConnectionMgr::ClearConnectionHistory()
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
     for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-        nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
+        RefPtr<nsConnectionEntry> ent = iter.Data();
         if (ent->mIdleConns.Length()    == 0 &&
             ent->mActiveConns.Length()  == 0 &&
             ent->mHalfOpens.Length()    == 0 &&
             ent->mUrgentStartQ.Length() == 0 &&
             ent->PendingQLength()       == 0 &&
             ent->mHalfOpenFastOpenBackups.Length() == 0 &&
             !ent->mDoNotDestroy) {
+            ent->mHowItWasRemoved = nsConnectionEntry::CONN_ENTRY_CLEAR_CONNECTION_HISTORY;
             iter.Remove();
         }
     }
 
     return NS_OK;
 }
 
 nsresult
@@ -633,17 +634,17 @@ nsHttpConnectionMgr::CloseIdleConnection
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     LOG(("nsHttpConnectionMgr::CloseIdleConnection %p conn=%p",
          this, conn));
 
     if (!conn->ConnectionInfo()) {
         return NS_ERROR_UNEXPECTED;
     }
 
-    nsConnectionEntry *ent = mCT.Get(conn->ConnectionInfo()->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(conn->ConnectionInfo()->HashKey());
 
     RefPtr<nsHttpConnection> deleteProtector(conn);
     if (!ent || !ent->mIdleConns.RemoveElement(conn))
         return NS_ERROR_UNEXPECTED;
 
     conn->Close(NS_ERROR_ABORT);
     mNumIdleConns--;
     ConditionallyStopPruneDeadConnectionsTimer();
@@ -657,17 +658,17 @@ nsHttpConnectionMgr::RemoveIdleConnectio
 
     LOG(("nsHttpConnectionMgr::RemoveIdleConnection %p conn=%p",
          this, conn));
 
     if (!conn->ConnectionInfo()) {
         return NS_ERROR_UNEXPECTED;
     }
 
-    nsConnectionEntry *ent = mCT.Get(conn->ConnectionInfo()->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(conn->ConnectionInfo()->HashKey());
 
     if (!ent || !ent->mIdleConns.RemoveElement(conn)) {
         return NS_ERROR_UNEXPECTED;
     }
 
     mNumIdleConns--;
     ConditionallyStopPruneDeadConnectionsTimer();
     return NS_OK;
@@ -784,17 +785,17 @@ nsHttpConnectionMgr::FindCoalescableConn
 void
 nsHttpConnectionMgr::UpdateCoalescingForNewConn(nsHttpConnection *newConn,
                                                 nsConnectionEntry *ent)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     MOZ_ASSERT(newConn);
     MOZ_ASSERT(newConn->ConnectionInfo());
     MOZ_ASSERT(ent);
-    MOZ_ASSERT(mCT.Get(newConn->ConnectionInfo()->HashKey()) == ent);
+    MOZ_ASSERT(mCT.GetWeak(newConn->ConnectionInfo()->HashKey()) == ent);
 
     nsHttpConnection *existingConn = FindCoalescableConnection(ent, true);
     if (existingConn) {
         LOG(("UpdateCoalescingForNewConn() found existing active conn that could have served newConn "
              "graceful close of newConn=%p to migrate to existingConn %p\n", newConn, existingConn));
         newConn->DontReuse();
         return;
     }
@@ -817,20 +818,25 @@ nsHttpConnectionMgr::UpdateCoalescingFor
         }
         listOfWeakConns->AppendElement(
             do_GetWeakReference(static_cast<nsISupportsWeakReference*>(newConn)));
     }
 
     // Cancel any other pending connections - their associated transactions
     // are in the pending queue and will be dispatched onto this new connection
     for (int32_t index = ent->mHalfOpens.Length() - 1; index >= 0; --index) {
-        nsHalfOpenSocket *half = ent->mHalfOpens[index];
+        RefPtr<nsHalfOpenSocket> half = ent->mHalfOpens[index];
         LOG(("UpdateCoalescingForNewConn() forcing halfopen abandon %p\n",
-             half));
+             half.get()));
         ent->mHalfOpens[index]->Abandon();
+        MOZ_DIAGNOSTIC_ASSERT(!half->mBackupTransport);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mBackupStreamOut);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mBackupStreamIn);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mSynTimer);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mEnt);
     }
 
     if (ent->mActiveConns.Length() > 1) {
         // this is a new connection that can be coalesced onto. hooray!
         // if there are other connection to this entry (e.g.
         // some could still be handshaking, shutting down, etc..) then close
         // them down after any transactions that are on them are complete.
         // This probably happened due to the parallel connection algorithm
@@ -844,17 +850,23 @@ nsHttpConnectionMgr::UpdateCoalescingFor
             }
         }
     }
 
     for (int32_t index = ent->mHalfOpenFastOpenBackups.Length() - 1; index >= 0; --index) {
         LOG(("UpdateCoalescingForNewConn() shutting down connection in fast "
              "open state (%p) because new spdy connection (%p) takes "
              "precedence\n", ent->mHalfOpenFastOpenBackups[index].get(), newConn));
-        ent->mHalfOpenFastOpenBackups[index]->CancelFastOpenConnection();
+        RefPtr<nsHalfOpenSocket> half = ent->mHalfOpenFastOpenBackups[index];
+        half->CancelFastOpenConnection();
+        MOZ_DIAGNOSTIC_ASSERT(!half->mBackupTransport);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mBackupStreamOut);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mBackupStreamIn);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mSynTimer);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mEnt);
     }
 }
 
 // This function lets a connection, after completing the NPN phase,
 // report whether or not it is using spdy through the usingSpdy
 // argument. It would not be necessary if NPN were driven out of
 // the connection manager. The connection entry associated with the
 // connection is then updated to indicate whether or not we want to use
@@ -863,17 +875,17 @@ nsHttpConnectionMgr::UpdateCoalescingFor
 void
 nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
                                           bool usingSpdy)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     if (!conn->ConnectionInfo()) {
         return;
     }
-    nsConnectionEntry *ent = mCT.Get(conn->ConnectionInfo()->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(conn->ConnectionInfo()->HashKey());
     if (!ent || !usingSpdy) {
         return;
     }
 
     ent->mUsingSpdy = true;
     mNumSpdyActiveConns++;
 
     // adjust timeout timer
@@ -1164,17 +1176,17 @@ nsHttpConnectionMgr::ProcessPendingQForE
     return dispatchedSuccessfully;
 }
 
 bool
 nsHttpConnectionMgr::ProcessPendingQForEntry(nsHttpConnectionInfo *ci)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
-    nsConnectionEntry *ent = mCT.Get(ci->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(ci->HashKey());
     if (ent)
         return ProcessPendingQForEntry(ent, false);
     return false;
 }
 
 // we're at the active connection limit if any one of the following conditions is true:
 //  (1) at max-connections
 //  (2) keep-alive enabled and at max-persistent-connections-per-server/proxy
@@ -1231,16 +1243,23 @@ nsHttpConnectionMgr::ClosePersistentConn
         ent->mIdleConns.RemoveElementAt(0);
         mNumIdleConns--;
         conn->Close(NS_ERROR_ABORT);
     }
 
     int32_t activeCount = ent->mActiveConns.Length();
     for (int32_t i=0; i < activeCount; i++)
         ent->mActiveConns[i]->DontReuse();
+    for (int32_t index = ent->mHalfOpenFastOpenBackups.Length() - 1; index >= 0; --index) {
+        RefPtr<nsHalfOpenSocket> half = ent->mHalfOpenFastOpenBackups[index];
+        half->CancelFastOpenConnection();
+        MOZ_DIAGNOSTIC_ASSERT(!half->mBackupTransport);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mSynTimer);
+        MOZ_DIAGNOSTIC_ASSERT(!half->mEnt);
+    }
 }
 
 bool
 nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
     if (ent->AvailableForDispatchNow()) {
@@ -1362,17 +1381,17 @@ nsHttpConnectionMgr::MakeNewConnection(n
 
     if ((mNumIdleConns + mNumActiveConns + 1 >= mMaxConns) && mNumIdleConns) {
         // If the global number of connections is preventing the opening of new
         // connections to a host without idle connections, then close them
         // regardless of their TTL.
         auto iter = mCT.Iter();
         while (mNumIdleConns + mNumActiveConns + 1 >= mMaxConns &&
                !iter.Done()) {
-            nsAutoPtr<nsConnectionEntry> &entry = iter.Data();
+            RefPtr<nsConnectionEntry> entry = iter.Data();
             if (!entry->mIdleConns.Length()) {
               iter.Next();
               continue;
             }
             RefPtr<nsHttpConnection> conn(entry->mIdleConns[0]);
             entry->mIdleConns.RemoveElementAt(0);
             conn->Close(NS_ERROR_ABORT);
             mNumIdleConns--;
@@ -1382,17 +1401,17 @@ nsHttpConnectionMgr::MakeNewConnection(n
 
     if ((mNumIdleConns + mNumActiveConns + 1 >= mMaxConns) &&
         mNumActiveConns && gHttpHandler->IsSpdyEnabled())
     {
         // If the global number of connections is preventing the opening of new
         // connections to a host without idle connections, then close any spdy
         // ASAP.
         for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-            nsAutoPtr<nsConnectionEntry> &entry = iter.Data();
+            RefPtr<nsConnectionEntry> entry = iter.Data();
             if (!entry->mUsingSpdy) {
                 continue;
             }
 
             for (uint32_t index = 0;
                  index < entry->mActiveConns.Length();
                  ++index) {
                 nsHttpConnection *conn = entry->mActiveConns[index];
@@ -1714,16 +1733,17 @@ NS_IMPL_ISUPPORTS0(ConnectionHandle)
 // concrete nsHttpTransaction
 nsresult
 nsHttpConnectionMgr::DispatchAbstractTransaction(nsConnectionEntry *ent,
                                                  nsAHttpTransaction *aTrans,
                                                  uint32_t caps,
                                                  nsHttpConnection *conn,
                                                  int32_t priority)
 {
+    MOZ_DIAGNOSTIC_ASSERT(ent);
     nsresult rv;
     MOZ_ASSERT(!conn->UsingSpdy(),
                "Spdy Must Not Use DispatchAbstractTransaction");
     LOG(("nsHttpConnectionMgr::DispatchAbstractTransaction "
          "[ci=%s trans=%p caps=%x conn=%p]\n",
          ent->mConnInfo->HashKey().get(), aTrans, caps, conn));
 
     RefPtr<nsAHttpTransaction> transaction(aTrans);
@@ -1789,16 +1809,17 @@ nsHttpConnectionMgr::ProcessNewTransacti
     }
 
     nsresult rv = NS_OK;
     nsHttpConnectionInfo *ci = trans->ConnectionInfo();
     MOZ_ASSERT(ci);
 
     nsConnectionEntry *ent =
         GetOrCreateConnectionEntry(ci, !!trans->TunnelProvider());
+    MOZ_DIAGNOSTIC_ASSERT(ent);
 
     ReportProxyTelemetry(ent);
 
     // Check if the transaction already has a sticky reference to a connection.
     // If so, then we can just use it directly by transferring its reference
     // to the new connection variable instead of searching for a new one
 
     nsAHttpConnection *wrappedConnection = trans->Connection();
@@ -2038,17 +2059,17 @@ nsHttpConnectionMgr::ProcessSpdyPendingQ
 }
 
 void
 nsHttpConnectionMgr::OnMsgProcessAllSpdyPendingQ(int32_t, ARefBase *)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     LOG(("nsHttpConnectionMgr::OnMsgProcessAllSpdyPendingQ\n"));
     for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-        ProcessSpdyPendingQ(iter.Data());
+        ProcessSpdyPendingQ(iter.Data().get());
     }
 }
 
 // Given a connection entry, return an active h2 connection
 // that can be directly activated or null
 nsHttpConnection *
 nsHttpConnectionMgr::GetSpdyActiveConn(nsConnectionEntry *ent)
 {
@@ -2083,17 +2104,24 @@ nsHttpConnectionMgr::GetSpdyActiveConn(n
                 tmp->DontReuse();
             }
         }
         for (int32_t index = ent->mHalfOpenFastOpenBackups.Length() - 1; index >= 0; --index) {
              LOG(("GetSpdyActiveConn() shutting down connection in fast "
                  "open state (%p) because we have an experienced spdy "
                  "connection (%p).\n",
                  ent->mHalfOpenFastOpenBackups[index].get(), experienced));
-             ent->mHalfOpenFastOpenBackups[index]->CancelFastOpenConnection();
+             RefPtr<nsHalfOpenSocket> half = ent->mHalfOpenFastOpenBackups[index];
+             half->CancelFastOpenConnection();
+
+             MOZ_DIAGNOSTIC_ASSERT(!half->mBackupTransport);
+             MOZ_DIAGNOSTIC_ASSERT(!half->mBackupStreamOut);
+             MOZ_DIAGNOSTIC_ASSERT(!half->mBackupStreamIn);
+             MOZ_DIAGNOSTIC_ASSERT(!half->mSynTimer);
+             MOZ_DIAGNOSTIC_ASSERT(!half->mEnt);
         }
 
         LOG(("GetSpdyActiveConn() request for ent %p %s "
              "found an active experienced connection %p in native connection entry\n",
              ent, ci->HashKey().get(), experienced));
         return experienced;
     }
 
@@ -2125,17 +2153,17 @@ void
 nsHttpConnectionMgr::OnMsgShutdown(int32_t, ARefBase *param)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     LOG(("nsHttpConnectionMgr::OnMsgShutdown\n"));
 
     gHttpHandler->StopRequestTokenBucket();
 
     for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-        nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
+        RefPtr<nsConnectionEntry> ent = iter.Data();
 
         // Close all active connections.
         while (ent->mActiveConns.Length()) {
             RefPtr<nsHttpConnection> conn(ent->mActiveConns[0]);
             ent->mActiveConns.RemoveElementAt(0);
             DecrementActiveConnCount(conn);
             // Since nsHttpConnection::Close doesn't break the bond with
             // the connection's transaction, we must explicitely tell it
@@ -2178,16 +2206,17 @@ nsHttpConnectionMgr::OnMsgShutdown(int32
 
         // Close all half open tcp connections.
         for (int32_t i = int32_t(ent->mHalfOpens.Length()) - 1; i >= 0; i--) {
             ent->mHalfOpens[i]->Abandon();
         }
 
         MOZ_DIAGNOSTIC_ASSERT(ent->mHalfOpenFastOpenBackups.Length() == 0 &&
                               !ent->mDoNotDestroy);
+        ent->mHowItWasRemoved = nsConnectionEntry::CONN_ENTRY_REMOVED_SHUTDOWN;
         iter.Remove();
     }
 
     if (mTimeoutTick) {
         mTimeoutTick->Cancel();
         mTimeoutTick = nullptr;
         mTimeoutTickArmed = false;
     }
@@ -2241,17 +2270,17 @@ nsHttpConnectionMgr::OnMsgReschedTransac
     LOG(("nsHttpConnectionMgr::OnMsgReschedTransaction [trans=%p]\n", param));
 
     RefPtr<nsHttpTransaction> trans = static_cast<nsHttpTransaction *>(param);
     trans->SetPriority(priority);
 
     if (!trans->ConnectionInfo()) {
         return;
     }
-    nsConnectionEntry *ent = mCT.Get(trans->ConnectionInfo()->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(trans->ConnectionInfo()->HashKey());
 
     if (ent) {
         int32_t caps = trans->Caps();
         nsTArray<RefPtr<PendingTransactionInfo>> *pendingQ = nullptr;
         if (caps & NS_HTTP_URGENT_START) {
             pendingQ = &(ent->mUrgentStartQ);
         } else {
             pendingQ =
@@ -2303,17 +2332,17 @@ nsHttpConnectionMgr::OnMsgCancelTransact
     // transaction directly (removing it from the pending queue first).
     //
     RefPtr<nsAHttpConnection> conn(trans->Connection());
     if (conn && !trans->IsDone()) {
         conn->CloseTransaction(trans, closeCode);
     } else {
         nsConnectionEntry *ent = nullptr;
         if (trans->ConnectionInfo()) {
-            ent = mCT.Get(trans->ConnectionInfo()->HashKey());
+            ent = mCT.GetWeak(trans->ConnectionInfo()->HashKey());
         }
         if (ent) {
             uint32_t caps = trans->Caps();
             int32_t transIndex;
             // We will abandon all half-open sockets belonging to the given
             // transaction.
             nsTArray<RefPtr<PendingTransactionInfo>> *infoArray;
             RefPtr<PendingTransactionInfo> pendingTransInfo;
@@ -2375,31 +2404,31 @@ nsHttpConnectionMgr::OnMsgProcessPending
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     nsHttpConnectionInfo *ci = static_cast<nsHttpConnectionInfo *>(param);
 
     if (!ci) {
         LOG(("nsHttpConnectionMgr::OnMsgProcessPendingQ [ci=nullptr]\n"));
         // Try and dispatch everything
         for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-            Unused << ProcessPendingQForEntry(iter.Data(), true);
+            Unused << ProcessPendingQForEntry(iter.Data().get(), true);
         }
         return;
     }
 
     LOG(("nsHttpConnectionMgr::OnMsgProcessPendingQ [ci=%s]\n",
          ci->HashKey().get()));
 
     // start by processing the queue identified by the given connection info.
-    nsConnectionEntry *ent = mCT.Get(ci->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(ci->HashKey());
     if (!(ent && ProcessPendingQForEntry(ent, false))) {
         // if we reach here, it means that we couldn't dispatch a transaction
         // for the specified connection info.  walk the connection table...
         for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-            if (ProcessPendingQForEntry(iter.Data(), false)) {
+            if (ProcessPendingQForEntry(iter.Data().get(), false)) {
                 break;
             }
         }
     }
 }
 
 nsresult
 nsHttpConnectionMgr::CancelTransactions(nsHttpConnectionInfo *ci, nsresult code)
@@ -2425,17 +2454,17 @@ nsHttpConnectionMgr::CancelTransactionsH
     pendingQ.Clear();
 }
 
 void
 nsHttpConnectionMgr::OnMsgCancelTransactions(int32_t code, ARefBase *param)
 {
     nsresult reason = static_cast<nsresult>(code);
     nsHttpConnectionInfo *ci = static_cast<nsHttpConnectionInfo *>(param);
-    nsConnectionEntry *ent = mCT.Get(ci->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(ci->HashKey());
     LOG(("nsHttpConnectionMgr::OnMsgCancelTransactions %s %p\n",
          ci->HashKey().get(), ent));
     if (!ent) {
         return;
     }
 
     CancelTransactionsHelper(ent->mUrgentStartQ, ci, ent, reason);
 
@@ -2455,17 +2484,17 @@ nsHttpConnectionMgr::OnMsgPruneDeadConne
 
     // Reset mTimeOfNextWakeUp so that we can find a new shortest value.
     mTimeOfNextWakeUp = UINT64_MAX;
 
     // check canreuse() for all idle connections plus any active connections on
     // connection entries that are using spdy.
     if (mNumIdleConns || (mNumActiveConns && gHttpHandler->IsSpdyEnabled())) {
         for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-            nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
+            RefPtr<nsConnectionEntry> ent = iter.Data();
 
             LOG(("  pruning [ci=%s]\n", ent->mConnInfo->HashKey().get()));
 
             // Find out how long it will take for next idle connection to not
             // be reusable anymore.
             uint32_t timeToNextExpire = UINT32_MAX;
             int32_t count = ent->mIdleConns.Length();
             if (count > 0) {
@@ -2551,17 +2580,17 @@ nsHttpConnectionMgr::OnMsgPruneNoTraffic
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     LOG(("nsHttpConnectionMgr::OnMsgPruneNoTraffic\n"));
 
     // Prune connections without traffic
     for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
 
         // Close the connections with no registered traffic.
-        nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
+        RefPtr<nsConnectionEntry> ent = iter.Data();
 
         LOG(("  pruning no traffic [ci=%s]\n",
              ent->mConnInfo->HashKey().get()));
 
         uint32_t numConns = ent->mActiveConns.Length();
         if (numConns) {
             // Walk the list backwards to allow us to remove entries easily.
             for (int index = numConns - 1; index >= 0; index--) {
@@ -2589,17 +2618,17 @@ nsHttpConnectionMgr::OnMsgVerifyTraffic(
     if (mPruningNoTraffic) {
       // Called in the time gap when the timeout to prune notraffic
       // connections has triggered but the pruning hasn't happened yet.
       return;
     }
 
     // Mark connections for traffic verification
     for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-        nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
+        RefPtr<nsConnectionEntry> ent = iter.Data();
 
         // Iterate over all active connections and check them.
         for (uint32_t index = 0; index < ent->mActiveConns.Length(); ++index) {
             ent->mActiveConns[index]->CheckForTraffic(true);
         }
         // Iterate the idle connections and unmark them for traffic checks.
         for (uint32_t index = 0; index < ent->mIdleConns.Length(); ++index) {
             ent->mIdleConns[index]->CheckForTraffic(false);
@@ -2647,18 +2676,19 @@ nsHttpConnectionMgr::OnMsgReclaimConnect
     nsHttpConnection *conn = static_cast<nsHttpConnection *>(param);
 
     //
     // 1) remove the connection from the active list
     // 2) if keep-alive, add connection to idle list
     // 3) post event to process the pending transaction queue
     //
 
+    MOZ_DIAGNOSTIC_ASSERT(conn);
     nsConnectionEntry *ent = conn->ConnectionInfo() ?
-        mCT.Get(conn->ConnectionInfo()->HashKey()) : nullptr;
+        mCT.GetWeak(conn->ConnectionInfo()->HashKey()) : nullptr;
 
     if (!ent) {
         // this can happen if the connection is made outside of the
         // connection manager and is being "reclaimed" for use with
         // future transactions. HTTP/2 tunnels work like this.
         ent = GetOrCreateConnectionEntry(conn->ConnectionInfo(), true);
         LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection conn %p "
              "forced new hash entry %s\n",
@@ -3114,17 +3144,17 @@ nsHttpConnectionMgr::ShouldStopReading(n
     }
 
     // There are only unthrottled transactions for background tabs: don't throttle.
     return false;
 }
 
 bool nsHttpConnectionMgr::IsConnEntryUnderPressure(nsHttpConnectionInfo *connInfo)
 {
-    nsConnectionEntry *ent = mCT.Get(connInfo->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(connInfo->HashKey());
     if (!ent) {
       // No entry, no pressure.
       return false;
     }
 
     nsTArray<RefPtr<PendingTransactionInfo>> *transactions =
         ent->mPendingTransactionTable.Get(mCurrentTopLevelOuterContentWindowId);
 
@@ -3386,17 +3416,17 @@ nsHttpConnectionMgr::TimeoutTick()
 
     LOG(("nsHttpConnectionMgr::TimeoutTick active=%d\n", mNumActiveConns));
     // The next tick will be between 1 second and 1 hr
     // Set it to the max value here, and the TimeoutTick()s can
     // reduce it to their local needs.
     mTimeoutTickNext = 3600; // 1hr
 
     for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-        nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
+        RefPtr<nsConnectionEntry> ent = iter.Data();
 
         LOG(("nsHttpConnectionMgr::TimeoutTick() this=%p host=%s "
              "idle=%" PRIuSIZE " active=%" PRIuSIZE
              " half-len=%" PRIuSIZE " pending=%" PRIuSIZE
              " urgentStart pending=%" PRIuSIZE "\n",
              this, ent->mConnInfo->Origin(), ent->mIdleConns.Length(),
              ent->mActiveConns.Length(), ent->mHalfOpens.Length(),
              ent->PendingQLength(), ent->mUrgentStartQ.Length()));
@@ -3458,31 +3488,31 @@ nsHttpConnectionMgr::TimeoutTick()
 // 2] otherwise use an ent of wildcard(ci) than can be dispatched immediately
 // 3] otherwise create an ent that matches ci and make new conn on it
 
 nsHttpConnectionMgr::nsConnectionEntry *
 nsHttpConnectionMgr::GetOrCreateConnectionEntry(nsHttpConnectionInfo *specificCI,
                                                 bool prohibitWildCard)
 {
     // step 1
-    nsConnectionEntry *specificEnt = mCT.Get(specificCI->HashKey());
+    nsConnectionEntry *specificEnt = mCT.GetWeak(specificCI->HashKey());
     if (specificEnt && specificEnt->AvailableForDispatchNow()) {
         return specificEnt;
     }
 
     if (!specificCI->UsingHttpsProxy()) {
         prohibitWildCard = true;
     }
 
     // step 2
     if (!prohibitWildCard) {
         RefPtr<nsHttpConnectionInfo> wildCardProxyCI;
         DebugOnly<nsresult> rv = specificCI->CreateWildCard(getter_AddRefs(wildCardProxyCI));
         MOZ_ASSERT(NS_SUCCEEDED(rv));
-        nsConnectionEntry *wildCardEnt = mCT.Get(wildCardProxyCI->HashKey());
+        nsConnectionEntry *wildCardEnt = mCT.GetWeak(wildCardProxyCI->HashKey());
         if (wildCardEnt && wildCardEnt->AvailableForDispatchNow()) {
             return wildCardEnt;
         }
     }
 
     // step 3
     if (!specificEnt) {
         RefPtr<nsHttpConnectionInfo> clone(specificCI->Clone());
@@ -3603,65 +3633,68 @@ NS_INTERFACE_MAP_BEGIN(nsHttpConnectionM
 NS_INTERFACE_MAP_END
 
 nsHttpConnectionMgr::
 nsHalfOpenSocket::nsHalfOpenSocket(nsConnectionEntry *ent,
                                    nsAHttpTransaction *trans,
                                    uint32_t caps,
                                    bool speculative,
                                    bool isFromPredictor)
-    : mEnt(ent)
-    , mTransaction(trans)
+    : mTransaction(trans)
     , mDispatchedMTransaction(false)
     , mCaps(caps)
     , mSpeculative(speculative)
     , mIsFromPredictor(isFromPredictor)
     , mAllow1918(true)
     , mHasConnected(false)
     , mPrimaryConnectedOK(false)
     , mBackupConnectedOK(false)
     , mFreeToUse(true)
     , mPrimaryStreamStatus(NS_OK)
     , mFastOpenInProgress(false)
+    , mEnt(ent)
 {
     MOZ_ASSERT(ent && trans, "constructor with null arguments");
     LOG(("Creating nsHalfOpenSocket [this=%p trans=%p ent=%s key=%s]\n",
          this, trans, ent->mConnInfo->Origin(), ent->mConnInfo->HashKey().get()));
 
     if (speculative) {
         Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_TOTAL_SPECULATIVE_CONN> totalSpeculativeConn;
         ++totalSpeculativeConn;
 
         if (isFromPredictor) {
           Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_CREATED> totalPreconnectsCreated;
           ++totalPreconnectsCreated;
         }
     }
+
+    MOZ_DIAGNOSTIC_ASSERT(mEnt);
 }
 
 nsHttpConnectionMgr::nsHalfOpenSocket::~nsHalfOpenSocket()
 {
-    MOZ_ASSERT(!mStreamOut);
-    MOZ_ASSERT(!mBackupStreamOut);
-    MOZ_ASSERT(!mSynTimer);
+    MOZ_DIAGNOSTIC_ASSERT(!mStreamOut);
+    MOZ_DIAGNOSTIC_ASSERT(!mBackupStreamOut);
+    MOZ_DIAGNOSTIC_ASSERT(!mSynTimer);
     LOG(("Destroying nsHalfOpenSocket [this=%p]\n", this));
 
     if (mEnt)
         mEnt->RemoveHalfOpen(this);
 }
 
 nsresult
 nsHttpConnectionMgr::
 nsHalfOpenSocket::SetupStreams(nsISocketTransport **transport,
                                nsIAsyncInputStream **instream,
                                nsIAsyncOutputStream **outstream,
                                bool isBackup)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
+    MOZ_DIAGNOSTIC_ASSERT(mEnt);
     nsresult rv;
     const char *socketTypes[1];
     uint32_t typeCount = 0;
     const nsHttpConnectionInfo *ci = mEnt->mConnInfo;
     if (ci->FirstHopSSL()) {
         socketTypes[typeCount++] = "ssl";
     } else {
         socketTypes[typeCount] = gHttpHandler->DefaultSocketType();
@@ -3836,18 +3869,19 @@ nsHttpConnectionMgr::nsHalfOpenSocket::S
         mBackupTransport = nullptr;
     }
     return rv;
 }
 
 void
 nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupTimer()
 {
+    MOZ_DIAGNOSTIC_ASSERT(mEnt);
     uint16_t timeout = gHttpHandler->GetIdleSynTimeout();
-    MOZ_ASSERT(!mSynTimer, "timer already initd");
+    MOZ_DIAGNOSTIC_ASSERT(!mSynTimer, "timer already initd");
     if (!timeout && mFastOpenInProgress) {
         timeout = 250;
     }
     // When using Fast Open the correct transport will be setup for sure (it is
     // guaranteed), but it can be that it will happened a bit later.
     if (mFastOpenInProgress ||
         (timeout && !mSpeculative)) {
         // Setup the timer that will establish a backup socket
@@ -3918,17 +3952,24 @@ nsHttpConnectionMgr::nsHalfOpenSocket::A
     }
     if (mBackupStreamOut) {
         gHttpHandler->ConnMgr()->RecvdConnect();
         mBackupStreamOut->AsyncWait(nullptr, 0, 0, nullptr);
         mBackupStreamOut = nullptr;
     }
 
     // Lose references to input stream (and backup).
-    mStreamIn = mBackupStreamIn = nullptr;
+    if (mStreamIn) {
+        mStreamIn->AsyncWait(nullptr, 0, 0, nullptr);
+        mStreamIn = nullptr;
+    }
+    if (mBackupStreamIn) {
+        mBackupStreamIn->AsyncWait(nullptr, 0, 0, nullptr);
+        mBackupStreamIn = nullptr;
+    }
 
     // Stop the timer - we don't want any new backups.
     CancelBackupTimer();
 
     // Remove the half open from the connection entry.
     if (mEnt) {
         mEnt->mDoNotDestroy = false;
         mEnt->RemoveHalfOpen(this);
@@ -3945,17 +3986,21 @@ nsHttpConnectionMgr::nsHalfOpenSocket::D
     return (epoch - mPrimarySynStarted).ToMilliseconds();
 }
 
 
 NS_IMETHODIMP // method for nsITimerCallback
 nsHttpConnectionMgr::nsHalfOpenSocket::Notify(nsITimer *timer)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-    MOZ_ASSERT(timer == mSynTimer, "wrong timer");
+    MOZ_DIAGNOSTIC_ASSERT(timer == mSynTimer, "wrong timer");
+
+    MOZ_DIAGNOSTIC_ASSERT(!mBackupTransport);
+    MOZ_DIAGNOSTIC_ASSERT(mSynTimer);
+    MOZ_DIAGNOSTIC_ASSERT(mEnt);
 
     DebugOnly<nsresult> rv = SetupBackupStreams();
     MOZ_ASSERT(NS_SUCCEEDED(rv));
 
     mSynTimer = nullptr;
     return NS_OK;
 }
 
@@ -3988,18 +4033,21 @@ nsHalfOpenSocket::FindTransactionHelper(
 }
 
 // method for nsIAsyncOutputStreamCallback
 NS_IMETHODIMP
 nsHttpConnectionMgr::
 nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-    MOZ_ASSERT(out == mStreamOut || out == mBackupStreamOut,
-               "stream mismatch");
+    MOZ_DIAGNOSTIC_ASSERT(mStreamOut || mBackupStreamOut);
+    MOZ_DIAGNOSTIC_ASSERT(out == mStreamOut || out == mBackupStreamOut,
+                          "stream mismatch");
+    MOZ_DIAGNOSTIC_ASSERT(mEnt);
+
     LOG(("nsHalfOpenSocket::OnOutputStreamReady [this=%p ent=%s %s]\n",
          this, mEnt->mConnInfo->Origin(),
          out == mStreamOut ? "primary" : "backup"));
 
     mEnt->mDoNotDestroy = true;
     gHttpHandler->ConnMgr()->RecvdConnect();
 
     CancelBackupTimer();
@@ -4111,18 +4159,19 @@ nsHalfOpenSocket::FastOpenEnabled()
 
     return true;
 }
 
 nsresult
 nsHttpConnectionMgr::
 nsHalfOpenSocket::StartFastOpen()
 {
-    MOZ_ASSERT(mStreamOut);
-    MOZ_ASSERT(mEnt && !mBackupTransport);
+    MOZ_DIAGNOSTIC_ASSERT(mStreamOut);
+    MOZ_DIAGNOSTIC_ASSERT(!mBackupTransport);
+    MOZ_DIAGNOSTIC_ASSERT(mEnt);
 
     LOG(("nsHalfOpenSocket::StartFastOpen [this=%p]\n",
          this));
 
     RefPtr<nsHalfOpenSocket> deleteProtector(this);
 
     mFastOpenInProgress = true;
     // Remove this HalfOpen from mEnt->mHalfOpens.
@@ -4191,17 +4240,18 @@ nsHalfOpenSocket::StartFastOpen()
     }
     return rv;
 }
 
 void
 nsHttpConnectionMgr::
 nsHalfOpenSocket::SetFastOpenConnected(nsresult aError, bool aWillRetry)
 {
-    MOZ_ASSERT(mFastOpenInProgress);
+    MOZ_DIAGNOSTIC_ASSERT(mFastOpenInProgress);
+    MOZ_DIAGNOSTIC_ASSERT(mEnt);
 
     LOG(("nsHalfOpenSocket::SetFastOpenConnected [this=%p conn=%p error=%x]\n",
          this, mConnectionNegotiatingFastOpen.get(),
          static_cast<uint32_t>(aError)));
 
     // mConnectionNegotiatingFastOpen is set after a StartFastOpen creates
     // and activates a nsHttpConnection successfully (SetupConn calls
     // DispatchTransaction and DispatchAbstractTransaction which calls
@@ -4261,60 +4311,62 @@ nsHalfOpenSocket::SetFastOpenConnected(n
         mEnt->mHalfOpens.AppendElement(this);
         gHttpHandler->ConnMgr()->mNumHalfOpenConns++;
         gHttpHandler->ConnMgr()->StartedConnect();
 
         // Restore callbacks.
         mStreamOut->AsyncWait(this, 0, 0, nullptr);
         mSocketTransport->SetEventSink(this, nullptr);
         mSocketTransport->SetSecurityCallbacks(this);
-        mStreamOut->AsyncWait(this, 0, 0, nullptr);
+        mStreamIn->AsyncWait(nullptr, 0, 0, nullptr);
 
     } else {
         // On success or other error we proceed with connection, we just need
         // to close backup timer and halfOpenSock.
         CancelBackupTimer();
         if (NS_SUCCEEDED(aError)) {
             NetAddr peeraddr;
             if (NS_SUCCEEDED(mSocketTransport->GetPeerAddr(&peeraddr))) {
                 mEnt->RecordIPFamilyPreference(peeraddr.raw.family);
             }
             gHttpHandler->ResetFastOpenConsecutiveFailureCounter();
         }
         mSocketTransport = nullptr;
         mStreamOut = nullptr;
         mStreamIn = nullptr;
 
-        // If backup transport ha already started put this HalfOpen back to
-        // mEnt list.
-        if (mBackupTransport) {
-            mEnt->mHalfOpens.AppendElement(this);
-            gHttpHandler->ConnMgr()->mNumHalfOpenConns++;
-        }
+        Abandon();
     }
 
     mFastOpenInProgress = false;
     mConnectionNegotiatingFastOpen = nullptr;
-    mEnt->mDoNotDestroy = false;
+    if (mEnt) {
+        mEnt->mDoNotDestroy = false;
+        MOZ_DIAGNOSTIC_ASSERT(mEnt->mHalfOpens.Contains(this));
+    } else {
+        MOZ_DIAGNOSTIC_ASSERT(!mSynTimer);
+        MOZ_DIAGNOSTIC_ASSERT(!mBackupTransport);
+        MOZ_DIAGNOSTIC_ASSERT(!mBackupStreamOut);
+    }
 }
 
 void
 nsHttpConnectionMgr::
 nsHalfOpenSocket::SetFastOpenStatus(uint8_t tfoStatus)
 {
     MOZ_ASSERT(mFastOpenInProgress);
     mConnectionNegotiatingFastOpen->SetFastOpenStatus(tfoStatus);
     mConnectionNegotiatingFastOpen->Transaction()->SetFastOpenStatus(tfoStatus);
 }
 
 void
 nsHttpConnectionMgr::
 nsHalfOpenSocket::CancelFastOpenConnection()
 {
-    MOZ_ASSERT(mFastOpenInProgress);
+    MOZ_DIAGNOSTIC_ASSERT(mFastOpenInProgress);
 
     LOG(("nsHalfOpenSocket::CancelFastOpenConnection [this=%p conn=%p]\n",
          this, mConnectionNegotiatingFastOpen.get()));
 
     RefPtr<nsHalfOpenSocket> deleteProtector(this);
     mEnt->mHalfOpenFastOpenBackups.RemoveElement(this);
     mSocketTransport->SetFastOpenCallback(nullptr);
     mConnectionNegotiatingFastOpen->SetFastOpen(false);
@@ -4334,16 +4386,19 @@ nsHalfOpenSocket::CancelFastOpenConnecti
         } else {
             mEnt->InsertTransaction(pendingTransInfo, true);
         }
     }
 
     mFastOpenInProgress = false;
     mConnectionNegotiatingFastOpen = nullptr;
     Abandon();
+    MOZ_DIAGNOSTIC_ASSERT(!mSynTimer);
+    MOZ_DIAGNOSTIC_ASSERT(!mBackupTransport);
+    MOZ_DIAGNOSTIC_ASSERT(!mBackupStreamOut);
 }
 
 void
 nsHttpConnectionMgr::
 nsHalfOpenSocket::FastOpenNotSupported()
 {
   MOZ_ASSERT(mFastOpenInProgress);
   gHttpHandler->SetFastOpenNotSupported();
@@ -4506,18 +4561,18 @@ nsHalfOpenSocket::SetupConn(nsIAsyncOutp
                 }
             }
         }
     }
 
     // If this connection has a transaction get reference to its
     // ConnectionHandler.
     if (aFastOpen) {
-        MOZ_ASSERT(mEnt);
-        MOZ_ASSERT(static_cast<int32_t>(mEnt->mIdleConns.IndexOf(conn)) == -1);
+        MOZ_DIAGNOSTIC_ASSERT(mEnt);
+        MOZ_DIAGNOSTIC_ASSERT(static_cast<int32_t>(mEnt->mIdleConns.IndexOf(conn)) == -1);
         int32_t idx = mEnt->mActiveConns.IndexOf(conn);
         if (NS_SUCCEEDED(rv) && (idx != -1)) {
             mConnectionNegotiatingFastOpen = conn;
         } else {
             conn->SetFastOpen(false);
         }
     }
 
@@ -4561,17 +4616,24 @@ nsHttpConnectionMgr::RegisterOriginCoale
 NS_IMETHODIMP
 nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport *trans,
                                                          nsresult status,
                                                          int64_t progress,
                                                          int64_t progressMax)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
+    MOZ_DIAGNOSTIC_ASSERT((trans == mSocketTransport) || (trans == mBackupTransport));
     MOZ_DIAGNOSTIC_ASSERT(mEnt);
+
+    if (mEnt->mHowItWasRemoved == nsConnectionEntry::CONN_ENTRY_CLEAR_CONNECTION_HISTORY) {
+        MOZ_DIAGNOSTIC_ASSERT(false);
+    } else if (mEnt->mHowItWasRemoved == nsConnectionEntry::CONN_ENTRY_REMOVED_SHUTDOWN) {
+        MOZ_DIAGNOSTIC_ASSERT(false);
+    }
     if (mTransaction) {
         RefPtr<PendingTransactionInfo> info = FindTransactionHelper(false);
         if ((trans == mSocketTransport) ||
             ((trans == mBackupTransport) && (status == NS_NET_STATUS_CONNECTED_TO) &&
             info)) {
             // Send this status event only if the transaction is still panding,
             // i.e. it has not found a free already connected socket.
             // Sockets in halfOpen state can only get following events:
@@ -4748,16 +4810,17 @@ ConnectionHandle::HttpConnection()
 nsHttpConnectionMgr::
 nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci)
     : mConnInfo(ci)
     , mUsingSpdy(false)
     , mPreferIPv4(false)
     , mPreferIPv6(false)
     , mUsedForConnection(false)
     , mDoNotDestroy(false)
+    , mHowItWasRemoved(CONN_ENTRY_NOT_REMOVED)
 {
     MOZ_COUNT_CTOR(nsConnectionEntry);
     mUseFastOpen = gHttpHandler->UseFastOpen();
 
     LOG(("nsConnectionEntry::nsConnectionEntry this=%p key=%s",
          this, ci->HashKey().get()));
 }
 
@@ -4771,17 +4834,17 @@ nsHttpConnectionMgr::nsConnectionEntry::
     return gHttpHandler->ConnMgr()->
         GetSpdyActiveConn(this) ? true : false;
 }
 
 bool
 nsHttpConnectionMgr::GetConnectionData(nsTArray<HttpRetParams> *aArg)
 {
     for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
-        nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
+        RefPtr<nsConnectionEntry> ent = iter.Data();
 
         if (ent->mConnInfo->GetPrivate()) {
             continue;
         }
 
         HttpRetParams data;
         data.host = ent->mConnInfo->Origin();
         data.port = ent->mConnInfo->OriginPort();
@@ -4818,17 +4881,17 @@ nsHttpConnectionMgr::GetConnectionData(n
 
     return true;
 }
 
 void
 nsHttpConnectionMgr::ResetIPFamilyPreference(nsHttpConnectionInfo *ci)
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-    nsConnectionEntry *ent = mCT.Get(ci->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(ci->HashKey());
     if (ent) {
         ent->ResetIPFamilyPreference();
     }
 }
 
 uint32_t
 nsHttpConnectionMgr::
 nsConnectionEntry::UnconnectedHalfOpens()
@@ -5016,17 +5079,17 @@ nsHttpConnectionMgr::MoveToWildCardConnE
 {
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     MOZ_ASSERT(specificCI->UsingHttpsProxy());
 
     LOG(("nsHttpConnectionMgr::MakeConnEntryWildCard conn %p has requested to "
          "change CI from %s to %s\n", proxyConn, specificCI->HashKey().get(),
          wildCardCI->HashKey().get()));
 
-    nsConnectionEntry *ent = mCT.Get(specificCI->HashKey());
+    nsConnectionEntry *ent = mCT.GetWeak(specificCI->HashKey());
     LOG(("nsHttpConnectionMgr::MakeConnEntryWildCard conn %p using ent %p (spdy %d)\n",
          proxyConn, ent, ent ? ent->mUsingSpdy : 0));
 
     if (!ent || !ent->mUsingSpdy) {
         return;
     }
 
     nsConnectionEntry *wcEnt = GetOrCreateConnectionEntry(wildCardCI, true);
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -239,22 +239,21 @@ private:
     class PendingTransactionInfo;
 
     // nsConnectionEntry
     //
     // mCT maps connection info hash key to nsConnectionEntry object, which
     // contains list of active and idle connections as well as the list of
     // pending transactions.
     //
-    class nsConnectionEntry : public SupportsWeakPtr<nsConnectionEntry>
+    class nsConnectionEntry
     {
     public:
-        MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsConnectionEntry)
+        NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsConnectionEntry)
         explicit nsConnectionEntry(nsHttpConnectionInfo *ci);
-        ~nsConnectionEntry();
 
         RefPtr<nsHttpConnectionInfo> mConnInfo;
         nsTArray<RefPtr<PendingTransactionInfo> > mUrgentStartQ;// the urgent start transaction queue
 
         // This table provides a mapping from top level outer content window id
         // to a queue of pending transaction information.
         // The transaction's order in pending queue is decided by whether it's a
         // blocking transaction and its priority.
@@ -332,16 +331,23 @@ private:
         // focused and non-focused windows.
         void AppendPendingQForNonFocusedWindows(
             uint64_t windowId,
             nsTArray<RefPtr<PendingTransactionInfo>> &result,
             uint32_t maxCount = 0);
 
         // Remove the empty pendingQ in |mPendingTransactionTable|.
         void RemoveEmptyPendingQ();
+        enum {
+          CONN_ENTRY_NOT_REMOVED,
+          CONN_ENTRY_CLEAR_CONNECTION_HISTORY,
+          CONN_ENTRY_REMOVED_SHUTDOWN,
+        }  mHowItWasRemoved;
+    private:
+        ~nsConnectionEntry();
     };
 
 public:
     static nsAHttpConnection *MakeConnectionHandle(nsHttpConnection *aWrapped);
     void RegisterOriginCoalescingKey(nsHttpConnection *, const nsACString &host, int32_t port);
 
 private:
 
@@ -401,27 +407,27 @@ private:
         void Unclaim();
 
         bool FastOpenEnabled() override;
         nsresult StartFastOpen() override;
         void SetFastOpenConnected(nsresult, bool aWillRetry) override;
         void FastOpenNotSupported() override;
         void SetFastOpenStatus(uint8_t tfoStatus) override;
         void CancelFastOpenConnection();
+
     private:
         nsresult SetupConn(nsIAsyncOutputStream *out,
                            bool aFastOpen);
 
         // To find out whether |mTransaction| is still in the connection entry's
         // pending queue. If the transaction is found and |removeWhenFound| is
         // true, the transaction will be removed from the pending queue.
         already_AddRefed<PendingTransactionInfo>
         FindTransactionHelper(bool removeWhenFound);
 
-        WeakPtr<nsConnectionEntry>     mEnt;
         RefPtr<nsAHttpTransaction>     mTransaction;
         bool                           mDispatchedMTransaction;
         nsCOMPtr<nsISocketTransport>   mSocketTransport;
         nsCOMPtr<nsIAsyncOutputStream> mStreamOut;
         nsCOMPtr<nsIAsyncInputStream>  mStreamIn;
         uint32_t                       mCaps;
 
         // mSpeculative is set if the socket was created from
@@ -438,38 +444,44 @@ private:
         // connections from the predictor.
         bool                           mIsFromPredictor;
 
         bool                           mAllow1918;
 
         TimeStamp             mPrimarySynStarted;
         TimeStamp             mBackupSynStarted;
 
-        // for syn retry
-        nsCOMPtr<nsITimer>             mSynTimer;
-        nsCOMPtr<nsISocketTransport>   mBackupTransport;
-        nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut;
-        nsCOMPtr<nsIAsyncInputStream>  mBackupStreamIn;
-
         // mHasConnected tracks whether one of the sockets has completed the
         // connection process. It may have completed unsuccessfully.
         bool                           mHasConnected;
 
         bool                           mPrimaryConnectedOK;
         bool                           mBackupConnectedOK;
 
         // A nsHalfOpenSocket can be made for a concrete non-null transaction,
         // but the transaction can be dispatch to another connection. In that
         // case we can free this transaction to be claimed by other
         // transactions.
         bool                           mFreeToUse;
         nsresult                       mPrimaryStreamStatus;
 
         bool                           mFastOpenInProgress;
         RefPtr<nsHttpConnection>       mConnectionNegotiatingFastOpen;
+
+    private:
+        // nsHttpConnectionMgr is friend class so that we can access them for
+        // diagnostic asserts. The this asserts are removed the following line
+        // needs to be removed.
+        friend class nsHttpConnectionMgr;
+
+        RefPtr<nsConnectionEntry>      mEnt;
+        nsCOMPtr<nsITimer>             mSynTimer;
+        nsCOMPtr<nsISocketTransport>   mBackupTransport;
+        nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut;
+        nsCOMPtr<nsIAsyncInputStream>  mBackupStreamIn;
     };
     friend class nsHalfOpenSocket;
 
     class PendingTransactionInfo : public ARefBase
     {
     public:
         explicit PendingTransactionInfo(nsHttpTransaction * trans)
             : mTransaction(trans)
@@ -653,17 +665,17 @@ private:
 
     //
     // the connection table
     //
     // this table is indexed by connection key.  each entry is a
     // nsConnectionEntry object. It is unlocked and therefore must only
     // be accessed from the socket thread.
     //
-    nsClassHashtable<nsCStringHashKey, nsConnectionEntry> mCT;
+    nsRefPtrHashtable<nsCStringHashKey, nsConnectionEntry> mCT;
 
     // Read Timeout Tick handlers
     void TimeoutTick();
 
     // For diagnostics
     void OnMsgPrintDiagnostics(int32_t, ARefBase *);
 
     nsCString mLogData;
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1144,9 +1144,9 @@ static const TransportSecurityPreload kP
   { "za.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
   { "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
 };
 
 // Pinning Preload List Length = 480;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1508775718131000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1508861597841000);
--- a/security/manager/ssl/nsSTSPreloadList.errors
+++ b/security/manager/ssl/nsSTSPreloadList.errors
@@ -23,20 +23,22 @@ 123share.org: could not connect to host
 123test.de: did not receive HSTS header
 123test.es: did not receive HSTS header
 123test.fr: did not receive HSTS header
 126ium.moe: could not connect to host
 127011-networks.ch: could not connect to host
 12vpnchina.com: could not connect to host
 163pwd.com: could not connect to host
 16packets.com: could not connect to host
+173vpn.cn: could not connect to host
 188betwarriors.co.uk: could not connect to host
 188trafalgar.ca: did not receive HSTS header
 195gm.com: could not connect to host
 1a-jva.de: could not connect to host
+1a-vermessung.at: could not connect to host
 1atic.com: could not connect to host
 1cover.com: could not connect to host
 1k8b.com: could not connect to host
 1password.com: did not receive HSTS header
 1s.tn: could not connect to host
 1stcapital.com.sg: did not receive HSTS header
 1xcess.com: did not receive HSTS header
 1years.cc: could not connect to host
@@ -70,16 +72,17 @@ 3click-loan.com: could not connect to ho
 3delivered.com: could not connect to host
 3dproteinimaging.com: did not receive HSTS header
 3sreporting.com: did not receive HSTS header
 3yearloans.com: could not connect to host
 404.sh: max-age too low: 0
 404404.info: could not connect to host
 420dongstorm.com: could not connect to host
 42ms.org: could not connect to host
+441jj.com: could not connect to host
 4455software.com: did not receive HSTS header
 4679.space: could not connect to host
 4azino777.ru: could not connect to host
 4cclothing.com: could not connect to host
 4elements.com: did not receive HSTS header
 4eyes.ch: did not receive HSTS header
 4miners.net: could not connect to host
 4sqsu.eu: could not connect to host
@@ -100,24 +103,25 @@ 960news.ca: could not connect to host
 9651678.ru: could not connect to host
 99511.fi: did not receive HSTS header
 9jadirect.com: could not connect to host
 9point6.com: could not connect to host
 9tolife.be: did not receive HSTS header
 a-plus.space: could not connect to host
 a-theme.com: could not connect to host
 a9c.co: could not connect to host
-aaeblog.com: could not connect to host
-aaeblog.net: could not connect to host
-aaeblog.org: could not connect to host
+aaeblog.com: did not receive HSTS header
+aaeblog.net: did not receive HSTS header
+aaeblog.org: did not receive HSTS header
 aaoo.net: could not connect to host
 aapp.space: could not connect to host
 aaron-gustafson.com: did not receive HSTS header
 aati.info: did not receive HSTS header
 abareplace.com: did not receive HSTS header
+abdullah.pw: could not connect to host
 abearofsoap.com: could not connect to host
 abecodes.net: did not receive HSTS header
 abilitylist.org: did not receive HSTS header
 abioniere.de: could not connect to host
 ablogagency.net: could not connect to host
 abnarnro.com: could not connect to host
 about.ge: did not receive HSTS header
 abouthrm.nl: did not receive HSTS header
@@ -191,29 +195,29 @@ aduedu.de: did not receive HSTS header
 adunanza.net: did not receive HSTS header
 advancedstudio.ro: did not receive HSTS header
 adver.top: could not connect to host
 adviespuntklokkenluiders.nl: could not connect to host
 aemoria.com: could not connect to host
 aerialmediapro.net: could not connect to host
 aes256.ru: could not connect to host
 aether.pw: could not connect to host
-aevpn.net: could not connect to host
 aeyoun.com: did not receive HSTS header
 af-fotografie.net: did not receive HSTS header
 affilie.de: did not receive HSTS header
 aficotroceni.ro: did not receive HSTS header
 afiru.net: could not connect to host
 afp548.tk: could not connect to host
 afvallendoeje.nu: could not connect to host
 afyou.co.kr: could not connect to host
 agalaxyfarfaraway.co.uk: could not connect to host
 agate.pw: did not receive HSTS header
 agatheetraphael.fr: could not connect to host
 agbremen.de: did not receive HSTS header
+agenciadeempregosdourados.com.br: could not connect to host
 agentseeker.ca: did not receive HSTS header
 agevio.com: could not connect to host
 agrimap.com: did not receive HSTS header
 agro-id.gov.ua: did not receive HSTS header
 ahabingo.com: did not receive HSTS header
 ahoynetwork.com: did not receive HSTS header
 ahri.ovh: could not connect to host
 aidanwoods.com: did not receive HSTS header
@@ -302,21 +306,20 @@ amishsecurity.com: could not connect to 
 amitube.com: could not connect to host
 amlvfs.net: could not connect to host
 amoory.com: did not receive HSTS header
 amri.nl: did not receive HSTS header
 anadoluefessporkulubu.org: could not connect to host
 anagra.ms: could not connect to host
 analytic-s.ml: did not receive HSTS header
 analyticsinmotion.net: could not connect to host
-analyticum.at: could not connect to host
-analyticum.com: could not connect to host
 ancientkarma.com: could not connect to host
 andere-gedanken.net: max-age too low: 10
 anderslind.dk: could not connect to host
+andre-ballensiefen.de: did not receive HSTS header
 andreasbreitenlohner.de: did not receive HSTS header
 andreasfritz-fotografie.de: could not connect to host
 andreastoneman.com: could not connect to host
 andreigec.net: did not receive HSTS header
 andrespaz.com: could not connect to host
 andrew.london: did not receive HSTS header
 andrewbroekman.com: could not connect to host
 andrewhowden.com: could not connect to host
@@ -394,17 +397,16 @@ appreciationkards.com: could not connect
 approlys.fr: did not receive HSTS header
 apps-for-fishing.com: could not connect to host
 appsbystudio.co.uk: could not connect to host
 appsdash.io: could not connect to host
 aqilacademy.com.au: could not connect to host
 aquilalab.com: could not connect to host
 arabdigitalexpression.org: did not receive HSTS header
 aradulconteaza.ro: could not connect to host
-aramido.de: could not connect to host
 aran.me.uk: could not connect to host
 arboineuropa.nl: did not receive HSTS header
 arboleda-hurtado.com: could not connect to host
 arboworks.com: could not connect to host
 arbu.eu: max-age too low: 2419200
 arcbit.io: could not connect to host
 ardao.me: could not connect to host
 argennon.xyz: could not connect to host
@@ -414,17 +416,16 @@ aristilabs.com: did not receive HSTS hea
 arlen.se: could not connect to host
 armingrodon.de: could not connect to host
 armor.com: did not receive HSTS header
 armory.consulting: could not connect to host
 armory.supplies: could not connect to host
 armsday.com: could not connect to host
 armytricka.cz: did not receive HSTS header
 arocloud.de: could not connect to host
-arod.tk: did not receive HSTS header
 aroundme.org: did not receive HSTS header
 arpa.ph: could not connect to host
 arpr.co: did not receive HSTS header
 arrayify.com: could not connect to host
 arrow-api.nl: did not receive HSTS header
 arrow-cloud.nl: could not connect to host
 arrowfunction.com: could not connect to host
 ars-design.net: could not connect to host
@@ -441,17 +442,17 @@ asahikoji.net: could not connect to host
 asasuou.pw: could not connect to host
 asc16.com: could not connect to host
 ascamso.com: could not connect to host
 aschaefer.net: could not connect to host
 asdpress.cn: could not connect to host
 aserver.co: could not connect to host
 ashlane-cottages.com: could not connect to host
 asianodor.com: could not connect to host
-ask.pe: could not connect to host
+ask.pe: did not receive HSTS header
 askfit.cz: did not receive HSTS header
 asm-x.com: could not connect to host
 asmui.ga: could not connect to host
 asmui.ml: could not connect to host
 ass.org.au: did not receive HSTS header
 assekuranzjobs.de: could not connect to host
 asset-alive.com: did not receive HSTS header
 asset-alive.net: did not receive HSTS header
@@ -461,16 +462,17 @@ astromelody.com: did not receive HSTS he
 asuhe.cc: did not receive HSTS header
 asuhe.win: did not receive HSTS header
 atavio.at: could not connect to host
 atavio.ch: could not connect to host
 atavio.de: did not receive HSTS header
 atbeckett.com: did not receive HSTS header
 athaliasoft.com: could not connect to host
 athenelive.com: could not connect to host
+athensbusinessresources.us: could not connect to host
 athul.xyz: could not connect to host
 atlex.nl: did not receive HSTS header
 atomic.menu: could not connect to host
 atomik.pro: could not connect to host
 atop.io: could not connect to host
 attic118.com: could not connect to host
 attimidesigns.com: did not receive HSTS header
 au.search.yahoo.com: max-age too low: 172800
@@ -592,16 +594,17 @@ bcweightlifting.ca: could not connect to
 bddemir.com: could not connect to host
 bde-epitech.fr: could not connect to host
 bdikaros-network.net: could not connect to host
 be.search.yahoo.com: did not receive HSTS header
 beach-inspector.com: did not receive HSTS header
 beachi.es: could not connect to host
 beaglewatch.com: could not connect to host
 beardydave.com: did not receive HSTS header
+beasel.biz: could not connect to host
 beastlog.tk: could not connect to host
 beastowner.com: did not receive HSTS header
 beautyconcept.co: did not receive HSTS header
 beavers.io: could not connect to host
 bebeefy.uk: could not connect to host
 bebesurdoue.com: could not connect to host
 bedabox.com: max-age too low: 0
 bedeta.de: could not connect to host
@@ -640,16 +643,17 @@ bestmodels.su: did not receive HSTS head
 betaclean.fr: did not receive HSTS header
 betafive.net: could not connect to host
 betcafearena.ro: could not connect to host
 bethditto.com: did not receive HSTS header
 betnet.fr: could not connect to host
 betplanning.it: did not receive HSTS header
 bets.de: did not receive HSTS header
 betshoot.com: did not receive HSTS header
+betterlifemakers.com: could not connect to host
 bettween.com: could not connect to host
 betz.ro: did not receive HSTS header
 beulahtabernacle.com: could not connect to host
 bevapehappy.com: did not receive HSTS header
 bewerbungsfibel.de: did not receive HSTS header
 beyond-edge.com: could not connect to host
 beyuna.co.uk: did not receive HSTS header
 beyuna.eu: did not receive HSTS header
@@ -662,26 +666,23 @@ bgcparkstad.nl: did not receive HSTS hea
 bgmn.net: could not connect to host
 bhatia.at: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
 bi.search.yahoo.com: did not receive HSTS header
 biblerhymes.com: did not receive HSTS header
 bidon.ca: did not receive HSTS header
 bieberium.de: could not connect to host
 bienenblog.cc: could not connect to host
 bierbringer.at: could not connect to host
-bierochs.org: could not connect to host
-big-andy.co.uk: could not connect to host
 big-black.de: did not receive HSTS header
 bigbbqbrush.bid: could not connect to host
 bigbrownpromotions.com.au: did not receive HSTS header
 bigshinylock.minazo.net: could not connect to host
 biguixhe.net: did not receive HSTS header
 bildiri.ci: did not receive HSTS header
 bildschirmflackern.de: did not receive HSTS header
-billaud.eu.org: could not connect to host
 billin.net: did not receive HSTS header
 billkiss.com: could not connect to host
 billninja.com: did not receive HSTS header
 billrusling.com: could not connect to host
 bimbo.com: did not receive HSTS header
 binaryfigments.com: could not connect to host
 binderapp.net: could not connect to host
 biofam.ru: did not receive HSTS header
@@ -699,22 +700,19 @@ bitcoinworld.me: could not connect to ho
 bitconcepts.co.uk: did not receive HSTS header
 biteoftech.com: did not receive HSTS header
 bitf.ly: could not connect to host
 bitfactory.ws: could not connect to host
 bitfarm-archiv.com: did not receive HSTS header
 bitfarm-archiv.de: did not receive HSTS header
 bitheus.com: could not connect to host
 bithosting.io: did not receive HSTS header
-bitlish.com: did not receive HSTS header
-bitmainwarranty.com: could not connect to host
 bitnet.io: did not receive HSTS header
 bitrage.de: could not connect to host
 bitraum.io: did not receive HSTS header
-bitref.com: did not receive HSTS header
 bitsafe.systems: did not receive HSTS header
 bitvigor.com: could not connect to host
 bivsi.com: could not connect to host
 bizcms.com: did not receive HSTS header
 bizon.sk: did not receive HSTS header
 bkb-skandal.ch: could not connect to host
 bl4ckb0x.com: could not connect to host
 bl4ckb0x.de: could not connect to host
@@ -725,16 +723,17 @@ bl4ckb0x.org: could not connect to host
 black-armada.com.pl: could not connect to host
 black-armada.pl: could not connect to host
 black-octopus.ru: did not receive HSTS header
 blackburn.link: could not connect to host
 blackdragoninc.org: could not connect to host
 blacklane.com: did not receive HSTS header
 blackly.uk: max-age too low: 0
 blackpayment.ru: could not connect to host
+blackphantom.de: could not connect to host
 blackunicorn.wtf: could not connect to host
 blakerandall.xyz: could not connect to host
 blantik.net: could not connect to host
 blaudev.es: did not receive HSTS header
 blauwwit.be: did not receive HSTS header
 blendle.nl: did not receive HSTS header
 blendlecdn.com: could not connect to host
 blenheimchalcot.com: did not receive HSTS header
@@ -767,24 +766,22 @@ bobep.ru: could not connect to host
 bodo-wolff.de: could not connect to host
 bodyblog.nl: did not receive HSTS header
 bodybuilding-legends.com: could not connect to host
 bodyweightsolution.com: could not connect to host
 boensou.com: did not receive HSTS header
 bogosity.se: could not connect to host
 bohan.life: could not connect to host
 boiadeirodeberna.com: could not connect to host
-boilesen.com: could not connect to host
 boltdata.io: could not connect to host
 bonapp.restaurant: could not connect to host
 bonfi.net: did not receive HSTS header
 bonitabrazilian.co.nz: did not receive HSTS header
 bonop.com: did not receive HSTS header
 bonta.one: could not connect to host
-boof.com: did not receive HSTS header
 bookcelerator.com: did not receive HSTS header
 booked.holiday: could not connect to host
 bookofraonlinecasinos.com: did not receive HSTS header
 bookourdjs.com: max-age too low: 0
 boomerang.com: did not receive HSTS header
 boosterlearnpro.com: did not receive HSTS header
 booth.in.th: did not receive HSTS header
 bootjp.me: did not receive HSTS header
@@ -879,17 +876,16 @@ businessloanstoday.com: max-age too low:
 busold.ws: could not connect to host
 bustimes.org: could not connect to host
 butchersworkshop.com: did not receive HSTS header
 buttercoin.com: could not connect to host
 butterfieldstraining.com: did not receive HSTS header
 buyaccessible.gov: did not receive HSTS header
 buybaby.eu: did not receive HSTS header
 buyfox.de: did not receive HSTS header
-buzzdeck.com: could not connect to host
 bw81.xyz: could not connect to host
 bwear4all.de: could not connect to host
 by4cqb.cn: could not connect to host
 bydisk.com: could not connect to host
 bypassed.bid: did not receive HSTS header
 bypassed.cc: did not receive HSTS header
 bypassed.club: did not receive HSTS header
 bypassed.date: did not receive HSTS header
@@ -954,16 +950,17 @@ cancelmyprofile.com: did not receive HST
 candicontrols.com: did not receive HSTS header
 candratech.com: could not connect to host
 candylion.rocks: could not connect to host
 cannyfoxx.me: could not connect to host
 canyonshoa.com: did not receive HSTS header
 capecycles.co.za: did not receive HSTS header
 capeyorkfire.com.au: did not receive HSTS header
 capitaltg.com: could not connect to host
+capitolpathways.org: could not connect to host
 captchatheprize.com: could not connect to host
 captianseb.de: could not connect to host
 captivatedbytabrett.com: could not connect to host
 car-navi.ph: did not receive HSTS header
 carano-service.de: did not receive HSTS header
 caraudio69.cz: could not connect to host
 carck.co.uk: could not connect to host
 carck.uk: could not connect to host
@@ -1095,16 +1092,17 @@ cim2b.de: could not connect to host
 cimalando.eu: could not connect to host
 cintdirect.com: could not connect to host
 cioconference.co.nz: could not connect to host
 ciplanutrition.com: did not receive HSTS header
 cirrohost.com: did not receive HSTS header
 ciscohomeanalytics.com: could not connect to host
 ciscommerce.net: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118"  data: no]
 citiagent.cz: could not connect to host
+citizing.org: could not connect to host
 cityoflaurel.org: did not receive HSTS header
 ciuciucadou.ro: could not connect to host
 cium.ru: could not connect to host
 cjcaron.org: could not connect to host
 clara-baumert.de: could not connect to host
 claralabs.com: did not receive HSTS header
 classicsandexotics.com: did not receive HSTS header
 classicspublishing.com: could not connect to host
@@ -1139,16 +1137,17 @@ cloudns.com.au: could not connect to hos
 cloudspeedy.net: could not connect to host
 cloudspotterapp.com: did not receive HSTS header
 cloudstoragemaus.com: could not connect to host
 cloudstorm.me: could not connect to host
 cloudstrike.co: could not connect to host
 cloudwalk.io: did not receive HSTS header
 cloverleaf.net: max-age too low: 0
 clowde.in: could not connect to host
+clubmate.rocks: could not connect to host
 clubmix.co.kr: could not connect to host
 cluster.id: did not receive HSTS header
 clustermaze.net: could not connect to host
 clvrwebdesign.com: did not receive HSTS header
 clywedogmaths.co.uk: could not connect to host
 cmc-versand.de: did not receive HSTS header
 cmci.dk: did not receive HSTS header
 cmsbattle.com: could not connect to host
@@ -1312,16 +1311,17 @@ crypt.guru: could not connect to host
 crypticshell.co.uk: could not connect to host
 cryptify.eu: could not connect to host
 cryptobin.org: could not connect to host
 cryptodash.net: could not connect to host
 cryptojar.io: did not receive HSTS header
 cryptolab.pro: could not connect to host
 cryptolab.tk: could not connect to host
 cryptonit.net: did not receive HSTS header
+cryptoparty.at: could not connect to host
 cryptopartyatx.org: could not connect to host
 cryptophobia.nl: did not receive HSTS header
 cryptopush.com: did not receive HSTS header
 crysadm.com: max-age too low: 1
 crystalclassics.co.uk: did not receive HSTS header
 csapak.com: could not connect to host
 csawctf.poly.edu: could not connect to host
 csfs.org.uk: could not connect to host
@@ -1340,16 +1340,17 @@ cubeserver.eu: could not connect to host
 cubewano.com: could not connect to host
 cubostecnologia.com: did not receive HSTS header
 cucc.date: did not receive HSTS header
 cujanovic.com: did not receive HSTS header
 culinae.nl: could not connect to host
 cumshots-video.ru: could not connect to host
 cuntflaps.me: could not connect to host
 cuongquach.com: did not receive HSTS header
+curacao-firma.com: did not receive HSTS header
 curlyroots.com: did not receive HSTS header
 curroapp.com: could not connect to host
 curveweb.co.uk: did not receive HSTS header
 custe.rs: could not connect to host
 cuteys.de: max-age too low: 86400
 cutorrent.com: could not connect to host
 cuvva.co.uk: did not receive HSTS header
 cuvva.eu: did not receive HSTS header
@@ -1360,18 +1361,19 @@ cuvva.me: did not receive HSTS header
 cuvva.net: did not receive HSTS header
 cuvva.org: did not receive HSTS header
 cuvva.uk: did not receive HSTS header
 cuvva.us: did not receive HSTS header
 cviip.com: could not connect to host
 cvtparking.co.uk: could not connect to host
 cyanogenmod.xxx: could not connect to host
 cyber.cafe: could not connect to host
+cybercecurity.com: did not receive HSTS header
+cyberfrancais.ro: did not receive HSTS header
 cyberlab.kiev.ua: did not receive HSTS header
-cyberlab.team: could not connect to host
 cyberpunk.ca: could not connect to host
 cybershambles.com: could not connect to host
 cybersins.com: did not receive HSTS header
 cybersmart.co.uk: did not receive HSTS header
 cycleluxembourg.lu: did not receive HSTS header
 cydia-search.io: could not connect to host
 cyhour.com: did not receive HSTS header
 cynoshair.com: could not connect to host
@@ -1435,17 +1437,16 @@ datarank.com: max-age too low: 0
 dataretention.solutions: could not connect to host
 datatekniikka.com: could not connect to host
 datenkeks.de: did not receive HSTS header
 dateno1.com: max-age too low: 0
 datenreiter.cf: could not connect to host
 datenreiter.gq: could not connect to host
 datenreiter.ml: could not connect to host
 datenreiter.tk: could not connect to host
-datorb.com: could not connect to host
 davidandkailey.com: could not connect to host
 davidglidden.eu: did not receive HSTS header
 davidhunter.scot: did not receive HSTS header
 davidnoren.com: did not receive HSTS header
 davidreinhardt.de: could not connect to host
 davidscherzer.at: could not connect to host
 daylightcompany.com: did not receive HSTS header
 daytonaseaside.com: did not receive HSTS header
@@ -1492,16 +1493,17 @@ demilitarized.ninja: could not connect t
 demo.swedbank.se: did not receive HSTS header
 demomanca.com: did not receive HSTS header
 demotops.com: did not receive HSTS header
 dengyong.org: could not connect to host
 denh.am: did not receive HSTS header
 denisjean.fr: could not connect to host
 dentaldomain.org: did not receive HSTS header
 dentaldomain.ph: could not connect to host
+denverprophit.us: did not receive HSTS header
 depeche-mode.moscow: max-age too low: 7200
 depijl-mz.nl: did not receive HSTS header
 depixion.agency: could not connect to host
 depo.space: could not connect to host
 dequehablamos.es: could not connect to host
 derevtsov.com: did not receive HSTS header
 dergeilstestammderwelt.de: did not receive HSTS header
 derpumpkinfuhrer.com: could not connect to host
@@ -1523,17 +1525,16 @@ devcu.net: could not connect to host
 devincrow.me: could not connect to host
 devmsg.com: did not receive HSTS header
 devnsec.com: could not connect to host
 devnull.team: could not connect to host
 devopps.me: did not receive HSTS header
 devopsconnected.com: could not connect to host
 devtub.com: did not receive HSTS header
 devuan.org: did not receive HSTS header
-dewalch.net: could not connect to host
 dewin.io: could not connect to host
 dfviana.com.br: max-age too low: 2592000
 dhpcs.com: did not receive HSTS header
 dhpiggott.net: did not receive HSTS header
 diablotine.rocks: could not connect to host
 dianlujitao.com: did not receive HSTS header
 diannaobos.com: did not receive HSTS header
 diarbag.us: max-age too low: 0
@@ -1549,16 +1550,17 @@ digioccumss.ddns.net: could not connect 
 digitalbank.kz: could not connect to host
 digitaldaddy.net: could not connect to host
 digitalero.rip: did not receive HSTS header
 digitalriver.tk: could not connect to host
 digitalskillswap.com: could not connect to host
 dillonkorman.com: could not connect to host
 dim.lighting: could not connect to host
 dinamoelektrik.com: could not connect to host
+dingcc.com: could not connect to host
 dingcc.me: could not connect to host
 dinkum.online: could not connect to host
 directhskincream.com: could not connect to host
 directorinegocis.cat: could not connect to host
 discovery.lookout.com: did not receive HSTS header
 dise-online.de: did not receive HSTS header
 dislocated.de: did not receive HSTS header
 disowned.net: max-age too low: 0
@@ -1571,17 +1573,16 @@ dittvertshus.no: could not connect to ho
 diva-ey.com: could not connect to host
 dixiediner.com: did not receive HSTS header
 dizihocasi.com: could not connect to host
 dizorg.net: could not connect to host<