Merge autoland to mozilla-central. a=merge
authorAlexandru Michis <malexandru@mozilla.com>
Thu, 20 Jan 2022 23:42:30 +0200
changeset 605042 d3a989967dd3775b1b08ec6d3fe046ae7d48c215
parent 605022 f26c5f46bdcd7ba4163f79788f8ba030b0eddd3e (current diff)
parent 605041 cf8829a3353a70a5f598f06151437a35adb712c5 (diff)
child 605043 9c925f2d42672f6927659d84089fda81758c0b3e
child 605075 97861a268eda610849210703ba6c6842e00bb9e3
push id39171
push usermalexandru@mozilla.com
push dateThu, 20 Jan 2022 21:43:17 +0000
treeherdermozilla-central@d3a989967dd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone98.0a1
first release with
nightly linux32
d3a989967dd3 / 98.0a1 / 20220120214317 / files
nightly linux64
d3a989967dd3 / 98.0a1 / 20220120214317 / files
nightly mac
d3a989967dd3 / 98.0a1 / 20220120214317 / files
nightly win32
d3a989967dd3 / 98.0a1 / 20220120214317 / files
nightly win64
d3a989967dd3 / 98.0a1 / 20220120214317 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla-central. a=merge
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../toolkit/content/globalOverlay.js */
-/* import-globals-from ../../../../toolkit/content/contentAreaUtils.js */
-/* import-globals-from ../../../../toolkit/content/treeUtils.js */
+/* import-globals-from /toolkit/content/globalOverlay.js */
+/* import-globals-from /toolkit/content/contentAreaUtils.js */
+/* import-globals-from /toolkit/content/treeUtils.js */
 /* import-globals-from ../utilityOverlay.js */
 /* import-globals-from permissions.js */
 /* import-globals-from security.js */
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   E10SUtils: "resource://gre/modules/E10SUtils.jsm",
 });
 
--- a/browser/base/content/sanitizeDialog.js
+++ b/browser/base/content/sanitizeDialog.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from /toolkit/content/preferencesBindings.js */
 
 var { Sanitizer } = ChromeUtils.import("resource:///modules/Sanitizer.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 Preferences.addAll([
   { id: "privacy.cpd.history", type: "bool" },
   { id: "privacy.cpd.formdata", type: "bool" },
   { id: "privacy.cpd.downloads", type: "bool", disabled: true },
--- a/browser/components/downloads/content/downloadsCommands.js
+++ b/browser/components/downloads/content/downloadsCommands.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* import-globals-from allDownloadsView.js */
-/* import-globals-from ../../../../toolkit/content/globalOverlay.js */
+/* import-globals-from /toolkit/content/globalOverlay.js */
 
 document.addEventListener("DOMContentLoaded", function() {
   let downloadCommands = document.getElementById("downloadCommands");
   downloadCommands.addEventListener("commandupdate", function() {
     goUpdateDownloadCommands();
   });
   downloadCommands.addEventListener("command", function(event) {
     let { id } = event.target;
--- a/browser/components/payments/res/components/address-option.js
+++ b/browser/components/payments/res/components/address-option.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../../browser/extensions/formautofill/content/autofillEditForms.js*/
+/* import-globals-from /browser/extensions/formautofill/content/autofillEditForms.js*/
 import ObservedPropertiesMixin from "../mixins/ObservedPropertiesMixin.js";
 import RichOption from "./rich-option.js";
 /* import-globals-from ../unprivileged-fallbacks.js */
 
 /**
  * Up to two-line address display. After bug 1475684 this will also be used for
  * the single-line <option> substitute too.
  *
--- a/browser/components/payments/res/containers/address-form.js
+++ b/browser/components/payments/res/containers/address-form.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../../browser/extensions/formautofill/content/autofillEditForms.js*/
+/* import-globals-from /browser/extensions/formautofill/content/autofillEditForms.js*/
 import LabelledCheckbox from "../components/labelled-checkbox.js";
 import PaymentRequestPage from "../components/payment-request-page.js";
 import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
 import paymentRequest from "../paymentRequest.js";
 import HandleEventMixin from "../mixins/HandleEventMixin.js";
 /* import-globals-from ../unprivileged-fallbacks.js */
 
 /**
--- a/browser/components/payments/res/containers/basic-card-form.js
+++ b/browser/components/payments/res/containers/basic-card-form.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../../browser/extensions/formautofill/content/autofillEditForms.js*/
+/* import-globals-from /browser/extensions/formautofill/content/autofillEditForms.js*/
 import AcceptedCards from "../components/accepted-cards.js";
 import BillingAddressPicker from "./billing-address-picker.js";
 import CscInput from "../components/csc-input.js";
 import LabelledCheckbox from "../components/labelled-checkbox.js";
 import PaymentRequestPage from "../components/payment-request-page.js";
 import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
 import paymentRequest from "../paymentRequest.js";
 import HandleEventMixin from "../mixins/HandleEventMixin.js";
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../base/content/utilityOverlay.js */
+/* import-globals-from /browser/base/content/utilityOverlay.js */
 /* import-globals-from ../PlacesUIUtils.jsm */
-/* import-globals-from ../../../../toolkit/components/places/PlacesUtils.jsm */
-/* import-globals-from ../../../../toolkit/components/places/PlacesTransactions.jsm */
+/* import-globals-from /toolkit/components/places/PlacesUtils.jsm */
+/* import-globals-from /toolkit/components/places/PlacesTransactions.jsm */
 /* import-globals-from ./places.js */
 
 /**
  * Represents an insertion point within a container where we can insert
  * items.
  * @param {object} an object containing the following properties:
  *   - parentId
  *     The identifier of the parent container
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* import-globals-from instantEditBookmark.js */
-/* import-globals-from ../../../../toolkit/content/contentAreaUtils.js */
-/* import-globals-from ../../downloads/content/allDownloadsView.js */
+/* import-globals-from /toolkit/content/contentAreaUtils.js */
+/* import-globals-from /browser/components/downloads/content/allDownloadsView.js */
 
 /* Shared Places Import - change other consumers if you change this: */
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 XPCOMUtils.defineLazyModuleGetters(this, {
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
--- a/browser/components/places/tests/browser/interactions/browser_interactions_typing.js
+++ b/browser/components/places/tests/browser/interactions/browser_interactions_typing.js
@@ -235,32 +235,32 @@ add_task(async function test_typing_and_
 
   const testStartTime = Cu.now();
 
   await BrowserTestUtils.withNewTab(TEST_URL, async browser => {
     await sendTextToInput(browser, sentenceFragments[0]);
 
     info("reload");
     browser.reload();
-    await BrowserTestUtils.browserLoaded(browser);
+    await BrowserTestUtils.browserLoaded(browser, false, TEST_URL);
 
     // First typing should have been recorded
     await assertDatabaseValues([
       {
         url: TEST_URL,
         keypresses: sentenceFragments[0].length,
         typingTimeIsGreaterThan: 0,
       },
     ]);
 
     await sendTextToInput(browser, sentenceFragments[1]);
 
     info("reload");
     browser.reload();
-    await BrowserTestUtils.browserLoaded(browser);
+    await BrowserTestUtils.browserLoaded(browser, false, TEST_URL);
 
     // Second typing should have been recorded
     await assertDatabaseValues([
       {
         url: TEST_URL,
         keypresses: sentenceFragments[0].length,
         typingTimeIsGreaterThan: 0,
         typingTimeIsLessThan: Cu.now() - testStartTime,
--- a/browser/components/preferences/dialogs/browserLanguages.js
+++ b/browser/components/preferences/dialogs/browserLanguages.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from /toolkit/content/preferencesBindings.js */
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 // This is exported by preferences.js but we can't import that in a subdialog.
 let { getAvailableLocales } = window.top;
 
 ChromeUtils.defineModuleGetter(
   this,
--- a/browser/components/preferences/dialogs/colors.js
+++ b/browser/components/preferences/dialogs/colors.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from /toolkit/content/preferencesBindings.js */
 
 document
   .getElementById("ColorsDialog")
   .addEventListener("dialoghelp", window.top.openPrefsHelp);
 
 Preferences.addAll([
   { id: "browser.display.document_color_use", type: "int" },
   { id: "browser.anchor_color", type: "string" },
--- a/browser/components/preferences/dialogs/connection.js
+++ b/browser/components/preferences/dialogs/connection.js
@@ -1,15 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../base/content/utilityOverlay.js */
-/* import-globals-from ../../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from /browser/base/content/utilityOverlay.js */
+/* import-globals-from /toolkit/content/preferencesBindings.js */
 /* import-globals-from ../extensionControlled.js */
 
 ChromeUtils.defineModuleGetter(
   this,
   "DoHConfigController",
   "resource:///modules/DoHConfig.jsm"
 );
 
--- a/browser/components/preferences/dialogs/fonts.js
+++ b/browser/components/preferences/dialogs/fonts.js
@@ -1,15 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../base/content/utilityOverlay.js */
-/* import-globals-from ../../../../toolkit/mozapps/preferences/fontbuilder.js */
+/* import-globals-from /browser/base/content/utilityOverlay.js */
+/* import-globals-from /toolkit/mozapps/preferences/fontbuilder.js */
 
 // browser.display.languageList LOCK ALL when LOCKED
 
 const kDefaultFontType = "font.default.%LANG%";
 const kFontNameFmtSerif = "font.name.serif.%LANG%";
 const kFontNameFmtSansSerif = "font.name.sans-serif.%LANG%";
 const kFontNameFmtMonospace = "font.name.monospace.%LANG%";
 const kFontNameListFmtSerif = "font.name-list.serif.%LANG%";
--- a/browser/components/preferences/dialogs/languages.js
+++ b/browser/components/preferences/dialogs/languages.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from /toolkit/content/preferencesBindings.js */
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 document
   .getElementById("LanguagesDialog")
   .addEventListener("dialoghelp", window.top.openPrefsHelp);
 
 Preferences.addAll([
--- a/browser/components/preferences/dialogs/sanitize.js
+++ b/browser/components/preferences/dialogs/sanitize.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from /toolkit/content/preferencesBindings.js */
 
 document
   .querySelector("dialog")
   .addEventListener("dialoghelp", window.top.openPrefsHelp);
 
 Preferences.addAll([
   { id: "privacy.clearOnShutdown.history", type: "bool" },
   { id: "privacy.clearOnShutdown.formdata", type: "bool" },
--- a/browser/components/preferences/dialogs/syncChooseWhatToSync.js
+++ b/browser/components/preferences/dialogs/syncChooseWhatToSync.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from /toolkit/content/preferencesBindings.js */
 
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 Preferences.addAll([
   { id: "services.sync.engine.addons", type: "bool" },
   { id: "services.sync.engine.bookmarks", type: "bool" },
   { id: "services.sync.engine.history", type: "bool" },
   { id: "services.sync.engine.tabs", type: "bool" },
--- a/browser/components/preferences/main.js
+++ b/browser/components/preferences/main.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* import-globals-from extensionControlled.js */
 /* import-globals-from preferences.js */
-/* import-globals-from ../../../toolkit/mozapps/preferences/fontbuilder.js */
-/* import-globals-from ../../base/content/aboutDialog-appUpdater.js */
+/* import-globals-from /toolkit/mozapps/preferences/fontbuilder.js */
+/* import-globals-from /browser/base/content/aboutDialog-appUpdater.js */
 /* global MozXULElement */
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   BackgroundUpdate: "resource://gre/modules/BackgroundUpdate.jsm",
 });
 
 // Constants & Enumeration Values
 const TYPE_PDF = "application/pdf";
--- a/browser/components/preferences/preferences.js
+++ b/browser/components/preferences/preferences.js
@@ -7,18 +7,18 @@
 /* import-globals-from home.js */
 /* import-globals-from search.js */
 /* import-globals-from containers.js */
 /* import-globals-from privacy.js */
 /* import-globals-from sync.js */
 /* import-globals-from experimental.js */
 /* import-globals-from moreFromMozilla.js */
 /* import-globals-from findInPage.js */
-/* import-globals-from ../../base/content/utilityOverlay.js */
-/* import-globals-from ../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from /browser/base/content/utilityOverlay.js */
+/* import-globals-from /toolkit/content/preferencesBindings.js */
 
 "use strict";
 
 var { AppConstants } = ChromeUtils.import(
   "resource://gre/modules/AppConstants.jsm"
 );
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
--- a/browser/components/shell/content/setDesktopBackground.js
+++ b/browser/components/shell/content/setDesktopBackground.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* import-globals-from ../../../base/content/utilityOverlay.js */
+/* import-globals-from /browser/base/content/utilityOverlay.js */
 
 var gSetBackground = {
   _position: AppConstants.platform == "macosx" ? "STRETCH" : "",
   _backgroundColor: AppConstants.platform != "macosx" ? 0 : undefined,
   _screenWidth: 0,
   _screenHeight: 0,
   _image: null,
   _canvas: null,
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -19,16 +19,17 @@
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/StructuredCloneTags.h"
 #include "mozilla/dom/SVGImageElement.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRef.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Logging.h"
+#include "mozilla/gfx/Scale.h"
 #include "mozilla/gfx/Swizzle.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/ScopeExit.h"
 #include "nsGlobalWindowInner.h"
 #include "nsIAsyncInputStream.h"
 #include "nsNetUtil.h"
 #include "nsLayoutUtils.h"
 #include "nsStreamUtils.h"
@@ -263,16 +264,93 @@ static already_AddRefed<DataSourceSurfac
       srcBufferPtr += srcMap.GetStride();
       dstBufferPtr += dstMap.GetStride();
     }
   }
 
   return dstDataSurface.forget();
 }
 
+/*
+ * This helper function scales the data of the given DataSourceSurface,
+ *  _aSurface_, in the given area, _aCropRect_, into a new DataSourceSurface.
+ * This might return null if it can not create a new SourceSurface or it cannot
+ * read data from the given _aSurface_.
+ *
+ */
+static already_AddRefed<DataSourceSurface> ScaleDataSourceSurface(
+    DataSourceSurface* aSurface, const ImageBitmapOptions& aOptions) {
+  MOZ_ASSERT(aSurface);
+
+  const SurfaceFormat format = aSurface->GetFormat();
+  const int bytesPerPixel = BytesPerPixel(format);
+
+  const IntSize srcSize = aSurface->GetSize();
+  int32_t tmp;
+
+  CheckedInt<int32_t> checked;
+  CheckedInt<int32_t> dstWidth(
+      aOptions.mResizeWidth.WasPassed() ? aOptions.mResizeWidth.Value() : 0);
+  CheckedInt<int32_t> dstHeight(
+      aOptions.mResizeHeight.WasPassed() ? aOptions.mResizeHeight.Value() : 0);
+
+  if (!dstWidth.isValid() || !dstHeight.isValid()) {
+    return nullptr;
+  }
+
+  if (!dstWidth.value()) {
+    checked = srcSize.width * dstHeight;
+    if (!checked.isValid()) {
+      return nullptr;
+    }
+
+    tmp = ceil(checked.value() / double(srcSize.height));
+    dstWidth = tmp;
+  } else if (!dstHeight.value()) {
+    checked = srcSize.height * dstWidth;
+    if (!checked.isValid()) {
+      return nullptr;
+    }
+
+    tmp = ceil(checked.value() / double(srcSize.width));
+    dstHeight = tmp;
+  }
+
+  const IntSize dstSize(dstWidth.value(), dstHeight.value());
+  const int32_t dstStride = dstSize.width * bytesPerPixel;
+
+  // Create a new SourceSurface.
+  RefPtr<DataSourceSurface> dstDataSurface =
+      Factory::CreateDataSourceSurfaceWithStride(dstSize, format, dstStride,
+                                                 true);
+
+  if (NS_WARN_IF(!dstDataSurface)) {
+    return nullptr;
+  }
+
+  // Copy the raw data into the newly created DataSourceSurface.
+  DataSourceSurface::ScopedMap srcMap(aSurface, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap dstMap(dstDataSurface, DataSourceSurface::WRITE);
+  if (NS_WARN_IF(!srcMap.IsMapped()) || NS_WARN_IF(!dstMap.IsMapped())) {
+    return nullptr;
+  }
+
+  uint8_t* srcBufferPtr = srcMap.GetData();
+  uint8_t* dstBufferPtr = dstMap.GetData();
+
+  bool res = Scale(srcBufferPtr, srcSize.width, srcSize.height,
+                   srcMap.GetStride(), dstBufferPtr, dstSize.width,
+                   dstSize.height, dstMap.GetStride(), aSurface->GetFormat());
+  if (!res) {
+    return nullptr;
+  }
+
+  return dstDataSurface.forget();
+}
+
 static DataSourceSurface* FlipYDataSourceSurface(DataSourceSurface* aSurface) {
   MOZ_ASSERT(aSurface);
 
   // Invert in y direction.
   DataSourceSurface::ScopedMap srcMap(aSurface, DataSourceSurface::READ_WRITE);
   if (NS_WARN_IF(!srcMap.IsMapped())) {
     return nullptr;
   }
@@ -369,16 +447,24 @@ static already_AddRefed<SourceSurface> C
   if (aOptions.mImageOrientation == ImageOrientation::FlipY) {
     result = FlipYDataSourceSurface(result);
 
     if (NS_WARN_IF(!result)) {
       return nullptr;
     }
   }
 
+  if (aOptions.mResizeWidth.WasPassed() || aOptions.mResizeHeight.WasPassed()) {
+    dataSurface = result->GetDataSurface();
+    result = ScaleDataSourceSurface(dataSurface, aOptions);
+    if (NS_WARN_IF(!result)) {
+      return nullptr;
+    }
+  }
+
   if (aOptions.mPremultiplyAlpha == PremultiplyAlpha::Premultiply) {
     result = AlphaPremultiplyDataSourceSurface(result);
 
     if (NS_WARN_IF(!result)) {
       return nullptr;
     }
   }
 
@@ -820,32 +906,49 @@ already_AddRefed<ImageBitmap> ImageBitma
 
     dataSurface = CropAndCopyDataSourceSurface(dataSurface, cropRect);
     if (NS_WARN_IF(!dataSurface)) {
       aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
       return nullptr;
     }
 
     surface = dataSurface;
-    cropRect.MoveTo(0, 0);
+    cropRect.SetRect(0, 0, dataSurface->GetSize().width,
+                     dataSurface->GetSize().height);
     needToReportMemoryAllocation = true;
   }
 
   // flip image in Y direction
   if (aOptions.mImageOrientation == ImageOrientation::FlipY) {
     if (!dataSurface) {
       dataSurface = surface->GetDataSurface();
     }
 
     surface = FlipYDataSourceSurface(dataSurface);
     if (NS_WARN_IF(!surface)) {
       return nullptr;
     }
   }
 
+  // resize if required
+  if (aOptions.mResizeWidth.WasPassed() || aOptions.mResizeHeight.WasPassed()) {
+    if (!dataSurface) {
+      dataSurface = surface->GetDataSurface();
+    };
+
+    surface = ScaleDataSourceSurface(dataSurface, aOptions);
+    if (NS_WARN_IF(!surface)) {
+      aRv.ThrowInvalidStateError("Failed to create resized image");
+      return nullptr;
+    }
+
+    needToReportMemoryAllocation = true;
+    cropRect.SetRect(0, 0, surface->GetSize().width, surface->GetSize().height);
+  }
+
   if (requiresPremultiply || requiresUnpremultiply) {
     if (!dataSurface) {
       dataSurface = surface->GetDataSurface();
     }
 
     surface =
         AlphaPremultiplyDataSourceSurface(dataSurface, requiresPremultiply);
     if (NS_WARN_IF(!surface)) {
@@ -1330,17 +1433,16 @@ class CreateImageBitmapFromBlob final : 
                             const ImageBitmapOptions& aOptions)
       : DiscardableRunnable("dom::CreateImageBitmapFromBlob"),
 
         mMutex("dom::CreateImageBitmapFromBlob::mMutex"),
         mPromise(aPromise),
         mGlobalObject(aGlobal),
         mInputStream(std::move(aInputStream)),
         mCropRect(aCropRect),
-        mOriginalCropRect(aCropRect),
         mMainThreadEventTarget(aMainThreadEventTarget),
         mOptions(aOptions),
         mThread(PR_GetCurrentThread()) {}
 
   virtual ~CreateImageBitmapFromBlob() = default;
 
   bool IsCurrentThread() const { return mThread == PR_GetCurrentThread(); }
 
@@ -1378,18 +1480,16 @@ class CreateImageBitmapFromBlob final : 
   // Touched only on the owning thread.
   RefPtr<Promise> mPromise;
 
   // Touched only on the owning thread.
   nsCOMPtr<nsIGlobalObject> mGlobalObject;
 
   nsCOMPtr<nsIInputStream> mInputStream;
   Maybe<IntRect> mCropRect;
-  Maybe<IntRect> mOriginalCropRect;
-  IntSize mSourceSize;
   nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
   const ImageBitmapOptions mOptions;
   void* mThread;
 };
 
 NS_IMPL_ISUPPORTS_INHERITED(CreateImageBitmapFromBlob, DiscardableRunnable,
                             imgIContainerCallback, nsIInputStreamCallback)
 
@@ -1462,16 +1562,29 @@ already_AddRefed<Promise> ImageBitmap::C
 
     if (aCropRect->Height() == 0) {
       aRv.ThrowRangeError(
           "The crop rect height passed to createImageBitmap must be nonzero");
       return promise.forget();
     }
   }
 
+  if (aOptions.mResizeWidth.WasPassed() && aOptions.mResizeWidth.Value() == 0) {
+    aRv.ThrowInvalidStateError(
+        "The resizeWidth passed to createImageBitmap must be nonzero");
+    return promise.forget();
+  }
+
+  if (aOptions.mResizeHeight.WasPassed() &&
+      aOptions.mResizeHeight.Value() == 0) {
+    aRv.ThrowInvalidStateError(
+        "The resizeHeight passed to createImageBitmap must be nonzero");
+    return promise.forget();
+  }
+
   RefPtr<ImageBitmap> imageBitmap;
 
   if (aSrc.IsHTMLImageElement()) {
     MOZ_ASSERT(
         NS_IsMainThread(),
         "Creating ImageBitmap from HTMLImageElement off the main thread.");
     imageBitmap = CreateInternal(aGlobal, aSrc.GetAsHTMLImageElement(),
                                  aCropRect, aOptions, aRv);
@@ -1840,20 +1953,16 @@ CreateImageBitmapFromBlob::OnImageReady(
       aImgContainer->GetFrame(whichFrame, frameFlags);
 
   if (NS_WARN_IF(!surface)) {
     MimeTypeAndDecodeAndCropBlobCompletedMainThread(
         nullptr, NS_ERROR_DOM_INVALID_STATE_ERR);
     return NS_OK;
   }
 
-  // Store the sourceSize value for the
-  // MimeTypeAndDecodeAndCropBlobCompletedMainThread call.
-  mSourceSize = surface->GetSize();
-
   // Crop the source surface if needed.
   RefPtr<SourceSurface> croppedSurface = surface;
   RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
 
   // force a copy into unprotected memory as a side effect of
   // CropAndCopyDataSourceSurface
   bool copyRequired = mCropRect.isSome() ||
                       mOptions.mImageOrientation == ImageOrientation::FlipY;
@@ -1880,24 +1989,39 @@ CreateImageBitmapFromBlob::OnImageReady(
       MimeTypeAndDecodeAndCropBlobCompletedMainThread(
           nullptr, NS_ERROR_DOM_INVALID_STATE_ERR);
       return NS_OK;
     }
 
     dataSurface = croppedSurface->GetDataSurface();
 
     if (mCropRect.isSome()) {
-      mCropRect->MoveTo(0, 0);
+      mCropRect->SetRect(0, 0, dataSurface->GetSize().width,
+                         dataSurface->GetSize().height);
     }
   }
 
   if (mOptions.mImageOrientation == ImageOrientation::FlipY) {
     croppedSurface = FlipYDataSourceSurface(dataSurface);
   }
 
+  if (mOptions.mResizeWidth.WasPassed() || mOptions.mResizeHeight.WasPassed()) {
+    dataSurface = croppedSurface->GetDataSurface();
+    croppedSurface = ScaleDataSourceSurface(dataSurface, mOptions);
+    if (NS_WARN_IF(!croppedSurface)) {
+      MimeTypeAndDecodeAndCropBlobCompletedMainThread(
+          nullptr, NS_ERROR_DOM_INVALID_STATE_ERR);
+      return NS_OK;
+    }
+    if (mCropRect.isSome()) {
+      mCropRect->SetRect(0, 0, croppedSurface->GetSize().width,
+                         croppedSurface->GetSize().height);
+    }
+  }
+
   if (NS_WARN_IF(!croppedSurface)) {
     MimeTypeAndDecodeAndCropBlobCompletedMainThread(
         nullptr, NS_ERROR_DOM_INVALID_STATE_ERR);
     return NS_OK;
   }
 
   // Create an Image from the source surface.
   RefPtr<layers::Image> image = CreateImageFromSurface(croppedSurface);
--- a/dom/ipc/SharedMessageBody.cpp
+++ b/dom/ipc/SharedMessageBody.cpp
@@ -252,16 +252,19 @@ bool SharedMessageBody::FromSharedToMess
   return true;
 }
 
 /* static */
 already_AddRefed<SharedMessageBody>
 SharedMessageBody::FromMessageToSharedParent(
     MessageData& aMessage,
     StructuredCloneHolder::TransferringSupport aSupportsTransferring) {
+  // TODO: This alloc is not fallible and there is no codepath that returns
+  // nullptr. But the caller checks for nullptr and handles array allocations
+  // for these items as fallible. See bug 1750497.
   RefPtr<SharedMessageBody> data =
       new SharedMessageBody(aSupportsTransferring, aMessage.agentClusterId());
 
   if (aMessage.data().type() == MessageDataType::TClonedMessageData) {
     data->mCloneData = MakeUnique<ipc::StructuredCloneData>(
         JS::StructuredCloneScope::UnknownDestination, aSupportsTransferring);
     data->mCloneData->StealFromClonedMessageDataForBackgroundParent(
         aMessage.data().get_ClonedMessageData());
--- a/dom/media/gmp/GMPContentChild.cpp
+++ b/dom/media/gmp/GMPContentChild.cpp
@@ -57,51 +57,48 @@ already_AddRefed<PChromiumCDMChild> GMPC
 
 mozilla::ipc::IPCResult GMPContentChild::RecvPGMPVideoDecoderConstructor(
     PGMPVideoDecoderChild* aActor) {
   auto vdc = static_cast<GMPVideoDecoderChild*>(aActor);
 
   void* vd = nullptr;
   GMPErr err = mGMPChild->GetAPI(GMP_API_VIDEO_DECODER, &vdc->Host(), &vd);
   if (err != GMPNoErr || !vd) {
-    NS_WARNING("GMPGetAPI call failed trying to construct decoder.");
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "GMPGetAPI call failed trying to construct decoder.");
   }
 
   vdc->Init(static_cast<GMPVideoDecoder*>(vd));
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPContentChild::RecvPGMPVideoEncoderConstructor(
     PGMPVideoEncoderChild* aActor) {
   auto vec = static_cast<GMPVideoEncoderChild*>(aActor);
 
   void* ve = nullptr;
   GMPErr err = mGMPChild->GetAPI(GMP_API_VIDEO_ENCODER, &vec->Host(), &ve);
   if (err != GMPNoErr || !ve) {
-    NS_WARNING("GMPGetAPI call failed trying to construct encoder.");
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "GMPGetAPI call failed trying to construct encoder.");
   }
 
   vec->Init(static_cast<GMPVideoEncoder*>(ve));
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPContentChild::RecvPChromiumCDMConstructor(
     PChromiumCDMChild* aActor, const nsCString& aKeySystem) {
   ChromiumCDMChild* child = static_cast<ChromiumCDMChild*>(aActor);
   cdm::Host_10* host10 = child;
 
   void* cdm = nullptr;
   GMPErr err = mGMPChild->GetAPI(CHROMIUM_CDM_API, host10, &cdm, aKeySystem);
   if (err != GMPNoErr || !cdm) {
-    NS_WARNING("GMPGetAPI call failed trying to get CDM.");
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "GMPGetAPI call failed trying to get CDM.");
   }
 
   child->Init(static_cast<cdm::ContentDecryptionModule_10*>(cdm),
               mGMPChild->mStorageId);
 
   return IPC_OK();
 }
 
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -696,18 +696,21 @@ bool GMPParent::DeallocPGMPStorageParent
   p->Shutdown();
   mStorage.RemoveElement(p);
   return true;
 }
 
 mozilla::ipc::IPCResult GMPParent::RecvPGMPStorageConstructor(
     PGMPStorageParent* aActor) {
   GMPStorageParent* p = (GMPStorageParent*)aActor;
-  if (NS_WARN_IF(NS_FAILED(p->Init()))) {
-    return IPC_FAIL_NO_REASON(this);
+  if (NS_FAILED(p->Init())) {
+    // TODO: Verify if this is really a good reason to IPC_FAIL.
+    // There might be shutdown edge cases here.
+    return IPC_FAIL(this,
+                    "GMPParent::RecvPGMPStorageConstructor: p->Init() failed.");
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPParent::RecvPGMPTimerConstructor(
     PGMPTimerParent* actor) {
   return IPC_OK();
 }
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -1821,17 +1821,19 @@ mozilla::ipc::IPCResult GMPServiceParent
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPServiceParent::RecvGetGMPNodeId(
     const nsString& aOrigin, const nsString& aTopLevelOrigin,
     const nsString& aGMPName, nsCString* aID) {
   nsresult rv = mService->GetNodeId(aOrigin, aTopLevelOrigin, aGMPName, *aID);
   if (!NS_SUCCEEDED(rv)) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(
+        this,
+        "GMPServiceParent::RecvGetGMPNodeId: mService->GetNodeId failed.");
   }
   return IPC_OK();
 }
 
 class OpenPGMPServiceParent : public mozilla::Runnable {
  public:
   OpenPGMPServiceParent(RefPtr<GMPServiceParent>&& aGMPServiceParent,
                         ipc::Endpoint<PGMPServiceParent>&& aEndpoint,
--- a/dom/media/gmp/GMPStorageParent.cpp
+++ b/dom/media/gmp/GMPStorageParent.cpp
@@ -55,17 +55,18 @@ nsresult GMPStorageParent::Init() {
 }
 
 mozilla::ipc::IPCResult GMPStorageParent::RecvOpen(
     const nsCString& aRecordName) {
   LOGD(
       ("GMPStorageParent[%p]::RecvOpen(record='%s')", this, aRecordName.get()));
 
   if (mShutdown) {
-    return IPC_FAIL_NO_REASON(this);
+    // Shutdown is an expected state, so we do not IPC_FAIL.
+    return IPC_OK();
   }
 
   if (mNodeId.EqualsLiteral("null")) {
     // Refuse to open storage if the page is opened from local disk,
     // or shared across origin.
     LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s') failed; null nodeId",
           this, aRecordName.get()));
     Unused << SendOpenComplete(aRecordName, GMPGenericErr);
@@ -97,17 +98,18 @@ mozilla::ipc::IPCResult GMPStorageParent
 }
 
 mozilla::ipc::IPCResult GMPStorageParent::RecvRead(
     const nsCString& aRecordName) {
   LOGD(
       ("GMPStorageParent[%p]::RecvRead(record='%s')", this, aRecordName.get()));
 
   if (mShutdown) {
-    return IPC_FAIL_NO_REASON(this);
+    // Shutdown is an expected state, so we do not IPC_FAIL.
+    return IPC_OK();
   }
 
   nsTArray<uint8_t> data;
   if (!mStorage->IsOpen(aRecordName)) {
     LOGD(("GMPStorageParent[%p]::RecvRead(record='%s') failed; record not open",
           this, aRecordName.get()));
     Unused << SendReadComplete(aRecordName, GMPClosedErr, data);
   } else {
@@ -123,17 +125,18 @@ mozilla::ipc::IPCResult GMPStorageParent
 }
 
 mozilla::ipc::IPCResult GMPStorageParent::RecvWrite(
     const nsCString& aRecordName, nsTArray<uint8_t>&& aBytes) {
   LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') %zu bytes", this,
         aRecordName.get(), aBytes.Length()));
 
   if (mShutdown) {
-    return IPC_FAIL_NO_REASON(this);
+    // Shutdown is an expected state, so we do not IPC_FAIL.
+    return IPC_OK();
   }
 
   if (!mStorage->IsOpen(aRecordName)) {
     LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') failed record not open",
           this, aRecordName.get()));
     Unused << SendWriteComplete(aRecordName, GMPClosedErr);
     return IPC_OK();
   }
--- a/dom/media/gmp/GMPVideoDecoderChild.cpp
+++ b/dom/media/gmp/GMPVideoDecoderChild.cpp
@@ -87,31 +87,31 @@ void GMPVideoDecoderChild::Error(GMPErr 
 
   SendError(aError);
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvInitDecode(
     const GMPVideoCodec& aCodecSettings, nsTArray<uint8_t>&& aCodecSpecific,
     const int32_t& aCoreCount) {
   if (!mVideoDecoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoDecoder->InitDecode(aCodecSettings, aCodecSpecific.Elements(),
                             aCodecSpecific.Length(), this, aCoreCount);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvDecode(
     const GMPVideoEncodedFrameData& aInputFrame, const bool& aMissingFrames,
     nsTArray<uint8_t>&& aCodecSpecificInfo, const int64_t& aRenderTimeMs) {
   if (!mVideoDecoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   auto f = new GMPVideoEncodedFrameImpl(aInputFrame, &mVideoHost);
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoDecoder->Decode(f, aMissingFrames, aCodecSpecificInfo.Elements(),
                         aCodecSpecificInfo.Length(), aRenderTimeMs);
@@ -125,29 +125,29 @@ mozilla::ipc::IPCResult GMPVideoDecoderC
     mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPFrameData,
                                                aFrameBuffer);
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvReset() {
   if (!mVideoDecoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoDecoder->Reset();
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvDrain() {
   if (!mVideoDecoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoDecoder->Drain();
 
   return IPC_OK();
 }
--- a/dom/media/gmp/GMPVideoDecoderParent.cpp
+++ b/dom/media/gmp/GMPVideoDecoderParent.cpp
@@ -282,145 +282,107 @@ void GMPVideoDecoderParent::ActorDestroy
 
 mozilla::ipc::IPCResult GMPVideoDecoderParent::RecvDecoded(
     const GMPVideoi420FrameData& aDecodedFrame) {
   --mFrameCount;
   GMP_LOG_VERBOSE("GMPVideoDecoderParent[%p]::RecvDecoded() timestamp=%" PRId64
                   " frameCount=%d",
                   this, aDecodedFrame.mTimestamp(), mFrameCount);
 
-  if (!mCallback) {
-    return IPC_FAIL_NO_REASON(this);
-  }
+  if (mCallback) {
+    if (GMPVideoi420FrameImpl::CheckFrameData(aDecodedFrame)) {
+      auto f = new GMPVideoi420FrameImpl(aDecodedFrame, &mVideoHost);
 
-  if (!GMPVideoi420FrameImpl::CheckFrameData(aDecodedFrame)) {
-    GMP_LOG_ERROR(
-        "GMPVideoDecoderParent[%p]::RecvDecoded() "
-        "timestamp=%" PRId64 " decoded frame corrupt, ignoring",
-        this, aDecodedFrame.mTimestamp());
-    return IPC_FAIL_NO_REASON(this);
+      mCallback->Decoded(f);
+    } else {
+      GMP_LOG_ERROR(
+          "GMPVideoDecoderParent[%p]::RecvDecoded() "
+          "timestamp=%" PRId64 " decoded frame corrupt, ignoring",
+          this, aDecodedFrame.mTimestamp());
+      // TODO: Verify if we should take more serious the arrival of
+      // a corrupted frame, see bug 1750506.
+    }
   }
-  auto f = new GMPVideoi420FrameImpl(aDecodedFrame, &mVideoHost);
-
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process.
-  mCallback->Decoded(f);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 GMPVideoDecoderParent::RecvReceivedDecodedReferenceFrame(
     const uint64_t& aPictureId) {
-  if (!mCallback) {
-    return IPC_FAIL_NO_REASON(this);
+  if (mCallback) {
+    mCallback->ReceivedDecodedReferenceFrame(aPictureId);
   }
 
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process.
-  mCallback->ReceivedDecodedReferenceFrame(aPictureId);
-
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderParent::RecvReceivedDecodedFrame(
     const uint64_t& aPictureId) {
-  if (!mCallback) {
-    return IPC_FAIL_NO_REASON(this);
+  if (mCallback) {
+    mCallback->ReceivedDecodedFrame(aPictureId);
   }
 
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process.
-  mCallback->ReceivedDecodedFrame(aPictureId);
-
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderParent::RecvInputDataExhausted() {
   GMP_LOG_VERBOSE("GMPVideoDecoderParent[%p]::RecvInputDataExhausted()", this);
 
-  if (!mCallback) {
-    return IPC_FAIL_NO_REASON(this);
+  if (mCallback) {
+    mCallback->InputDataExhausted();
   }
 
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process.
-  mCallback->InputDataExhausted();
-
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderParent::RecvDrainComplete() {
   GMP_LOG_DEBUG("GMPVideoDecoderParent[%p]::RecvDrainComplete() frameCount=%d",
                 this, mFrameCount);
   nsAutoString msg;
   msg.AppendLiteral(
       "GMPVideoDecoderParent::RecvDrainComplete() outstanding frames=");
   msg.AppendInt(mFrameCount);
   LogToBrowserConsole(msg);
 
-  if (!mCallback) {
-    // We anticipate shutting down in the middle of a drain in the
-    // `UnblockResetAndDrain` method, which is called when we shutdown, so
-    // everything is sunny.
-    return IPC_OK();
-  }
+  if (mCallback && mIsAwaitingDrainComplete) {
+    mIsAwaitingDrainComplete = false;
 
-  if (!mIsAwaitingDrainComplete) {
-    return IPC_OK();
+    mCallback->DrainComplete();
   }
-  mIsAwaitingDrainComplete = false;
-
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process.
-  mCallback->DrainComplete();
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderParent::RecvResetComplete() {
   GMP_LOG_DEBUG("GMPVideoDecoderParent[%p]::RecvResetComplete()", this);
 
   CancelResetCompleteTimeout();
 
-  if (!mCallback) {
-    // We anticipate shutting down in the middle of a reset in the
-    // `UnblockResetAndDrain` method, which is called when we shutdown, so
-    // everything is good if we reach here.
-    return IPC_OK();
-  }
+  if (mCallback && mIsAwaitingResetComplete) {
+    mIsAwaitingResetComplete = false;
+    mFrameCount = 0;
 
-  if (!mIsAwaitingResetComplete) {
-    return IPC_OK();
+    mCallback->ResetComplete();
   }
-  mIsAwaitingResetComplete = false;
-  mFrameCount = 0;
-
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process.
-  mCallback->ResetComplete();
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderParent::RecvError(const GMPErr& aError) {
   GMP_LOG_DEBUG("GMPVideoDecoderParent[%p]::RecvError(error=%d)", this, aError);
 
-  if (!mCallback) {
-    return IPC_FAIL_NO_REASON(this);
-  }
+  if (mCallback) {
+    // Ensure if we've received an error while waiting for a ResetComplete
+    // or DrainComplete notification, we'll unblock the caller before processing
+    // the error.
+    UnblockResetAndDrain();
 
-  // Ensure if we've received an error while waiting for a ResetComplete
-  // or DrainComplete notification, we'll unblock the caller before processing
-  // the error.
-  UnblockResetAndDrain();
-
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process.
-  mCallback->Error(aError);
+    mCallback->Error(aError);
+  }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderParent::RecvShutdown() {
   GMP_LOG_DEBUG("GMPVideoDecoderParent[%p]::RecvShutdown()", this);
 
   Shutdown();
@@ -440,17 +402,17 @@ mozilla::ipc::IPCResult GMPVideoDecoderP
     const uint32_t& aFrameBufferSize, Shmem* aMem) {
   ipc::Shmem mem;
 
   if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(
           GMPSharedMem::kGMPFrameData, aFrameBufferSize,
           ipc::SharedMemory::TYPE_BASIC, &mem)) {
     GMP_LOG_ERROR("%s: Failed to get a shared mem buffer for Child! size %u",
                   __FUNCTION__, aFrameBufferSize);
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "Failed to get a shared mem buffer for Child!");
   }
   *aMem = mem;
   mem = ipc::Shmem();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoDecoderParent::Recv__delete__() {
   GMP_LOG_DEBUG("GMPVideoDecoderParent[%p]::Recv__delete__()", this);
--- a/dom/media/gmp/GMPVideoEncoderChild.cpp
+++ b/dom/media/gmp/GMPVideoEncoderChild.cpp
@@ -57,34 +57,34 @@ void GMPVideoEncoderChild::Error(GMPErr 
 
   SendError(aError);
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvInitEncode(
     const GMPVideoCodec& aCodecSettings, nsTArray<uint8_t>&& aCodecSpecific,
     const int32_t& aNumberOfCores, const uint32_t& aMaxPayloadSize) {
   if (!mVideoEncoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoEncoder->InitEncode(aCodecSettings, aCodecSpecific.Elements(),
                             aCodecSpecific.Length(), this, aNumberOfCores,
                             aMaxPayloadSize);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvEncode(
     const GMPVideoi420FrameData& aInputFrame,
     nsTArray<uint8_t>&& aCodecSpecificInfo,
     nsTArray<GMPVideoFrameType>&& aFrameTypes) {
   if (!mVideoEncoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   auto f = new GMPVideoi420FrameImpl(aInputFrame, &mVideoHost);
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoEncoder->Encode(f, aCodecSpecificInfo.Elements(),
                         aCodecSpecificInfo.Length(), aFrameTypes.Elements(),
@@ -100,43 +100,43 @@ mozilla::ipc::IPCResult GMPVideoEncoderC
                                                aEncodedBuffer);
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvSetChannelParameters(
     const uint32_t& aPacketLoss, const uint32_t& aRTT) {
   if (!mVideoEncoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoEncoder->SetChannelParameters(aPacketLoss, aRTT);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvSetRates(
     const uint32_t& aNewBitRate, const uint32_t& aFrameRate) {
   if (!mVideoEncoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoEncoder->SetRates(aNewBitRate, aFrameRate);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvSetPeriodicKeyFrames(
     const bool& aEnable) {
   if (!mVideoEncoder) {
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "!mVideoDecoder");
   }
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoEncoder->SetPeriodicKeyFrames(aEnable);
 
   return IPC_OK();
 }
@@ -149,18 +149,19 @@ mozilla::ipc::IPCResult GMPVideoEncoderC
     // return a frame they can use. Don't call the GMP's EncodingComplete()
     // now and don't delete the GMPVideoEncoderChild, defer processing the
     // EncodingComplete() until once the Alloc() finishes.
     mPendingEncodeComplete = true;
     return IPC_OK();
   }
 
   if (!mVideoEncoder) {
+    // There is not much to clean up anymore.
     Unused << Send__delete__(this);
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_OK();
   }
 
   // Ignore any return code. It is OK for this to fail without killing the
   // process.
   mVideoEncoder->EncodingComplete();
 
   mVideoHost.DoneWithAPI();
 
--- a/dom/media/gmp/GMPVideoEncoderParent.cpp
+++ b/dom/media/gmp/GMPVideoEncoderParent.cpp
@@ -229,37 +229,29 @@ void GMPVideoEncoderParent::ActorDestroy
   }
   mVideoHost.ActorDestroyed();  // same as DoneWithAPI
   MaybeDisconnect(aWhy == AbnormalShutdown);
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderParent::RecvEncoded(
     const GMPVideoEncodedFrameData& aEncodedFrame,
     nsTArray<uint8_t>&& aCodecSpecificInfo) {
-  if (!mCallback) {
-    return IPC_FAIL_NO_REASON(this);
+  if (mCallback) {
+    auto f = new GMPVideoEncodedFrameImpl(aEncodedFrame, &mVideoHost);
+    mCallback->Encoded(f, aCodecSpecificInfo);
+    f->Destroy();
   }
-
-  auto f = new GMPVideoEncodedFrameImpl(aEncodedFrame, &mVideoHost);
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process. This can be called on any thread (or more than one)
-  mCallback->Encoded(f, aCodecSpecificInfo);
-  f->Destroy();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderParent::RecvError(const GMPErr& aError) {
-  if (!mCallback) {
-    return IPC_FAIL_NO_REASON(this);
+  if (mCallback) {
+    mCallback->Error(aError);
   }
 
-  // Ignore any return code. It is OK for this to fail without killing the
-  // process.
-  mCallback->Error(aError);
-
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderParent::RecvShutdown() {
   Shutdown();
   return IPC_OK();
 }
 
@@ -289,17 +281,17 @@ mozilla::ipc::IPCResult GMPVideoEncoderP
   // in ::Shutdown, but doesn't hurt
   if (!mVideoHost.SharedMemMgr() ||
       !mVideoHost.SharedMemMgr()->MgrAllocShmem(
           GMPSharedMem::kGMPEncodedData, aEncodedBufferSize,
           ipc::SharedMemory::TYPE_BASIC, &mem)) {
     GMP_LOG_ERROR(
         "%s::%s: Failed to get a shared mem buffer for Child! size %u",
         __CLASS__, __FUNCTION__, aEncodedBufferSize);
-    return IPC_FAIL_NO_REASON(this);
+    return IPC_FAIL(this, "Failed to get a shared mem buffer for Child!");
   }
   *aMem = mem;
   mem = ipc::Shmem();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GMPVideoEncoderParent::Recv__delete__() {
   if (mPlugin) {
--- a/dom/messagechannel/MessagePortParent.cpp
+++ b/dom/messagechannel/MessagePortParent.cpp
@@ -34,62 +34,79 @@ bool MessagePortParent::Entangle(const n
 
   MOZ_ASSERT(!mEntangled);
 
   return mService->RequestEntangling(this, aDestinationUUID, aSequenceID);
 }
 
 mozilla::ipc::IPCResult MessagePortParent::RecvPostMessages(
     nsTArray<MessageData>&& aMessages) {
+  if (!mService) {
+    NS_WARNING("PostMessages is called after a shutdown!");
+    // This implies most probably that CloseAndDelete() has been already called
+    // such that we have no better option than to silently ignore this call.
+    return IPC_OK();
+  }
+
+  if (!mEntangled) {
+    // If we were shut down, the above condition already bailed out. So this
+    // should actually never happen and returning a failure is fine.
+    return IPC_FAIL(this, "RecvPostMessages not entangled");
+  }
+
   // This converts the object in a data struct where we have BlobImpls.
   FallibleTArray<RefPtr<SharedMessageBody>> messages;
   if (NS_WARN_IF(!SharedMessageBody::FromMessagesToSharedParent(aMessages,
                                                                 messages))) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-
-  if (!mEntangled) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-
-  if (!mService) {
-    NS_WARNING("Entangle is called after a shutdown!");
-    return IPC_FAIL_NO_REASON(this);
+    // FromMessagesToSharedParent() returns false only if the array allocation
+    // failed.
+    // See bug 1750497 for further discussion if this is the wanted behavior.
+    return IPC_FAIL(this, "SharedMessageBody::FromMessagesToSharedParent");
   }
 
   if (messages.IsEmpty()) {
-    return IPC_FAIL_NO_REASON(this);
+    // An empty payload can be safely ignored.
+    return IPC_OK();
   }
 
   if (!mService->PostMessages(this, std::move(messages))) {
-    return IPC_FAIL_NO_REASON(this);
+    // TODO: Verify if all failure conditions of PostMessages() merit an
+    // IPC_FAIL. See bug 1750499.
+    return IPC_FAIL(this, "RecvPostMessages->PostMessages");
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult MessagePortParent::RecvDisentangle(
     nsTArray<MessageData>&& aMessages) {
+  if (!mService) {
+    NS_WARNING("Entangle is called after a shutdown!");
+    // This implies most probably that CloseAndDelete() has been already called
+    // such that we can silently ignore this call.
+    return IPC_OK();
+  }
+
+  if (!mEntangled) {
+    // If we were shut down, the above condition already bailed out. So this
+    // should actually never happen and returning a failure is fine.
+    return IPC_FAIL(this, "RecvDisentangle not entangled");
+  }
+
   // This converts the object in a data struct where we have BlobImpls.
   FallibleTArray<RefPtr<SharedMessageBody>> messages;
   if (NS_WARN_IF(!SharedMessageBody::FromMessagesToSharedParent(aMessages,
                                                                 messages))) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-
-  if (!mEntangled) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-
-  if (!mService) {
-    NS_WARNING("Entangle is called after a shutdown!");
-    return IPC_FAIL_NO_REASON(this);
+    // TODO: Verify if failed allocations merit an IPC_FAIL. See bug 1750497.
+    return IPC_FAIL(this, "SharedMessageBody::FromMessagesToSharedParent");
   }
 
   if (!mService->DisentanglePort(this, std::move(messages))) {
-    return IPC_FAIL_NO_REASON(this);
+    // TODO: Verify if all failure conditions of DisentanglePort() merit an
+    // IPC_FAIL. See bug 1750501.
+    return IPC_FAIL(this, "RecvDisentangle->DisentanglePort");
   }
 
   CloseAndDelete();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult MessagePortParent::RecvStopSendingData() {
   if (!mEntangled) {
@@ -101,17 +118,17 @@ mozilla::ipc::IPCResult MessagePortParen
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult MessagePortParent::RecvClose() {
   if (mService) {
     MOZ_ASSERT(mEntangled);
 
     if (!mService->ClosePort(this)) {
-      return IPC_FAIL_NO_REASON(this);
+      return IPC_FAIL(this, "RecvClose->ClosePort");
     }
 
     Close();
   }
 
   MOZ_ASSERT(!mEntangled);
 
   Unused << Send__delete__(this);
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -675,16 +675,20 @@ static void LogHTTPSOnlyInfo(nsILoadInfo
   }
   if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_EXEMPT) {
     MOZ_LOG(sCSMLog, LogLevel::Verbose, ("    - HTTPS_ONLY_EXEMPT"));
   }
   if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_TOP_LEVEL_LOAD_IN_PROGRESS) {
     MOZ_LOG(sCSMLog, LogLevel::Verbose,
             ("    - HTTPS_ONLY_TOP_LEVEL_LOAD_IN_PROGRESS"));
   }
+  if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_DOWNLOAD_IN_PROGRESS) {
+    MOZ_LOG(sCSMLog, LogLevel::Verbose,
+            ("    - HTTPS_ONLY_DOWNLOAD_IN_PROGRESS"));
+  }
   if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_DO_NOT_LOG_TO_CONSOLE) {
     MOZ_LOG(sCSMLog, LogLevel::Verbose,
             ("    - HTTPS_ONLY_DO_NOT_LOG_TO_CONSOLE"));
   }
   if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_UPGRADED_HTTPS_FIRST) {
     MOZ_LOG(sCSMLog, LogLevel::Verbose,
             ("    - HTTPS_ONLY_UPGRADED_HTTPS_FIRST"));
   }
--- a/dom/security/nsHTTPSOnlyUtils.cpp
+++ b/dom/security/nsHTTPSOnlyUtils.cpp
@@ -981,18 +981,21 @@ TestHTTPAnswerRunnable::Notify(nsITimer*
     mTimer = nullptr;
   }
 
   // If the original channel has already started loading at this point
   // then there is no need to do the dance.
   nsCOMPtr<nsIChannel> origChannel = mDocumentLoadListener->GetChannel();
   nsCOMPtr<nsILoadInfo> origLoadInfo = origChannel->LoadInfo();
   uint32_t origHttpsOnlyStatus = origLoadInfo->GetHttpsOnlyStatus();
-  if ((origHttpsOnlyStatus &
-       nsILoadInfo::HTTPS_ONLY_TOP_LEVEL_LOAD_IN_PROGRESS)) {
+  uint32_t topLevelLoadInProgress =
+      origHttpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_TOP_LEVEL_LOAD_IN_PROGRESS;
+  uint32_t downloadInProgress =
+      origHttpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_DOWNLOAD_IN_PROGRESS;
+  if (topLevelLoadInProgress || downloadInProgress) {
     return NS_OK;
   }
 
   mozilla::OriginAttributes attrs = origLoadInfo->GetOriginAttributes();
   RefPtr<nsIPrincipal> nullPrincipal =
       mozilla::NullPrincipal::CreateWithInheritedAttributes(attrs);
 
   uint32_t loadFlags =
--- a/dom/security/test/https-first/browser.ini
+++ b/dom/security/test/https-first/browser.ini
@@ -16,8 +16,12 @@ support-files = file_httpsfirst_speculat
 support-files = file_download_attribute.html
                 file_download_attribute.sjs
 
 [browser_mixed_content_download.js]
 skip-if = win10_2004 && debug # Bug 1723573
 support-files =
   download_page.html
   download_server.sjs
+[browser_slow_download.js]
+support-files =
+  file_slow_download.html
+  file_slow_download.sjs
new file mode 100644
--- /dev/null
+++ b/dom/security/test/https-first/browser_slow_download.js
@@ -0,0 +1,162 @@
+"use strict";
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
+});
+// Create a uri for an https site
+const testPath = getRootDirectory(gTestPath).replace(
+  "chrome://mochitests/content",
+  "https://example.com"
+);
+const TEST_URI = testPath + "file_slow_download.html";
+const EXPECTED_DOWNLOAD_URL =
+  "example.com/browser/dom/security/test/https-first/file_slow_download.sjs";
+
+// Since the server send the complete download file after 3 seconds we need an longer timeout
+requestLongerTimeout(4);
+
+function promisePanelOpened() {
+  if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
+    return Promise.resolve();
+  }
+  return BrowserTestUtils.waitForEvent(DownloadsPanel.panel, "popupshown");
+}
+
+/**
+ * Waits for a download to finish, in case it has not finished already.
+ *
+ * @param aDownload
+ *        The Download object to wait upon.
+ *
+ * @return {Promise}
+ * @resolves When the download has finished successfully.
+ * @rejects JavaScript exception if the download failed.
+ */
+function promiseDownloadStopped(aDownload) {
+  if (!aDownload.stopped) {
+    // The download is in progress, wait for the current attempt to finish and
+    // report any errors that may occur.
+    return aDownload.start();
+  }
+
+  if (aDownload.succeeded) {
+    return Promise.resolve();
+  }
+
+  // The download failed or was canceled.
+  return Promise.reject(aDownload.error || new Error("Download canceled."));
+}
+
+// Verifys that no background request was send
+let requestCounter = 0;
+function examiner() {
+  SpecialPowers.addObserver(this, "specialpowers-http-notify-request");
+}
+
+examiner.prototype = {
+  observe(subject, topic, data) {
+    if (topic !== "specialpowers-http-notify-request") {
+      return;
+    }
+    // On Android we have other requests appear here as well. Let's make
+    // sure we only evaluate requests triggered by the test.
+    if (
+      !data.startsWith("http://example.com") &&
+      !data.startsWith("https://example.com")
+    ) {
+      return;
+    }
+    ++requestCounter;
+    if (requestCounter == 1) {
+      is(data, TEST_URI, "Download start page is https");
+      return;
+    }
+    if (requestCounter == 2) {
+      // The specialpowers-http-notify-request fires before the internal redirect( /upgrade) to
+      // https happens.
+      is(
+        data,
+        "http://" + EXPECTED_DOWNLOAD_URL,
+        "First download request is http (internal)"
+      );
+      return;
+    }
+    if (requestCounter == 3) {
+      is(
+        data,
+        "https://" + EXPECTED_DOWNLOAD_URL,
+        "Download got upgraded to https"
+      );
+      return;
+    }
+    ok(false, "we should never get here, but just in case");
+  },
+  remove() {
+    SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
+  },
+};
+
+// Test description:
+// 1. Open https://example.com
+// 2. Start download - location of download is http
+// 3. https-first upgrades to https
+// 4. Server send first part of download and after 3 seconds the rest
+// 5. Complete download of text file
+add_task(async function test_slow_download() {
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      ["dom.security.https_first", true],
+      // ensure that download panel gets opened
+      ["browser.download.improvements_to_download_panel", true],
+    ],
+  });
+
+  // remove all previous downloads
+  let downloadsList = await Downloads.getList(Downloads.PUBLIC);
+  await downloadsList.removeFinished();
+
+  // add observer to ensure that the background request gets canceled for the upgraded Download
+  this.examiner = new examiner();
+
+  let downloadsPanelPromise = promisePanelOpened();
+  let downloadsPromise = Downloads.getList(Downloads.PUBLIC);
+  BrowserTestUtils.loadURI(gBrowser, TEST_URI);
+  // wait for downloadsPanel to open before continuing with test
+  await downloadsPanelPromise;
+  let downloadList = await downloadsPromise;
+  is(DownloadsPanel.isPanelShowing, true, "DownloadsPanel should be open.");
+  is(downloadList._downloads.length, 1, "File should be downloaded.");
+  let [download] = downloadList._downloads;
+  // wait for download to finish (with success or error)
+  await promiseDownloadStopped(download);
+  is(download.contentType, "text/plain", "File contentType should be correct.");
+  // ensure https-first did upgrade the scheme.
+  is(
+    download.source.url,
+    "https://" + EXPECTED_DOWNLOAD_URL,
+    "Scheme should be https."
+  );
+  // ensure that no background request was send
+  is(
+    requestCounter,
+    3,
+    "three requests total (download page, download http, download https/ upgraded)"
+  );
+  // ensure that downloaded is complete
+  is(download.target.size, 25, "Download size is correct");
+  //clean up
+  this.examiner.remove();
+  info("cleaning up downloads");
+  try {
+    if (Services.appinfo.OS === "WINNT") {
+      // We need to make the file writable to delete it on Windows.
+      await IOUtils.setPermissions(download.target.path, 0o600);
+    }
+    await IOUtils.remove(download.target.path);
+  } catch (error) {
+    info("The file " + download.target.path + " is not removed, " + error);
+  }
+
+  await downloadList.remove(download);
+  await download.finalize();
+});
new file mode 100644
--- /dev/null
+++ b/dom/security/test/https-first/file_slow_download.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test slow download from an http site that gets upgraded to https</title>
+</head>
+<body>
+  <a href="http://example.com/browser/dom/security/test/https-first/file_slow_download.sjs" download="large-dummy-file.txt" id="testlink">download by attribute</a>
+  <script>
+    // click the link to start download
+    let testlink = document.getElementById("testlink");
+    testlink.click();
+  </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/security/test/https-first/file_slow_download.sjs
@@ -0,0 +1,26 @@
+"use strict";
+let timer;
+
+// Send a part of the file then wait for 3 second before sending the rest.
+// If download isn't exempt from background timer of https-only/-first then the download
+// gets cancelled before it completed.
+const DELAY_MS = 3500;
+function handleRequest(request, response) {
+  response.processAsync();
+  timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader(
+    "Content-Disposition",
+    "attachment; filename=large-dummy-file.txt"
+  );
+  response.setHeader("Content-Type", "text/plain");
+  response.write("Begin the file");
+  timer.init(
+    () => {
+      response.write("End of file");
+      response.finish();
+    },
+    DELAY_MS,
+    Ci.nsITimer.TYPE_ONE_SHOT
+  );
+}
--- a/dom/webgpu/Queue.cpp
+++ b/dom/webgpu/Queue.cpp
@@ -111,44 +111,23 @@ void Queue::WriteTexture(const dom::GPUI
   if (aData.IsArrayBuffer()) {
     const auto& ab = aData.GetAsArrayBuffer();
     ab.ComputeState();
     availableSize = ab.Length();
     data = ab.Data();
   }
   MOZ_ASSERT(data != nullptr);
 
-  const auto bpb = aDestination.mTexture->mBytesPerBlock;
-  if (!bpb) {
-    aRv.ThrowAbortError(nsPrintfCString("Invalid texture format"));
-    return;
-  }
-  if (extent.width == 0 || extent.height == 0 ||
-      extent.depth_or_array_layers == 0) {
-    aRv.ThrowAbortError(nsPrintfCString("Invalid copy size"));
+  const auto checkedSize =
+      CheckedInt<size_t>(availableSize) - aDataLayout.mOffset;
+  if (!checkedSize.isValid()) {
+    aRv.ThrowAbortError(nsPrintfCString("Offset is higher than the size"));
     return;
   }
-
-  // TODO: support block-compressed formats
-  const auto fullRows = (CheckedInt<size_t>(extent.depth_or_array_layers - 1) *
-                             aDataLayout.mRowsPerImage +
-                         extent.height - 1);
-  const auto checkedSize = fullRows * aDataLayout.mBytesPerRow +
-                           CheckedInt<size_t>(extent.width) * bpb.value();
-  if (!checkedSize.isValid()) {
-    aRv.ThrowRangeError("Mapped size is too large");
-    return;
-  }
-
-  const auto& size = checkedSize.value();
-  if (availableSize < aDataLayout.mOffset ||
-      size > (availableSize - aDataLayout.mOffset)) {
-    aRv.ThrowAbortError(nsPrintfCString("Wrong data size %" PRIuPTR, size));
-    return;
-  }
+  const auto size = checkedSize.value();
 
   ipc::Shmem shmem;
   if (!mBridge->AllocShmem(size, ipc::Shmem::SharedMemory::TYPE_BASIC,
                            &shmem)) {
     aRv.ThrowAbortError(
         nsPrintfCString("Unable to allocate shmem of size %" PRIuPTR, size));
     return;
   }
--- a/dom/webidl/ImageBitmap.webidl
+++ b/dom/webidl/ImageBitmap.webidl
@@ -392,12 +392,12 @@ enum PremultiplyAlpha { "none", "premult
 enum ColorSpaceConversion { "none", "default" };
 //enum ResizeQuality { "pixelated", "low", "medium", "high" };
 
 dictionary ImageBitmapOptions {
   ImageOrientation imageOrientation = "none";
   PremultiplyAlpha premultiplyAlpha = "default";
   // options to be added  bugs: 1363861
   ColorSpaceConversion colorSpaceConversion = "default";
-  //[EnforceRange] unsigned long resizeWidth;
-  //[EnforceRange] unsigned long resizeHeight;
+  [EnforceRange] unsigned long resizeWidth;
+  [EnforceRange] unsigned long resizeHeight;
   //ResizeQuality resizeQuality = "low";
 };
--- a/gfx/wgpu_bindings/src/server.rs
+++ b/gfx/wgpu_bindings/src/server.rs
@@ -613,17 +613,17 @@ pub unsafe extern "C" fn wgpu_server_que
 ) {
     let action: QueueWriteAction = bincode::deserialize(byte_buf.as_slice()).unwrap();
     let data = slice::from_raw_parts(data, data_length);
     let result = match action {
         QueueWriteAction::Buffer { dst, offset } => {
             gfx_select!(self_id => global.queue_write_buffer(self_id, dst, offset, data))
         }
         QueueWriteAction::Texture { dst, layout, size } => {
-            gfx_select!(self_id => global.queue_write_texture(self_id, &dst, &data, &layout, &size))
+            gfx_select!(self_id => global.queue_write_texture(self_id, &dst, data, &layout, &size))
         }
     };
     if let Err(err) = result {
         error_buf.init(err);
     }
 }
 
 #[no_mangle]
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -57,16 +57,21 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLAT
 namespace ipc {
 
 IPCResult IPCResult::Fail(NotNull<IProtocol*> actor, const char* where,
                           const char* why) {
   // Calls top-level protocol to handle the error.
   nsPrintfCString errorMsg("%s %s\n", where, why);
   actor->GetIPCChannel()->Listener()->ProcessingError(
       HasResultCodes::MsgProcessingError, errorMsg.get());
+
+  MOZ_ASSERT_UNLESS_FUZZING(false,
+                            "Please ensure to IPC_FAIL only when in an "
+                            "unrecoverable, unexpected state.");
+
   return IPCResult(false);
 }
 
 void AnnotateSystemError() {
   int64_t error = 0;
 #if defined(XP_WIN)
   error = ::GetLastError();
 #elif defined(OS_POSIX)
--- a/js/src/jit-test/tests/wasm/simd/avx2-x64-ion-codegen.js
+++ b/js/src/jit-test/tests/wasm/simd/avx2-x64-ion-codegen.js
@@ -18,16 +18,30 @@ function codegenTestX64_v128xv128_v128_a
          (func (export "f") (param v128 v128 v128) (result v128)
            (${op} (local.get 1) (local.get 2)))`),
                               'f',
                               expected,
                               options);
      }
 }
 
+// Utility function to test SIMD operations encoding, where the input argument
+// has the specified type (T).
+// inputs: [[type, complete-opname, expected-pattern], ...]
+function codegenTestX64_T_v128_avxhack(inputs, options = {}) {
+     for ( let [ty, op, expected] of inputs ) {
+         codegenTestX64_adhoc(wrap(options, `
+         (func (export "f") (param ${ty}) (result v128)
+           (${op} (local.get 0)))`),
+                              'f',
+                              expected,
+                              options);
+     }
+}
+
 // Simple binary ops: e.g. add, sub, mul
 codegenTestX64_v128xv128_v128_avxhack(
      [['i32x4.add', `c5 f1 fe c2               vpaddd %xmm2, %xmm1, %xmm0`],
       ['i32x4.sub', `c5 f1 fa c2               vpsubd %xmm2, %xmm1, %xmm0`],
       ['i32x4.mul', `c4 e2 71 40 c2            vpmulld %xmm2, %xmm1, %xmm0`],
       ['f32x4.add', `c5 f0 58 c2               vaddps %xmm2, %xmm1, %xmm0`],
       ['f32x4.sub', `c5 f0 5c c2               vsubps %xmm2, %xmm1, %xmm0`],
       ['f32x4.mul', `c5 f0 59 c2               vmulps %xmm2, %xmm1, %xmm0`],
@@ -65,8 +79,30 @@ codegenTestX64_v128xv128_v128_avxhack(
 codegenTestX64_adhoc(`(module
      (func (export "f") (param v128 v128 i64) (result v128)
           (i64x2.replace_lane 1 (local.get 1) (local.get 2))))`,
                               'f',
                               `
 c4 .. f1 22 .. 01         vpinsrq \\$0x01, %r\\w+, %xmm1, %xmm0` ); // rdi (Linux) or r8 (Win)
      
                              
+if (isAvxPresent(2)) {
+     // First i32 arg is: edi on Linux, and ecx on Windows.
+     codegenTestX64_T_v128_avxhack(
+          [['i32', 'i8x16.splat', `
+c5 f9 6e ..               vmovd %e\\w+, %xmm0
+c4 e2 79 78 c0            vpbroadcastb %xmm0, %xmm0`],
+           ['i32', 'i16x8.splat', `
+c5 f9 6e ..               vmovd %e\\w+, %xmm0
+c4 e2 79 79 c0            vpbroadcastw %xmm0, %xmm0`],
+           ['i32', 'i32x4.splat', `
+c5 f9 6e ..               vmovd %e\\w+, %xmm0
+c4 e2 79 58 c0            vpbroadcastd %xmm0, %xmm0`],
+           ['f32', 'f32x4.splat', `c4 e2 79 18 c0            vbroadcastss %xmm0, %xmm0`]]);
+
+     codegenTestX64_T_v128_avxhack(
+          [['i32', 'v128.load8_splat',
+            'c4 c2 79 78 04 ..         vpbroadcastbb \\(%r15,%r\\w+,1\\), %xmm0'],
+           ['i32', 'v128.load16_splat',
+            'c4 c2 79 79 04 ..         vpbroadcastww \\(%r15,%r\\w+,1\\), %xmm0'],
+           ['i32', 'v128.load32_splat',
+            'c4 c2 79 18 04 ..         vbroadcastssl \\(%r15,%r\\w+,1\\), %xmm0']], {memory: 1});
+}
--- a/js/src/jit-test/tests/wasm/simd/splat-x64-ion-codegen.js
+++ b/js/src/jit-test/tests/wasm/simd/splat-x64-ion-codegen.js
@@ -2,17 +2,17 @@
 
 // Test that there are no extraneous moves or other instructions for splat and
 // other splat-like operations that can reuse its input for its output and/or
 // has a specializable code path.  See README-codegen.md for general information
 // about this type of test case.
 
 codegenTestX64_PTYPE_v128(
     [['f32x4.splat', 'f32', `0f c6 c0 00               shufps \\$0x00, %xmm0, %xmm0`],
-     ['f64x2.splat', 'f64', `66 0f c6 c0 00            shufpd \\$0x00, %xmm0, %xmm0`]] );
+     ['f64x2.splat', 'f64', `f2 0f 12 c0               movddup %xmm0, %xmm0`]] , {log:true});
 
 // Skip these on Win64 because the ABI differs and there's a different parameter
 // register, this changes not just the name slightly but the binary encoding in
 // larger ways.
 
 if (!getBuildConfiguration().windows) {
     codegenTestX64_PTYPE_v128(
         [['v128.load32_splat', 'i32', `
--- a/js/src/jit/shared/Assembler-shared.h
+++ b/js/src/jit/shared/Assembler-shared.h
@@ -557,17 +557,18 @@ class MemoryAccessDesc {
   void setZeroExtendSimd128Load() {
     MOZ_ASSERT(type() == Scalar::Float32 || type() == Scalar::Float64);
     MOZ_ASSERT(!isAtomic());
     MOZ_ASSERT(loadOp_ == Plain);
     loadOp_ = ZeroExtend;
   }
 
   void setSplatSimd128Load() {
-    MOZ_ASSERT(type() == Scalar::Float64);
+    MOZ_ASSERT(type() == Scalar::Uint8 || type() == Scalar::Uint16 ||
+               type() == Scalar::Float32 || type() == Scalar::Float64);
     MOZ_ASSERT(!isAtomic());
     MOZ_ASSERT(loadOp_ == Plain);
     loadOp_ = Splat;
   }
 
   void setWidenSimd128Load(wasm::SimdOp op) {
     MOZ_ASSERT(type() == Scalar::Float64);
     MOZ_ASSERT(!isAtomic());
--- a/js/src/jit/x64/MacroAssembler-x64.cpp
+++ b/js/src/jit/x64/MacroAssembler-x64.cpp
@@ -922,40 +922,55 @@ void MacroAssembler::PushBoxed(FloatRegi
 
 void MacroAssembler::wasmLoad(const wasm::MemoryAccessDesc& access,
                               Operand srcAddr, AnyRegister out) {
   memoryBarrierBefore(access.sync());
 
   MOZ_ASSERT_IF(
       access.isZeroExtendSimd128Load(),
       access.type() == Scalar::Float32 || access.type() == Scalar::Float64);
-  MOZ_ASSERT_IF(access.isSplatSimd128Load(), access.type() == Scalar::Float64);
+  MOZ_ASSERT_IF(
+      access.isSplatSimd128Load(),
+      access.type() == Scalar::Uint8 || access.type() == Scalar::Uint16 ||
+          access.type() == Scalar::Float32 || access.type() == Scalar::Float64);
   MOZ_ASSERT_IF(access.isWidenSimd128Load(), access.type() == Scalar::Float64);
 
   append(access, size());
   switch (access.type()) {
     case Scalar::Int8:
       movsbl(srcAddr, out.gpr());
       break;
     case Scalar::Uint8:
-      movzbl(srcAddr, out.gpr());
+      if (access.isSplatSimd128Load()) {
+        vbroadcastb(srcAddr, out.fpu());
+      } else {
+        movzbl(srcAddr, out.gpr());
+      }
       break;
     case Scalar::Int16:
       movswl(srcAddr, out.gpr());
       break;
     case Scalar::Uint16:
-      movzwl(srcAddr, out.gpr());
+      if (access.isSplatSimd128Load()) {
+        vbroadcastw(srcAddr, out.fpu());
+      } else {
+        movzwl(srcAddr, out.gpr());
+      }
       break;
     case Scalar::Int32:
     case Scalar::Uint32:
       movl(srcAddr, out.gpr());
       break;
     case Scalar::Float32:
-      // vmovss does the right thing also for access.isZeroExtendSimd128Load()
-      vmovss(srcAddr, out.fpu());
+      if (access.isSplatSimd128Load()) {
+        vbroadcastss(srcAddr, out.fpu());
+      } else {
+        // vmovss does the right thing also for access.isZeroExtendSimd128Load()
+        vmovss(srcAddr, out.fpu());
+      }
       break;
     case Scalar::Float64:
       if (access.isSplatSimd128Load()) {
         vmovddup(srcAddr, out.fpu());
       } else if (access.isWidenSimd128Load()) {
         switch (access.widenSimdOp()) {
           case wasm::SimdOp::V128Load8x8S:
             vpmovsxbw(srcAddr, out.fpu());
--- a/js/src/jit/x86-shared/Assembler-x86-shared.h
+++ b/js/src/jit/x86-shared/Assembler-x86-shared.h
@@ -4673,16 +4673,102 @@ class AssemblerX86Shared : public Assemb
       case Operand::MEM_REG_DISP:
         masm.fstp32_m(src.disp(), src.base());
         break;
       default:
         MOZ_CRASH("unexpected operand kind");
     }
   }
 
+  void vbroadcastb(const Operand& src, FloatRegister dest) {
+    MOZ_ASSERT(HasAVX2());
+    switch (src.kind()) {
+      case Operand::FPREG:
+        masm.vbroadcastb_rr(src.fpu(), dest.encoding());
+        break;
+      case Operand::MEM_REG_DISP:
+        masm.vbroadcastb_mr(src.disp(), src.base(), dest.encoding());
+        break;
+      case Operand::MEM_SCALE:
+        masm.vbroadcastb_mr(src.disp(), src.base(), src.index(), src.scale(),
+                            dest.encoding());
+        break;
+      default:
+        MOZ_CRASH("unexpected operand kind");
+    }
+  }
+  void vbroadcastw(const Operand& src, FloatRegister dest) {
+    MOZ_ASSERT(HasAVX2());
+    switch (src.kind()) {
+      case Operand::FPREG:
+        masm.vbroadcastw_rr(src.fpu(), dest.encoding());
+        break;
+      case Operand::MEM_REG_DISP:
+        masm.vbroadcastw_mr(src.disp(), src.base(), dest.encoding());
+        break;
+      case Operand::MEM_SCALE:
+        masm.vbroadcastw_mr(src.disp(), src.base(), src.index(), src.scale(),
+                            dest.encoding());
+        break;
+      default:
+        MOZ_CRASH("unexpected operand kind");
+    }
+  }
+  void vbroadcastd(const Operand& src, FloatRegister dest) {
+    MOZ_ASSERT(HasAVX2());
+    switch (src.kind()) {
+      case Operand::FPREG:
+        masm.vbroadcastd_rr(src.fpu(), dest.encoding());
+        break;
+      case Operand::MEM_REG_DISP:
+        masm.vbroadcastd_mr(src.disp(), src.base(), dest.encoding());
+        break;
+      case Operand::MEM_SCALE:
+        masm.vbroadcastd_mr(src.disp(), src.base(), src.index(), src.scale(),
+                            dest.encoding());
+        break;
+      default:
+        MOZ_CRASH("unexpected operand kind");
+    }
+  }
+  void vbroadcastq(const Operand& src, FloatRegister dest) {
+    MOZ_ASSERT(HasAVX2());
+    switch (src.kind()) {
+      case Operand::FPREG:
+        masm.vbroadcastq_rr(src.fpu(), dest.encoding());
+        break;
+      case Operand::MEM_REG_DISP:
+        masm.vbroadcastq_mr(src.disp(), src.base(), dest.encoding());
+        break;
+      case Operand::MEM_SCALE:
+        masm.vbroadcastq_mr(src.disp(), src.base(), src.index(), src.scale(),
+                            dest.encoding());
+        break;
+      default:
+        MOZ_CRASH("unexpected operand kind");
+    }
+  }
+  void vbroadcastss(const Operand& src, FloatRegister dest) {
+    MOZ_ASSERT(HasAVX2());
+    switch (src.kind()) {
+      case Operand::FPREG:
+        masm.vbroadcastss_rr(src.fpu(), dest.encoding());
+        break;
+      case Operand::MEM_REG_DISP:
+        masm.vbroadcastss_mr(src.disp(), src.base(), dest.encoding());
+        break;
+      case Operand::MEM_SCALE:
+        masm.vbroadcastss_mr(src.disp(), src.base(), src.index(), src.scale(),
+                             dest.encoding());
+        break;
+      default:
+        MOZ_CRASH("unexpected operand kind");
+    }
+  }
+
   void flushBuffer() {}
 
   // Patching.
 
   static size_t PatchWrite_NearCallSize() { return 5; }
   static uintptr_t GetPointer(uint8_t* instPtr) {
     uintptr_t* ptr = ((uintptr_t*)instPtr) - 1;
     return *ptr;
--- a/js/src/jit/x86-shared/BaseAssembler-x86-shared.h
+++ b/js/src/jit/x86-shared/BaseAssembler-x86-shared.h
@@ -4266,16 +4266,82 @@ class BaseAssembler : public GenericAsse
 
   void vpaddq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
     twoByteOpSimd("vpaddq", VEX_PD, OP2_PADDQ_VdqWdq, src1, src0, dst);
   }
   void vpsubq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
     twoByteOpSimd("vpsubq", VEX_PD, OP2_PSUBQ_VdqWdq, src1, src0, dst);
   }
 
+  void vbroadcastb_rr(XMMRegisterID src, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastb", VEX_PD, OP3_VBROADCASTB_VxWx, ESCAPE_38, src,
+                    invalid_xmm, dst);
+  }
+  void vbroadcastb_mr(int32_t offset, RegisterID base, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastb", VEX_PD, OP3_VBROADCASTB_VxWx, ESCAPE_38,
+                    offset, base, invalid_xmm, dst);
+  }
+  void vbroadcastb_mr(int32_t offset, RegisterID base, RegisterID index,
+                      int32_t scale, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastb", VEX_PD, OP3_VBROADCASTB_VxWx, ESCAPE_38,
+                    offset, base, index, scale, invalid_xmm, dst);
+  }
+  void vbroadcastw_rr(XMMRegisterID src, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastw", VEX_PD, OP3_VBROADCASTW_VxWx, ESCAPE_38, src,
+                    invalid_xmm, dst);
+  }
+  void vbroadcastw_mr(int32_t offset, RegisterID base, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastw", VEX_PD, OP3_VBROADCASTW_VxWx, ESCAPE_38,
+                    offset, base, invalid_xmm, dst);
+  }
+  void vbroadcastw_mr(int32_t offset, RegisterID base, RegisterID index,
+                      int32_t scale, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastw", VEX_PD, OP3_VBROADCASTW_VxWx, ESCAPE_38,
+                    offset, base, index, scale, invalid_xmm, dst);
+  }
+  void vbroadcastd_rr(XMMRegisterID src, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastd", VEX_PD, OP3_VBROADCASTD_VxWx, ESCAPE_38, src,
+                    invalid_xmm, dst);
+  }
+  void vbroadcastd_mr(int32_t offset, RegisterID base, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastd", VEX_PD, OP3_VBROADCASTD_VxWx, ESCAPE_38,
+                    offset, base, invalid_xmm, dst);
+  }
+  void vbroadcastd_mr(int32_t offset, RegisterID base, RegisterID index,
+                      int32_t scale, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastd", VEX_PD, OP3_VBROADCASTD_VxWx, ESCAPE_38,
+                    offset, base, index, scale, invalid_xmm, dst);
+  }
+  void vbroadcastq_rr(XMMRegisterID src, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastq", VEX_PD, OP3_VBROADCASTQ_VxWx, ESCAPE_38, src,
+                    invalid_xmm, dst);
+  }
+  void vbroadcastq_mr(int32_t offset, RegisterID base, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastq", VEX_PD, OP3_VBROADCASTQ_VxWx, ESCAPE_38,
+                    offset, base, invalid_xmm, dst);
+  }
+  void vbroadcastq_mr(int32_t offset, RegisterID base, RegisterID index,
+                      int32_t scale, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastq", VEX_PD, OP3_VBROADCASTQ_VxWx, ESCAPE_38,
+                    offset, base, index, scale, invalid_xmm, dst);
+  }
+  void vbroadcastss_rr(XMMRegisterID src, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastss", VEX_PD, OP3_VBROADCASTSS_VxWd, ESCAPE_38,
+                    src, invalid_xmm, dst);
+  }
+  void vbroadcastss_mr(int32_t offset, RegisterID base, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastss", VEX_PD, OP3_VBROADCASTSS_VxWd, ESCAPE_38,
+                    offset, base, invalid_xmm, dst);
+  }
+  void vbroadcastss_mr(int32_t offset, RegisterID base, RegisterID index,
+                       int32_t scale, XMMRegisterID dst) {
+    threeByteOpSimd("vbroadcastss", VEX_PD, OP3_VBROADCASTSS_VxWd, ESCAPE_38,
+                    offset, base, index, scale, invalid_xmm, dst);
+  }
+
   // BMI instructions:
 
   void sarxl_rrr(RegisterID src, RegisterID shift, RegisterID dst) {
     spew("sarxl      %s, %s, %s", GPReg32Name(src), GPReg32Name(shift),
          GPReg32Name(dst));
 
     RegisterID rm = src;
     XMMRegisterID src0 = static_cast<XMMRegisterID>(shift);
--- a/js/src/jit/x86-shared/Encoding-x86-shared.h
+++ b/js/src/jit/x86-shared/Encoding-x86-shared.h
@@ -355,16 +355,17 @@ enum ThreeByteOpcodeID {
   OP3_PBLENDVB_VdqWdq = 0x10,
   OP3_BLENDVPS_VdqWdq = 0x14,
   OP3_PEXTRB_EvVdqIb = 0x14,
   OP3_PEXTRW_EwVdqIb = 0x15,
   OP3_PEXTRD_EvVdqIb = 0x16,
   OP3_PEXTRQ_EvVdqIb = 0x16,
   OP3_PTEST_VdVd = 0x17,
   OP3_EXTRACTPS_EdVdqIb = 0x17,
+  OP3_VBROADCASTSS_VxWd = 0x18,
   OP3_PABSB_VdqWdq = 0x1C,
   OP3_PABSW_VdqWdq = 0x1D,
   OP3_PABSD_VdqWdq = 0x1E,
   OP3_PINSRB_VdqEvIb = 0x20,
   OP3_PMOVSXBW_VdqWdq = 0x20,
   OP3_INSERTPS_VpsUps = 0x21,
   OP3_PINSRD_VdqEvIb = 0x22,
   OP3_PINSRQ_VdqEvIb = 0x22,
@@ -382,16 +383,20 @@ enum ThreeByteOpcodeID {
   OP3_PMINUW_VdqWdq = 0x3A,
   OP3_PMINUD_VdqWdq = 0x3B,
   OP3_PMAXSB_VdqWdq = 0x3C,
   OP3_PMAXSD_VdqWdq = 0x3D,
   OP3_PMAXUW_VdqWdq = 0x3E,
   OP3_PMAXUD_VdqWdq = 0x3F,
   OP3_PMULLD_VdqWdq = 0x40,
   OP3_VBLENDVPS_VdqWdq = 0x4A,
+  OP3_VBROADCASTD_VxWx = 0x58,
+  OP3_VBROADCASTQ_VxWx = 0x59,
+  OP3_VBROADCASTB_VxWx = 0x78,
+  OP3_VBROADCASTW_VxWx = 0x79,
   OP3_SHLX_GyEyBy = 0xF7,
   OP3_SARX_GyEyBy = 0xF7,
   OP3_SHRX_GyEyBy = 0xF7,
 };
 
 // Test whether the given opcode should be printed with its operands reversed.
 inline bool IsXMMReversedOperands(TwoByteOpcodeID opcode) {
   switch (opcode) {
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-SIMD.cpp
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-SIMD.cpp
@@ -16,43 +16,58 @@ using mozilla::DebugOnly;
 using mozilla::FloatingPoint;
 using mozilla::Maybe;
 using mozilla::SpecificNaN;
 
 void MacroAssemblerX86Shared::splatX16(Register input, FloatRegister output) {
   ScratchSimd128Scope scratch(asMasm());
 
   vmovd(input, output);
+  if (HasAVX2()) {
+    vbroadcastb(Operand(output), output);
+    return;
+  }
   zeroSimd128Int(scratch);
   vpshufb(scratch, output, output);
 }
 
 void MacroAssemblerX86Shared::splatX8(Register input, FloatRegister output) {
   vmovd(input, output);
+  if (HasAVX2()) {
+    vbroadcastw(Operand(output), output);
+    return;
+  }
   vpshuflw(0, output, output);
   vpshufd(0, output, output);
 }
 
 void MacroAssemblerX86Shared::splatX4(Register input, FloatRegister output) {
   vmovd(input, output);
+  if (HasAVX2()) {
+    vbroadcastd(Operand(output), output);
+    return;
+  }
   vpshufd(0, output, output);
 }
 
 void MacroAssemblerX86Shared::splatX4(FloatRegister input,
                                       FloatRegister output) {
   MOZ_ASSERT(input.isSingle() && output.isSimd128());
+  if (HasAVX2()) {
+    vbroadcastss(Operand(input), output);
+    return;
+  }
   asMasm().moveSimd128Float(input.asSimd128(), output);
   vshufps(0, output, output, output);
 }
 
 void MacroAssemblerX86Shared::splatX2(FloatRegister input,
                                       FloatRegister output) {
   MOZ_ASSERT(input.isDouble() && output.isSimd128());
-  asMasm().moveSimd128Float(input.asSimd128(), output);
-  vshufpd(0, output, output, output);
+  vmovddup(Operand(input.asSimd128()), output);
 }
 
 void MacroAssemblerX86Shared::extractLaneInt32x4(FloatRegister input,
                                                  Register output,
                                                  unsigned lane) {
   if (lane == 0) {
     // The value we want to extract is in the low double-word
     moveLowInt32(input, output);
--- a/js/src/jit/x86/MacroAssembler-x86.cpp
+++ b/js/src/jit/x86/MacroAssembler-x86.cpp
@@ -947,42 +947,57 @@ template void MacroAssembler::storeUnbox
 void MacroAssembler::wasmLoad(const wasm::MemoryAccessDesc& access,
                               Operand srcAddr, AnyRegister out) {
   MOZ_ASSERT(srcAddr.kind() == Operand::MEM_REG_DISP ||
              srcAddr.kind() == Operand::MEM_SCALE);
 
   MOZ_ASSERT_IF(
       access.isZeroExtendSimd128Load(),
       access.type() == Scalar::Float32 || access.type() == Scalar::Float64);
-  MOZ_ASSERT_IF(access.isSplatSimd128Load(), access.type() == Scalar::Float64);
+  MOZ_ASSERT_IF(
+      access.isSplatSimd128Load(),
+      access.type() == Scalar::Uint8 || access.type() == Scalar::Uint16 ||
+          access.type() == Scalar::Float32 || access.type() == Scalar::Float64);
   MOZ_ASSERT_IF(access.isWidenSimd128Load(), access.type() == Scalar::Float64);
 
   memoryBarrierBefore(access.sync());
 
   append(access, size());
   switch (access.type()) {
     case Scalar::Int8:
       movsbl(srcAddr, out.gpr());
       break;
     case Scalar::Uint8:
-      movzbl(srcAddr, out.gpr());
+      if (access.isSplatSimd128Load()) {
+        vbroadcastb(srcAddr, out.fpu());
+      } else {
+        movzbl(srcAddr, out.gpr());
+      }
       break;
     case Scalar::Int16:
       movswl(srcAddr, out.gpr());
       break;
     case Scalar::Uint16:
-      movzwl(srcAddr, out.gpr());
+      if (access.isSplatSimd128Load()) {
+        vbroadcastw(srcAddr, out.fpu());
+      } else {
+        movzwl(srcAddr, out.gpr());
+      }
       break;
     case Scalar::Int32:
     case Scalar::Uint32:
       movl(srcAddr, out.gpr());
       break;
     case Scalar::Float32:
-      // vmovss does the right thing also for access.isZeroExtendSimd128Load()
-      vmovss(srcAddr, out.fpu());
+      if (access.isSplatSimd128Load()) {
+        vbroadcastss(srcAddr, out.fpu());
+      } else {
+        // vmovss does the right thing also for access.isZeroExtendSimd128Load()
+        vmovss(srcAddr, out.fpu());
+      }
       break;
     case Scalar::Float64:
       if (access.isSplatSimd128Load()) {
         vmovddup(srcAddr, out.fpu());
       } else if (access.isWidenSimd128Load()) {
         switch (access.widenSimdOp()) {
           case wasm::SimdOp::V128Load8x8S:
             vpmovsxbw(srcAddr, out.fpu());
--- a/js/src/wasm/WasmIonCompile.cpp
+++ b/js/src/wasm/WasmIonCompile.cpp
@@ -1602,17 +1602,24 @@ class FunctionCompiler {
     if (inDeadCode()) {
       return nullptr;
     }
 
     MemoryAccessDesc access(viewType, addr.align, addr.offset,
                             bytecodeIfNotAsmJS());
 
     // Generate better code (on x86)
-    if (viewType == Scalar::Float64) {
+    // If AVX2 is enabled, more broadcast operators are available.
+    if (viewType == Scalar::Float64
+#  if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
+        || (js::jit::CPUInfo::IsAVX2Present() &&
+            (viewType == Scalar::Uint8 || viewType == Scalar::Uint16 ||
+             viewType == Scalar::Float32))
+#  endif
+    ) {
       access.setSplatSimd128Load();
       return load(addr.base, &access, ValType::V128);
     }
 
     ValType resultType = ValType::I32;
     if (viewType == Scalar::Float32) {
       resultType = ValType::F32;
       splatOp = wasm::SimdOp::F32x4Splat;
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -23,16 +23,17 @@
 #include "nsIFrameInlines.h"
 #include "nsIScrollableFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsStyleConsts.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::layout;
+using image::ImgDrawResult;
 
 nsContainerFrame* NS_NewFieldSetFrame(PresShell* aPresShell,
                                       ComputedStyle* aStyle) {
   return new (aPresShell) nsFieldSetFrame(aStyle, aPresShell->GetPresContext());
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsFieldSetFrame)
 NS_QUERYFRAME_HEAD(nsFieldSetFrame)
@@ -121,19 +122,18 @@ class nsDisplayFieldSetBorder final : pu
       nsDisplayListBuilder* aDisplayListBuilder) override;
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
                            bool* aSnap) const override;
   NS_DISPLAY_DECL_NAME("FieldSetBorder", TYPE_FIELDSET_BORDER_BACKGROUND)
 };
 
 void nsDisplayFieldSetBorder::Paint(nsDisplayListBuilder* aBuilder,
                                     gfxContext* aCtx) {
-  image::ImgDrawResult result =
-      static_cast<nsFieldSetFrame*>(mFrame)->PaintBorder(
-          aBuilder, *aCtx, ToReferenceFrame(), GetPaintRect(aBuilder, aCtx));
+  ImgDrawResult result = static_cast<nsFieldSetFrame*>(mFrame)->PaintBorder(
+      aBuilder, *aCtx, ToReferenceFrame(), GetPaintRect(aBuilder, aCtx));
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
 nsDisplayItemGeometry* nsDisplayFieldSetBorder::AllocateGeometry(
     nsDisplayListBuilder* aBuilder) {
   return new nsDisplayItemGenericImageGeometry(this, aBuilder);
 }
@@ -167,22 +167,23 @@ nsRect nsDisplayFieldSetBorder::GetBound
 bool nsDisplayFieldSetBorder::CreateWebRenderCommands(
     mozilla::wr::DisplayListBuilder& aBuilder,
     mozilla::wr::IpcResourceUpdateQueue& aResources,
     const StackingContextHelper& aSc,
     mozilla::layers::RenderRootStateManager* aManager,
     nsDisplayListBuilder* aDisplayListBuilder) {
   auto frame = static_cast<nsFieldSetFrame*>(mFrame);
   auto offset = ToReferenceFrame();
-  nsRect rect;
   Maybe<wr::SpaceAndClipChainHelper> clipOut;
 
+  nsRect rect = frame->VisualBorderRectRelativeToSelf() + offset;
+  nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands(
+      aBuilder, aSc, rect, mFrame, rect);
+
   if (nsIFrame* legend = frame->GetLegend()) {
-    rect = frame->VisualBorderRectRelativeToSelf() + offset;
-
     nsRect legendRect = legend->GetNormalRect() + offset;
 
     // Make sure we clip all of the border in case the legend is smaller.
     nscoord borderTopWidth = frame->GetUsedBorder().top;
     if (legendRect.height < borderTopWidth) {
       legendRect.height = borderTopWidth;
       legendRect.y = offset.y;
     }
@@ -270,19 +271,20 @@ void nsFieldSetFrame::BuildDisplayList(n
   }
   // Put the inner frame's display items on the master list. Note that this
   // moves its border/background display items to our BorderBackground() list,
   // which isn't really correct, but it's OK because the inner frame is
   // anonymous and can't have its own border and background.
   contentDisplayItems.MoveTo(aLists);
 }
 
-image::ImgDrawResult nsFieldSetFrame::PaintBorder(
-    nsDisplayListBuilder* aBuilder, gfxContext& aRenderingContext, nsPoint aPt,
-    const nsRect& aDirtyRect) {
+ImgDrawResult nsFieldSetFrame::PaintBorder(nsDisplayListBuilder* aBuilder,
+                                           gfxContext& aRenderingContext,
+                                           nsPoint aPt,
+                                           const nsRect& aDirtyRect) {
   // If the border is smaller than the legend, move the border down
   // to be centered on the legend.  We call VisualBorderRectRelativeToSelf() to
   // compute the border positioning.
   // FIXME: This means border-radius clamping is incorrect; we should
   // override nsIFrame::GetBorderRadii.
   nsRect rect = VisualBorderRectRelativeToSelf() + aPt;
   nsPresContext* presContext = PresContext();
 
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -3558,17 +3558,18 @@ void nsTextFrame::PropertyProvider::GetS
   }
 }
 
 // aX and the result are in whole appunits.
 static gfxFloat AdvanceToNextTab(gfxFloat aX, gfxFloat aTabWidth,
                                  gfxFloat aMinAdvance) {
   // Advance aX to the next multiple of aTabWidth. We must advance
   // by at least aMinAdvance.
-  return ceil((aX + aMinAdvance) / aTabWidth) * aTabWidth;
+  gfxFloat nextPos = aX + aMinAdvance;
+  return aTabWidth > 0.0 ? ceil(nextPos / aTabWidth) * aTabWidth : nextPos;
 }
 
 void nsTextFrame::PropertyProvider::CalcTabWidths(Range aRange,
                                                   gfxFloat aTabWidth) const {
   MOZ_ASSERT(aTabWidth > 0);
 
   if (!mTabWidths) {
     if (mReflowing && !mLineContainer) {
--- a/layout/reftests/box-shadow/reftest.list
+++ b/layout/reftests/box-shadow/reftest.list
@@ -36,14 +36,14 @@ fuzzy(0-26,0-3610) fuzzy-if(d2d,0-26,0-5
 fuzzy(12-15,9400-13267) == boxshadow-inset-large-offset.html boxshadow-inset-large-offset-ref.html
 
 == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref.html
 == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref2.html
 == overflow-not-scrollable-2.html overflow-not-scrollable-2-ref.html
 fuzzy(0-1,0-655) == 611574-1.html 611574-1-ref.html
 fuzzy(0-4,0-144) fuzzy-if(d2d,0-1,0-36) == 611574-2.html 611574-2-ref.html
 fuzzy(0-16,0-10) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows
-fuzzy(0-16,0-10) fails-if(!useDrawSnapshot) == fieldset-inset.html fieldset-inset-ref.html # minor anti-aliasing problem on Windows
+fuzzy(0-16,0-10) == fieldset-inset.html fieldset-inset-ref.html # minor anti-aliasing problem on Windows
 == 1178575.html 1178575-ref.html
 == 1178575-2.html 1178575-2-ref.html
 fuzzy(0-159,0-2) fails-if(!dwrite||!nativeThemePref) == 1212823-1.html 1212823-1-ref.html
 fuzzy(0-93,0-8) fails-if(nativeThemePref) == 1212823-2.html 1212823-2-ref.html
 == boxshadow-large-offset.html boxshadow-large-offset-ref.html
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -459,27 +459,35 @@ interface nsILoadInfo : nsISupports
   /**
    * This flag can only ever be set on top-level loads. It indicates
    * that the top-level https connection succeeded. This flag is mostly
    * used to counter time-outs which allows to cancel the channel
    * if the https load has not started.
    */
   const unsigned long HTTPS_ONLY_TOP_LEVEL_LOAD_IN_PROGRESS = (1 << 4);
 
-  /**
-   * This flag indicates that the request should not be logged to the
-   * console.
+   /**
+   * This flag can only ever be set on downloads. It indicates
+   * that the download https connection succeeded. This flag is mostly
+   * used to counter time-outs which allows to cancel the channel
+   * if the https load has not started.
    */
-  const unsigned long HTTPS_ONLY_DO_NOT_LOG_TO_CONSOLE = (1 << 5);
+  const unsigned long HTTPS_ONLY_DOWNLOAD_IN_PROGRESS = (1 << 5);
 
   /**
    * This flag indicates that the request should not be logged to the
    * console.
    */
-  const unsigned long HTTPS_ONLY_UPGRADED_HTTPS_FIRST = (1 << 6);
+  const unsigned long HTTPS_ONLY_DO_NOT_LOG_TO_CONSOLE = (1 << 6);
+
+  /**
+   * This flag indicates that the request should not be logged to the
+   * console.
+   */
+  const unsigned long HTTPS_ONLY_UPGRADED_HTTPS_FIRST = (1 << 7);
 
   /**
    * Upgrade state of HTTPS-Only Mode. The flag HTTPS_ONLY_EXEMPT can get
    * set on requests that should be excempt from an upgrade.
    */
   [infallible] attribute unsigned long httpsOnlyStatus;
 
   /**
--- a/testing/web-platform/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini
+++ b/testing/web-platform/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini
@@ -1,117 +1,42 @@
 [createImageBitmap-drawImage.html]
   [createImageBitmap from an OffscreenCanvas resized, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from a vector HTMLImageElement resized, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an OffscreenCanvas, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from a bitmap HTMLImageElement resized, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an HTMLVideoElement from a data URL scaled down, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from an ImageData scaled down, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an OffscreenCanvas scaled down, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from a bitmap SVGImageElement resized, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from an HTMLCanvasElement scaled down, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from an ImageData scaled up, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a bitmap SVGImageElement scaled up, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a vector SVGImageElement resized, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a bitmap HTMLImageElement scaled up, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a vector SVGImageElement scaled down, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a bitmap HTMLImageElement scaled down, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an HTMLVideoElement scaled down, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from a Blob scaled down, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from an ImageData resized, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a vector HTMLImageElement scaled down, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a vector SVGImageElement scaled up, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a Blob scaled up, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a bitmap SVGImageElement scaled down, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an HTMLVideoElement scaled up, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from an HTMLCanvasElement resized, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an HTMLVideoElement resized, and drawImage on the created ImageBitmap]
     expected: FAIL
 
   [createImageBitmap from an HTMLVideoElement from a data URL scaled up, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from an ImageBitmap scaled down, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a Blob with negative sw/sh, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from an ImageBitmap scaled up, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from an ImageBitmap resized, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an OffscreenCanvas scaled up, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from an HTMLCanvasElement scaled up, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
-  [createImageBitmap from a Blob resized, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an HTMLVideoElement from a data URL resized, and drawImage on the created ImageBitmap]
     expected: FAIL
 
   [createImageBitmap from an OffscreenCanvas with negative sw/sh, and drawImage on the created ImageBitmap]
     expected: FAIL
 
-  [createImageBitmap from a vector HTMLImageElement scaled up, and drawImage on the created ImageBitmap]
-    expected: FAIL
-
   [createImageBitmap from an HTMLVideoElement, and drawImage on the created ImageBitmap]
     expected: FAIL
 
   [createImageBitmap from an HTMLVideoElement with negative sw/sh, and drawImage on the created ImageBitmap]
     expected: FAIL
 
   [createImageBitmap from an HTMLVideoElement from a data URL, and drawImage on the created ImageBitmap]
     expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-backgrounds/fieldset-inset-shadow-ref.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<style>
+  div {
+    width: 100px;
+    height: 100px;
+    box-sizing: border-box;
+    box-shadow: 0 0 0 10px inset black;
+  }
+</style>
+<div></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-backgrounds/fieldset-inset-shadow.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>inset box shadow works on fieldset</title>
+<link rel=help href="https://drafts.csswg.org/css-backgrounds/#box-shadow">
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1750276">
+<link rel=author title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel=author title="Mozilla" href="https://mozilla.org">
+<link rel=match href="fieldset-inset-shadow-ref.html">
+<style>
+  fieldset {
+    width: 100px;
+    height: 100px;
+    border: none;
+    margin: 0;
+    box-sizing: border-box;
+    box-shadow: 0 0 0 10px inset black;
+  }
+</style>
+<fieldset></fieldset>
--- a/toolkit/components/nimbus/ExperimentAPI.jsm
+++ b/toolkit/components/nimbus/ExperimentAPI.jsm
@@ -441,18 +441,17 @@ class _ExperimentFeature {
     const branch = ExperimentAPI.activateBranch({ featureId: this.featureId });
     const featureValue = featuresCompat(branch).find(
       ({ featureId }) => featureId === this.featureId
     )?.value;
 
     return {
       ...this.prefGetters,
       ...defaultValues,
-      ...this.getRollout()?.value,
-      ...(featureValue || null),
+      ...(featureValue ? featureValue : this.getRollout()?.value),
       ...userPrefs,
     };
   }
 
   getVariable(variable) {
     const prefName = this.getPreferenceName(variable);
     const prefValue = prefName ? this.prefGetters[variable] : undefined;
 
--- a/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature_getAllVariables.js
+++ b/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature_getAllVariables.js
@@ -23,16 +23,19 @@ async function setupForExperimentFeature
 const FEATURE_ID = "aboutwelcome";
 const TEST_FALLBACK_PREF = "browser.aboutwelcome.screens";
 const FAKE_FEATURE_MANIFEST = {
   variables: {
     screens: {
       type: "json",
       fallbackPref: TEST_FALLBACK_PREF,
     },
+    source: {
+      type: "string",
+    },
   },
 };
 
 add_task(
   async function test_ExperimentFeature_getAllVariables_prefsOverDefaults() {
     const { sandbox } = await setupForExperimentFeature();
 
     const featureInstance = new ExperimentFeature(
@@ -113,16 +116,81 @@ add_task(
 
     Services.prefs.clearUserPref(TEST_FALLBACK_PREF);
     await doExperimentCleanup();
     sandbox.restore();
   }
 );
 
 add_task(
+  async function test_ExperimentFeature_getAllVariables_experimentOverRemote() {
+    Services.prefs.clearUserPref(TEST_FALLBACK_PREF);
+    const { manager } = await setupForExperimentFeature();
+    const { doExperimentCleanup } = ExperimentFakes.enrollmentHelper(
+      undefined,
+      {
+        manager,
+      }
+    );
+    const featureInstance = new ExperimentFeature(
+      FEATURE_ID,
+      FAKE_FEATURE_MANIFEST
+    );
+    const recipe = ExperimentFakes.experiment("aw-experiment", {
+      branch: {
+        slug: "treatment",
+        features: [
+          {
+            featureId: FEATURE_ID,
+            value: { screens: ["test-value"] },
+          },
+        ],
+      },
+    });
+    const rollout = ExperimentFakes.rollout("aw-rollout", {
+      branch: {
+        slug: "treatment",
+        features: [
+          { featureId: FEATURE_ID, value: { screens: [], source: "rollout" } },
+        ],
+      },
+    });
+    // We're using the store in this test we need to wait for it to load
+    await manager.store.ready();
+
+    const rolloutPromise = new Promise(resolve =>
+      featureInstance.onUpdate((feature, reason) => {
+        if (reason === "rollout-updated") {
+          resolve();
+        }
+      })
+    );
+    const experimentPromise = new Promise(resolve =>
+      featureInstance.onUpdate((feature, reason) => {
+        if (reason === "experiment-updated") {
+          resolve();
+        }
+      })
+    );
+    manager.store.addEnrollment(recipe);
+    manager.store.addEnrollment(rollout);
+    await rolloutPromise;
+    await experimentPromise;
+
+    let allVariables = featureInstance.getAllVariables();
+
+    Assert.equal(allVariables.screens.length, 1, "Returns experiment value");
+    Assert.ok(!allVariables.source, "Does not include rollout value");
+
+    await doExperimentCleanup();
+    cleanupStorePrefCache();
+  }
+);
+
+add_task(
   async function test_ExperimentFeature_getAllVariables_remoteOverPrefDefaults() {
     const { manager } = await setupForExperimentFeature();
     const featureInstance = new ExperimentFeature(
       FEATURE_ID,
       FAKE_FEATURE_MANIFEST
     );
     const rollout = ExperimentFakes.rollout("foo-aw", {
       branch: {
--- a/toolkit/components/telemetry/app/ClientID.jsm
+++ b/toolkit/components/telemetry/app/ClientID.jsm
@@ -145,59 +145,40 @@ var ClientIDImpl = {
     // If there's a removal in progress, let's wait for it
     await this._removeClientIdTask;
 
     // Try to load the client id from the DRS state file.
     let hasCurrentClientID = false;
     try {
       let state = await IOUtils.readJSON(gStateFilePath);
       if (state) {
-        try {
-          if (Services.prefs.prefHasUserValue(PREF_CACHED_CLIENTID)) {
-            let cachedID = Services.prefs.getStringPref(
-              PREF_CACHED_CLIENTID,
-              null
-            );
-            if (cachedID && cachedID != state.clientID) {
-              Services.telemetry.scalarAdd(
-                "telemetry.loaded_client_id_doesnt_match_pref",
-                1
-              );
-            }
-          }
-        } catch (e) {
-          // This data collection's not that important.
-        }
         hasCurrentClientID = this.updateClientID(state.clientID);
         if (hasCurrentClientID) {
           this._log.trace(`_doLoadClientID: Client IDs loaded from state.`);
           return {
             clientID: this._clientID,
           };
         }
       }
     } catch (e) {
-      Services.telemetry.scalarAdd("telemetry.state_file_read_errors", 1);
       // fall through to next option
     }
 
     // Absent or broken state file? Check prefs as last resort.
     if (!hasCurrentClientID) {
       const cachedID = this.getCachedClientID();
       // Calling `updateClientID` with `null` logs an error, which breaks tests.
       if (cachedID) {
-        Services.telemetry.scalarAdd("telemetry.using_pref_client_id", 1);
         hasCurrentClientID = this.updateClientID(cachedID);
       }
     }
 
     // We're missing the ID from the DRS state file and prefs.
     // Generate a new one.
     if (!hasCurrentClientID) {
-      Services.telemetry.scalarSet("telemetry.generated_new_client_id", true);
       this.updateClientID(CommonUtils.generateUUID());
     }
     this._saveClientIdTask = this._saveClientID();
 
     // Wait on persisting the id. Otherwise failure to save the ID would result in
     // the client creating and subsequently sending multiple IDs to the server.
     // This would appear as multiple clients submitting similar data, which would
     // result in orphaning.
@@ -221,18 +202,16 @@ var ClientIDImpl = {
         clientID: this._clientID,
       };
       await IOUtils.makeDirectory(gDatareportingPath);
       await IOUtils.writeJSON(gStateFilePath, obj, {
         tmpPath: `${gStateFilePath}.tmp`,
       });
       this._saveClientIdTask = null;
     } catch (ex) {
-      Services.telemetry.scalarAdd("telemetry.state_file_save_errors", 1);
-
       if (!(ex instanceof DOMException) || ex.name !== "AbortError") {
         throw ex;
       }
     }
   },
 
   /**
    * This returns a promise resolving to the the stable client ID we use for
@@ -336,17 +315,16 @@ var ClientIDImpl = {
     await this._saveClientIdTask;
 
     // Remove the client-id-containing state file from disk
     await IOUtils.remove(gStateFilePath);
   },
 
   async removeClientID() {
     this._log.trace("removeClientID");
-    Services.telemetry.scalarAdd("telemetry.removed_client_ids", 1);
 
     // Wait for the removal.
     // Asynchronous calls to getClientID will also be blocked on this.
     this._removeClientIdTask = this._doRemoveClientID();
     let clear = () => (this._removeClientIdTask = null);
     this._removeClientIdTask.then(clear, clear);
 
     await this._removeClientIdTask;
--- a/toolkit/crashreporter/CrashAnnotations.yaml
+++ b/toolkit/crashreporter/CrashAnnotations.yaml
@@ -617,16 +617,22 @@ MacMemoryPressureSysctl:
   type: integer
 
 MacAvailableMemorySysctl:
   description: >
     The value of the available memory sysctl 'kern.memorystatus_level'.
     Expected to be a percentage integer value.
   type: integer
 
+LinuxUnderMemoryPressure:
+  description: >
+    Set to true if the memory pressure watcher was under memory pressure when
+    the crash occurred.
+  type: boolean
+
 LauncherProcessState:
   description: >
     Launcher process enabled state. The integer value of this annotation must
     match with one of the values in the
     mozilla::LauncherRegistryInfo::EnableState enum
   type: integer
 
 LowPhysicalMemoryEvents:
--- a/toolkit/mozapps/extensions/content/view-controller.js
+++ b/toolkit/mozapps/extensions/content/view-controller.js
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-/* import-globals-from ../../../content/customElements.js */
+/* import-globals-from /toolkit/content/customElements.js */
 /* import-globals-from aboutaddonsCommon.js */
 /* exported loadView */
 
 const { AddonManager } = ChromeUtils.import(
   "resource://gre/modules/AddonManager.jsm"
 );
 
 ChromeUtils.defineModuleGetter(
--- a/toolkit/mozapps/update/content/updateElevation.js
+++ b/toolkit/mozapps/update/content/updateElevation.js
@@ -3,17 +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/. */
 
 /* This is temporary until bug 1521632 is fixed */
 
 "use strict";
 
-/* import-globals-from ../../../content/contentAreaUtils.js */
+/* import-globals-from /toolkit/content/contentAreaUtils.js */
 
 const gUpdateElevationDialog = {
   openUpdateURL(event) {
     if (event.button == 0) {
       openURL(event.target.getAttribute("url"));
     }
   },
   getAUSString(key, strings) {
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/globals.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/globals.js
@@ -115,16 +115,18 @@ GlobalsForNode.prototype = {
       if (!match) {
         continue;
       }
 
       let filePath = match[1].trim();
 
       if (!path.isAbsolute(filePath)) {
         filePath = path.resolve(this.dirname, filePath);
+      } else {
+        filePath = path.join(helpers.rootDir, filePath);
       }
       globals = globals.concat(module.exports.getGlobalsForFile(filePath));
     }
 
     return globals;
   },
 
   ExpressionStatement(node, parents, globalScope) {
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -91,16 +91,18 @@
 
 #include "nsIRandomGenerator.h"
 
 #include "ContentChild.h"
 #include "nsXULAppAPI.h"
 #include "nsPIDOMWindow.h"
 #include "ExternalHelperAppChild.h"
 
+#include "mozilla/dom/nsHTTPSOnlyUtils.h"
+
 #ifdef XP_WIN
 #  include "nsWindowsHelpers.h"
 #endif
 
 #include "mozilla/Components.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ipc/URIUtils.h"
@@ -1736,16 +1738,27 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
   nsresult rv;
   nsAutoCString MIMEType;
   if (mMimeInfo) {
     mMimeInfo->GetMIMEType(MIMEType);
   }
   // Now get the URI
   if (aChannel) {
     aChannel->GetURI(getter_AddRefs(mSourceUrl));
+    // HTTPS-Only/HTTPS-FirstMode tries to upgrade connections to https. Once
+    // the download is in progress we set that flag so that timeout counter
+    // measures do not kick in.
+    nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
+    bool isPrivateWin = loadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
+    if (nsHTTPSOnlyUtils::IsHttpsOnlyModeEnabled(isPrivateWin) ||
+        nsHTTPSOnlyUtils::IsHttpsFirstModeEnabled(isPrivateWin)) {
+      uint32_t httpsOnlyStatus = loadInfo->GetHttpsOnlyStatus();
+      httpsOnlyStatus |= nsILoadInfo::HTTPS_ONLY_DOWNLOAD_IN_PROGRESS;
+      loadInfo->SetHttpsOnlyStatus(httpsOnlyStatus);
+    }
   }
 
   if (!mForceSave && StaticPrefs::browser_download_enable_spam_prevention() &&
       IsDownloadSpam(aChannel)) {
     RecordDownloadTelemetry(aChannel, "spam");
     return NS_OK;
   }
 
--- a/widget/windows/nsAppShell.cpp
+++ b/widget/windows/nsAppShell.cpp
@@ -529,17 +529,17 @@ nsresult nsAppShell::Init() {
       wc.cbClsExtra = 0;
       wc.cbWndExtra = 0;
       wc.hInstance = module;
       wc.hIcon = nullptr;
       wc.hCursor = nullptr;
       wc.hbrBackground = (HBRUSH) nullptr;
       wc.lpszMenuName = (LPCWSTR) nullptr;
       wc.lpszClassName = kWindowClass;
-      ATOM wcA = RegisterClassW(&wc);
+      [[maybe_unused]] ATOM wcA = RegisterClassW(&wc);
       MOZ_DIAGNOSTIC_ASSERT(wcA, "RegisterClassW for EventWindowClass failed");
     }
 
     mEventWnd = CreateWindowW(kWindowClass, L"nsAppShell:EventWindow", 0, 0, 0,
                               10, 10, HWND_MESSAGE, nullptr, module, nullptr);
     MOZ_DIAGNOSTIC_ASSERT(mEventWnd, "CreateWindowW for EventWindow failed");
     NS_ENSURE_STATE(mEventWnd);
   } else if (XRE_IsContentProcess() && !IsWin32kLockedDown()) {
--- a/xpcom/base/AvailableMemoryWatcherLinux.cpp
+++ b/xpcom/base/AvailableMemoryWatcherLinux.cpp
@@ -35,16 +35,17 @@ class nsAvailableMemoryWatcher final : p
   void HandleLowMemory();
   void MaybeHandleHighMemory();
 
  private:
   ~nsAvailableMemoryWatcher() = default;
   void StartPolling(const MutexAutoLock&);
   void StopPolling(const MutexAutoLock&);
   void ShutDown(const MutexAutoLock&);
+  void UpdateCrashAnnotation(const MutexAutoLock&);
   static bool IsMemoryLow();
 
   nsCOMPtr<nsITimer> mTimer;
   nsCOMPtr<nsIThread> mThread;
 
   bool mPolling;
   bool mUnderMemoryPressure;
 
@@ -84,16 +85,19 @@ nsresult nsAvailableMemoryWatcher::Init(
     NS_WARNING("Couldn't make a thread for nsAvailableMemoryWatcher.");
     // In this scenario we can't poll for low memory, since we can't dispatch
     // to our memory watcher thread.
     return rv;
   }
   mThread = thread;
 
   MutexAutoLock lock(mMutex);
+  // Set the crash annotation to its initial state.
+  UpdateCrashAnnotation(lock);
+
   StartPolling(lock);
 
   return NS_OK;
 }
 
 already_AddRefed<nsAvailableMemoryWatcherBase> CreateAvailableMemoryWatcher() {
   RefPtr watcher(new nsAvailableMemoryWatcher);
 
@@ -177,37 +181,45 @@ nsAvailableMemoryWatcher::Notify(nsITime
   }
   return NS_OK;
 }
 
 void nsAvailableMemoryWatcher::HandleLowMemory() {
   MutexAutoLock lock(mMutex);
   if (!mUnderMemoryPressure) {
     mUnderMemoryPressure = true;
+    UpdateCrashAnnotation(lock);
     // Poll more frequently under memory pressure.
     StartPolling(lock);
   }
   UpdateLowMemoryTimeStamp();
   // We handle low memory offthread, but we want to unload
   // tabs only from the main thread, so we will dispatch this
   // back to the main thread.
   NS_DispatchToMainThread(NS_NewRunnableFunction(
       "nsAvailableMemoryWatcher::OnLowMemory",
       [self = RefPtr{this}]() { self->mTabUnloader->UnloadTabAsync(); }));
 }
 
+void nsAvailableMemoryWatcher::UpdateCrashAnnotation(const MutexAutoLock&) {
+  CrashReporter::AnnotateCrashReport(
+      CrashReporter::Annotation::LinuxUnderMemoryPressure,
+      mUnderMemoryPressure);
+}
+
 // If memory is not low, we may need to dispatch an
 // event for it if we have been under memory pressure.
 // We can also adjust our polling interval.
 void nsAvailableMemoryWatcher::MaybeHandleHighMemory() {
   MutexAutoLock lock(mMutex);
   if (mUnderMemoryPressure) {
     RecordTelemetryEventOnHighMemory();
     NS_NotifyOfEventualMemoryPressure(MemoryPressureState::NoPressure);
     mUnderMemoryPressure = false;
+    UpdateCrashAnnotation(lock);
   }
   StartPolling(lock);
 }
 
 // When we change the polling interval, we will need to restart the timer
 // on the new interval.
 void nsAvailableMemoryWatcher::StartPolling(const MutexAutoLock& aLock) {
   uint32_t pollingInterval = mUnderMemoryPressure