Merge mozilla-central to autoland. a=merge CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Thu, 04 Apr 2019 07:39:40 +0300
changeset 467904 5e7dea1ca822eaca4e56534d90c29e12df3fd471
parent 467903 78745e4537faac3932ae7cf944ceecc73288aa95 (current diff)
parent 467900 a5ba6ffec2a7b6431404bf1d87a67b90a6fe8a35 (diff)
child 467905 e835fbf63aeac40e8682fb797c06abc5616f58bb
push id35813
push useraiakab@mozilla.com
push dateThu, 04 Apr 2019 16:07:30 +0000
treeherdermozilla-central@aa623df2ae8f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland. a=merge CLOSED TREE
toolkit/mozapps/extensions/internal/LightweightThemePersister.jsm
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -709,29 +709,29 @@ name = "crossbeam-utils"
 version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cssparser"
-version = "0.25.0"
+version = "0.25.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cssparser-macros"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1171,17 +1171,17 @@ dependencies = [
  "zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckoservo"
 version = "0.0.1"
 dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "nsstring 0.1.0",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.21.0",
@@ -1658,17 +1658,17 @@ dependencies = [
  "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "malloc_size_of"
 version = "0.0.1"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "hashglobe 0.1.0",
  "selectors 0.21.0",
  "servo_arc 0.1.1",
  "smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2478,17 +2478,17 @@ dependencies = [
  "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "selectors"
 version = "0.21.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_arc 0.1.1",
@@ -2700,17 +2700,17 @@ name = "style"
 version = "0.0.1"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bindgen 0.49.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "fallible 0.0.1",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "hashglobe 0.1.0",
  "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2762,32 +2762,32 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.21.0",
  "servo_arc 0.1.1",
  "to_shmem 0.0.1",
  "to_shmem_derive 0.0.1",
 ]
 
 [[package]]
 name = "stylo_tests"
 version = "0.0.1"
 dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "geckoservo 0.0.1",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.21.0",
@@ -2944,17 +2944,17 @@ dependencies = [
  "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "to_shmem"
 version = "0.0.1"
 dependencies = [
- "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_arc 0.1.1",
  "smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "to_shmem_derive"
@@ -3570,17 +3570,17 @@ dependencies = [
 "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2af0e75710d6181e234c8ecc79f14a97907850a541b13b0be1dd10992f2e4620"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
 "checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a"
-"checksum cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "730363a45c4e248d4f21d3e5c1156d1a9cdec0855056c0d9539e814bc59865c3"
+"checksum cssparser 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ba1ab4e1814be64bf6b6064ff532db0e34087f11b37706d6c96a21d32478761d"
 "checksum cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5383ae18dbfdeb569ed62019f5bddb2a95cd2d3833313c475a0d014777805"
 "checksum cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b6557bdb1dc9647eae1cf7f5601b14cd45fc3c7ccf2df618387416fe542da6ea"
 "checksum cstr-macros 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0472c17c83d3ec1af32fb6ee2b3ad56ae0b6e69355d63d1d30602055c34324a8"
 "checksum cubeb 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "db3f0df2ad5cb453126364a77921466ba6c1034e8bd9247f326cdb31430dbc2a"
 "checksum cubeb-backend 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "442cd5cfb980ff62730525278ce320d9b2ff635b725857ad3176832664262fec"
 "checksum cubeb-core 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0161f9327864922ba7a172c90bd86bc9094938433eca415e2c75629954045022"
 "checksum cubeb-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba7540c17b90159cf7d7854da370998ff0560d9b90e2c9290bb588afa0edf95"
 "checksum darling 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f593353cad5af2df6d54810de2b61aa8acba5b5fbc70b0d75e7cc5bdd80aca73"
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -177,16 +177,18 @@ pref("app.update.service.enabled", true)
 pref("extensions.update.enabled", true);
 pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
 pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
 pref("extensions.update.interval", 86400);  // Check for updates to Extensions and
                                             // Themes every day
 
 pref("extensions.webextensions.themes.icons.buttons", "back,forward,reload,stop,bookmark_star,bookmark_menu,downloads,home,app_menu,cut,copy,paste,new_window,new_private_window,save_page,print,history,full_screen,find,options,addons,developer,synced_tabs,open_file,sidebars,share_page,subscribe,text_encoding,email_link,forget,pocket");
 
+pref("lightweightThemes.getMoreURL", "https://addons.mozilla.org/%LOCALE%/firefox/themes");
+
 #if defined(MOZ_WIDEVINE_EME)
 pref("browser.eme.ui.enabled", true);
 #else
 pref("browser.eme.ui.enabled", false);
 #endif
 
 // UI tour experience.
 pref("browser.uitour.enabled", true);
--- a/browser/base/content/test/general/browser_compacttheme.js
+++ b/browser/base/content/test/general/browser_compacttheme.js
@@ -1,17 +1,16 @@
 /*
  * Testing changes for compact themes.
  * A special stylesheet should be added to the browser.xul document
  * when the firefox-compact-light and firefox-compact-dark lightweight
  * themes are applied.
  */
 
 const DEFAULT_THEME = "default-theme@mozilla.org";
-const PREF_LWTHEME_USED_THEMES = "lightweightThemes.usedThemes";
 const COMPACT_LIGHT_ID = "firefox-compact-light@mozilla.org";
 const COMPACT_DARK_ID = "firefox-compact-dark@mozilla.org";
 const {AddonManager} = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
 
 async function selectTheme(id) {
   let theme = await AddonManager.getAddonByID(id || DEFAULT_THEME);
   await theme.enable();
 }
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -299,17 +299,17 @@ let ACTORS = {
 };
 
 (function earlyBlankFirstPaint() {
   if (!Services.prefs.getBoolPref("browser.startup.blankWindow", false))
     return;
 
   // Until bug 1450626 and bug 1488384 are fixed, skip the blank window when
   // using a non-default theme.
-  if (Services.prefs.getCharPref("lightweightThemes.selectedThemeID", "") !=
+  if (Services.prefs.getCharPref("extensions.activeThemeID", "") !=
         "default-theme@mozilla.org")
     return;
 
   let store = Services.xulStore;
   let getValue = attr =>
     store.getValue(AppConstants.BROWSER_CHROME_URL, "main-window", attr);
   let width = getValue("width");
   let height = getValue("height");
@@ -2240,26 +2240,16 @@ BrowserGlue.prototype = {
       return;
     }
 
     if (currentUIVersion >= UI_VERSION)
       return;
 
     let xulStore = Services.xulStore;
 
-    if (currentUIVersion < 51) {
-      // Switch to compact UI density if the user is using a formerly compact
-      // dark or light theme.
-      let currentTheme = Services.prefs.getCharPref("lightweightThemes.selectedThemeID", "");
-      if (currentTheme == "firefox-compact-dark@mozilla.org" ||
-          currentTheme == "firefox-compact-light@mozilla.org") {
-        Services.prefs.setIntPref("browser.uidensity", 1);
-      }
-    }
-
     if (currentUIVersion < 52) {
       // Keep old devtools log persistence behavior after splitting netmonitor and
       // webconsole prefs (bug 1307881).
       if (Services.prefs.getBoolPref("devtools.webconsole.persistlog", false)) {
         Services.prefs.setBoolPref("devtools.netmonitor.persistlog", true);
       }
     }
 
@@ -2286,34 +2276,16 @@ BrowserGlue.prototype = {
       // Now, the sidebarcommand always indicates the last opened sidebar, and we
       // correctly persist the checked attribute to indicate whether or not the
       // sidebar was open. We should set the checked attribute in case it wasn't:
       if (xulStore.getValue(BROWSER_DOCURL, "sidebar-box", "sidebarcommand")) {
         xulStore.setValue(BROWSER_DOCURL, "sidebar-box", "checked", "true");
       }
     }
 
-    if (currentUIVersion < 57) {
-      // Beginning Firefox 57, the theme accent color is shown as highlight
-      // on top of tabs. This didn't look too good with the "A Web Browser Renaissance"
-      // theme, so we're changing its accent color.
-      let lwthemePrefs = Services.prefs.getBranch("lightweightThemes.");
-      if (lwthemePrefs.prefHasUserValue("usedThemes")) {
-        try {
-          let usedThemes = lwthemePrefs.getStringPref("usedThemes");
-          usedThemes = JSON.parse(usedThemes);
-          let renaissanceTheme = usedThemes.find(theme => theme.id == "recommended-1");
-          if (renaissanceTheme) {
-            renaissanceTheme.accentcolor = "#834d29";
-            lwthemePrefs.setStringPref("usedThemes", JSON.stringify(usedThemes));
-          }
-        } catch (e) { /* Don't panic if this pref isn't what we expect it to be. */ }
-      }
-    }
-
     if (currentUIVersion < 58) {
       // With Firefox 57, we are doing a one time reset of the geo prefs due to bug 1413652
       Services.prefs.clearUserPref("browser.search.countryCode");
       Services.prefs.clearUserPref("browser.search.region");
       Services.prefs.clearUserPref("browser.search.isUS");
     }
 
     if (currentUIVersion < 59) {
--- a/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
+++ b/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
@@ -4,18 +4,16 @@
 
 "use strict";
 
 const DEFAULT_THEME_ID = "default-theme@mozilla.org";
 const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
 const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
 
 add_task(async function() {
-  Services.prefs.clearUserPref("lightweightThemes.usedThemes");
-
   await startCustomizing();
   // Check restore defaults button is disabled.
   ok(document.getElementById("customization-reset-button").disabled,
      "Reset button should start out disabled");
 
   let themesButton = document.getElementById("customization-lwtheme-button");
   let themesButtonIcon = document.getAnonymousElementByAttribute(themesButton,
       "class", "button-icon");
@@ -127,17 +125,16 @@ add_task(async function() {
 
   // check that "Restore Defaults" button resets theme
   await gCustomizeMode.reset();
 
   defaultTheme = await AddonManager.getAddonByID(DEFAULT_THEME_ID);
   is(defaultTheme.isActive, true, "Current theme reset to default");
 
   await endCustomizing();
-  Services.prefs.setCharPref("lightweightThemes.usedThemes", "[]");
   await startCustomizing();
   popupShownPromise = popupShown(popup);
   EventUtils.synthesizeMouseAtCenter(themesButton, {});
   info("Clicked on themes button a fifth time");
   await popupShownPromise;
   header = document.getElementById("customization-lwtheme-menu-header");
   is(header.hidden, false, "Header should never be hidden");
   let themeNode = header.nextElementSibling;
@@ -150,11 +147,9 @@ add_task(async function() {
 
   themeNode = themeNode.nextElementSibling;
   is(themeNode.theme.id, DARK_THEME_ID, "The third theme should be the Dark theme");
   is(themeNode.hidden, false, "The dark theme should never be hidden");
 });
 
 add_task(async function asyncCleanup() {
   await endCustomizing();
-
-  Services.prefs.clearUserPref("lightweightThemes.usedThemes");
 });
--- a/browser/components/customizableui/test/browser_lwt_telemetry.js
+++ b/browser/components/customizableui/test/browser_lwt_telemetry.js
@@ -3,18 +3,16 @@
 add_task(function clearTelemetry() {
   Services.telemetry.clearEvents();
 });
 
 add_task(async function testCustomize() {
   let getMoreURL = "about:blank#getMoreThemes";
 
   // Reset the theme prefs to ensure they haven't been messed with.
-  Services.prefs.clearUserPref("lightweightThemes.recommendedThemes");
-  Services.prefs.clearUserPref("lightweightThemes.usedThemes");
   await SpecialPowers.pushPrefEnv({set: [
     ["lightweightThemes.getMoreURL", getMoreURL],
   ]});
 
   await startCustomizing();
 
   // Find the footer buttons to test.
   let footerRow = document.getElementById("customization-lwtheme-menu-footer");
@@ -49,18 +47,14 @@ add_task(async function testCustomize() 
     .map(relatedEvent => relatedEvent.slice(2, 6));
 
   // Events are now [method, object, value, extra] as expected.
   Assert.deepEqual(relatedEvents, [
     ["link", "customize", "manageThemes"],
     ["link", "customize", "getThemes"],
   ], "The events are recorded correctly");
 
-  // Reset the theme prefs to leave them in a clean state.
-  Services.prefs.clearUserPref("lightweightThemes.recommendedThemes");
-  Services.prefs.clearUserPref("lightweightThemes.usedThemes");
-
   // Wait for customize mode to be re-entered now that the customize tab is
   // active. This is needed for endCustomizing() to work properly.
   await TestUtils.waitForCondition(
     () => document.documentElement.getAttribute("customizing") == "true");
   await endCustomizing();
 });
--- a/dom/localstorage/ActorsChild.cpp
+++ b/dom/localstorage/ActorsChild.cpp
@@ -16,17 +16,17 @@ namespace mozilla {
 namespace dom {
 
 /*******************************************************************************
  * LSDatabaseChild
  ******************************************************************************/
 
 LSDatabaseChild::LSDatabaseChild(LSDatabase* aDatabase) : mDatabase(aDatabase) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
+  MOZ_ASSERT(aDatabase);
 
   MOZ_COUNT_CTOR(LSDatabaseChild);
 }
 
 LSDatabaseChild::~LSDatabaseChild() {
   AssertIsOnOwningThread();
 
   MOZ_COUNT_DTOR(LSDatabaseChild);
@@ -73,29 +73,29 @@ PBackgroundLSSnapshotChild* LSDatabaseCh
     const nsString& aDocumentURI, const bool& aIncreasePeakUsage,
     const int64_t& aRequestedSize, const int64_t& aMinSize,
     LSSnapshotInitInfo* aInitInfo) {
   MOZ_CRASH("PBackgroundLSSnapshotChild actor should be manually constructed!");
 }
 
 bool LSDatabaseChild::DeallocPBackgroundLSSnapshotChild(
     PBackgroundLSSnapshotChild* aActor) {
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
+  MOZ_ASSERT(aActor);
 
   delete aActor;
   return true;
 }
 
 /*******************************************************************************
  * LSObserverChild
  ******************************************************************************/
 
 LSObserverChild::LSObserverChild(LSObserver* aObserver) : mObserver(aObserver) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObserver);
+  MOZ_ASSERT(aObserver);
 
   MOZ_COUNT_CTOR(LSObserverChild);
 }
 
 LSObserverChild::~LSObserverChild() {
   AssertIsOnOwningThread();
 
   MOZ_COUNT_DTOR(LSObserverChild);
@@ -174,42 +174,44 @@ bool LSRequestChild::Finishing() const {
 
 void LSRequestChild::ActorDestroy(ActorDestroyReason aWhy) {
   AssertIsOnOwningThread();
 }
 
 mozilla::ipc::IPCResult LSRequestChild::Recv__delete__(
     const LSRequestResponse& aResponse) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mCallback);
+  MOZ_ASSERT(mCallback);
 
   mCallback->OnResponse(aResponse);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult LSRequestChild::RecvReady() {
   AssertIsOnOwningThread();
 
   mFinishing = true;
 
-  SendFinish();
+  // We only expect this to return false if the channel has been closed, but
+  // PBackground's channel never gets shutdown.
+  MOZ_ALWAYS_TRUE(SendFinish());
 
   return IPC_OK();
 }
 
 /*******************************************************************************
  * LSSimpleRequestChild
  ******************************************************************************/
 
 LSSimpleRequestChild::LSSimpleRequestChild(
     LSSimpleRequestChildCallback* aCallback)
     : mCallback(aCallback) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aCallback);
+  MOZ_ASSERT(aCallback);
 
   MOZ_COUNT_CTOR(LSSimpleRequestChild);
 }
 
 LSSimpleRequestChild::~LSSimpleRequestChild() {
   AssertIsOnOwningThread();
 
   MOZ_COUNT_DTOR(LSSimpleRequestChild);
@@ -229,17 +231,17 @@ mozilla::ipc::IPCResult LSSimpleRequestC
 }
 
 /*******************************************************************************
  * LSSnapshotChild
  ******************************************************************************/
 
 LSSnapshotChild::LSSnapshotChild(LSSnapshot* aSnapshot) : mSnapshot(aSnapshot) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aSnapshot);
+  MOZ_ASSERT(aSnapshot);
 
   MOZ_COUNT_CTOR(LSSnapshotChild);
 }
 
 LSSnapshotChild::~LSSnapshotChild() {
   AssertIsOnOwningThread();
 
   MOZ_COUNT_DTOR(LSSnapshotChild);
--- a/dom/localstorage/ActorsParent.cpp
+++ b/dom/localstorage/ActorsParent.cpp
@@ -34,32 +34,33 @@
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/ipc/PBackgroundParent.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/Logging.h"
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
+#include "nsExceptionHandler.h"
 #include "nsInterfaceHashtable.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsISimpleEnumerator.h"
 #include "nsNetUtil.h"
 #include "nsRefPtrHashtable.h"
 #include "ReportInternalError.h"
 
 #define DISABLE_ASSERTS_FOR_FUZZING 0
 
 #if DISABLE_ASSERTS_FOR_FUZZING
 #  define ASSERT_UNLESS_FUZZING(...) \
     do {                             \
     } while (0)
 #else
-#  define ASSERT_UNLESS_FUZZING(...) MOZ_DIAGNOSTIC_ASSERT(false, __VA_ARGS__)
+#  define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
 #endif
 
 #define LS_LOG_TEST() MOZ_LOG_TEST(GetLocalStorageLogger(), LogLevel::Info)
 #define LS_LOG(_args) MOZ_LOG(GetLocalStorageLogger(), LogLevel::Info, _args)
 
 #if defined(MOZ_WIDGET_ANDROID)
 #  define LS_MOBILE
 #endif
@@ -248,16 +249,30 @@ const uint32_t kPreparedDatastoreTimeout
  */
 #define WEB_APPS_STORE_FILE_NAME "webappsstore.sqlite"
 
 // Shadow database Write Ahead Log's maximum size is 512KB
 const uint32_t kShadowMaxWALSize = 512 * 1024;
 
 const uint32_t kShadowJournalSizeLimit = kShadowMaxWALSize * 3;
 
+/**
+ * Automatically crash the browser if LocalStorage shutdown takes this long.
+ * We've chosen a value that is longer than the value for QuotaManager shutdown
+ * timer which is currently set to 30 seconds.  We've also chosen a value that
+ * is long enough that it is unlikely for the problem to be falsely triggered by
+ * slow system I/O.  We've also chosen a value long enough so that automated
+ * tests should time out and fail if LocalStorage shutdown hangs.  Also, this
+ * value is long enough so that testers can notice the LocalStorage shutdown
+ * hang; we want to know about the hangs, not hide them.  On the other hand this
+ * value is less than 60 seconds which is used by nsTerminator to crash a hung
+ * main process.
+ */
+#define SHUTDOWN_TIMEOUT_MS 50000
+
 bool IsOnConnectionThread();
 
 void AssertIsOnConnectionThread();
 
 /*******************************************************************************
  * SQLite functions
  ******************************************************************************/
 
@@ -268,17 +283,17 @@ int32_t MakeSchemaVersion(uint32_t aMajo
 
 nsCString GetArchivedOriginHashKey(const nsACString& aOriginSuffix,
                                    const nsACString& aOriginNoSuffix) {
   return aOriginSuffix + NS_LITERAL_CSTRING(":") + aOriginNoSuffix;
 }
 
 nsresult CreateTables(mozIStorageConnection* aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   // Table `database`
   nsresult rv = aConnection->ExecuteSimpleSQL(
       NS_LITERAL_CSTRING("CREATE TABLE database"
                          "( origin TEXT NOT NULL"
                          ", usage INTEGER NOT NULL DEFAULT 0"
                          ", last_vacuum_time INTEGER NOT NULL DEFAULT 0"
                          ", last_analyze_time INTEGER NOT NULL DEFAULT 0"
@@ -305,17 +320,17 @@ nsresult CreateTables(mozIStorageConnect
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult UpgradeSchemaFrom1_0To2_0(mozIStorageConnection* aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
       "ALTER TABLE database ADD COLUMN usage INTEGER NOT NULL DEFAULT 0;"));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
@@ -331,17 +346,17 @@ nsresult UpgradeSchemaFrom1_0To2_0(mozIS
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult SetDefaultPragmas(mozIStorageConnection* aConnection) {
   MOZ_ASSERT(!NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   nsresult rv = aConnection->ExecuteSimpleSQL(
       NS_LITERAL_CSTRING("PRAGMA synchronous = FULL;"));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
 #ifndef LS_MOBILE
@@ -359,20 +374,20 @@ nsresult SetDefaultPragmas(mozIStorageCo
   return NS_OK;
 }
 
 nsresult CreateStorageConnection(nsIFile* aDBFile, nsIFile* aUsageFile,
                                  const nsACString& aOrigin,
                                  mozIStorageConnection** aConnection,
                                  bool* aRemovedUsageFile) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDBFile);
-  MOZ_DIAGNOSTIC_ASSERT(aUsageFile);
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
-  MOZ_DIAGNOSTIC_ASSERT(aRemovedUsageFile);
+  MOZ_ASSERT(aDBFile);
+  MOZ_ASSERT(aUsageFile);
+  MOZ_ASSERT(aConnection);
+  MOZ_ASSERT(aRemovedUsageFile);
 
   // aRemovedUsageFile has to be initialized even when this method fails.
   *aRemovedUsageFile = false;
 
   nsresult rv;
 
   nsCOMPtr<mozIStorageService> ss =
       do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
@@ -455,19 +470,18 @@ nsresult CreateStorageConnection(nsIFile
         connection, false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
 
     if (newDatabase) {
       rv = CreateTables(connection);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
-      MOZ_DIAGNOSTIC_ASSERT(
-          NS_SUCCEEDED(connection->GetSchemaVersion(&schemaVersion)));
-      MOZ_DIAGNOSTIC_ASSERT(schemaVersion == kSQLiteSchemaVersion);
+      MOZ_ASSERT(NS_SUCCEEDED(connection->GetSchemaVersion(&schemaVersion)));
+      MOZ_ASSERT(schemaVersion == kSQLiteSchemaVersion);
 
       nsCOMPtr<mozIStorageStatement> stmt;
       nsresult rv = connection->CreateStatement(
           NS_LITERAL_CSTRING("INSERT INTO database (origin) "
                              "VALUES (:origin)"),
           getter_AddRefs(stmt));
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
@@ -502,17 +516,17 @@ nsresult CreateStorageConnection(nsIFile
         }
 
         rv = connection->GetSchemaVersion(&schemaVersion);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
 
-      MOZ_DIAGNOSTIC_ASSERT(schemaVersion == kSQLiteSchemaVersion);
+      MOZ_ASSERT(schemaVersion == kSQLiteSchemaVersion);
     }
 
     rv = transaction.Commit();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     if (newDatabase) {
@@ -524,20 +538,20 @@ nsresult CreateStorageConnection(nsIFile
       }
 
       int64_t fileSize;
       rv = aDBFile->GetFileSize(&fileSize);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
-      MOZ_DIAGNOSTIC_ASSERT(fileSize > 0);
+      MOZ_ASSERT(fileSize > 0);
 
       PRTime vacuumTime = PR_Now();
-      MOZ_DIAGNOSTIC_ASSERT(vacuumTime);
+      MOZ_ASSERT(vacuumTime);
 
       nsCOMPtr<mozIStorageStatement> vacuumTimeStmt;
       rv = connection->CreateStatement(
           NS_LITERAL_CSTRING("UPDATE database "
                              "SET last_vacuum_time = :time"
                              ", last_vacuum_size = :size;"),
           getter_AddRefs(vacuumTimeStmt));
       if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -565,20 +579,19 @@ nsresult CreateStorageConnection(nsIFile
 
   connection.forget(aConnection);
   return NS_OK;
 }
 
 nsresult GetStorageConnection(const nsAString& aDatabaseFilePath,
                               mozIStorageConnection** aConnection) {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aDatabaseFilePath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(
-      StringEndsWith(aDatabaseFilePath, NS_LITERAL_STRING(".sqlite")));
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(!aDatabaseFilePath.IsEmpty());
+  MOZ_ASSERT(StringEndsWith(aDatabaseFilePath, NS_LITERAL_STRING(".sqlite")));
+  MOZ_ASSERT(aConnection);
 
   nsCOMPtr<nsIFile> databaseFile;
   nsresult rv =
       NS_NewLocalFile(aDatabaseFilePath, false, getter_AddRefs(databaseFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -610,18 +623,18 @@ nsresult GetStorageConnection(const nsAS
   }
 
   connection.forget(aConnection);
   return NS_OK;
 }
 
 nsresult GetArchiveFile(const nsAString& aStoragePath, nsIFile** aArchiveFile) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aStoragePath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aArchiveFile);
+  MOZ_ASSERT(!aStoragePath.IsEmpty());
+  MOZ_ASSERT(aArchiveFile);
 
   nsCOMPtr<nsIFile> archiveFile;
   nsresult rv =
       NS_NewLocalFile(aStoragePath, false, getter_AddRefs(archiveFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -632,31 +645,29 @@ nsresult GetArchiveFile(const nsAString&
 
   archiveFile.forget(aArchiveFile);
   return NS_OK;
 }
 
 nsresult CreateArchiveStorageConnection(const nsAString& aStoragePath,
                                         mozIStorageConnection** aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aStoragePath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(!aStoragePath.IsEmpty());
+  MOZ_ASSERT(aConnection);
 
   nsCOMPtr<nsIFile> archiveFile;
   nsresult rv = GetArchiveFile(aStoragePath, getter_AddRefs(archiveFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   // QuotaManager ensures this file always exists.
-  bool exists;
-  MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(archiveFile->Exists(&exists)));
-  MOZ_DIAGNOSTIC_ASSERT(exists);
-#endif
+  DebugOnly<bool> exists;
+  MOZ_ASSERT(NS_SUCCEEDED(archiveFile->Exists(&exists)));
+  MOZ_ASSERT(exists);
 
   bool isDirectory;
   rv = archiveFile->IsDirectory(&isDirectory);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (isDirectory) {
@@ -692,33 +703,33 @@ nsresult CreateArchiveStorageConnection(
 
   connection.forget(aConnection);
   return NS_OK;
 }
 
 nsresult AttachArchiveDatabase(const nsAString& aStoragePath,
                                mozIStorageConnection* aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aStoragePath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(!aStoragePath.IsEmpty());
+  MOZ_ASSERT(aConnection);
   nsCOMPtr<nsIFile> archiveFile;
 
   nsresult rv = GetArchiveFile(aStoragePath, getter_AddRefs(archiveFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool exists;
   rv = archiveFile->Exists(&exists);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(exists);
+  MOZ_ASSERT(exists);
 #endif
 
   nsString path;
   rv = archiveFile->GetPath(path);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -740,31 +751,31 @@ nsresult AttachArchiveDatabase(const nsA
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult DetachArchiveDatabase(mozIStorageConnection* aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   nsresult rv = aConnection->ExecuteSimpleSQL(
       NS_LITERAL_CSTRING("DETACH DATABASE archive"));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult GetShadowFile(const nsAString& aBasePath, nsIFile** aArchiveFile) {
   MOZ_ASSERT(IsOnIOThread() || IsOnConnectionThread());
-  MOZ_DIAGNOSTIC_ASSERT(!aBasePath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aArchiveFile);
+  MOZ_ASSERT(!aBasePath.IsEmpty());
+  MOZ_ASSERT(aArchiveFile);
 
   nsCOMPtr<nsIFile> archiveFile;
   nsresult rv = NS_NewLocalFile(aBasePath, false, getter_AddRefs(archiveFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = archiveFile->Append(NS_LITERAL_STRING(WEB_APPS_STORE_FILE_NAME));
@@ -773,17 +784,17 @@ nsresult GetShadowFile(const nsAString& 
   }
 
   archiveFile.forget(aArchiveFile);
   return NS_OK;
 }
 
 nsresult SetShadowJournalMode(mozIStorageConnection* aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   // Try enabling WAL mode. This can fail in various circumstances so we have to
   // check the results here.
   NS_NAMED_LITERAL_CSTRING(journalModeQueryStart, "PRAGMA journal_mode = ");
   NS_NAMED_LITERAL_CSTRING(journalModeWAL, "wal");
 
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = aConnection->CreateStatement(
@@ -793,17 +804,17 @@ nsresult SetShadowJournalMode(mozIStorag
   }
 
   bool hasResult;
   rv = stmt->ExecuteStep(&hasResult);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(hasResult);
+  MOZ_ASSERT(hasResult);
 
   nsCString journalMode;
   rv = stmt->GetUTF8String(0, journalMode);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (journalMode.Equals(journalModeWAL)) {
@@ -818,25 +829,25 @@ nsresult SetShadowJournalMode(mozIStorag
     }
 
     bool hasResult;
     rv = stmt->ExecuteStep(&hasResult);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    MOZ_DIAGNOSTIC_ASSERT(hasResult);
+    MOZ_ASSERT(hasResult);
 
     int32_t pageSize;
     rv = stmt->GetInt32(0, &pageSize);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    MOZ_DIAGNOSTIC_ASSERT(pageSize >= 512 && pageSize <= 65536);
+    MOZ_ASSERT(pageSize >= 512 && pageSize <= 65536);
 
     nsAutoCString pageCount;
     pageCount.AppendInt(static_cast<int32_t>(kShadowMaxWALSize / pageSize));
 
     rv = aConnection->ExecuteSimpleSQL(
         NS_LITERAL_CSTRING("PRAGMA wal_autocheckpoint = ") + pageCount);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
@@ -861,18 +872,18 @@ nsresult SetShadowJournalMode(mozIStorag
   }
 
   return NS_OK;
 }
 
 nsresult CreateShadowStorageConnection(const nsAString& aBasePath,
                                        mozIStorageConnection** aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aBasePath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(!aBasePath.IsEmpty());
+  MOZ_ASSERT(aConnection);
 
   nsCOMPtr<nsIFile> shadowFile;
   nsresult rv = GetShadowFile(aBasePath, getter_AddRefs(shadowFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsCOMPtr<mozIStorageService> ss =
@@ -930,18 +941,18 @@ nsresult CreateShadowStorageConnection(c
 
   connection.forget(aConnection);
   return NS_OK;
 }
 
 nsresult GetShadowStorageConnection(const nsAString& aBasePath,
                                     mozIStorageConnection** aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aBasePath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(!aBasePath.IsEmpty());
+  MOZ_ASSERT(aConnection);
 
   nsCOMPtr<nsIFile> shadowFile;
   nsresult rv = GetShadowFile(aBasePath, getter_AddRefs(shadowFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   bool exists;
@@ -968,33 +979,33 @@ nsresult GetShadowStorageConnection(cons
 
   connection.forget(aConnection);
   return NS_OK;
 }
 
 nsresult AttachShadowDatabase(const nsAString& aBasePath,
                               mozIStorageConnection* aConnection) {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aBasePath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(!aBasePath.IsEmpty());
+  MOZ_ASSERT(aConnection);
 
   nsCOMPtr<nsIFile> shadowFile;
   nsresult rv = GetShadowFile(aBasePath, getter_AddRefs(shadowFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool exists;
   rv = shadowFile->Exists(&exists);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(exists);
+  MOZ_ASSERT(exists);
 #endif
 
   nsString path;
   rv = shadowFile->GetPath(path);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -1016,31 +1027,31 @@ nsresult AttachShadowDatabase(const nsAS
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult DetachShadowDatabase(mozIStorageConnection* aConnection) {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   nsresult rv = aConnection->ExecuteSimpleSQL(
       NS_LITERAL_CSTRING("DETACH DATABASE shadow"));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult GetUsageFile(const nsAString& aDirectoryPath, nsIFile** aUsageFile) {
   MOZ_ASSERT(IsOnIOThread() || IsOnConnectionThread());
-  MOZ_DIAGNOSTIC_ASSERT(!aDirectoryPath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aUsageFile);
+  MOZ_ASSERT(!aDirectoryPath.IsEmpty());
+  MOZ_ASSERT(aUsageFile);
 
   nsCOMPtr<nsIFile> usageFile;
   nsresult rv =
       NS_NewLocalFile(aDirectoryPath, false, getter_AddRefs(usageFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -1051,18 +1062,18 @@ nsresult GetUsageFile(const nsAString& a
 
   usageFile.forget(aUsageFile);
   return NS_OK;
 }
 
 nsresult GetUsageJournalFile(const nsAString& aDirectoryPath,
                              nsIFile** aUsageJournalFile) {
   MOZ_ASSERT(IsOnIOThread() || IsOnConnectionThread());
-  MOZ_DIAGNOSTIC_ASSERT(!aDirectoryPath.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aUsageJournalFile);
+  MOZ_ASSERT(!aDirectoryPath.IsEmpty());
+  MOZ_ASSERT(aUsageJournalFile);
 
   nsCOMPtr<nsIFile> usageJournalFile;
   nsresult rv =
       NS_NewLocalFile(aDirectoryPath, false, getter_AddRefs(usageJournalFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -1073,19 +1084,19 @@ nsresult GetUsageJournalFile(const nsASt
 
   usageJournalFile.forget(aUsageJournalFile);
   return NS_OK;
 }
 
 nsresult UpdateUsageFile(nsIFile* aUsageFile, nsIFile* aUsageJournalFile,
                          int64_t aUsage) {
   MOZ_ASSERT(IsOnIOThread() || IsOnConnectionThread());
-  MOZ_DIAGNOSTIC_ASSERT(aUsageFile);
-  MOZ_DIAGNOSTIC_ASSERT(aUsageJournalFile);
-  MOZ_DIAGNOSTIC_ASSERT(aUsage >= 0);
+  MOZ_ASSERT(aUsageFile);
+  MOZ_ASSERT(aUsageJournalFile);
+  MOZ_ASSERT(aUsage >= 0);
 
   nsresult rv = aUsageJournalFile->Create(nsIFile::NORMAL_FILE_TYPE, 0644);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsCOMPtr<nsIOutputStream> stream;
   rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aUsageFile);
@@ -1111,18 +1122,18 @@ nsresult UpdateUsageFile(nsIFile* aUsage
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult LoadUsageFile(nsIFile* aUsageFile, int64_t* aUsage) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aUsageFile);
-  MOZ_DIAGNOSTIC_ASSERT(aUsage);
+  MOZ_ASSERT(aUsageFile);
+  MOZ_ASSERT(aUsage);
 
   int64_t fileSize;
   nsresult rv = aUsageFile->GetFileSize(&fileSize);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (NS_WARN_IF(fileSize != kUsageFileSize)) {
@@ -1191,17 +1202,17 @@ class WriteOptimizer final {
   int64_t mTotalDelta;
 
  public:
   WriteOptimizer() : mTotalDelta(0) {}
 
   WriteOptimizer(WriteOptimizer&& aWriteOptimizer)
       : mClearInfo(std::move(aWriteOptimizer.mClearInfo)) {
     AssertIsOnBackgroundThread();
-    MOZ_DIAGNOSTIC_ASSERT(&aWriteOptimizer != this);
+    MOZ_ASSERT(&aWriteOptimizer != this);
 
     mWriteInfos.SwapElements(aWriteOptimizer.mWriteInfos);
     mTotalDelta = aWriteOptimizer.mTotalDelta;
     aWriteOptimizer.mTotalDelta = 0;
   }
 
   void AddItem(const nsString& aKey, const nsString& aValue,
                int64_t aDelta = 0);
@@ -1305,45 +1316,45 @@ class WriteOptimizer::ClearInfo final : 
 class DatastoreOperationBase : public Runnable {
   nsCOMPtr<nsIEventTarget> mOwningEventTarget;
   nsresult mResultCode;
   Atomic<bool> mMayProceedOnNonOwningThread;
   bool mMayProceed;
 
  public:
   nsIEventTarget* OwningEventTarget() const {
-    MOZ_DIAGNOSTIC_ASSERT(mOwningEventTarget);
+    MOZ_ASSERT(mOwningEventTarget);
 
     return mOwningEventTarget;
   }
 
   bool IsOnOwningThread() const {
-    MOZ_DIAGNOSTIC_ASSERT(mOwningEventTarget);
+    MOZ_ASSERT(mOwningEventTarget);
 
     bool current;
     return NS_SUCCEEDED(mOwningEventTarget->IsOnCurrentThread(&current)) &&
            current;
   }
 
   void AssertIsOnOwningThread() const {
     MOZ_ASSERT(IsOnBackgroundThread());
     MOZ_ASSERT(IsOnOwningThread());
   }
 
   nsresult ResultCode() const { return mResultCode; }
 
   void SetFailureCode(nsresult aErrorCode) {
-    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(mResultCode));
-    MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(aErrorCode));
+    MOZ_ASSERT(NS_SUCCEEDED(mResultCode));
+    MOZ_ASSERT(NS_FAILED(aErrorCode));
 
     mResultCode = aErrorCode;
   }
 
   void MaybeSetFailureCode(nsresult aErrorCode) {
-    MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(aErrorCode));
+    MOZ_ASSERT(NS_FAILED(aErrorCode));
 
     if (NS_SUCCEEDED(mResultCode)) {
       mResultCode = aErrorCode;
     }
   }
 
   void NoteComplete() {
     AssertIsOnOwningThread();
@@ -1367,17 +1378,17 @@ class DatastoreOperationBase : public Ru
  protected:
   DatastoreOperationBase()
       : Runnable("dom::DatastoreOperationBase"),
         mOwningEventTarget(GetCurrentThreadEventTarget()),
         mResultCode(NS_OK),
         mMayProceedOnNonOwningThread(true),
         mMayProceed(true) {}
 
-  ~DatastoreOperationBase() override { MOZ_DIAGNOSTIC_ASSERT(!mMayProceed); }
+  ~DatastoreOperationBase() override { MOZ_ASSERT(!mMayProceed); }
 };
 
 class ConnectionDatastoreOperationBase : public DatastoreOperationBase {
  protected:
   RefPtr<Connection> mConnection;
 
  public:
   // This callback will be called on the background thread before releasing the
@@ -1425,17 +1436,17 @@ class Connection final {
   nsCOMPtr<mozIStorageConnection> mStorageConnection;
   nsAutoPtr<ArchivedOriginScope> mArchivedOriginScope;
   nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
       mCachedStatements;
   WriteOptimizer mWriteOptimizer;
   const nsCString mOrigin;
   const nsString mDirectoryPath;
   bool mFlushScheduled;
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool mInUpdateBatch;
 #endif
 
  public:
   NS_INLINE_DECL_REFCOUNTING(mozilla::dom::Connection)
 
   void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(Connection); }
 
@@ -1472,17 +1483,17 @@ class Connection final {
 
   //////////////////////////////////////////////////////////////////////////////
   // Methods which can only be called on the connection thread.
 
   nsresult EnsureStorageConnection();
 
   mozIStorageConnection* StorageConnection() const {
     AssertIsOnConnectionThread();
-    MOZ_DIAGNOSTIC_ASSERT(mStorageConnection);
+    MOZ_ASSERT(mStorageConnection);
 
     return mStorageConnection;
   }
 
   void CloseStorageConnection();
 
   nsresult GetCachedStatement(const nsACString& aQuery,
                               CachedStatement* aCachedStatement);
@@ -1561,16 +1572,18 @@ class ConnectionThread final {
   ConnectionThread();
 
   void AssertIsOnOwningThread() const {
     NS_ASSERT_OWNINGTHREAD(ConnectionThread);
   }
 
   bool IsOnConnectionThread();
 
+  void AssertIsOnConnectionThread();
+
   already_AddRefed<Connection> CreateConnection(
       const nsACString& aOrigin, const nsAString& aDirectoryPath,
       nsAutoPtr<ArchivedOriginScope>&& aArchivedOriginScope);
 
   void Shutdown();
 
   NS_INLINE_DECL_REFCOUNTING(ConnectionThread)
 
@@ -1630,17 +1643,17 @@ class Datastore final {
   WriteOptimizer mWriteOptimizer;
   const nsCString mOrigin;
   const uint32_t mPrivateBrowsingId;
   int64_t mUsage;
   int64_t mUpdateBatchUsage;
   int64_t mSizeOfKeys;
   int64_t mSizeOfItems;
   bool mClosed;
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool mInUpdateBatch;
 #endif
 
  public:
   // Created by PrepareDatastoreOp.
   Datastore(const nsACString& aOrigin, uint32_t aPrivateBrowsingId,
             int64_t aUsage, int64_t aSizeOfKeys, int64_t aSizeOfItems,
             already_AddRefed<DirectoryLock>&& aDirectoryLock,
@@ -1673,25 +1686,25 @@ class Datastore final {
   void NoteLivePrepareDatastoreOp(PrepareDatastoreOp* aPrepareDatastoreOp);
 
   void NoteFinishedPrepareDatastoreOp(PrepareDatastoreOp* aPrepareDatastoreOp);
 
   void NoteLivePreparedDatastore(PreparedDatastore* aPreparedDatastore);
 
   void NoteFinishedPreparedDatastore(PreparedDatastore* aPreparedDatastore);
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool HasLivePreparedDatastores() const;
 #endif
 
   void NoteLiveDatabase(Database* aDatabase);
 
   void NoteFinishedDatabase(Database* aDatabase);
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool HasLiveDatabases() const;
 #endif
 
   void NoteActiveDatabase(Database* aDatabase);
 
   void NoteInactiveDatabase(Database* aDatabase);
 
   void GetSnapshotInitInfo(nsTHashtable<nsStringHashKey>& aLoadedItems,
@@ -1773,38 +1786,38 @@ class PreparedDatastore {
       : mDatastore(aDatastore),
         mTimer(NS_NewTimer()),
         mContentParentId(aContentParentId),
         mOrigin(aOrigin),
         mDatastoreId(aDatastoreId),
         mForPreload(aForPreload),
         mInvalidated(false) {
     AssertIsOnBackgroundThread();
-    MOZ_DIAGNOSTIC_ASSERT(aDatastore);
-    MOZ_DIAGNOSTIC_ASSERT(mTimer);
+    MOZ_ASSERT(aDatastore);
+    MOZ_ASSERT(mTimer);
 
     aDatastore->NoteLivePreparedDatastore(this);
 
     MOZ_ALWAYS_SUCCEEDS(mTimer->InitWithNamedFuncCallback(
         TimerCallback, this, kPreparedDatastoreTimeoutMs,
         nsITimer::TYPE_ONE_SHOT, "PreparedDatastore::TimerCallback"));
   }
 
   ~PreparedDatastore() {
-    MOZ_DIAGNOSTIC_ASSERT(mDatastore);
-    MOZ_DIAGNOSTIC_ASSERT(mTimer);
+    MOZ_ASSERT(mDatastore);
+    MOZ_ASSERT(mTimer);
 
     mTimer->Cancel();
 
     mDatastore->NoteFinishedPreparedDatastore(this);
   }
 
   Datastore* GetDatastore() const {
     AssertIsOnBackgroundThread();
-    MOZ_DIAGNOSTIC_ASSERT(mDatastore);
+    MOZ_ASSERT(mDatastore);
 
     return mDatastore;
   }
 
   const Maybe<ContentParentId>& GetContentParentId() const {
     return mContentParentId;
   }
 
@@ -1847,17 +1860,17 @@ class Database final : public PBackgroun
   const Maybe<ContentParentId> mContentParentId;
   // Strings share buffers if possible, so it's not a problem to duplicate the
   // origin here.
   nsCString mOrigin;
   uint32_t mPrivateBrowsingId;
   bool mAllowedToClose;
   bool mActorDestroyed;
   bool mRequestedAllowToClose;
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool mActorWasAlive;
 #endif
 
  public:
   // Created in AllocPBackgroundLSDatabaseParent.
   Database(const PrincipalInfo& aPrincipalInfo,
            const Maybe<ContentParentId>& aContentParentId,
            const nsACString& aOrigin, uint32_t aPrivateBrowsingId);
@@ -2020,24 +2033,23 @@ class Snapshot final : public PBackgroun
  public:
   // Created in AllocPBackgroundLSSnapshotParent.
   Snapshot(Database* aDatabase, const nsAString& aDocumentURI);
 
   void Init(nsTHashtable<nsStringHashKey>& aLoadedItems, uint32_t aTotalLength,
             int64_t aInitialUsage, int64_t aPeakUsage,
             LSSnapshot::LoadState aLoadState) {
     AssertIsOnBackgroundThread();
-    MOZ_DIAGNOSTIC_ASSERT(aInitialUsage >= 0);
-    MOZ_DIAGNOSTIC_ASSERT(aPeakUsage >= aInitialUsage);
-    MOZ_DIAGNOSTIC_ASSERT_IF(
-        aLoadState == LSSnapshot::LoadState::AllOrderedItems,
-        aLoadedItems.Count() == 0);
-    MOZ_DIAGNOSTIC_ASSERT(mTotalLength == 0);
-    MOZ_DIAGNOSTIC_ASSERT(mUsage == -1);
-    MOZ_DIAGNOSTIC_ASSERT(mPeakUsage == -1);
+    MOZ_ASSERT(aInitialUsage >= 0);
+    MOZ_ASSERT(aPeakUsage >= aInitialUsage);
+    MOZ_ASSERT_IF(aLoadState == LSSnapshot::LoadState::AllOrderedItems,
+                  aLoadedItems.Count() == 0);
+    MOZ_ASSERT(mTotalLength == 0);
+    MOZ_ASSERT(mUsage == -1);
+    MOZ_ASSERT(mPeakUsage == -1);
 
     mLoadedItems.SwapElements(aLoadedItems);
     mTotalLength = aTotalLength;
     mUsage = aInitialUsage;
     mPeakUsage = aPeakUsage;
     if (aLoadState == LSSnapshot::LoadState::AllOrderedKeys) {
       mLoadKeysReceived = true;
     } else if (aLoadState == LSSnapshot::LoadState::AllOrderedItems) {
@@ -2269,34 +2281,34 @@ class PrepareDatastoreOp : public LSRequ
   int64_t mSizeOfKeys;
   int64_t mSizeOfItems;
   NestedState mNestedState;
   const bool mCreateIfNotExists;
   bool mDatabaseNotAvailable;
   bool mRequestedDirectoryLock;
   bool mInvalidated;
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   int64_t mDEBUGUsage;
 #endif
 
  public:
   PrepareDatastoreOp(nsIEventTarget* aMainEventTarget,
                      const LSRequestParams& aParams,
                      const Maybe<ContentParentId>& aContentParentId);
 
   bool OriginIsKnown() const {
     AssertIsOnOwningThread();
 
     return !mOrigin.IsEmpty();
   }
 
   const nsCString& Origin() const {
     AssertIsOnOwningThread();
-    MOZ_DIAGNOSTIC_ASSERT(OriginIsKnown());
+    MOZ_ASSERT(OriginIsKnown());
 
     return mOrigin;
   }
 
   bool RequestedDirectoryLock() const {
     AssertIsOnOwningThread();
 
     return mRequestedDirectoryLock;
@@ -2504,17 +2516,17 @@ class ArchivedOriginScope {
         : mPattern(MakeUnique<OriginAttributesPattern>(aPattern)) {}
 
     Pattern(const Pattern& aOther)
         : mPattern(MakeUnique<OriginAttributesPattern>(*aOther.mPattern)) {}
 
     Pattern(Pattern&& aOther) = default;
 
     const OriginAttributesPattern& GetPattern() const {
-      MOZ_DIAGNOSTIC_ASSERT(mPattern);
+      MOZ_ASSERT(mPattern);
       return *mPattern;
     }
   };
 
   struct Null {};
 
   using DataType = Variant<Origin, Pattern, Prefix, Null>;
 
@@ -2535,32 +2547,32 @@ class ArchivedOriginScope {
 
   bool IsPrefix() const { return mData.is<Prefix>(); }
 
   bool IsPattern() const { return mData.is<Pattern>(); }
 
   bool IsNull() const { return mData.is<Null>(); }
 
   const nsACString& OriginSuffix() const {
-    MOZ_DIAGNOSTIC_ASSERT(IsOrigin());
+    MOZ_ASSERT(IsOrigin());
 
     return mData.as<Origin>().OriginSuffix();
   }
 
   const nsACString& OriginNoSuffix() const {
-    MOZ_DIAGNOSTIC_ASSERT(IsOrigin() || IsPrefix());
+    MOZ_ASSERT(IsOrigin() || IsPrefix());
 
     if (IsOrigin()) {
       return mData.as<Origin>().OriginNoSuffix();
     }
     return mData.as<Prefix>().OriginNoSuffix();
   }
 
   const OriginAttributesPattern& GetPattern() const {
-    MOZ_DIAGNOSTIC_ASSERT(IsPattern());
+    MOZ_ASSERT(IsPattern());
 
     return mData.as<Pattern>().GetPattern();
   }
 
   void GetBindingClause(nsACString& aBindingClause) const;
 
   nsresult BindToStatement(mozIStorageStatement* aStatement) const;
 
@@ -2659,16 +2671,18 @@ class QuotaClient final : public mozilla
 
   void StopIdleMaintenance() override;
 
   void ShutdownWorkThreads() override;
 
  private:
   ~QuotaClient() override;
 
+  void ShutdownTimedOut();
+
   nsresult CreateArchivedOriginScope(
       const OriginScope& aOriginScope,
       nsAutoPtr<ArchivedOriginScope>& aArchivedOriginScope);
 
   nsresult PerformDelete(mozIStorageConnection* aConnection,
                          const nsACString& aSchemaName,
                          ArchivedOriginScope* aArchivedOriginScope) const;
 };
@@ -2703,17 +2717,17 @@ class QuotaClient::MatchFunction final :
   NS_DECL_ISUPPORTS
   NS_DECL_MOZISTORAGEFUNCTION
 };
 
 /*******************************************************************************
  * Globals
  ******************************************************************************/
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
 bool gLocalStorageInitialized = false;
 #endif
 
 typedef nsTArray<PrepareDatastoreOp*> PrepareDatastoreOpArray;
 
 StaticAutoPtr<PrepareDatastoreOpArray> gPrepareDatastoreOps;
 
 typedef nsDataHashtable<nsCStringHashKey, Datastore*> DatastoreHashtable;
@@ -2756,47 +2770,50 @@ typedef nsDataHashtable<nsCStringHashKey
 StaticAutoPtr<UsageHashtable> gUsages;
 
 StaticAutoPtr<ArchivedOriginHashtable> gArchivedOrigins;
 
 // Can only be touched on the Quota Manager I/O thread.
 bool gInitializedShadowStorage = false;
 
 bool IsOnConnectionThread() {
-  MOZ_DIAGNOSTIC_ASSERT(gConnectionThread);
+  MOZ_ASSERT(gConnectionThread);
   return gConnectionThread->IsOnConnectionThread();
 }
 
-void AssertIsOnConnectionThread() { MOZ_ASSERT(IsOnConnectionThread()); }
+void AssertIsOnConnectionThread() {
+  MOZ_ASSERT(gConnectionThread);
+  gConnectionThread->AssertIsOnConnectionThread();
+}
 
 void InitUsageForOrigin(const nsACString& aOrigin, int64_t aUsage) {
   AssertIsOnIOThread();
 
   if (!gUsages) {
     gUsages = new UsageHashtable();
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(!gUsages->Contains(aOrigin));
+  MOZ_ASSERT(!gUsages->Contains(aOrigin));
   gUsages->Put(aOrigin, aUsage);
 }
 
 void UpdateUsageForOrigin(const nsACString& aOrigin, int64_t aUsage) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(gUsages);
-  MOZ_DIAGNOSTIC_ASSERT(gUsages->Contains(aOrigin));
+  MOZ_ASSERT(gUsages);
+  MOZ_ASSERT(gUsages->Contains(aOrigin));
 
   gUsages->Put(aOrigin, aUsage);
 }
 
 nsresult LoadArchivedOrigins() {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(!gArchivedOrigins);
+  MOZ_ASSERT(!gArchivedOrigins);
 
   QuotaManager* quotaManager = QuotaManager::Get();
-  MOZ_DIAGNOSTIC_ASSERT(quotaManager);
+  MOZ_ASSERT(quotaManager);
 
   // Ensure that the webappsstore.sqlite is moved to new place.
   nsresult rv = quotaManager->EnsureStorageIsInitialized();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsCOMPtr<mozIStorageConnection> connection;
@@ -2855,18 +2872,18 @@ nsresult LoadArchivedOrigins() {
 
   gArchivedOrigins = archivedOrigins.forget();
   return NS_OK;
 }
 
 nsresult GetUsage(mozIStorageConnection* aConnection,
                   ArchivedOriginScope* aArchivedOriginScope, int64_t* aUsage) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
-  MOZ_DIAGNOSTIC_ASSERT(aUsage);
+  MOZ_ASSERT(aConnection);
+  MOZ_ASSERT(aUsage);
 
   nsresult rv;
 
   nsCOMPtr<mozIStorageStatement> stmt;
   if (aArchivedOriginScope) {
     rv = aConnection->CreateStatement(
         NS_LITERAL_CSTRING("SELECT "
                            "total(utf16Length(key) + utf16Length(value)) "
@@ -2905,57 +2922,57 @@ nsresult GetUsage(mozIStorageConnection*
   }
 
   *aUsage = usage;
   return NS_OK;
 }
 
 void ShadowWritesPrefChangedCallback(const char* aPrefName, void* aClosure) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(!strcmp(aPrefName, kShadowWritesPref));
-  MOZ_DIAGNOSTIC_ASSERT(!aClosure);
+  MOZ_ASSERT(!strcmp(aPrefName, kShadowWritesPref));
+  MOZ_ASSERT(!aClosure);
 
   gShadowWrites = Preferences::GetBool(aPrefName, kDefaultShadowWrites);
 }
 
 void SnapshotPrefillPrefChangedCallback(const char* aPrefName, void* aClosure) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(!strcmp(aPrefName, kSnapshotPrefillPref));
-  MOZ_DIAGNOSTIC_ASSERT(!aClosure);
+  MOZ_ASSERT(!strcmp(aPrefName, kSnapshotPrefillPref));
+  MOZ_ASSERT(!aClosure);
 
   int32_t snapshotPrefill =
       Preferences::GetInt(aPrefName, kDefaultSnapshotPrefill);
 
   // The magic -1 is for use only by tests.
   if (snapshotPrefill == -1) {
     snapshotPrefill = INT32_MAX;
   }
 
   gSnapshotPrefill = snapshotPrefill;
 }
 
 void ClientValidationPrefChangedCallback(const char* aPrefName,
                                          void* aClosure) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(!strcmp(aPrefName, kClientValidationPref));
-  MOZ_DIAGNOSTIC_ASSERT(!aClosure);
+  MOZ_ASSERT(!strcmp(aPrefName, kClientValidationPref));
+  MOZ_ASSERT(!aClosure);
 
   gClientValidation = Preferences::GetBool(aPrefName, kDefaultClientValidation);
 }
 
 }  // namespace
 
 /*******************************************************************************
  * Exported functions
  ******************************************************************************/
 
 void InitializeLocalStorage() {
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(!gLocalStorageInitialized);
+  MOZ_ASSERT(!gLocalStorageInitialized);
 
   if (!QuotaManager::IsRunningGTests()) {
     // This service has to be started on the main thread currently.
     nsCOMPtr<mozIStorageService> ss;
     if (NS_WARN_IF(!(ss = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID)))) {
       NS_WARNING("Failed to get storage service!");
     }
   }
@@ -2978,17 +2995,17 @@ void InitializeLocalStorage() {
                                        kShadowWritesPref);
 
   Preferences::RegisterCallbackAndCall(SnapshotPrefillPrefChangedCallback,
                                        kSnapshotPrefillPref);
 
   Preferences::RegisterCallbackAndCall(ClientValidationPrefChangedCallback,
                                        kClientValidationPref);
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   gLocalStorageInitialized = true;
 #endif
 }
 
 bool GetCurrentNextGenPrefValue() { return gNextGen; }
 
 PBackgroundLSDatabaseParent* AllocPBackgroundLSDatabaseParent(
     const PrincipalInfo& aPrincipalInfo, const uint32_t& aPrivateBrowsingId,
@@ -3024,28 +3041,28 @@ PBackgroundLSDatabaseParent* AllocPBackg
   return database.forget().take();
 }
 
 bool RecvPBackgroundLSDatabaseConstructor(PBackgroundLSDatabaseParent* aActor,
                                           const PrincipalInfo& aPrincipalInfo,
                                           const uint32_t& aPrivateBrowsingId,
                                           const uint64_t& aDatastoreId) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
-  MOZ_DIAGNOSTIC_ASSERT(gPreparedDatastores);
-  MOZ_DIAGNOSTIC_ASSERT(gPreparedDatastores->Get(aDatastoreId));
-  MOZ_DIAGNOSTIC_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
+  MOZ_ASSERT(aActor);
+  MOZ_ASSERT(gPreparedDatastores);
+  MOZ_ASSERT(gPreparedDatastores->Get(aDatastoreId));
+  MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
 
   // The actor is now completely built (it has a manager, channel and it's
   // registered as a subprotocol).
   // ActorDestroy will be called if we fail here.
 
   nsAutoPtr<PreparedDatastore> preparedDatastore;
   gPreparedDatastores->Remove(aDatastoreId, &preparedDatastore);
-  MOZ_DIAGNOSTIC_ASSERT(preparedDatastore);
+  MOZ_ASSERT(preparedDatastore);
 
   auto* database = static_cast<Database*>(aActor);
 
   database->SetActorAlive(preparedDatastore->GetDatastore());
 
   // It's possible that AbortOperations was called before the database actor
   // was created and became live. Let the child know that the database in no
   // longer valid.
@@ -3053,17 +3070,17 @@ bool RecvPBackgroundLSDatabaseConstructo
     database->RequestAllowToClose();
   }
 
   return true;
 }
 
 bool DeallocPBackgroundLSDatabaseParent(PBackgroundLSDatabaseParent* aActor) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
+  MOZ_ASSERT(aActor);
 
   // Transfer ownership back from IPDL.
   RefPtr<Database> actor = dont_AddRef(static_cast<Database*>(aActor));
 
   return true;
 }
 
 PBackgroundLSObserverParent* AllocPBackgroundLSObserverParent(
@@ -3089,23 +3106,23 @@ PBackgroundLSObserverParent* AllocPBackg
 
   // Transfer ownership to IPDL.
   return observer.forget().take();
 }
 
 bool RecvPBackgroundLSObserverConstructor(PBackgroundLSObserverParent* aActor,
                                           const uint64_t& aObserverId) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
-  MOZ_DIAGNOSTIC_ASSERT(gPreparedObsevers);
-  MOZ_DIAGNOSTIC_ASSERT(gPreparedObsevers->GetWeak(aObserverId));
+  MOZ_ASSERT(aActor);
+  MOZ_ASSERT(gPreparedObsevers);
+  MOZ_ASSERT(gPreparedObsevers->GetWeak(aObserverId));
 
   RefPtr<Observer> observer;
   gPreparedObsevers->Remove(aObserverId, observer.StartAssignment());
-  MOZ_DIAGNOSTIC_ASSERT(observer);
+  MOZ_ASSERT(observer);
 
   if (!gPreparedObsevers->Count()) {
     gPreparedObsevers = nullptr;
   }
 
   if (!gObservers) {
     gObservers = new ObserverHashtable();
   }
@@ -3117,17 +3134,17 @@ bool RecvPBackgroundLSObserverConstructo
   }
   array->AppendElement(observer);
 
   return true;
 }
 
 bool DeallocPBackgroundLSObserverParent(PBackgroundLSObserverParent* aActor) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
+  MOZ_ASSERT(aActor);
 
   // Transfer ownership back from IPDL.
   RefPtr<Observer> actor = dont_AddRef(static_cast<Observer*>(aActor));
 
   return true;
 }
 
 bool VerifyPrincipalInfo(const Maybe<ContentParentId>& aContentParentId,
@@ -3172,17 +3189,17 @@ bool VerifyOriginKey(const nsACString& a
   }
 
   return true;
 }
 
 bool VerifyRequestParams(const Maybe<ContentParentId>& aContentParentId,
                          const LSRequestParams& aParams) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aParams.type() != LSRequestParams::T__None);
+  MOZ_ASSERT(aParams.type() != LSRequestParams::T__None);
 
   switch (aParams.type()) {
     case LSRequestParams::TLSRequestPreloadDatastoreParams: {
       const LSRequestCommonParams& params =
           aParams.get_LSRequestPreloadDatastoreParams().commonParams();
 
       if (NS_WARN_IF(!VerifyPrincipalInfo(aContentParentId,
                                           params.principalInfo(), Nothing()))) {
@@ -3236,23 +3253,23 @@ bool VerifyRequestParams(const Maybe<Con
   }
 
   return true;
 }
 
 PBackgroundLSRequestParent* AllocPBackgroundLSRequestParent(
     PBackgroundParent* aBackgroundActor, const LSRequestParams& aParams) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aParams.type() != LSRequestParams::T__None);
+  MOZ_ASSERT(aParams.type() != LSRequestParams::T__None);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread())) {
     return nullptr;
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   // Always verify parameters in DEBUG builds!
   bool trustParams = false;
 #else
   bool trustParams = !BackgroundParent::IsOtherProcessActor(aBackgroundActor);
 #endif
 
   Maybe<ContentParentId> contentParentId;
 
@@ -3307,19 +3324,19 @@ PBackgroundLSRequestParent* AllocPBackgr
 
   // Transfer ownership to IPDL.
   return actor.forget().take();
 }
 
 bool RecvPBackgroundLSRequestConstructor(PBackgroundLSRequestParent* aActor,
                                          const LSRequestParams& aParams) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
-  MOZ_DIAGNOSTIC_ASSERT(aParams.type() != LSRequestParams::T__None);
-  MOZ_DIAGNOSTIC_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
+  MOZ_ASSERT(aActor);
+  MOZ_ASSERT(aParams.type() != LSRequestParams::T__None);
+  MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
 
   // The actor is now completely built.
 
   auto* op = static_cast<LSRequestBase*>(aActor);
 
   op->Dispatch();
 
   return true;
@@ -3333,17 +3350,17 @@ bool DeallocPBackgroundLSRequestParent(P
       dont_AddRef(static_cast<LSRequestBase*>(aActor));
 
   return true;
 }
 
 bool VerifyRequestParams(const Maybe<ContentParentId>& aContentParentId,
                          const LSSimpleRequestParams& aParams) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
+  MOZ_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
 
   switch (aParams.type()) {
     case LSSimpleRequestParams::TLSSimpleRequestPreloadedParams: {
       const LSSimpleRequestPreloadedParams& params =
           aParams.get_LSSimpleRequestPreloadedParams();
 
       if (NS_WARN_IF(!VerifyPrincipalInfo(aContentParentId,
                                           params.principalInfo(), Nothing()))) {
@@ -3358,23 +3375,23 @@ bool VerifyRequestParams(const Maybe<Con
   }
 
   return true;
 }
 
 PBackgroundLSSimpleRequestParent* AllocPBackgroundLSSimpleRequestParent(
     PBackgroundParent* aBackgroundActor, const LSSimpleRequestParams& aParams) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
+  MOZ_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread())) {
     return nullptr;
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   // Always verify parameters in DEBUG builds!
   bool trustParams = false;
 #else
   bool trustParams = !BackgroundParent::IsOtherProcessActor(aBackgroundActor);
 #endif
 
   if (!trustParams) {
     Maybe<ContentParentId> contentParentId;
@@ -3408,19 +3425,19 @@ PBackgroundLSSimpleRequestParent* AllocP
   // Transfer ownership to IPDL.
   return actor.forget().take();
 }
 
 bool RecvPBackgroundLSSimpleRequestConstructor(
     PBackgroundLSSimpleRequestParent* aActor,
     const LSSimpleRequestParams& aParams) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
-  MOZ_DIAGNOSTIC_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
-  MOZ_DIAGNOSTIC_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
+  MOZ_ASSERT(aActor);
+  MOZ_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
+  MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
 
   // The actor is now completely built.
 
   auto* op = static_cast<LSSimpleRequestBase*>(aActor);
 
   op->Dispatch();
 
   return true;
@@ -3438,32 +3455,32 @@ bool DeallocPBackgroundLSSimpleRequestPa
 }
 
 bool RecvLSClearPrivateBrowsing() {
   AssertIsOnBackgroundThread();
 
   if (gDatastores) {
     for (auto iter = gDatastores->ConstIter(); !iter.Done(); iter.Next()) {
       Datastore* datastore = iter.Data();
-      MOZ_DIAGNOSTIC_ASSERT(datastore);
+      MOZ_ASSERT(datastore);
 
       if (datastore->PrivateBrowsingId()) {
         datastore->PrivateBrowsingClear();
       }
     }
   }
 
   return true;
 }
 
 namespace localstorage {
 
 already_AddRefed<mozilla::dom::quota::Client> CreateQuotaClient() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(CachedNextGenLocalStorageEnabled());
+  MOZ_ASSERT(CachedNextGenLocalStorageEnabled());
 
   RefPtr<QuotaClient> client = new QuotaClient();
   return client.forget();
 }
 
 }  // namespace localstorage
 
 /*******************************************************************************
@@ -3565,32 +3582,32 @@ void WriteOptimizer::ApplyWrites(nsTArra
           MOZ_CRASH("Bad type!");
       }
     }
   }
 
   for (auto iter = mWriteInfos.ConstIter(); !iter.Done(); iter.Next()) {
     WriteInfo* writeInfo = iter.Data();
 
-    MOZ_DIAGNOSTIC_ASSERT(writeInfo->GetType() == WriteInfo::AddItem);
+    MOZ_ASSERT(writeInfo->GetType() == WriteInfo::AddItem);
 
     auto addItemInfo = static_cast<AddItemInfo*>(writeInfo);
 
     LSItemInfo* itemInfo = aOrderedItems.AppendElement();
     itemInfo->key() = addItemInfo->GetKey();
     itemInfo->value() = addItemInfo->GetValue();
   }
 
   mWriteInfos.Clear();
 }
 
 nsresult WriteOptimizer::PerformWrites(Connection* aConnection,
                                        bool aShadowWrites, int64_t& aOutUsage) {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   nsresult rv;
 
   if (mClearInfo) {
     rv = mClearInfo->Perform(aConnection, aShadowWrites);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
@@ -3647,17 +3664,17 @@ nsresult WriteOptimizer::PerformWrites(C
 
   aOutUsage = usage;
   return NS_OK;
 }
 
 nsresult WriteOptimizer::AddItemInfo::Perform(Connection* aConnection,
                                               bool aShadowWrites) {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   Connection::CachedStatement stmt;
   nsresult rv = aConnection->GetCachedStatement(
       NS_LITERAL_CSTRING("INSERT OR REPLACE INTO data (key, value) "
                          "VALUES(:key, :value)"),
       &stmt);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -3724,17 +3741,17 @@ nsresult WriteOptimizer::AddItemInfo::Pe
   }
 
   return NS_OK;
 }
 
 nsresult WriteOptimizer::RemoveItemInfo::Perform(Connection* aConnection,
                                                  bool aShadowWrites) {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   Connection::CachedStatement stmt;
   nsresult rv =
       aConnection->GetCachedStatement(NS_LITERAL_CSTRING("DELETE FROM data "
                                                          "WHERE key = :key;"),
                                       &stmt);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -3780,17 +3797,17 @@ nsresult WriteOptimizer::RemoveItemInfo:
   }
 
   return NS_OK;
 }
 
 nsresult WriteOptimizer::ClearInfo::Perform(Connection* aConnection,
                                             bool aShadowWrites) {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   Connection::CachedStatement stmt;
   nsresult rv = aConnection->GetCachedStatement(
       NS_LITERAL_CSTRING("DELETE FROM data;"), &stmt);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -3831,69 +3848,68 @@ nsresult WriteOptimizer::ClearInfo::Perf
 
 /*******************************************************************************
  * ConnectionDatastoreOperationBase
  ******************************************************************************/
 
 ConnectionDatastoreOperationBase::ConnectionDatastoreOperationBase(
     Connection* aConnection)
     : mConnection(aConnection) {
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 }
 
 ConnectionDatastoreOperationBase::~ConnectionDatastoreOperationBase() {
-  MOZ_DIAGNOSTIC_ASSERT(
-      !mConnection,
-      "ConnectionDatabaseOperationBase::Cleanup() was not called by a "
-      "subclass!");
+  MOZ_ASSERT(!mConnection,
+             "ConnectionDatabaseOperationBase::Cleanup() was not called by a "
+             "subclass!");
 }
 
 void ConnectionDatastoreOperationBase::Cleanup() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
+  MOZ_ASSERT(mConnection);
 
   mConnection = nullptr;
 
   NoteComplete();
 }
 
 void ConnectionDatastoreOperationBase::OnSuccess() { AssertIsOnOwningThread(); }
 
 void ConnectionDatastoreOperationBase::OnFailure(nsresult aResultCode) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(aResultCode));
+  MOZ_ASSERT(NS_FAILED(aResultCode));
 }
 
 void ConnectionDatastoreOperationBase::RunOnConnectionThread() {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
-  MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(ResultCode()));
+  MOZ_ASSERT(mConnection);
+  MOZ_ASSERT(NS_SUCCEEDED(ResultCode()));
 
   if (!MayProceedOnNonOwningThread()) {
     SetFailureCode(NS_ERROR_FAILURE);
   } else {
     nsresult rv = mConnection->EnsureStorageConnection();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       SetFailureCode(rv);
     } else {
-      MOZ_DIAGNOSTIC_ASSERT(mConnection->StorageConnection());
+      MOZ_ASSERT(mConnection->StorageConnection());
 
       rv = DoDatastoreWork();
       if (NS_FAILED(rv)) {
         SetFailureCode(rv);
       }
     }
   }
 
   MOZ_ALWAYS_SUCCEEDS(OwningEventTarget()->Dispatch(this, NS_DISPATCH_NORMAL));
 }
 
 void ConnectionDatastoreOperationBase::RunOnOwningThread() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
+  MOZ_ASSERT(mConnection);
 
   if (!MayProceed()) {
     MaybeSetFailureCode(NS_ERROR_FAILURE);
   }
 
   if (NS_SUCCEEDED(ResultCode())) {
     OnSuccess();
   } else {
@@ -3922,108 +3938,108 @@ Connection::Connection(ConnectionThread*
                        const nsACString& aOrigin,
                        const nsAString& aDirectoryPath,
                        nsAutoPtr<ArchivedOriginScope>&& aArchivedOriginScope)
     : mConnectionThread(aConnectionThread),
       mArchivedOriginScope(std::move(aArchivedOriginScope)),
       mOrigin(aOrigin),
       mDirectoryPath(aDirectoryPath),
       mFlushScheduled(false)
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
       ,
       mInUpdateBatch(false)
 #endif
 {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aOrigin.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(!aDirectoryPath.IsEmpty());
+  MOZ_ASSERT(!aOrigin.IsEmpty());
+  MOZ_ASSERT(!aDirectoryPath.IsEmpty());
 }
 
 Connection::~Connection() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mStorageConnection);
-  MOZ_DIAGNOSTIC_ASSERT(!mCachedStatements.Count());
-  MOZ_DIAGNOSTIC_ASSERT(!mInUpdateBatch);
-  MOZ_DIAGNOSTIC_ASSERT(!mFlushScheduled);
+  MOZ_ASSERT(!mStorageConnection);
+  MOZ_ASSERT(!mCachedStatements.Count());
+  MOZ_ASSERT(!mInUpdateBatch);
+  MOZ_ASSERT(!mFlushScheduled);
 }
 
 void Connection::Dispatch(ConnectionDatastoreOperationBase* aOp) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mConnectionThread);
+  MOZ_ASSERT(mConnectionThread);
 
   MOZ_ALWAYS_SUCCEEDS(
       mConnectionThread->mThread->Dispatch(aOp, NS_DISPATCH_NORMAL));
 }
 
 void Connection::Close(nsIRunnable* aCallback) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aCallback);
+  MOZ_ASSERT(aCallback);
 
   if (mFlushScheduled) {
-    MOZ_DIAGNOSTIC_ASSERT(mFlushTimer);
+    MOZ_ASSERT(mFlushTimer);
     MOZ_ALWAYS_SUCCEEDS(mFlushTimer->Cancel());
 
     Flush();
 
     mFlushTimer = nullptr;
   }
 
   RefPtr<CloseOp> op = new CloseOp(this, aCallback);
 
   Dispatch(op);
 }
 
 void Connection::AddItem(const nsString& aKey, const nsString& aValue,
                          int64_t aDelta) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(mInUpdateBatch);
 
   mWriteOptimizer.AddItem(aKey, aValue, aDelta);
 }
 
 void Connection::UpdateItem(const nsString& aKey, const nsString& aValue,
                             int64_t aDelta) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(mInUpdateBatch);
 
   mWriteOptimizer.UpdateItem(aKey, aValue, aDelta);
 }
 
 void Connection::RemoveItem(const nsString& aKey, int64_t aDelta) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(mInUpdateBatch);
 
   mWriteOptimizer.RemoveItem(aKey, aDelta);
 }
 
 void Connection::Clear(int64_t aDelta) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(mInUpdateBatch);
 
   mWriteOptimizer.Clear(aDelta);
 }
 
 void Connection::BeginUpdateBatch() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mInUpdateBatch);
-
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  MOZ_ASSERT(!mInUpdateBatch);
+
+#ifdef DEBUG
   mInUpdateBatch = true;
 #endif
 }
 
 void Connection::EndUpdateBatch() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(mInUpdateBatch);
 
   if (mWriteOptimizer.HasWrites() && !mFlushScheduled) {
     ScheduleFlush();
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   mInUpdateBatch = false;
 #endif
 }
 
 nsresult Connection::EnsureStorageConnection() {
   AssertIsOnConnectionThread();
 
   if (!mStorageConnection) {
@@ -4053,30 +4069,30 @@ nsresult Connection::EnsureStorageConnec
     mStorageConnection = storageConnection;
   }
 
   return NS_OK;
 }
 
 void Connection::CloseStorageConnection() {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(mStorageConnection);
+  MOZ_ASSERT(mStorageConnection);
 
   mCachedStatements.Clear();
 
   MOZ_ALWAYS_SUCCEEDS(mStorageConnection->Close());
   mStorageConnection = nullptr;
 }
 
 nsresult Connection::GetCachedStatement(const nsACString& aQuery,
                                         CachedStatement* aCachedStatement) {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aQuery.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(aCachedStatement);
-  MOZ_DIAGNOSTIC_ASSERT(mStorageConnection);
+  MOZ_ASSERT(!aQuery.IsEmpty());
+  MOZ_ASSERT(aCachedStatement);
+  MOZ_ASSERT(mStorageConnection);
 
   nsCOMPtr<mozIStorageStatement> stmt;
 
   if (!mCachedStatements.Get(aQuery, getter_AddRefs(stmt))) {
     nsresult rv =
         mStorageConnection->CreateStatement(aQuery, getter_AddRefs(stmt));
     if (NS_FAILED(rv)) {
 #ifdef DEBUG
@@ -4097,51 +4113,51 @@ nsresult Connection::GetCachedStatement(
   }
 
   aCachedStatement->Assign(this, stmt.forget());
   return NS_OK;
 }
 
 void Connection::ScheduleFlush() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mWriteOptimizer.HasWrites());
-  MOZ_DIAGNOSTIC_ASSERT(!mFlushScheduled);
+  MOZ_ASSERT(mWriteOptimizer.HasWrites());
+  MOZ_ASSERT(!mFlushScheduled);
 
   if (!mFlushTimer) {
     mFlushTimer = NS_NewTimer();
-    MOZ_DIAGNOSTIC_ASSERT(mFlushTimer);
+    MOZ_ASSERT(mFlushTimer);
   }
 
   MOZ_ALWAYS_SUCCEEDS(mFlushTimer->InitWithNamedFuncCallback(
       FlushTimerCallback, this, kFlushTimeoutMs, nsITimer::TYPE_ONE_SHOT,
       "Connection::FlushTimerCallback"));
 
   mFlushScheduled = true;
 }
 
 void Connection::Flush() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mFlushScheduled);
+  MOZ_ASSERT(mFlushScheduled);
 
   if (mWriteOptimizer.HasWrites()) {
     RefPtr<FlushOp> op = new FlushOp(this, std::move(mWriteOptimizer));
 
     Dispatch(op);
   }
 
   mFlushScheduled = false;
 }
 
 // static
 void Connection::FlushTimerCallback(nsITimer* aTimer, void* aClosure) {
-  MOZ_DIAGNOSTIC_ASSERT(aClosure);
+  MOZ_ASSERT(aClosure);
 
   auto* self = static_cast<Connection*>(aClosure);
-  MOZ_DIAGNOSTIC_ASSERT(self);
-  MOZ_DIAGNOSTIC_ASSERT(self->mFlushScheduled);
+  MOZ_ASSERT(self);
+  MOZ_ASSERT(self->mFlushScheduled);
 
   self->Flush();
 }
 
 Connection::CachedStatement::CachedStatement() {
   AssertIsOnConnectionThread();
 
   MOZ_COUNT_CTOR(Connection::CachedStatement);
@@ -4156,17 +4172,17 @@ Connection::CachedStatement::~CachedStat
 Connection::CachedStatement::operator mozIStorageStatement*() const {
   AssertIsOnConnectionThread();
 
   return mStatement;
 }
 
 mozIStorageStatement* Connection::CachedStatement::operator->() const {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(mStatement);
+  MOZ_ASSERT(mStatement);
 
   return mStatement;
 }
 
 void Connection::CachedStatement::Assign(
     Connection* aConnection,
     already_AddRefed<mozIStorageStatement> aStatement) {
   AssertIsOnConnectionThread();
@@ -4181,36 +4197,36 @@ void Connection::CachedStatement::Assign
 }
 
 Connection::FlushOp::FlushOp(Connection* aConnection,
                              WriteOptimizer&& aWriteOptimizer)
     : ConnectionDatastoreOperationBase(aConnection),
       mQuotaClient(QuotaClient::GetInstance()),
       mWriteOptimizer(std::move(aWriteOptimizer)),
       mShadowWrites(gShadowWrites) {
-  MOZ_DIAGNOSTIC_ASSERT(mQuotaClient);
+  MOZ_ASSERT(mQuotaClient);
 }
 
 nsresult Connection::FlushOp::DoDatastoreWork() {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
+  MOZ_ASSERT(mConnection);
 
   QuotaManager* quotaManager = QuotaManager::Get();
-  MOZ_DIAGNOSTIC_ASSERT(quotaManager);
+  MOZ_ASSERT(quotaManager);
 
   nsCOMPtr<mozIStorageConnection> storageConnection =
       mConnection->StorageConnection();
-  MOZ_DIAGNOSTIC_ASSERT(storageConnection);
+  MOZ_ASSERT(storageConnection);
 
   nsresult rv;
 
   Maybe<MutexAutoLock> shadowDatabaseLock;
 
   if (mShadowWrites) {
-    MOZ_DIAGNOSTIC_ASSERT(mQuotaClient);
+    MOZ_ASSERT(mQuotaClient);
 
     shadowDatabaseLock.emplace(mQuotaClient->ShadowDatabaseMutex());
 
     rv = AttachShadowDatabase(quotaManager->GetBasePath(), storageConnection);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
@@ -4284,26 +4300,26 @@ nsresult Connection::FlushOp::DoDatastor
   MOZ_ALWAYS_SUCCEEDS(
       quotaManager->IOThread()->Dispatch(runnable, NS_DISPATCH_NORMAL));
 
   return NS_OK;
 }
 
 nsresult Connection::CloseOp::DoDatastoreWork() {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
+  MOZ_ASSERT(mConnection);
 
   mConnection->CloseStorageConnection();
 
   return NS_OK;
 }
 
 void Connection::CloseOp::Cleanup() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
+  MOZ_ASSERT(mConnection);
 
   mConnection->mConnectionThread->mConnections.Remove(mConnection->mOrigin);
 
   nsCOMPtr<nsIRunnable> callback;
   mCallback.swap(callback);
 
   callback->Run();
 
@@ -4318,43 +4334,47 @@ ConnectionThread::ConnectionThread() {
   AssertIsOnOwningThread();
   AssertIsOnBackgroundThread();
 
   MOZ_ALWAYS_SUCCEEDS(NS_NewNamedThread("LS Thread", getter_AddRefs(mThread)));
 }
 
 ConnectionThread::~ConnectionThread() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mConnections.Count());
+  MOZ_ASSERT(!mConnections.Count());
 }
 
 bool ConnectionThread::IsOnConnectionThread() {
-  MOZ_DIAGNOSTIC_ASSERT(mThread);
+  MOZ_ASSERT(mThread);
 
   bool current;
   return NS_SUCCEEDED(mThread->IsOnCurrentThread(&current)) && current;
 }
 
+void ConnectionThread::AssertIsOnConnectionThread() {
+  MOZ_ASSERT(IsOnConnectionThread());
+}
+
 already_AddRefed<Connection> ConnectionThread::CreateConnection(
     const nsACString& aOrigin, const nsAString& aDirectoryPath,
     nsAutoPtr<ArchivedOriginScope>&& aArchivedOriginScope) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!aOrigin.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(!mConnections.GetWeak(aOrigin));
+  MOZ_ASSERT(!aOrigin.IsEmpty());
+  MOZ_ASSERT(!mConnections.GetWeak(aOrigin));
 
   RefPtr<Connection> connection = new Connection(
       this, aOrigin, aDirectoryPath, std::move(aArchivedOriginScope));
   mConnections.Put(aOrigin, connection);
 
   return connection.forget();
 }
 
 void ConnectionThread::Shutdown() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mThread);
+  MOZ_ASSERT(mThread);
 
   mThread->Shutdown();
 }
 
 /*******************************************************************************
  * Datastore
  ******************************************************************************/
 
@@ -4370,219 +4390,215 @@ Datastore::Datastore(const nsACString& a
       mQuotaObject(std::move(aQuotaObject)),
       mOrigin(aOrigin),
       mPrivateBrowsingId(aPrivateBrowsingId),
       mUsage(aUsage),
       mUpdateBatchUsage(-1),
       mSizeOfKeys(aSizeOfKeys),
       mSizeOfItems(aSizeOfItems),
       mClosed(false)
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
       ,
       mInUpdateBatch(false)
 #endif
 {
   AssertIsOnBackgroundThread();
 
   mValues.SwapElements(aValues);
   mOrderedItems.SwapElements(aOrderedItems);
 }
 
 Datastore::~Datastore() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(mClosed);
+  MOZ_ASSERT(mClosed);
 }
 
 void Datastore::Close() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
-  MOZ_DIAGNOSTIC_ASSERT(!mDatabases.Count());
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(!mClosed);
+  MOZ_ASSERT(!mDatabases.Count());
+  MOZ_ASSERT(mDirectoryLock);
 
   mClosed = true;
 
   if (IsPersistent()) {
-    MOZ_DIAGNOSTIC_ASSERT(mConnection);
-    MOZ_DIAGNOSTIC_ASSERT(mQuotaObject);
+    MOZ_ASSERT(mConnection);
+    MOZ_ASSERT(mQuotaObject);
 
     // We can't release the directory lock and unregister itself from the
     // hashtable until the connection is fully closed.
     nsCOMPtr<nsIRunnable> callback =
         NewRunnableMethod("dom::Datastore::ConnectionClosedCallback", this,
                           &Datastore::ConnectionClosedCallback);
     mConnection->Close(callback);
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(!mConnection);
-    MOZ_DIAGNOSTIC_ASSERT(!mQuotaObject);
+    MOZ_ASSERT(!mConnection);
+    MOZ_ASSERT(!mQuotaObject);
 
     // There's no connection, so it's safe to release the directory lock and
     // unregister itself from the hashtable.
 
     mDirectoryLock = nullptr;
 
     CleanupMetadata();
   }
 }
 
 void Datastore::WaitForConnectionToComplete(nsIRunnable* aCallback) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aCallback);
-  MOZ_DIAGNOSTIC_ASSERT(!mCompleteCallback);
-  MOZ_DIAGNOSTIC_ASSERT(mClosed);
+  MOZ_ASSERT(aCallback);
+  MOZ_ASSERT(!mCompleteCallback);
+  MOZ_ASSERT(mClosed);
 
   mCompleteCallback = aCallback;
 }
 
 void Datastore::NoteLivePrepareDatastoreOp(
     PrepareDatastoreOp* aPrepareDatastoreOp) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aPrepareDatastoreOp);
-  MOZ_DIAGNOSTIC_ASSERT(!mPrepareDatastoreOps.GetEntry(aPrepareDatastoreOp));
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(aPrepareDatastoreOp);
+  MOZ_ASSERT(!mPrepareDatastoreOps.GetEntry(aPrepareDatastoreOp));
+  MOZ_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(!mClosed);
 
   mPrepareDatastoreOps.PutEntry(aPrepareDatastoreOp);
 }
 
 void Datastore::NoteFinishedPrepareDatastoreOp(
     PrepareDatastoreOp* aPrepareDatastoreOp) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aPrepareDatastoreOp);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOps.GetEntry(aPrepareDatastoreOp));
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(aPrepareDatastoreOp);
+  MOZ_ASSERT(mPrepareDatastoreOps.GetEntry(aPrepareDatastoreOp));
+  MOZ_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(!mClosed);
 
   mPrepareDatastoreOps.RemoveEntry(aPrepareDatastoreOp);
 
   MaybeClose();
 }
 
 void Datastore::NoteLivePreparedDatastore(
     PreparedDatastore* aPreparedDatastore) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aPreparedDatastore);
-  MOZ_DIAGNOSTIC_ASSERT(!mPreparedDatastores.GetEntry(aPreparedDatastore));
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(aPreparedDatastore);
+  MOZ_ASSERT(!mPreparedDatastores.GetEntry(aPreparedDatastore));
+  MOZ_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(!mClosed);
 
   mPreparedDatastores.PutEntry(aPreparedDatastore);
 }
 
 void Datastore::NoteFinishedPreparedDatastore(
     PreparedDatastore* aPreparedDatastore) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aPreparedDatastore);
-  MOZ_DIAGNOSTIC_ASSERT(mPreparedDatastores.GetEntry(aPreparedDatastore));
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(aPreparedDatastore);
+  MOZ_ASSERT(mPreparedDatastores.GetEntry(aPreparedDatastore));
+  MOZ_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(!mClosed);
 
   mPreparedDatastores.RemoveEntry(aPreparedDatastore);
 
   MaybeClose();
 }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
 bool Datastore::HasLivePreparedDatastores() const {
   AssertIsOnBackgroundThread();
 
   return mPreparedDatastores.Count();
 }
 #endif
 
 void Datastore::NoteLiveDatabase(Database* aDatabase) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(!mDatabases.GetEntry(aDatabase));
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(aDatabase);
+  MOZ_ASSERT(!mDatabases.GetEntry(aDatabase));
+  MOZ_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(!mClosed);
 
   mDatabases.PutEntry(aDatabase);
 }
 
 void Datastore::NoteFinishedDatabase(Database* aDatabase) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(mDatabases.GetEntry(aDatabase));
-  MOZ_DIAGNOSTIC_ASSERT(!mActiveDatabases.GetEntry(aDatabase));
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(aDatabase);
+  MOZ_ASSERT(mDatabases.GetEntry(aDatabase));
+  MOZ_ASSERT(!mActiveDatabases.GetEntry(aDatabase));
+  MOZ_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(!mClosed);
 
   mDatabases.RemoveEntry(aDatabase);
 
   MaybeClose();
 }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
 bool Datastore::HasLiveDatabases() const {
   AssertIsOnBackgroundThread();
 
   return mDatabases.Count();
 }
 #endif
 
 void Datastore::NoteActiveDatabase(Database* aDatabase) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(mDatabases.GetEntry(aDatabase));
-  MOZ_DIAGNOSTIC_ASSERT(!mActiveDatabases.GetEntry(aDatabase));
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(aDatabase);
+  MOZ_ASSERT(mDatabases.GetEntry(aDatabase));
+  MOZ_ASSERT(!mActiveDatabases.GetEntry(aDatabase));
+  MOZ_ASSERT(!mClosed);
 
   mActiveDatabases.PutEntry(aDatabase);
 }
 
 void Datastore::NoteInactiveDatabase(Database* aDatabase) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(mDatabases.GetEntry(aDatabase));
-  MOZ_DIAGNOSTIC_ASSERT(mActiveDatabases.GetEntry(aDatabase));
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(aDatabase);
+  MOZ_ASSERT(mDatabases.GetEntry(aDatabase));
+  MOZ_ASSERT(mActiveDatabases.GetEntry(aDatabase));
+  MOZ_ASSERT(!mClosed);
 
   mActiveDatabases.RemoveEntry(aDatabase);
 
   if (!mActiveDatabases.Count() && mPendingUsageDeltas.Length()) {
     int64_t finalDelta = 0;
 
     for (auto delta : mPendingUsageDeltas) {
       finalDelta += delta;
     }
 
-    MOZ_DIAGNOSTIC_ASSERT(finalDelta <= 0);
+    MOZ_ASSERT(finalDelta <= 0);
 
     if (finalDelta != 0) {
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-      bool ok = UpdateUsage(finalDelta);
-      MOZ_DIAGNOSTIC_ASSERT(ok);
-#else
-      UpdateUsage(finalDelta);
-#endif
+      DebugOnly<bool> ok = UpdateUsage(finalDelta);
+      MOZ_ASSERT(ok);
     }
 
     mPendingUsageDeltas.Clear();
   }
 }
 
 void Datastore::GetSnapshotInitInfo(nsTHashtable<nsStringHashKey>& aLoadedItems,
                                     nsTArray<LSItemInfo>& aItemInfos,
                                     uint32_t& aTotalLength,
                                     int64_t& aInitialUsage, int64_t& aPeakUsage,
                                     LSSnapshot::LoadState& aLoadState) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
-  MOZ_DIAGNOSTIC_ASSERT(!mInUpdateBatch);
-
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  MOZ_ASSERT(!mClosed);
+  MOZ_ASSERT(!mInUpdateBatch);
+
+#ifdef DEBUG
   int64_t sizeOfKeys = 0;
   int64_t sizeOfItems = 0;
   for (auto item : mOrderedItems) {
     int64_t sizeOfKey = static_cast<int64_t>(item.key().Length());
     sizeOfKeys += sizeOfKey;
     sizeOfItems += sizeOfKey + static_cast<int64_t>(item.value().Length());
   }
-  MOZ_DIAGNOSTIC_ASSERT(mSizeOfKeys == sizeOfKeys);
-  MOZ_DIAGNOSTIC_ASSERT(mSizeOfItems == sizeOfItems);
+  MOZ_ASSERT(mSizeOfKeys == sizeOfKeys);
+  MOZ_ASSERT(mSizeOfItems == sizeOfItems);
 #endif
 
   int64_t size = 0;
   if (mSizeOfKeys <= gSnapshotPrefill) {
     if (mSizeOfItems <= gSnapshotPrefill) {
       aItemInfos.AppendElements(mOrderedItems);
       aLoadState = LSSnapshot::LoadState::AllOrderedItems;
     } else {
@@ -4622,51 +4638,51 @@ void Datastore::GetSnapshotInitInfo(nsTH
 
       aLoadedItems.PutEntry(key);
 
       LSItemInfo* itemInfo = aItemInfos.AppendElement();
       itemInfo->key() = iter.Key();
       itemInfo->value() = iter.Data();
     }
 
-    MOZ_DIAGNOSTIC_ASSERT(aItemInfos.Length() < mOrderedItems.Length());
+    MOZ_ASSERT(aItemInfos.Length() < mOrderedItems.Length());
     aLoadState = LSSnapshot::LoadState::Partial;
   }
 
   aTotalLength = mValues.Count();
 
   aInitialUsage = mUsage;
   aPeakUsage = aInitialUsage;
 }
 
 void Datastore::GetItem(const nsString& aKey, nsString& aValue) const {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(!mClosed);
 
   if (!mValues.Get(aKey, &aValue)) {
     aValue.SetIsVoid(true);
   }
 }
 
 void Datastore::GetKeys(nsTArray<nsString>& aKeys) const {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
+  MOZ_ASSERT(!mClosed);
 
   for (auto item : mOrderedItems) {
     aKeys.AppendElement(item.key());
   }
 }
 
 void Datastore::SetItem(Database* aDatabase, const nsString& aDocumentURI,
                         const nsString& aKey, const nsString& aOldValue,
                         const nsString& aValue) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(aDatabase);
+  MOZ_ASSERT(!mClosed);
+  MOZ_ASSERT(mInUpdateBatch);
 
   nsString oldValue;
   GetItem(aKey, oldValue);
 
   if (oldValue != aValue || oldValue.IsVoid() != aValue.IsVoid()) {
     bool isNewItem = oldValue.IsVoid();
 
     NotifySnapshots(aDatabase, aKey, oldValue, /* affectsOrder */ isNewItem);
@@ -4706,19 +4722,19 @@ void Datastore::SetItem(Database* aDatab
   }
 
   NotifyObservers(aDatabase, aDocumentURI, aKey, aOldValue, aValue);
 }
 
 void Datastore::RemoveItem(Database* aDatabase, const nsString& aDocumentURI,
                            const nsString& aKey, const nsString& aOldValue) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(aDatabase);
+  MOZ_ASSERT(!mClosed);
+  MOZ_ASSERT(mInUpdateBatch);
 
   nsString oldValue;
   GetItem(aKey, oldValue);
 
   if (!oldValue.IsVoid()) {
     NotifySnapshots(aDatabase, aKey, oldValue, /* aAffectsOrder */ true);
 
     mValues.Remove(aKey);
@@ -4738,19 +4754,19 @@ void Datastore::RemoveItem(Database* aDa
     }
   }
 
   NotifyObservers(aDatabase, aDocumentURI, aKey, aOldValue, VoidString());
 }
 
 void Datastore::Clear(Database* aDatabase, const nsString& aDocumentURI) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(aDatabase);
+  MOZ_ASSERT(!mClosed);
+  MOZ_ASSERT(mInUpdateBatch);
 
   if (mValues.Count()) {
     int64_t sizeOfItems = 0;
     for (auto iter = mValues.ConstIter(); !iter.Done(); iter.Next()) {
       const nsAString& key = iter.Key();
       const nsAString& value = iter.Data();
 
       sizeOfItems += (static_cast<int64_t>(key.Length()) +
@@ -4774,106 +4790,98 @@ void Datastore::Clear(Database* aDatabas
   }
 
   NotifyObservers(aDatabase, aDocumentURI, VoidString(), VoidString(),
                   VoidString());
 }
 
 void Datastore::PrivateBrowsingClear() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(mPrivateBrowsingId);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
-  MOZ_DIAGNOSTIC_ASSERT(!mInUpdateBatch);
+  MOZ_ASSERT(mPrivateBrowsingId);
+  MOZ_ASSERT(!mClosed);
+  MOZ_ASSERT(!mInUpdateBatch);
 
   if (mValues.Count()) {
     MarkSnapshotsDirty();
 
     mValues.Clear();
 
     mOrderedItems.Clear();
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-    bool ok = UpdateUsage(-mSizeOfItems);
-    MOZ_DIAGNOSTIC_ASSERT(ok);
-#else
-    UpdateUsage(-mSizeOfItems);
-#endif
+    DebugOnly<bool> ok = UpdateUsage(-mSizeOfItems);
+    MOZ_ASSERT(ok);
 
     mSizeOfKeys = 0;
     mSizeOfItems = 0;
   }
 }
 
 void Datastore::BeginUpdateBatch(int64_t aSnapshotInitialUsage) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aSnapshotInitialUsage >= 0);
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
-  MOZ_DIAGNOSTIC_ASSERT(mUpdateBatchUsage == -1);
-  MOZ_DIAGNOSTIC_ASSERT(!mInUpdateBatch);
+  MOZ_ASSERT(aSnapshotInitialUsage >= 0);
+  MOZ_ASSERT(!mClosed);
+  MOZ_ASSERT(mUpdateBatchUsage == -1);
+  MOZ_ASSERT(!mInUpdateBatch);
 
   mUpdateBatchUsage = aSnapshotInitialUsage;
 
   if (IsPersistent()) {
     mConnection->BeginUpdateBatch();
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   mInUpdateBatch = true;
 #endif
 }
 
 int64_t Datastore::EndUpdateBatch(int64_t aSnapshotPeakUsage) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
-  MOZ_DIAGNOSTIC_ASSERT(mInUpdateBatch);
+  MOZ_ASSERT(!mClosed);
+  MOZ_ASSERT(mInUpdateBatch);
 
   mWriteOptimizer.ApplyWrites(mOrderedItems);
 
   if (aSnapshotPeakUsage >= 0) {
     int64_t delta = mUpdateBatchUsage - aSnapshotPeakUsage;
 
     if (mActiveDatabases.Count()) {
       // We can't apply deltas while other databases are still active.
       // The final delta must be zero or negative, but individual deltas can
       // be positive. A positive delta can't be applied asynchronously since
       // there's no way to fire the quota exceeded error event.
 
       mPendingUsageDeltas.AppendElement(delta);
     } else {
-      MOZ_DIAGNOSTIC_ASSERT(delta <= 0);
+      MOZ_ASSERT(delta <= 0);
       if (delta != 0) {
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-        bool ok = UpdateUsage(delta);
-        MOZ_DIAGNOSTIC_ASSERT(ok);
-#else
-        UpdateUsage(delta);
-#endif
+        DebugOnly<bool> ok = UpdateUsage(delta);
+        MOZ_ASSERT(ok);
       }
     }
   }
 
   int64_t result = mUpdateBatchUsage;
   mUpdateBatchUsage = -1;
 
   if (IsPersistent()) {
     mConnection->EndUpdateBatch();
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   mInUpdateBatch = false;
 #endif
 
   return result;
 }
 
 int64_t Datastore::RequestUpdateUsage(int64_t aRequestedSize,
                                       int64_t aMinSize) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aRequestedSize > 0);
-  MOZ_DIAGNOSTIC_ASSERT(aMinSize > 0);
+  MOZ_ASSERT(aRequestedSize > 0);
+  MOZ_ASSERT(aMinSize > 0);
 
   if (UpdateUsage(aRequestedSize)) {
     return aRequestedSize;
   }
 
   if (UpdateUsage(aMinSize)) {
     return aMinSize;
   }
@@ -4882,25 +4890,25 @@ int64_t Datastore::RequestUpdateUsage(in
 }
 
 bool Datastore::UpdateUsage(int64_t aDelta) {
   AssertIsOnBackgroundThread();
 
   // Check internal LocalStorage origin limit.
   int64_t newUsage = mUsage + aDelta;
 
-  MOZ_DIAGNOSTIC_ASSERT(newUsage >= 0);
+  MOZ_ASSERT(newUsage >= 0);
 
   if (newUsage > gOriginLimitKB * 1024) {
     return false;
   }
 
   // Check QuotaManager limits (group and global limit).
   if (IsPersistent()) {
-    MOZ_DIAGNOSTIC_ASSERT(mQuotaObject);
+    MOZ_ASSERT(mQuotaObject);
 
     if (!mQuotaObject->MaybeUpdateSize(newUsage, /* aTruncate */ true)) {
       return false;
     }
   }
 
   // Quota checks passed, set new usage.
   mUsage = newUsage;
@@ -4914,20 +4922,20 @@ void Datastore::MaybeClose() {
   if (!mPrepareDatastoreOps.Count() && !mPreparedDatastores.Count() &&
       !mDatabases.Count()) {
     Close();
   }
 }
 
 void Datastore::ConnectionClosedCallback() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
-  MOZ_DIAGNOSTIC_ASSERT(mQuotaObject);
-  MOZ_DIAGNOSTIC_ASSERT(mClosed);
+  MOZ_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(mConnection);
+  MOZ_ASSERT(mQuotaObject);
+  MOZ_ASSERT(mClosed);
 
   // Release the quota object first.
   mQuotaObject = nullptr;
 
   // Now it's safe to release the directory lock and unregister itself from
   // the hashtable.
 
   mDirectoryLock = nullptr;
@@ -4938,30 +4946,30 @@ void Datastore::ConnectionClosedCallback
   if (mCompleteCallback) {
     MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(mCompleteCallback.forget()));
   }
 }
 
 void Datastore::CleanupMetadata() {
   AssertIsOnBackgroundThread();
 
-  MOZ_DIAGNOSTIC_ASSERT(gDatastores);
-  MOZ_DIAGNOSTIC_ASSERT(gDatastores->Get(mOrigin));
+  MOZ_ASSERT(gDatastores);
+  MOZ_ASSERT(gDatastores->Get(mOrigin));
   gDatastores->Remove(mOrigin);
 
   if (!gDatastores->Count()) {
     gDatastores = nullptr;
   }
 }
 
 void Datastore::NotifySnapshots(Database* aDatabase, const nsAString& aKey,
                                 const nsAString& aOldValue,
                                 bool aAffectsOrder) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
+  MOZ_ASSERT(aDatabase);
 
   for (auto iter = mDatabases.ConstIter(); !iter.Done(); iter.Next()) {
     Database* database = iter.Get()->GetKey();
     if (database == aDatabase) {
       continue;
     }
 
     Snapshot* snapshot = database->GetSnapshot();
@@ -4984,28 +4992,28 @@ void Datastore::MarkSnapshotsDirty() {
   }
 }
 
 void Datastore::NotifyObservers(Database* aDatabase,
                                 const nsString& aDocumentURI,
                                 const nsString& aKey, const nsString& aOldValue,
                                 const nsString& aNewValue) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
+  MOZ_ASSERT(aDatabase);
 
   if (!gObservers) {
     return;
   }
 
   nsTArray<Observer*>* array;
   if (!gObservers->Get(mOrigin, &array)) {
     return;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(array);
+  MOZ_ASSERT(array);
 
   // We do not want to send information about events back to the content process
   // that caused the change.
   PBackgroundParent* databaseBackgroundActor = aDatabase->Manager();
 
   for (Observer* observer : *array) {
     if (observer->Manager() != databaseBackgroundActor) {
       observer->Observe(aDatabase, aDocumentURI, aKey, aOldValue, aNewValue);
@@ -5014,30 +5022,30 @@ void Datastore::NotifyObservers(Database
 }
 
 /*******************************************************************************
  * PreparedDatastore
  ******************************************************************************/
 
 void PreparedDatastore::Destroy() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(gPreparedDatastores);
-  MOZ_DIAGNOSTIC_ASSERT(gPreparedDatastores->Get(mDatastoreId));
+  MOZ_ASSERT(gPreparedDatastores);
+  MOZ_ASSERT(gPreparedDatastores->Get(mDatastoreId));
 
   nsAutoPtr<PreparedDatastore> preparedDatastore;
   gPreparedDatastores->Remove(mDatastoreId, &preparedDatastore);
-  MOZ_DIAGNOSTIC_ASSERT(preparedDatastore);
+  MOZ_ASSERT(preparedDatastore);
 }
 
 // static
 void PreparedDatastore::TimerCallback(nsITimer* aTimer, void* aClosure) {
   AssertIsOnBackgroundThread();
 
   auto* self = static_cast<PreparedDatastore*>(aClosure);
-  MOZ_DIAGNOSTIC_ASSERT(self);
+  MOZ_ASSERT(self);
 
   self->Destroy();
 }
 
 /*******************************************************************************
  * Database
  ******************************************************************************/
 
@@ -5047,64 +5055,64 @@ Database::Database(const PrincipalInfo& 
     : mSnapshot(nullptr),
       mPrincipalInfo(aPrincipalInfo),
       mContentParentId(aContentParentId),
       mOrigin(aOrigin),
       mPrivateBrowsingId(aPrivateBrowsingId),
       mAllowedToClose(false),
       mActorDestroyed(false),
       mRequestedAllowToClose(false)
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
       ,
       mActorWasAlive(false)
 #endif
 {
   AssertIsOnBackgroundThread();
 }
 
 Database::~Database() {
-  MOZ_DIAGNOSTIC_ASSERT_IF(mActorWasAlive, mAllowedToClose);
-  MOZ_DIAGNOSTIC_ASSERT_IF(mActorWasAlive, mActorDestroyed);
+  MOZ_ASSERT_IF(mActorWasAlive, mAllowedToClose);
+  MOZ_ASSERT_IF(mActorWasAlive, mActorDestroyed);
 }
 
 void Database::SetActorAlive(Datastore* aDatastore) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mActorWasAlive);
-  MOZ_DIAGNOSTIC_ASSERT(!mActorDestroyed);
-
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  MOZ_ASSERT(!mActorWasAlive);
+  MOZ_ASSERT(!mActorDestroyed);
+
+#ifdef DEBUG
   mActorWasAlive = true;
 #endif
 
   mDatastore = aDatastore;
 
   mDatastore->NoteLiveDatabase(this);
 
   if (!gLiveDatabases) {
     gLiveDatabases = new LiveDatabaseArray();
   }
 
   gLiveDatabases->AppendElement(this);
 }
 
 void Database::RegisterSnapshot(Snapshot* aSnapshot) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aSnapshot);
-  MOZ_DIAGNOSTIC_ASSERT(!mSnapshot);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aSnapshot);
+  MOZ_ASSERT(!mSnapshot);
+  MOZ_ASSERT(!mAllowedToClose);
 
   // Only one snapshot at a time is currently supported.
   mSnapshot = aSnapshot;
 
   mDatastore->NoteActiveDatabase(this);
 }
 
 void Database::UnregisterSnapshot(Snapshot* aSnapshot) {
-  MOZ_DIAGNOSTIC_ASSERT(aSnapshot);
-  MOZ_DIAGNOSTIC_ASSERT(mSnapshot == aSnapshot);
+  MOZ_ASSERT(aSnapshot);
+  MOZ_ASSERT(mSnapshot == aSnapshot);
 
   mSnapshot = nullptr;
 
   mDatastore->NoteInactiveDatabase(this);
 }
 
 void Database::RequestAllowToClose() {
   AssertIsOnBackgroundThread();
@@ -5113,55 +5121,55 @@ void Database::RequestAllowToClose() {
     return;
   }
 
   mRequestedAllowToClose = true;
 
   // Send the RequestAllowToClose message to the child to avoid racing with the
   // child actor. Except the case when the actor was already destroyed.
   if (mActorDestroyed) {
-    MOZ_DIAGNOSTIC_ASSERT(mAllowedToClose);
+    MOZ_ASSERT(mAllowedToClose);
   } else {
     Unused << SendRequestAllowToClose();
   }
 }
 
 void Database::AllowToClose() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
-  MOZ_DIAGNOSTIC_ASSERT(mDatastore);
+  MOZ_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(mDatastore);
 
   mAllowedToClose = true;
 
   mDatastore->NoteFinishedDatabase(this);
 
   mDatastore = nullptr;
 
-  MOZ_DIAGNOSTIC_ASSERT(gLiveDatabases);
+  MOZ_ASSERT(gLiveDatabases);
   gLiveDatabases->RemoveElement(this);
 
   if (gLiveDatabases->IsEmpty()) {
     gLiveDatabases = nullptr;
   }
 }
 
 void Database::ActorDestroy(ActorDestroyReason aWhy) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mActorDestroyed);
+  MOZ_ASSERT(!mActorDestroyed);
 
   mActorDestroyed = true;
 
   if (!mAllowedToClose) {
     AllowToClose();
   }
 }
 
 mozilla::ipc::IPCResult Database::RecvDeleteMe() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mActorDestroyed);
+  MOZ_ASSERT(!mActorDestroyed);
 
   IProtocol* mgr = Manager();
   if (!PBackgroundLSDatabaseParent::Send__delete__(this)) {
     return IPC_FAIL_NO_REASON(mgr);
   }
   return IPC_OK();
 }
 
@@ -5205,20 +5213,20 @@ PBackgroundLSSnapshotParent* Database::A
   return snapshot.forget().take();
 }
 
 mozilla::ipc::IPCResult Database::RecvPBackgroundLSSnapshotConstructor(
     PBackgroundLSSnapshotParent* aActor, const nsString& aDocumentURI,
     const bool& aIncreasePeakUsage, const int64_t& aRequestedSize,
     const int64_t& aMinSize, LSSnapshotInitInfo* aInitInfo) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT_IF(aIncreasePeakUsage, aRequestedSize > 0);
-  MOZ_DIAGNOSTIC_ASSERT_IF(aIncreasePeakUsage, aMinSize > 0);
-  MOZ_DIAGNOSTIC_ASSERT(aInitInfo);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT_IF(aIncreasePeakUsage, aRequestedSize > 0);
+  MOZ_ASSERT_IF(aIncreasePeakUsage, aMinSize > 0);
+  MOZ_ASSERT(aInitInfo);
+  MOZ_ASSERT(!mAllowedToClose);
 
   auto* snapshot = static_cast<Snapshot*>(aActor);
 
   // TODO: This can be optimized depending on which operation triggers snapshot
   //       creation. For example clear() doesn't need to receive items at all.
   nsTHashtable<nsStringHashKey> loadedItems;
   nsTArray<LSItemInfo> itemInfos;
   uint32_t totalLength;
@@ -5244,17 +5252,17 @@ mozilla::ipc::IPCResult Database::RecvPB
   aInitInfo->loadState() = loadState;
 
   return IPC_OK();
 }
 
 bool Database::DeallocPBackgroundLSSnapshotParent(
     PBackgroundLSSnapshotParent* aActor) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
+  MOZ_ASSERT(aActor);
 
   // Transfer ownership back from IPDL.
   RefPtr<Snapshot> actor = dont_AddRef(static_cast<Snapshot*>(aActor));
 
   return true;
 }
 
 /*******************************************************************************
@@ -5271,22 +5279,22 @@ Snapshot::Snapshot(Database* aDatabase, 
       mSavedKeys(false),
       mActorDestroyed(false),
       mFinishReceived(false),
       mLoadedReceived(false),
       mLoadedAllItems(false),
       mLoadKeysReceived(false),
       mSentMarkDirty(false) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
+  MOZ_ASSERT(aDatabase);
 }
 
 Snapshot::~Snapshot() {
-  MOZ_DIAGNOSTIC_ASSERT(mActorDestroyed);
-  MOZ_DIAGNOSTIC_ASSERT(mFinishReceived);
+  MOZ_ASSERT(mActorDestroyed);
+  MOZ_ASSERT(mFinishReceived);
 }
 
 void Snapshot::SaveItem(const nsAString& aKey, const nsAString& aOldValue,
                         bool aAffectsOrder) {
   AssertIsOnBackgroundThread();
 
   MarkDirty();
 
@@ -5311,56 +5319,56 @@ void Snapshot::MarkDirty() {
   if (!mSentMarkDirty) {
     Unused << SendMarkDirty();
     mSentMarkDirty = true;
   }
 }
 
 void Snapshot::Finish() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(mDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(mDatastore);
-  MOZ_DIAGNOSTIC_ASSERT(!mFinishReceived);
+  MOZ_ASSERT(mDatabase);
+  MOZ_ASSERT(mDatastore);
+  MOZ_ASSERT(!mFinishReceived);
 
   mDatastore->BeginUpdateBatch(mUsage);
 
   mDatastore->EndUpdateBatch(mPeakUsage);
 
   mDatabase->UnregisterSnapshot(this);
 
   mFinishReceived = true;
 }
 
 void Snapshot::ActorDestroy(ActorDestroyReason aWhy) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mActorDestroyed);
+  MOZ_ASSERT(!mActorDestroyed);
 
   mActorDestroyed = true;
 
   if (!mFinishReceived) {
     Finish();
   }
 }
 
 mozilla::ipc::IPCResult Snapshot::RecvDeleteMe() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mActorDestroyed);
+  MOZ_ASSERT(!mActorDestroyed);
 
   IProtocol* mgr = Manager();
   if (!PBackgroundLSSnapshotParent::Send__delete__(this)) {
     return IPC_FAIL_NO_REASON(mgr);
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult Snapshot::RecvCheckpoint(
     nsTArray<LSWriteInfo>&& aWriteInfos) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(mUsage >= 0);
-  MOZ_DIAGNOSTIC_ASSERT(mPeakUsage >= mUsage);
+  MOZ_ASSERT(mUsage >= 0);
+  MOZ_ASSERT(mPeakUsage >= mUsage);
 
   if (NS_WARN_IF(aWriteInfos.IsEmpty())) {
     ASSERT_UNLESS_FUZZING();
     return IPC_FAIL_NO_REASON(this);
   }
 
   mDatastore->BeginUpdateBatch(mUsage);
 
@@ -5447,18 +5455,18 @@ mozilla::ipc::IPCResult Snapshot::RecvLo
   mLoadKeysReceived = true;
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult Snapshot::RecvLoadItem(const nsString& aKey,
                                                nsString* aValue) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aValue);
-  MOZ_DIAGNOSTIC_ASSERT(mDatastore);
+  MOZ_ASSERT(aValue);
+  MOZ_ASSERT(mDatastore);
 
   if (NS_WARN_IF(mFinishReceived)) {
     ASSERT_UNLESS_FUZZING();
     return IPC_FAIL_NO_REASON(this);
   }
 
   if (NS_WARN_IF(mLoadedReceived)) {
     ASSERT_UNLESS_FUZZING();
@@ -5485,33 +5493,33 @@ mozilla::ipc::IPCResult Snapshot::RecvLo
   if (aValue->IsVoid()) {
     mUnknownItems.PutEntry(aKey);
   } else {
     mLoadedItems.PutEntry(aKey);
 
     if (mLoadedItems.Count() == mTotalLength) {
       mLoadedItems.Clear();
       mUnknownItems.Clear();
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
       for (auto iter = mValues.ConstIter(); !iter.Done(); iter.Next()) {
-        MOZ_DIAGNOSTIC_ASSERT(iter.Data().IsVoid());
+        MOZ_ASSERT(iter.Data().IsVoid());
       }
 #endif
       mValues.Clear();
       mLoadedAllItems = true;
     }
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult Snapshot::RecvLoadKeys(nsTArray<nsString>* aKeys) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aKeys);
-  MOZ_DIAGNOSTIC_ASSERT(mDatastore);
+  MOZ_ASSERT(aKeys);
+  MOZ_ASSERT(mDatastore);
 
   if (NS_WARN_IF(mFinishReceived)) {
     ASSERT_UNLESS_FUZZING();
     return IPC_FAIL_NO_REASON(this);
   }
 
   if (NS_WARN_IF(mLoadedReceived)) {
     ASSERT_UNLESS_FUZZING();
@@ -5532,17 +5540,17 @@ mozilla::ipc::IPCResult Snapshot::RecvLo
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult Snapshot::RecvIncreasePeakUsage(
     const int64_t& aRequestedSize, const int64_t& aMinSize, int64_t* aSize) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aSize);
+  MOZ_ASSERT(aSize);
 
   if (NS_WARN_IF(aRequestedSize <= 0)) {
     ASSERT_UNLESS_FUZZING();
     return IPC_FAIL_NO_REASON(this);
   }
 
   if (NS_WARN_IF(aMinSize <= 0)) {
     ASSERT_UNLESS_FUZZING();
@@ -5576,55 +5584,55 @@ mozilla::ipc::IPCResult Snapshot::RecvPi
  * Observer
  ******************************************************************************/
 
 Observer::Observer(const nsACString& aOrigin)
     : mOrigin(aOrigin), mActorDestroyed(false) {
   AssertIsOnBackgroundThread();
 }
 
-Observer::~Observer() { MOZ_DIAGNOSTIC_ASSERT(mActorDestroyed); }
+Observer::~Observer() { MOZ_ASSERT(mActorDestroyed); }
 
 void Observer::Observe(Database* aDatabase, const nsString& aDocumentURI,
                        const nsString& aKey, const nsString& aOldValue,
                        const nsString& aNewValue) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(aDatabase);
+  MOZ_ASSERT(aDatabase);
 
   Unused << SendObserve(aDatabase->GetPrincipalInfo(),
                         aDatabase->PrivateBrowsingId(), aDocumentURI, aKey,
                         aOldValue, aNewValue);
 }
 
 void Observer::ActorDestroy(ActorDestroyReason aWhy) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mActorDestroyed);
+  MOZ_ASSERT(!mActorDestroyed);
 
   mActorDestroyed = true;
 
-  MOZ_DIAGNOSTIC_ASSERT(gObservers);
+  MOZ_ASSERT(gObservers);
 
   nsTArray<Observer*>* array;
   gObservers->Get(mOrigin, &array);
-  MOZ_DIAGNOSTIC_ASSERT(array);
+  MOZ_ASSERT(array);
 
   array->RemoveElement(this);
 
   if (array->IsEmpty()) {
     gObservers->Remove(mOrigin);
   }
 
   if (!gObservers->Count()) {
     gObservers = nullptr;
   }
 }
 
 mozilla::ipc::IPCResult Observer::RecvDeleteMe() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mActorDestroyed);
+  MOZ_ASSERT(!mActorDestroyed);
 
   IProtocol* mgr = Manager();
   if (!PBackgroundLSObserverParent::Send__delete__(this)) {
     return IPC_FAIL_NO_REASON(mgr);
   }
   return IPC_OK();
 }
 
@@ -5633,19 +5641,18 @@ mozilla::ipc::IPCResult Observer::RecvDe
  ******************************************************************************/
 
 LSRequestBase::LSRequestBase(nsIEventTarget* aMainEventTarget)
     : mMainEventTarget(aMainEventTarget),
       mState(State::Initial),
       mWaitingForFinish(false) {}
 
 LSRequestBase::~LSRequestBase() {
-  MOZ_DIAGNOSTIC_ASSERT_IF(
-      MayProceedOnNonOwningThread(),
-      mState == State::Initial || mState == State::Completed);
+  MOZ_ASSERT_IF(MayProceedOnNonOwningThread(),
+                mState == State::Initial || mState == State::Completed);
 }
 
 void LSRequestBase::Dispatch() {
   AssertIsOnOwningThread();
 
   mState = State::Opening;
 
   MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(this));
@@ -5705,34 +5712,34 @@ void LSRequestBase::LogState() {
       break;
 
     default:;
   }
 }
 
 void LSRequestBase::SendReadyMessage() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::SendingReadyMessage);
+  MOZ_ASSERT(mState == State::SendingReadyMessage);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     MaybeSetFailureCode(NS_ERROR_FAILURE);
   }
 
   nsresult rv = SendReadyMessageInternal();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     MaybeSetFailureCode(rv);
 
     FinishInternal();
   }
 }
 
 nsresult LSRequestBase::SendReadyMessageInternal() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::SendingReadyMessage);
+  MOZ_ASSERT(mState == State::SendingReadyMessage);
 
   if (!MayProceed()) {
     return NS_ERROR_FAILURE;
   }
 
   if (NS_WARN_IF(!SendReady())) {
     return NS_ERROR_FAILURE;
   }
@@ -5741,40 +5748,40 @@ nsresult LSRequestBase::SendReadyMessage
 
   mWaitingForFinish = true;
 
   return NS_OK;
 }
 
 void LSRequestBase::Finish() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::WaitingForFinish);
+  MOZ_ASSERT(mState == State::WaitingForFinish);
 
   mWaitingForFinish = false;
 
   FinishInternal();
 }
 
 void LSRequestBase::FinishInternal() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::SendingReadyMessage ||
-                        mState == State::WaitingForFinish);
+  MOZ_ASSERT(mState == State::SendingReadyMessage ||
+             mState == State::WaitingForFinish);
 
   mState = State::SendingResults;
 
   // This LSRequestBase can only be held alive by the IPDL. Run() can end up
   // with clearing that last reference. So we need to add a self reference here.
   RefPtr<LSRequestBase> kungFuDeathGrip = this;
 
   MOZ_ALWAYS_SUCCEEDS(this->Run());
 }
 
 void LSRequestBase::SendResults() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::SendingResults);
+  MOZ_ASSERT(mState == State::SendingResults);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     MaybeSetFailureCode(NS_ERROR_FAILURE);
   }
 
   if (MayProceed()) {
     LSRequestResponse response;
@@ -5905,106 +5912,103 @@ PrepareDatastoreOp::PrepareDatastoreOp(
       mSizeOfKeys(0),
       mSizeOfItems(0),
       mNestedState(NestedState::BeforeNesting),
       mCreateIfNotExists(aParams.type() ==
                          LSRequestParams::TLSRequestPrepareDatastoreParams),
       mDatabaseNotAvailable(false),
       mRequestedDirectoryLock(false),
       mInvalidated(false)
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
       ,
       mDEBUGUsage(0)
 #endif
 {
-  MOZ_DIAGNOSTIC_ASSERT(
+  MOZ_ASSERT(
       aParams.type() == LSRequestParams::TLSRequestPreloadDatastoreParams ||
       aParams.type() == LSRequestParams::TLSRequestPrepareDatastoreParams);
 }
 
 PrepareDatastoreOp::~PrepareDatastoreOp() {
-  MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT_IF(
-      MayProceedOnNonOwningThread(),
-      mState == State::Initial || mState == State::Completed);
-  MOZ_DIAGNOSTIC_ASSERT(!mLoadDataOp);
+  MOZ_ASSERT(!mDirectoryLock);
+  MOZ_ASSERT_IF(MayProceedOnNonOwningThread(),
+                mState == State::Initial || mState == State::Completed);
+  MOZ_ASSERT(!mLoadDataOp);
 }
 
 nsresult PrepareDatastoreOp::Open() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Opening);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::BeforeNesting);
+  MOZ_ASSERT(mState == State::Opening);
+  MOZ_ASSERT(mNestedState == NestedState::BeforeNesting);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceedOnNonOwningThread()) {
     return NS_ERROR_FAILURE;
   }
 
   const PrincipalInfo& principalInfo = mParams.principalInfo();
 
   if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
     QuotaManager::GetInfoForChrome(&mSuffix, &mGroup, &mOrigin);
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(principalInfo.type() ==
-                          PrincipalInfo::TContentPrincipalInfo);
+    MOZ_ASSERT(principalInfo.type() == PrincipalInfo::TContentPrincipalInfo);
 
     QuotaManager::GetInfoFromValidatedPrincipalInfo(
         principalInfo, &mSuffix, &mGroup, &mMainThreadOrigin);
   }
 
   mState = State::Nesting;
   mNestedState = NestedState::CheckExistingOperations;
 
   MOZ_ALWAYS_SUCCEEDS(OwningEventTarget()->Dispatch(this, NS_DISPATCH_NORMAL));
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::CheckExistingOperations() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::CheckExistingOperations);
-  MOZ_DIAGNOSTIC_ASSERT(gPrepareDatastoreOps);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::CheckExistingOperations);
+  MOZ_ASSERT(gPrepareDatastoreOps);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     return NS_ERROR_FAILURE;
   }
 
   const PrincipalInfo& principalInfo = mParams.principalInfo();
 
   nsCString originAttrSuffix;
   uint32_t privateBrowsingId;
 
   if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
     privateBrowsingId = 0;
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(principalInfo.type() ==
-                          PrincipalInfo::TContentPrincipalInfo);
+    MOZ_ASSERT(principalInfo.type() == PrincipalInfo::TContentPrincipalInfo);
 
     const ContentPrincipalInfo& info = principalInfo.get_ContentPrincipalInfo();
     const OriginAttributes& attrs = info.attrs();
     attrs.CreateSuffix(originAttrSuffix);
 
     privateBrowsingId = attrs.mPrivateBrowsingId;
   }
 
   mArchivedOriginScope = ArchivedOriginScope::CreateFromOrigin(
       originAttrSuffix, mParams.originKey());
-  MOZ_DIAGNOSTIC_ASSERT(mArchivedOriginScope);
+  MOZ_ASSERT(mArchivedOriginScope);
 
   // Normally it's safe to access member variables without a mutex because even
   // though we hop between threads, the variables are never accessed by multiple
   // threads at the same time.
   // However, the methods OriginIsKnown and Origin can be called at any time.
   // So we have to make sure the member variable is set on the same thread as
   // those methods are called.
   mOrigin = mMainThreadOrigin;
 
-  MOZ_DIAGNOSTIC_ASSERT(!mOrigin.IsEmpty());
+  MOZ_ASSERT(!mOrigin.IsEmpty());
 
   mPrivateBrowsingId = privateBrowsingId;
 
   mNestedState = NestedState::CheckClosingDatastore;
 
   // See if this PrepareDatastoreOp needs to wait.
   bool foundThis = false;
   for (uint32_t index = gPrepareDatastoreOps->Length(); index > 0; index--) {
@@ -6012,55 +6016,55 @@ nsresult PrepareDatastoreOp::CheckExisti
 
     if (existingOp == this) {
       foundThis = true;
       continue;
     }
 
     if (foundThis && existingOp->Origin() == mOrigin) {
       // Only one op can be delayed.
-      MOZ_DIAGNOSTIC_ASSERT(!existingOp->mDelayedOp);
+      MOZ_ASSERT(!existingOp->mDelayedOp);
       existingOp->mDelayedOp = this;
 
       return NS_OK;
     }
   }
 
   nsresult rv = CheckClosingDatastoreInternal();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::CheckClosingDatastore() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::CheckClosingDatastore);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::CheckClosingDatastore);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = CheckClosingDatastoreInternal();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::CheckClosingDatastoreInternal() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::CheckClosingDatastore);
-  MOZ_DIAGNOSTIC_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
-  MOZ_DIAGNOSTIC_ASSERT(MayProceed());
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::CheckClosingDatastore);
+  MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
+  MOZ_ASSERT(MayProceed());
 
   mNestedState = NestedState::PreparationPending;
 
   RefPtr<Datastore> datastore;
   if (gDatastores && (datastore = gDatastores->Get(mOrigin)) &&
       datastore->IsClosed()) {
     datastore->WaitForConnectionToComplete(this);
 
@@ -6072,41 +6076,41 @@ nsresult PrepareDatastoreOp::CheckClosin
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::BeginDatastorePreparation() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::PreparationPending);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::PreparationPending);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = BeginDatastorePreparationInternal();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::BeginDatastorePreparationInternal() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::PreparationPending);
-  MOZ_DIAGNOSTIC_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
-  MOZ_DIAGNOSTIC_ASSERT(MayProceed());
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::PreparationPending);
+  MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
+  MOZ_ASSERT(MayProceed());
 
   if (gDatastores && (mDatastore = gDatastores->Get(mOrigin))) {
-    MOZ_DIAGNOSTIC_ASSERT(!mDatastore->IsClosed());
+    MOZ_ASSERT(!mDatastore->IsClosed());
 
     mDatastore->NoteLivePrepareDatastoreOp(this);
 
     FinishNesting();
 
     return NS_OK;
   }
 
@@ -6122,18 +6126,18 @@ nsresult PrepareDatastoreOp::BeginDatast
   mNestedState = NestedState::QuotaManagerPending;
   QuotaManager::GetOrCreate(this, mMainEventTarget);
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::QuotaManagerOpen() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::QuotaManagerPending);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::QuotaManagerPending);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     return NS_ERROR_FAILURE;
   }
 
   if (NS_WARN_IF(!QuotaManager::Get())) {
     return NS_ERROR_FAILURE;
@@ -6144,48 +6148,48 @@ nsresult PrepareDatastoreOp::QuotaManage
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::OpenDirectory() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::PreparationPending ||
-                        mNestedState == NestedState::QuotaManagerPending);
-  MOZ_DIAGNOSTIC_ASSERT(!mOrigin.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
-  MOZ_DIAGNOSTIC_ASSERT(MayProceed());
-  MOZ_DIAGNOSTIC_ASSERT(QuotaManager::Get());
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::PreparationPending ||
+             mNestedState == NestedState::QuotaManagerPending);
+  MOZ_ASSERT(!mOrigin.IsEmpty());
+  MOZ_ASSERT(!mDirectoryLock);
+  MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
+  MOZ_ASSERT(MayProceed());
+  MOZ_ASSERT(QuotaManager::Get());
 
   mNestedState = NestedState::DirectoryOpenPending;
   RefPtr<DirectoryLock> pendingDirectoryLock =
       QuotaManager::Get()->CreateDirectoryLock(PERSISTENCE_TYPE_DEFAULT, mGroup,
                                                mOrigin,
                                                mozilla::dom::quota::Client::LS,
                                                /* aExclusive */ false, this);
-  MOZ_DIAGNOSTIC_ASSERT(pendingDirectoryLock);
+  MOZ_ASSERT(pendingDirectoryLock);
 
   if (mNestedState == NestedState::DirectoryOpenPending) {
     mPendingDirectoryLock = pendingDirectoryLock.forget();
   }
 
   mRequestedDirectoryLock = true;
 
   return NS_OK;
 }
 
 void PrepareDatastoreOp::SendToIOThread() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::DirectoryOpenPending);
-  MOZ_DIAGNOSTIC_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
-  MOZ_DIAGNOSTIC_ASSERT(MayProceed());
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::DirectoryOpenPending);
+  MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
+  MOZ_ASSERT(MayProceed());
 
   // Skip all disk related stuff and transition to SendingReadyMessage if we
   // are preparing a datastore for private browsing.
   // Note that we do use a directory lock for private browsing even though we
   // don't do any stuff on disk. The thing is that without a directory lock,
   // quota manager wouldn't call AbortOperations for our private browsing
   // origin when a clear origin operation is requested. AbortOperations
   // requests all databases to close and the datastore is destroyed in the end.
@@ -6193,47 +6197,47 @@ void PrepareDatastoreOp::SendToIOThread(
   // (empty) datastore.
   if (mPrivateBrowsingId) {
     FinishNesting();
 
     return;
   }
 
   QuotaManager* quotaManager = QuotaManager::Get();
-  MOZ_DIAGNOSTIC_ASSERT(quotaManager);
+  MOZ_ASSERT(quotaManager);
 
   // Must set this before dispatching otherwise we will race with the IO thread.
   mNestedState = NestedState::DatabaseWorkOpen;
 
   MOZ_ALWAYS_SUCCEEDS(
       quotaManager->IOThread()->Dispatch(this, NS_DISPATCH_NORMAL));
 }
 
 nsresult PrepareDatastoreOp::DatabaseWork() {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(mArchivedOriginScope);
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::DatabaseWorkOpen);
+  MOZ_ASSERT(mArchivedOriginScope);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::DatabaseWorkOpen);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
       !MayProceedOnNonOwningThread()) {
     return NS_ERROR_FAILURE;
   }
 
   QuotaManager* quotaManager = QuotaManager::Get();
-  MOZ_DIAGNOSTIC_ASSERT(quotaManager);
+  MOZ_ASSERT(quotaManager);
 
   nsresult rv;
 
   if (!gArchivedOrigins) {
     rv = LoadArchivedOrigins();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
-    MOZ_DIAGNOSTIC_ASSERT(gArchivedOrigins);
+    MOZ_ASSERT(gArchivedOrigins);
   }
 
   bool hasDataForMigration = mArchivedOriginScope->HasMatches(gArchivedOrigins);
 
   bool createIfNotExists = mCreateIfNotExists || hasDataForMigration;
 
   nsCOMPtr<nsIFile> directoryEntry;
   rv = quotaManager->EnsureOriginIsInitialized(
@@ -6276,25 +6280,21 @@ nsresult PrepareDatastoreOp::DatabaseWor
   if (rv == NS_ERROR_NOT_AVAILABLE) {
     return DatabaseNotAvailable();
   }
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (alreadyExisted) {
-    MOZ_DIAGNOSTIC_ASSERT(gUsages);
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-    bool hasUsage = gUsages->Get(mOrigin, &mUsage);
-    MOZ_DIAGNOSTIC_ASSERT(hasUsage);
-#else
-    gUsages->Get(mOrigin, &mUsage);
-#endif
+    MOZ_ASSERT(gUsages);
+    DebugOnly<bool> hasUsage = gUsages->Get(mOrigin, &mUsage);
+    MOZ_ASSERT(hasUsage);
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(mUsage == 0);
+    MOZ_ASSERT(mUsage == 0);
     InitUsageForOrigin(mOrigin, mUsage);
   }
 
   rv = directoryEntry->GetPath(mDatabaseFilePath);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -6322,31 +6322,31 @@ nsresult PrepareDatastoreOp::DatabaseWor
   }
 
   rv = VerifyDatabaseInformation(connection);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (hasDataForMigration) {
-    MOZ_DIAGNOSTIC_ASSERT(mUsage == 0);
+    MOZ_ASSERT(mUsage == 0);
 
     rv = AttachArchiveDatabase(quotaManager->GetStoragePath(), connection);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     int64_t newUsage;
     rv = GetUsage(connection, mArchivedOriginScope, &newUsage);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     RefPtr<QuotaObject> quotaObject = GetQuotaObject();
-    MOZ_DIAGNOSTIC_ASSERT(quotaObject);
+    MOZ_ASSERT(quotaObject);
 
     if (!quotaObject->MaybeUpdateSize(newUsage, /* aTruncate */ true)) {
       return NS_ERROR_FILE_NO_DEVICE_SPACE;
     }
 
     mozStorageTransaction transaction(
         connection, false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
 
@@ -6415,24 +6415,24 @@ nsresult PrepareDatastoreOp::DatabaseWor
       return rv;
     }
 
     rv = DetachArchiveDatabase(connection);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    MOZ_DIAGNOSTIC_ASSERT(gArchivedOrigins);
-    MOZ_DIAGNOSTIC_ASSERT(mArchivedOriginScope->HasMatches(gArchivedOrigins));
+    MOZ_ASSERT(gArchivedOrigins);
+    MOZ_ASSERT(mArchivedOriginScope->HasMatches(gArchivedOrigins));
     mArchivedOriginScope->RemoveMatches(gArchivedOrigins);
 
     mUsage = newUsage;
 
-    MOZ_DIAGNOSTIC_ASSERT(gUsages);
-    MOZ_DIAGNOSTIC_ASSERT(gUsages->Contains(mOrigin));
+    MOZ_ASSERT(gUsages);
+    MOZ_ASSERT(gUsages->Contains(mOrigin));
     gUsages->Put(mOrigin, newUsage);
   }
 
   nsCOMPtr<mozIStorageConnection> shadowConnection;
   if (!gInitializedShadowStorage) {
     rv = CreateShadowStorageConnection(quotaManager->GetBasePath(),
                                        getter_AddRefs(shadowConnection));
     if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -6459,35 +6459,35 @@ nsresult PrepareDatastoreOp::DatabaseWor
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::DatabaseNotAvailable() {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::DatabaseWorkOpen);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::DatabaseWorkOpen);
 
   mDatabaseNotAvailable = true;
 
   nsresult rv = FinishNestingOnNonOwningThread();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::EnsureDirectoryEntry(nsIFile* aEntry,
                                                   bool aCreateIfNotExists,
                                                   bool aIsDirectory,
                                                   bool* aAlreadyExisted) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aEntry);
+  MOZ_ASSERT(aEntry);
 
   bool exists;
   nsresult rv = aEntry->Exists(&exists);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (!exists) {
@@ -6497,34 +6497,34 @@ nsresult PrepareDatastoreOp::EnsureDirec
 
     if (aIsDirectory) {
       rv = aEntry->Create(nsIFile::DIRECTORY_TYPE, 0755);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
   }
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   else {
     bool isDirectory;
-    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(aEntry->IsDirectory(&isDirectory)));
-    MOZ_DIAGNOSTIC_ASSERT(isDirectory == aIsDirectory);
+    MOZ_ASSERT(NS_SUCCEEDED(aEntry->IsDirectory(&isDirectory)));
+    MOZ_ASSERT(isDirectory == aIsDirectory);
   }
 #endif
 
   if (aAlreadyExisted) {
     *aAlreadyExisted = exists;
   }
   return NS_OK;
 }
 
 nsresult PrepareDatastoreOp::VerifyDatabaseInformation(
     mozIStorageConnection* aConnection) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
+  MOZ_ASSERT(aConnection);
 
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv =
       aConnection->CreateStatement(NS_LITERAL_CSTRING("SELECT origin "
                                                       "FROM database"),
                                    getter_AddRefs(stmt));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -6550,48 +6550,48 @@ nsresult PrepareDatastoreOp::VerifyDatab
     return NS_ERROR_FILE_CORRUPTED;
   }
 
   return NS_OK;
 }
 
 already_AddRefed<QuotaObject> PrepareDatastoreOp::GetQuotaObject() {
   MOZ_ASSERT(IsOnOwningThread() || IsOnIOThread());
-  MOZ_DIAGNOSTIC_ASSERT(!mGroup.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(!mOrigin.IsEmpty());
-  MOZ_DIAGNOSTIC_ASSERT(!mDatabaseFilePath.IsEmpty());
+  MOZ_ASSERT(!mGroup.IsEmpty());
+  MOZ_ASSERT(!mOrigin.IsEmpty());
+  MOZ_ASSERT(!mDatabaseFilePath.IsEmpty());
 
   QuotaManager* quotaManager = QuotaManager::Get();
-  MOZ_DIAGNOSTIC_ASSERT(quotaManager);
+  MOZ_ASSERT(quotaManager);
 
   RefPtr<QuotaObject> quotaObject = quotaManager->GetQuotaObject(
       PERSISTENCE_TYPE_DEFAULT, mGroup, mOrigin, mDatabaseFilePath, mUsage);
-  MOZ_DIAGNOSTIC_ASSERT(quotaObject);
+  MOZ_ASSERT(quotaObject);
 
   return quotaObject.forget();
 }
 
 nsresult PrepareDatastoreOp::BeginLoadData() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::BeginLoadData);
-  MOZ_DIAGNOSTIC_ASSERT(!mConnection);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::BeginLoadData);
+  MOZ_ASSERT(!mConnection);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     return NS_ERROR_FAILURE;
   }
 
   if (!gConnectionThread) {
     gConnectionThread = new ConnectionThread();
   }
 
   mConnection = gConnectionThread->CreateConnection(
       mOrigin, mDirectoryPath, std::move(mArchivedOriginScope));
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
+  MOZ_ASSERT(mConnection);
 
   // Must set this before dispatching otherwise we will race with the
   // connection thread.
   mNestedState = NestedState::DatabaseWorkLoadData;
 
   // Can't assign to mLoadDataOp directly since that's a weak reference and
   // LoadDataOp is reference counted.
   RefPtr<LoadDataOp> loadDataOp = new LoadDataOp(this);
@@ -6603,30 +6603,30 @@ nsresult PrepareDatastoreOp::BeginLoadDa
   // destroyed.
   mLoadDataOp = loadDataOp;
 
   return NS_OK;
 }
 
 void PrepareDatastoreOp::FinishNesting() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mState == State::Nesting);
 
   // The caller holds a strong reference to us, no need for a self reference
   // before calling Run().
 
   mState = State::SendingReadyMessage;
   mNestedState = NestedState::AfterNesting;
 
   MOZ_ALWAYS_SUCCEEDS(Run());
 }
 
 nsresult PrepareDatastoreOp::FinishNestingOnNonOwningThread() {
   MOZ_ASSERT(!IsOnOwningThread());
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mState == State::Nesting);
 
   // Must set mState before dispatching otherwise we will race with the owning
   // thread.
   mState = State::SendingReadyMessage;
   mNestedState = NestedState::AfterNesting;
 
   nsresult rv = OwningEventTarget()->Dispatch(this, NS_DISPATCH_NORMAL);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -6674,51 +6674,51 @@ nsresult PrepareDatastoreOp::NestedRun()
     return rv;
   }
 
   return NS_OK;
 }
 
 void PrepareDatastoreOp::GetResponse(LSRequestResponse& aResponse) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::SendingResults);
-  MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(ResultCode()));
+  MOZ_ASSERT(mState == State::SendingResults);
+  MOZ_ASSERT(NS_SUCCEEDED(ResultCode()));
 
   if (mDatabaseNotAvailable) {
-    MOZ_DIAGNOSTIC_ASSERT(!mCreateIfNotExists);
+    MOZ_ASSERT(!mCreateIfNotExists);
 
     LSRequestPreloadDatastoreResponse preloadDatastoreResponse;
 
     aResponse = preloadDatastoreResponse;
 
     return;
   }
 
   if (!mDatastore) {
-    MOZ_DIAGNOSTIC_ASSERT(mUsage == mDEBUGUsage);
+    MOZ_ASSERT(mUsage == mDEBUGUsage);
 
     RefPtr<QuotaObject> quotaObject;
 
     if (mPrivateBrowsingId == 0) {
       quotaObject = GetQuotaObject();
-      MOZ_DIAGNOSTIC_ASSERT(quotaObject);
+      MOZ_ASSERT(quotaObject);
     }
 
     mDatastore = new Datastore(mOrigin, mPrivateBrowsingId, mUsage, mSizeOfKeys,
                                mSizeOfItems, mDirectoryLock.forget(),
                                mConnection.forget(), quotaObject.forget(),
                                mValues, mOrderedItems);
 
     mDatastore->NoteLivePrepareDatastoreOp(this);
 
     if (!gDatastores) {
       gDatastores = new DatastoreHashtable();
     }
 
-    MOZ_DIAGNOSTIC_ASSERT(!gDatastores->Get(mOrigin));
+    MOZ_ASSERT(!gDatastores->Get(mOrigin));
     gDatastores->Put(mOrigin, mDatastore);
   }
 
   uint64_t datastoreId = ++gLastDatastoreId;
 
   nsAutoPtr<PreparedDatastore> preparedDatastore(
       new PreparedDatastore(mDatastore, mContentParentId, mOrigin, datastoreId,
                             /* aForPreload */ !mCreateIfNotExists));
@@ -6745,82 +6745,82 @@ void PrepareDatastoreOp::GetResponse(LSR
     aResponse = preloadDatastoreResponse;
   }
 }
 
 void PrepareDatastoreOp::Cleanup() {
   AssertIsOnOwningThread();
 
   if (mDatastore) {
-    MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock);
-    MOZ_DIAGNOSTIC_ASSERT(!mConnection);
+    MOZ_ASSERT(!mDirectoryLock);
+    MOZ_ASSERT(!mConnection);
 
     if (NS_FAILED(ResultCode())) {
-      MOZ_DIAGNOSTIC_ASSERT(!mDatastore->IsClosed());
-      MOZ_DIAGNOSTIC_ASSERT(!mDatastore->HasLiveDatabases());
-      MOZ_DIAGNOSTIC_ASSERT(!mDatastore->HasLivePreparedDatastores());
+      MOZ_ASSERT(!mDatastore->IsClosed());
+      MOZ_ASSERT(!mDatastore->HasLiveDatabases());
+      MOZ_ASSERT(!mDatastore->HasLivePreparedDatastores());
       mDatastore->Close();
     }
 
     // Make sure to release the datastore on this thread.
 
     mDatastore->NoteFinishedPrepareDatastoreOp(this);
 
     mDatastore = nullptr;
 
     CleanupMetadata();
   } else if (mConnection) {
     // If we have a connection then the operation must have failed and there
     // must be a directory lock too.
-    MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(ResultCode()));
-    MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
+    MOZ_ASSERT(NS_FAILED(ResultCode()));
+    MOZ_ASSERT(mDirectoryLock);
 
     // We must close the connection on the connection thread before releasing
     // it on this thread. The directory lock can't be released either.
     nsCOMPtr<nsIRunnable> callback =
         NewRunnableMethod("dom::OpenDatabaseOp::ConnectionClosedCallback", this,
                           &PrepareDatastoreOp::ConnectionClosedCallback);
 
     mConnection->Close(callback);
   } else {
     // If we don't have a connection, but we do have a directory lock then the
     // operation must have failed or we were preloading a datastore and there
     // was no physical database on disk.
-    MOZ_DIAGNOSTIC_ASSERT_IF(mDirectoryLock,
-                             NS_FAILED(ResultCode()) || mDatabaseNotAvailable);
+    MOZ_ASSERT_IF(mDirectoryLock,
+                  NS_FAILED(ResultCode()) || mDatabaseNotAvailable);
 
     // There's no connection, so it's safe to release the directory lock and
     // unregister itself from the array.
 
     mDirectoryLock = nullptr;
 
     CleanupMetadata();
   }
 }
 
 void PrepareDatastoreOp::ConnectionClosedCallback() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(ResultCode()));
-  MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock);
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
+  MOZ_ASSERT(NS_FAILED(ResultCode()));
+  MOZ_ASSERT(mDirectoryLock);
+  MOZ_ASSERT(mConnection);
 
   mConnection = nullptr;
   mDirectoryLock = nullptr;
 
   CleanupMetadata();
 }
 
 void PrepareDatastoreOp::CleanupMetadata() {
   AssertIsOnOwningThread();
 
   if (mDelayedOp) {
     MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(mDelayedOp.forget()));
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(gPrepareDatastoreOps);
+  MOZ_ASSERT(gPrepareDatastoreOps);
   gPrepareDatastoreOps->RemoveElement(this);
 
   if (gPrepareDatastoreOps->IsEmpty()) {
     gPrepareDatastoreOps = nullptr;
   }
 }
 
 void PrepareDatastoreOp::LogNestedState() {
@@ -6889,17 +6889,17 @@ void PrepareDatastoreOp::LogNestedState(
           break;
         }
       }
 
       break;
     }
 
     case NestedState::DirectoryOpenPending: {
-      MOZ_DIAGNOSTIC_ASSERT(mPendingDirectoryLock);
+      MOZ_ASSERT(mPendingDirectoryLock);
 
       LS_LOG(("  mPendingDirectoryLock: [%p]", mPendingDirectoryLock.get()));
 
       mPendingDirectoryLock->LogState();
 
       break;
     }
 
@@ -6916,19 +6916,19 @@ void PrepareDatastoreOp::ActorDestroy(Ac
 
   if (mLoadDataOp) {
     mLoadDataOp->NoteComplete();
   }
 }
 
 void PrepareDatastoreOp::DirectoryLockAcquired(DirectoryLock* aLock) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::DirectoryOpenPending);
-  MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::DirectoryOpenPending);
+  MOZ_ASSERT(!mDirectoryLock);
 
   mPendingDirectoryLock = nullptr;
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     MaybeSetFailureCode(NS_ERROR_FAILURE);
 
     FinishNesting();
@@ -6938,34 +6938,34 @@ void PrepareDatastoreOp::DirectoryLockAc
 
   mDirectoryLock = aLock;
 
   SendToIOThread();
 }
 
 void PrepareDatastoreOp::DirectoryLockFailed() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mNestedState == NestedState::DirectoryOpenPending);
-  MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock);
+  MOZ_ASSERT(mState == State::Nesting);
+  MOZ_ASSERT(mNestedState == NestedState::DirectoryOpenPending);
+  MOZ_ASSERT(!mDirectoryLock);
 
   mPendingDirectoryLock = nullptr;
 
   MaybeSetFailureCode(NS_ERROR_FAILURE);
 
   FinishNesting();
 }
 
 nsresult PrepareDatastoreOp::LoadDataOp::DoDatastoreWork() {
   AssertIsOnConnectionThread();
-  MOZ_DIAGNOSTIC_ASSERT(mConnection);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mNestedState ==
-                        NestedState::DatabaseWorkLoadData);
+  MOZ_ASSERT(mConnection);
+  MOZ_ASSERT(mPrepareDatastoreOp);
+  MOZ_ASSERT(mPrepareDatastoreOp->mState == State::Nesting);
+  MOZ_ASSERT(mPrepareDatastoreOp->mNestedState ==
+             NestedState::DatabaseWorkLoadData);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
       !MayProceedOnNonOwningThread()) {
     return NS_ERROR_FAILURE;
   }
 
   Connection::CachedStatement stmt;
   nsresult rv =
@@ -6991,105 +6991,104 @@ nsresult PrepareDatastoreOp::LoadDataOp:
     }
 
     mPrepareDatastoreOp->mValues.Put(key, value);
     auto item = mPrepareDatastoreOp->mOrderedItems.AppendElement();
     item->key() = key;
     item->value() = value;
     mPrepareDatastoreOp->mSizeOfKeys += key.Length();
     mPrepareDatastoreOp->mSizeOfItems += key.Length() + value.Length();
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
     mPrepareDatastoreOp->mDEBUGUsage += key.Length() + value.Length();
 #endif
   }
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 void PrepareDatastoreOp::LoadDataOp::OnSuccess() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mNestedState ==
-                        NestedState::DatabaseWorkLoadData);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mLoadDataOp == this);
+  MOZ_ASSERT(mPrepareDatastoreOp);
+  MOZ_ASSERT(mPrepareDatastoreOp->mState == State::Nesting);
+  MOZ_ASSERT(mPrepareDatastoreOp->mNestedState ==
+             NestedState::DatabaseWorkLoadData);
+  MOZ_ASSERT(mPrepareDatastoreOp->mLoadDataOp == this);
 
   mPrepareDatastoreOp->FinishNesting();
 }
 
 void PrepareDatastoreOp::LoadDataOp::OnFailure(nsresult aResultCode) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mState == State::Nesting);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mNestedState ==
-                        NestedState::DatabaseWorkLoadData);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mLoadDataOp == this);
+  MOZ_ASSERT(mPrepareDatastoreOp);
+  MOZ_ASSERT(mPrepareDatastoreOp->mState == State::Nesting);
+  MOZ_ASSERT(mPrepareDatastoreOp->mNestedState ==
+             NestedState::DatabaseWorkLoadData);
+  MOZ_ASSERT(mPrepareDatastoreOp->mLoadDataOp == this);
 
   mPrepareDatastoreOp->SetFailureCode(aResultCode);
 
   mPrepareDatastoreOp->FinishNesting();
 }
 
 void PrepareDatastoreOp::LoadDataOp::Cleanup() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp);
-  MOZ_DIAGNOSTIC_ASSERT(mPrepareDatastoreOp->mLoadDataOp == this);
+  MOZ_ASSERT(mPrepareDatastoreOp);
+  MOZ_ASSERT(mPrepareDatastoreOp->mLoadDataOp == this);
 
   mPrepareDatastoreOp->mLoadDataOp = nullptr;
   mPrepareDatastoreOp = nullptr;
 
   ConnectionDatastoreOperationBase::Cleanup();
 }
 
 /*******************************************************************************
  * PrepareObserverOp
  ******************************************************************************/
 
 PrepareObserverOp::PrepareObserverOp(nsIEventTarget* aMainEventTarget,
                                      const LSRequestParams& aParams)
     : LSRequestBase(aMainEventTarget),
       mParams(aParams.get_LSRequestPrepareObserverParams()) {
-  MOZ_DIAGNOSTIC_ASSERT(aParams.type() ==
-                        LSRequestParams::TLSRequestPrepareObserverParams);
+  MOZ_ASSERT(aParams.type() ==
+             LSRequestParams::TLSRequestPrepareObserverParams);
 }
 
 nsresult PrepareObserverOp::Open() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Opening);
+  MOZ_ASSERT(mState == State::Opening);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceedOnNonOwningThread()) {
     return NS_ERROR_FAILURE;
   }
 
   const PrincipalInfo& principalInfo = mParams.principalInfo();
 
   if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
     QuotaManager::GetInfoForChrome(nullptr, nullptr, &mOrigin);
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(principalInfo.type() ==
-                          PrincipalInfo::TContentPrincipalInfo);
+    MOZ_ASSERT(principalInfo.type() == PrincipalInfo::TContentPrincipalInfo);
 
     QuotaManager::GetInfoFromValidatedPrincipalInfo(principalInfo, nullptr,
                                                     nullptr, &mOrigin);
   }
 
   mState = State::SendingReadyMessage;
   MOZ_ALWAYS_SUCCEEDS(OwningEventTarget()->Dispatch(this, NS_DISPATCH_NORMAL));
 
   return NS_OK;
 }
 
 void PrepareObserverOp::GetResponse(LSRequestResponse& aResponse) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::SendingResults);
-  MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(ResultCode()));
+  MOZ_ASSERT(mState == State::SendingResults);
+  MOZ_ASSERT(NS_SUCCEEDED(ResultCode()));
 
   uint64_t observerId = ++gLastObserverId;
 
   RefPtr<Observer> observer = new Observer(mOrigin);
 
   if (!gPreparedObsevers) {
     gPreparedObsevers = new PreparedObserverHashtable();
   }
@@ -7104,32 +7103,31 @@ void PrepareObserverOp::GetResponse(LSRe
 /*******************************************************************************
 + * LSSimpleRequestBase
 +
 ******************************************************************************/
 
 LSSimpleRequestBase::LSSimpleRequestBase() : mState(State::Initial) {}
 
 LSSimpleRequestBase::~LSSimpleRequestBase() {
-  MOZ_DIAGNOSTIC_ASSERT_IF(
-      MayProceedOnNonOwningThread(),
-      mState == State::Initial || mState == State::Completed);
+  MOZ_ASSERT_IF(MayProceedOnNonOwningThread(),
+                mState == State::Initial || mState == State::Completed);
 }
 
 void LSSimpleRequestBase::Dispatch() {
   AssertIsOnOwningThread();
 
   mState = State::Opening;
 
   MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(this));
 }
 
 void LSSimpleRequestBase::SendResults() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::SendingResults);
+  MOZ_ASSERT(mState == State::SendingResults);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceed()) {
     MaybeSetFailureCode(NS_ERROR_FAILURE);
   }
 
   if (MayProceed()) {
     LSSimpleRequestResponse response;
@@ -7188,51 +7186,50 @@ void LSSimpleRequestBase::ActorDestroy(A
 }
 
 /*******************************************************************************
  * PreloadedOp
  ******************************************************************************/
 
 PreloadedOp::PreloadedOp(const LSSimpleRequestParams& aParams)
     : mParams(aParams.get_LSSimpleRequestPreloadedParams()) {
-  MOZ_DIAGNOSTIC_ASSERT(aParams.type() ==
-                        LSSimpleRequestParams::TLSSimpleRequestPreloadedParams);
+  MOZ_ASSERT(aParams.type() ==
+             LSSimpleRequestParams::TLSSimpleRequestPreloadedParams);
 }
 
 nsresult PreloadedOp::Open() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Opening);
+  MOZ_ASSERT(mState == State::Opening);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
       !MayProceedOnNonOwningThread()) {
     return NS_ERROR_FAILURE;
   }
 
   const PrincipalInfo& principalInfo = mParams.principalInfo();
 
   if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
     QuotaManager::GetInfoForChrome(nullptr, nullptr, &mOrigin);
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(principalInfo.type() ==
-                          PrincipalInfo::TContentPrincipalInfo);
+    MOZ_ASSERT(principalInfo.type() == PrincipalInfo::TContentPrincipalInfo);
 
     QuotaManager::GetInfoFromValidatedPrincipalInfo(principalInfo, nullptr,
                                                     nullptr, &mOrigin);
   }
 
   mState = State::SendingResults;
   MOZ_ALWAYS_SUCCEEDS(OwningEventTarget()->Dispatch(this, NS_DISPATCH_NORMAL));
 
   return NS_OK;
 }
 
 void PreloadedOp::GetResponse(LSSimpleRequestResponse& aResponse) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::SendingResults);
-  MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(ResultCode()));
+  MOZ_ASSERT(mState == State::SendingResults);
+  MOZ_ASSERT(NS_SUCCEEDED(ResultCode()));
 
   bool preloaded;
   RefPtr<Datastore> datastore;
   if (gDatastores && (datastore = gDatastores->Get(mOrigin)) &&
       !datastore->IsClosed()) {
     preloaded = true;
   } else {
     preloaded = false;
@@ -7298,17 +7295,17 @@ void ArchivedOriginScope::GetBindingClau
   };
 
   mData.match(Matcher(&aBindingClause));
 }
 
 nsresult ArchivedOriginScope::BindToStatement(
     mozIStorageStatement* aStmt) const {
   MOZ_ASSERT(IsOnIOThread() || IsOnConnectionThread());
-  MOZ_DIAGNOSTIC_ASSERT(aStmt);
+  MOZ_ASSERT(aStmt);
 
   struct Matcher {
     mozIStorageStatement* mStmt;
 
     explicit Matcher(mozIStorageStatement* aStmt) : mStmt(aStmt) {}
 
     nsresult operator()(const Origin& aOrigin) {
       nsresult rv = mStmt->BindUTF8StringByName(NS_LITERAL_CSTRING("originKey"),
@@ -7356,17 +7353,17 @@ nsresult ArchivedOriginScope::BindToStat
   }
 
   return NS_OK;
 }
 
 bool ArchivedOriginScope::HasMatches(
     ArchivedOriginHashtable* aHashtable) const {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aHashtable);
+  MOZ_ASSERT(aHashtable);
 
   struct Matcher {
     ArchivedOriginHashtable* mHashtable;
 
     explicit Matcher(ArchivedOriginHashtable* aHashtable)
         : mHashtable(aHashtable) {}
 
     bool operator()(const Origin& aOrigin) {
@@ -7406,17 +7403,17 @@ bool ArchivedOriginScope::HasMatches(
   };
 
   return mData.match(Matcher(aHashtable));
 }
 
 void ArchivedOriginScope::RemoveMatches(
     ArchivedOriginHashtable* aHashtable) const {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aHashtable);
+  MOZ_ASSERT(aHashtable);
 
   struct Matcher {
     ArchivedOriginHashtable* mHashtable;
 
     explicit Matcher(ArchivedOriginHashtable* aHashtable)
         : mHashtable(aHashtable) {}
 
     void operator()(const Origin& aOrigin) {
@@ -7458,24 +7455,24 @@ void ArchivedOriginScope::RemoveMatches(
  ******************************************************************************/
 
 QuotaClient* QuotaClient::sInstance = nullptr;
 
 QuotaClient::QuotaClient()
     : mShadowDatabaseMutex("LocalStorage mShadowDatabaseMutex"),
       mShutdownRequested(false) {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!sInstance, "We expect this to be a singleton!");
+  MOZ_ASSERT(!sInstance, "We expect this to be a singleton!");
 
   sInstance = this;
 }
 
 QuotaClient::~QuotaClient() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(sInstance == this, "We expect this to be a singleton!");
+  MOZ_ASSERT(sInstance == this, "We expect this to be a singleton!");
 
   sInstance = nullptr;
 }
 
 // static
 nsresult QuotaClient::Initialize() {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -7492,46 +7489,46 @@ mozilla::dom::quota::Client::Type QuotaC
 }
 
 nsresult QuotaClient::InitOrigin(PersistenceType aPersistenceType,
                                  const nsACString& aGroup,
                                  const nsACString& aOrigin,
                                  const AtomicBool& aCanceled,
                                  UsageInfo* aUsageInfo) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aPersistenceType == PERSISTENCE_TYPE_DEFAULT);
+  MOZ_ASSERT(aPersistenceType == PERSISTENCE_TYPE_DEFAULT);
 
   QuotaManager* quotaManager = QuotaManager::Get();
-  MOZ_DIAGNOSTIC_ASSERT(quotaManager);
+  MOZ_ASSERT(quotaManager);
 
   nsCOMPtr<nsIFile> directory;
   nsresult rv = quotaManager->GetDirectoryForOrigin(aPersistenceType, aOrigin,
                                                     getter_AddRefs(directory));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     REPORT_TELEMETRY_INIT_ERR(kExternalError, LS_GetDirForOrigin);
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(directory);
+  MOZ_ASSERT(directory);
 
   rv = directory->Append(NS_LITERAL_STRING(LS_DIRECTORY_NAME));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     REPORT_TELEMETRY_INIT_ERR(kExternalError, LS_Append);
     return rv;
   }
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool exists;
   rv = directory->Exists(&exists);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     REPORT_TELEMETRY_INIT_ERR(kExternalError, LS_Exists);
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(exists);
+  MOZ_ASSERT(exists);
 #endif
 
   nsString directoryPath;
   rv = directory->GetPath(directoryPath);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     REPORT_TELEMETRY_INIT_ERR(kExternalError, LS_GetPath);
     return rv;
   }
@@ -7653,17 +7650,17 @@ nsresult QuotaClient::InitOrigin(Persist
 
       rv = usageJournalFile->Remove(false);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         REPORT_TELEMETRY_INIT_ERR(kExternalError, LS_Remove3);
         return rv;
       }
     }
 
-    MOZ_DIAGNOSTIC_ASSERT(usage >= 0);
+    MOZ_ASSERT(usage >= 0);
 
     InitUsageForOrigin(aOrigin, usage);
 
     aUsageInfo->AppendToDatabaseUsage(uint64_t(usage));
   } else if (usageFileExists) {
     rv = usageFile->Remove(false);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       REPORT_TELEMETRY_INIT_ERR(kExternalError, LS_Remove4);
@@ -7738,26 +7735,26 @@ nsresult QuotaClient::InitOrigin(Persist
 }
 
 nsresult QuotaClient::GetUsageForOrigin(PersistenceType aPersistenceType,
                                         const nsACString& aGroup,
                                         const nsACString& aOrigin,
                                         const AtomicBool& aCanceled,
                                         UsageInfo* aUsageInfo) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aPersistenceType == PERSISTENCE_TYPE_DEFAULT);
-  MOZ_DIAGNOSTIC_ASSERT(aUsageInfo);
+  MOZ_ASSERT(aPersistenceType == PERSISTENCE_TYPE_DEFAULT);
+  MOZ_ASSERT(aUsageInfo);
 
   // We can't open the database at this point, since it can be already used
   // by the connection thread. Use the cached value instead.
 
   if (gUsages) {
     int64_t usage;
     if (gUsages->Get(aOrigin, &usage)) {
-      MOZ_DIAGNOSTIC_ASSERT(usage >= 0);
+      MOZ_ASSERT(usage >= 0);
       aUsageInfo->AppendToDatabaseUsage(usage);
     }
   }
 
   return NS_OK;
 }
 
 nsresult QuotaClient::AboutToClearOrigins(
@@ -7792,23 +7789,23 @@ nsresult QuotaClient::AboutToClearOrigin
     return rv;
   }
 
   if (!gArchivedOrigins) {
     rv = LoadArchivedOrigins();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
-    MOZ_DIAGNOSTIC_ASSERT(gArchivedOrigins);
+    MOZ_ASSERT(gArchivedOrigins);
   }
 
   bool hasDataForRemoval = archivedOriginScope->HasMatches(gArchivedOrigins);
 
   QuotaManager* quotaManager = QuotaManager::Get();
-  MOZ_DIAGNOSTIC_ASSERT(quotaManager);
+  MOZ_ASSERT(quotaManager);
 
   nsString basePath = quotaManager->GetBasePath();
 
   {
     MutexAutoLock shadowDatabaseLock(mShadowDatabaseMutex);
 
     nsCOMPtr<mozIStorageConnection> connection;
     if (gInitializedShadowStorage) {
@@ -7891,18 +7888,18 @@ nsresult QuotaClient::AboutToClearOrigin
     }
 
     if (hasDataForRemoval) {
       rv = DetachArchiveDatabase(connection);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
-      MOZ_DIAGNOSTIC_ASSERT(gArchivedOrigins);
-      MOZ_DIAGNOSTIC_ASSERT(archivedOriginScope->HasMatches(gArchivedOrigins));
+      MOZ_ASSERT(gArchivedOrigins);
+      MOZ_ASSERT(archivedOriginScope->HasMatches(gArchivedOrigins));
       archivedOriginScope->RemoveMatches(gArchivedOrigins);
     }
 
     rv = connection->Close();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
@@ -7962,42 +7959,42 @@ void QuotaClient::AbortOperations(const 
   // immediatelly (avoiding the creation of the Datastore and PreparedDatastore
   // object). We will call RequestAllowToClose on the database actor once it's
   // created and the child actor will respond by sending AllowToClose which
   // will close the Datastore on the parent side (the closing releases the
   // directory lock).
 
   if (gPrepareDatastoreOps) {
     for (PrepareDatastoreOp* prepareDatastoreOp : *gPrepareDatastoreOps) {
-      MOZ_DIAGNOSTIC_ASSERT(prepareDatastoreOp);
+      MOZ_ASSERT(prepareDatastoreOp);
 
       // Explicitely check if a directory lock has been requested.
       // Origin clearing can't be blocked by this PrepareDatastoreOp if it
       // hasn't requested a directory lock yet, so we can just ignore it.
       // This will also guarantee that PrepareDatastoreOp has a known origin.
       // And it also ensures that the ordering is right. Without the check we
       // could invalidate ops whose directory locks were requested after we
       // requested a directory lock for origin clearing.
       if (!prepareDatastoreOp->RequestedDirectoryLock()) {
         continue;
       }
 
-      MOZ_DIAGNOSTIC_ASSERT(prepareDatastoreOp->OriginIsKnown());
+      MOZ_ASSERT(prepareDatastoreOp->OriginIsKnown());
 
       if (aOrigin.IsVoid() || prepareDatastoreOp->Origin() == aOrigin) {
         prepareDatastoreOp->Invalidate();
       }
     }
   }
 
   if (gPreparedDatastores) {
     for (auto iter = gPreparedDatastores->ConstIter(); !iter.Done();
          iter.Next()) {
       PreparedDatastore* preparedDatastore = iter.Data();
-      MOZ_DIAGNOSTIC_ASSERT(preparedDatastore);
+      MOZ_ASSERT(preparedDatastore);
 
       if (aOrigin.IsVoid() || preparedDatastore->Origin() == aOrigin) {
         preparedDatastore->Invalidate();
       }
     }
   }
 
   if (gLiveDatabases) {
@@ -8026,17 +8023,17 @@ void QuotaClient::AbortOperationsForProc
 }
 
 void QuotaClient::StartIdleMaintenance() { AssertIsOnBackgroundThread(); }
 
 void QuotaClient::StopIdleMaintenance() { AssertIsOnBackgroundThread(); }
 
 void QuotaClient::ShutdownWorkThreads() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mShutdownRequested);
+  MOZ_ASSERT(!mShutdownRequested);
 
   mShutdownRequested = true;
 
   // gPrepareDatastoreOps are short lived objects running a state machine.
   // The shutdown flag is checked between states, so we don't have to notify
   // all the objects here.
   // Allocation of a new PrepareDatastoreOp object is prevented once the
   // shutdown flag is set.
@@ -8054,31 +8051,74 @@ void QuotaClient::ShutdownWorkThreads() 
     }
   }
 
   if (gPreparedObsevers) {
     gPreparedObsevers->Clear();
     gPreparedObsevers = nullptr;
   }
 
+  nsCOMPtr<nsITimer> timer = NS_NewTimer();
+
+  MOZ_ALWAYS_SUCCEEDS(timer->InitWithNamedFuncCallback(
+      [](nsITimer* aTimer, void* aClosure) {
+        auto quotaClient = static_cast<QuotaClient*>(aClosure);
+
+        quotaClient->ShutdownTimedOut();
+      },
+      this, SHUTDOWN_TIMEOUT_MS, nsITimer::TYPE_ONE_SHOT,
+      "localstorage::QuotaClient::ShutdownWorkThreads::SpinEventLoopTimer"));
+
   // This should release any local storage related quota objects or directory
   // locks.
   MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() {
     // Don't have to check gPreparedDatastores since we nulled it out above.
     return !gPrepareDatastoreOps && !gDatastores && !gLiveDatabases;
   }));
 
+  MOZ_ALWAYS_SUCCEEDS(timer->Cancel());
+
   // And finally, shutdown the connection thread.
   if (gConnectionThread) {
     gConnectionThread->Shutdown();
 
     gConnectionThread = nullptr;
   }
 }
 
+void QuotaClient::ShutdownTimedOut() {
+  AssertIsOnBackgroundThread();
+  MOZ_DIAGNOSTIC_ASSERT(gPrepareDatastoreOps || gDatastores || gLiveDatabases);
+
+  nsCString data;
+
+  if (gPrepareDatastoreOps) {
+    data.Append("gPrepareDatastoreOps: ");
+    data.AppendInt(static_cast<uint32_t>(gPrepareDatastoreOps->Length()));
+    data.Append("\n");
+  }
+
+  if (gDatastores) {
+    data.Append("gDatastores: ");
+    data.AppendInt(gDatastores->Count());
+    data.Append("\n");
+  }
+
+  if (gLiveDatabases) {
+    data.Append("gLiveDatabases: ");
+    data.AppendInt(static_cast<uint32_t>(gLiveDatabases->Length()));
+    data.Append("\n");
+  }
+
+  CrashReporter::AnnotateCrashReport(
+      CrashReporter::Annotation::LocalStorageShutdownTimeout, data);
+
+  MOZ_CRASH("LocalStorage shutdown timed out");
+}
+
 nsresult QuotaClient::CreateArchivedOriginScope(
     const OriginScope& aOriginScope,
     nsAutoPtr<ArchivedOriginScope>& aArchivedOriginScope) {
   AssertIsOnIOThread();
 
   nsresult rv;
 
   nsAutoPtr<ArchivedOriginScope> archivedOriginScope;
@@ -8127,33 +8167,33 @@ nsresult QuotaClient::CreateArchivedOrig
       return rv;
     }
 
     archivedOriginScope = ArchivedOriginScope::CreateFromPrefix(originKey);
   } else if (aOriginScope.IsPattern()) {
     archivedOriginScope =
         ArchivedOriginScope::CreateFromPattern(aOriginScope.GetPattern());
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(aOriginScope.IsNull());
+    MOZ_ASSERT(aOriginScope.IsNull());
 
     archivedOriginScope = ArchivedOriginScope::CreateFromNull();
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(archivedOriginScope);
+  MOZ_ASSERT(archivedOriginScope);
 
   aArchivedOriginScope = std::move(archivedOriginScope);
   return NS_OK;
 }
 
 nsresult QuotaClient::PerformDelete(
     mozIStorageConnection* aConnection, const nsACString& aSchemaName,
     ArchivedOriginScope* aArchivedOriginScope) const {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aConnection);
-  MOZ_DIAGNOSTIC_ASSERT(aArchivedOriginScope);
+  MOZ_ASSERT(aConnection);
+  MOZ_ASSERT(aArchivedOriginScope);
 
   nsresult rv;
 
   nsCString bindingClause;
   aArchivedOriginScope->GetBindingClause(bindingClause);
 
   nsCOMPtr<mozIStorageStatement> stmt;
   rv = aConnection->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM ") +
@@ -8271,18 +8311,18 @@ QuotaClient::Observer::Observe(nsISuppor
 }
 
 NS_IMPL_ISUPPORTS(QuotaClient::MatchFunction, mozIStorageFunction)
 
 NS_IMETHODIMP
 QuotaClient::MatchFunction::OnFunctionCall(
     mozIStorageValueArray* aFunctionArguments, nsIVariant** aResult) {
   AssertIsOnIOThread();
-  MOZ_DIAGNOSTIC_ASSERT(aFunctionArguments);
-  MOZ_DIAGNOSTIC_ASSERT(aResult);
+  MOZ_ASSERT(aFunctionArguments);
+  MOZ_ASSERT(aResult);
 
   nsCString suffix;
   nsresult rv = aFunctionArguments->GetUTF8String(1, suffix);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   OriginAttributes oa;
--- a/dom/localstorage/LSDatabase.cpp
+++ b/dom/localstorage/LSDatabase.cpp
@@ -40,54 +40,54 @@ LSDatabase::LSDatabase(const nsACString&
       mOrigin(aOrigin),
       mAllowedToClose(false),
       mRequestedAllowToClose(false) {
   AssertIsOnOwningThread();
 
   if (!gLSDatabases) {
     gLSDatabases = new LSDatabaseHashtable();
 
-    MOZ_DIAGNOSTIC_ASSERT(!sObserver);
+    MOZ_ASSERT(!sObserver);
 
     sObserver = new Observer();
 
     nsCOMPtr<nsIObserverService> obsSvc = GetObserverService();
-    MOZ_DIAGNOSTIC_ASSERT(obsSvc);
+    MOZ_ASSERT(obsSvc);
 
     MOZ_ALWAYS_SUCCEEDS(
         obsSvc->AddObserver(sObserver, XPCOM_SHUTDOWN_OBSERVER_TOPIC, false));
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(!gLSDatabases->Get(mOrigin));
+  MOZ_ASSERT(!gLSDatabases->Get(mOrigin));
   gLSDatabases->Put(mOrigin, this);
 }
 
 LSDatabase::~LSDatabase() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mSnapshot);
+  MOZ_ASSERT(!mSnapshot);
 
   if (!mAllowedToClose) {
     AllowToClose();
   }
 
   if (mActor) {
     mActor->SendDeleteMeInternal();
-    MOZ_DIAGNOSTIC_ASSERT(!mActor, "SendDeleteMeInternal should have cleared!");
+    MOZ_ASSERT(!mActor, "SendDeleteMeInternal should have cleared!");
   }
 }
 
 // static
 LSDatabase* LSDatabase::Get(const nsACString& aOrigin) {
   return gLSDatabases ? gLSDatabases->Get(aOrigin) : nullptr;
 }
 
 void LSDatabase::SetActor(LSDatabaseChild* aActor) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mActor);
+  MOZ_ASSERT(aActor);
+  MOZ_ASSERT(!mActor);
 
   mActor = aActor;
 }
 
 void LSDatabase::RequestAllowToClose() {
   AssertIsOnOwningThread();
 
   if (mRequestedAllowToClose) {
@@ -100,30 +100,30 @@ void LSDatabase::RequestAllowToClose() {
     mSnapshot->MarkDirty();
   } else {
     AllowToClose();
   }
 }
 
 void LSDatabase::NoteFinishedSnapshot(LSSnapshot* aSnapshot) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aSnapshot == mSnapshot);
+  MOZ_ASSERT(aSnapshot == mSnapshot);
 
   mSnapshot = nullptr;
 
   if (mRequestedAllowToClose) {
     AllowToClose();
   }
 }
 
 nsresult LSDatabase::GetLength(LSObject* aObject, uint32_t* aResult) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   nsresult rv = EnsureSnapshot(aObject);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = mSnapshot->GetLength(aResult);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -131,19 +131,19 @@ nsresult LSDatabase::GetLength(LSObject*
   }
 
   return NS_OK;
 }
 
 nsresult LSDatabase::GetKey(LSObject* aObject, uint32_t aIndex,
                             nsAString& aResult) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   nsresult rv = EnsureSnapshot(aObject);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = mSnapshot->GetKey(aIndex, aResult);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -151,38 +151,38 @@ nsresult LSDatabase::GetKey(LSObject* aO
   }
 
   return NS_OK;
 }
 
 nsresult LSDatabase::GetItem(LSObject* aObject, const nsAString& aKey,
                              nsAString& aResult) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   nsresult rv = EnsureSnapshot(aObject);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = mSnapshot->GetItem(aKey, aResult);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult LSDatabase::GetKeys(LSObject* aObject, nsTArray<nsString>& aKeys) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   nsresult rv = EnsureSnapshot(aObject);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = mSnapshot->GetKeys(aKeys);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -191,19 +191,19 @@ nsresult LSDatabase::GetKeys(LSObject* a
 
   return NS_OK;
 }
 
 nsresult LSDatabase::SetItem(LSObject* aObject, const nsAString& aKey,
                              const nsAString& aValue,
                              LSNotifyInfo& aNotifyInfo) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   nsresult rv = EnsureSnapshot(aObject);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = mSnapshot->SetItem(aKey, aValue, aNotifyInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -211,95 +211,95 @@ nsresult LSDatabase::SetItem(LSObject* a
   }
 
   return NS_OK;
 }
 
 nsresult LSDatabase::RemoveItem(LSObject* aObject, const nsAString& aKey,
                                 LSNotifyInfo& aNotifyInfo) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   nsresult rv = EnsureSnapshot(aObject);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = mSnapshot->RemoveItem(aKey, aNotifyInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult LSDatabase::Clear(LSObject* aObject, LSNotifyInfo& aNotifyInfo) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   nsresult rv = EnsureSnapshot(aObject);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = mSnapshot->Clear(aNotifyInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult LSDatabase::BeginExplicitSnapshot(LSObject* aObject) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   if (mSnapshot) {
     return NS_ERROR_ALREADY_INITIALIZED;
   }
 
   nsresult rv = EnsureSnapshot(aObject, /* aExplicit */ true);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult LSDatabase::EndExplicitSnapshot(LSObject* aObject) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mAllowedToClose);
 
   if (!mSnapshot) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(mSnapshot->Explicit());
+  MOZ_ASSERT(mSnapshot->Explicit());
 
   nsresult rv = mSnapshot->End();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult LSDatabase::EnsureSnapshot(LSObject* aObject, bool aExplicit) {
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT_IF(mSnapshot, !aExplicit);
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(aObject);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT_IF(mSnapshot, !aExplicit);
+  MOZ_ASSERT(!mAllowedToClose);
 
   if (mSnapshot) {
     return NS_OK;
   }
 
   RefPtr<LSSnapshot> snapshot = new LSSnapshot(this);
 
   LSSnapshotChild* actor = new LSSnapshotChild(snapshot);
@@ -325,58 +325,58 @@ nsresult LSDatabase::EnsureSnapshot(LSOb
   // This is cleared in LSSnapshot::Run() before the snapshot is destroyed.
   mSnapshot = snapshot;
 
   return NS_OK;
 }
 
 void LSDatabase::AllowToClose() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mAllowedToClose);
-  MOZ_DIAGNOSTIC_ASSERT(!mSnapshot);
+  MOZ_ASSERT(!mAllowedToClose);
+  MOZ_ASSERT(!mSnapshot);
 
   mAllowedToClose = true;
 
   if (mActor) {
     mActor->SendAllowToClose();
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(gLSDatabases);
-  MOZ_DIAGNOSTIC_ASSERT(gLSDatabases->Get(mOrigin));
+  MOZ_ASSERT(gLSDatabases);
+  MOZ_ASSERT(gLSDatabases->Get(mOrigin));
   gLSDatabases->Remove(mOrigin);
 
   if (!gLSDatabases->Count()) {
     gLSDatabases = nullptr;
 
-    MOZ_DIAGNOSTIC_ASSERT(sObserver);
+    MOZ_ASSERT(sObserver);
 
     nsCOMPtr<nsIObserverService> obsSvc = GetObserverService();
-    MOZ_DIAGNOSTIC_ASSERT(obsSvc);
+    MOZ_ASSERT(obsSvc);
 
     MOZ_ALWAYS_SUCCEEDS(
         obsSvc->RemoveObserver(sObserver, XPCOM_SHUTDOWN_OBSERVER_TOPIC));
 
     sObserver = nullptr;
   }
 }
 
 NS_IMPL_ISUPPORTS(LSDatabase::Observer, nsIObserver)
 
 NS_IMETHODIMP
 LSDatabase::Observer::Observe(nsISupports* aSubject, const char* aTopic,
                               const char16_t* aData) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(!strcmp(aTopic, XPCOM_SHUTDOWN_OBSERVER_TOPIC));
-  MOZ_DIAGNOSTIC_ASSERT(gLSDatabases);
+  MOZ_ASSERT(!strcmp(aTopic, XPCOM_SHUTDOWN_OBSERVER_TOPIC));
+  MOZ_ASSERT(gLSDatabases);
 
   nsTArray<RefPtr<LSDatabase>> databases;
 
   for (auto iter = gLSDatabases->ConstIter(); !iter.Done(); iter.Next()) {
     LSDatabase* database = iter.Data();
-    MOZ_DIAGNOSTIC_ASSERT(database);
+    MOZ_ASSERT(database);
 
     databases.AppendElement(database);
   }
 
   for (RefPtr<LSDatabase>& database : databases) {
     database->RequestAllowToClose();
   }
 
--- a/dom/localstorage/LSDatabase.h
+++ b/dom/localstorage/LSDatabase.h
@@ -35,17 +35,17 @@ class LSDatabase final {
   NS_INLINE_DECL_REFCOUNTING(LSDatabase)
 
   void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(LSDatabase); }
 
   void SetActor(LSDatabaseChild* aActor);
 
   void ClearActor() {
     AssertIsOnOwningThread();
-    MOZ_DIAGNOSTIC_ASSERT(mActor);
+    MOZ_ASSERT(mActor);
 
     mActor = nullptr;
   }
 
   bool IsAllowedToClose() const {
     AssertIsOnOwningThread();
 
     return mAllowedToClose;
--- a/dom/localstorage/LSObject.cpp
+++ b/dom/localstorage/LSObject.cpp
@@ -159,17 +159,17 @@ class RequestHelper final : public Runna
         mActor(nullptr),
         mParams(aParams),
         mResultCode(NS_OK),
         mState(State::Initial),
         mWaiting(true),
         mCancelled(false) {}
 
   bool IsOnOwningThread() const {
-    MOZ_DIAGNOSTIC_ASSERT(mOwningEventTarget);
+    MOZ_ASSERT(mOwningEventTarget);
 
     bool current;
     return NS_SUCCEEDED(mOwningEventTarget->IsOnCurrentThread(&current)) &&
            current;
   }
 
   void AssertIsOnOwningThread() const {
     MOZ_ASSERT(NS_IsMainThread());
@@ -195,17 +195,17 @@ class RequestHelper final : public Runna
 
 }  // namespace
 
 LSObject::LSObject(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal)
     : Storage(aWindow, aPrincipal),
       mPrivateBrowsingId(0),
       mInExplicitSnapshot(false) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(NextGenLocalStorageEnabled());
+  MOZ_ASSERT(NextGenLocalStorageEnabled());
 }
 
 LSObject::~LSObject() {
   AssertIsOnOwningThread();
 
   DropObserver();
 }
 
@@ -236,24 +236,24 @@ void LSObject::Initialize() {
     return;
   }
 }
 
 // static
 nsresult LSObject::CreateForWindow(nsPIDOMWindowInner* aWindow,
                                    Storage** aStorage) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aWindow);
-  MOZ_DIAGNOSTIC_ASSERT(aStorage);
-  MOZ_DIAGNOSTIC_ASSERT(NextGenLocalStorageEnabled());
-  MOZ_DIAGNOSTIC_ASSERT(nsContentUtils::StorageAllowedForWindow(aWindow) >
-                        nsContentUtils::StorageAccess::eDeny);
+  MOZ_ASSERT(aWindow);
+  MOZ_ASSERT(aStorage);
+  MOZ_ASSERT(NextGenLocalStorageEnabled());
+  MOZ_ASSERT(nsContentUtils::StorageAllowedForWindow(aWindow) >
+             nsContentUtils::StorageAccess::eDeny);
 
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
-  MOZ_DIAGNOSTIC_ASSERT(sop);
+  MOZ_ASSERT(sop);
 
   nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
   if (NS_WARN_IF(!principal)) {
     return NS_ERROR_FAILURE;
   }
 
   if (nsContentUtils::IsSystemPrincipal(principal)) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -270,31 +270,30 @@ nsresult LSObject::CreateForWindow(nsPID
   }
 
   nsAutoPtr<PrincipalInfo> principalInfo(new PrincipalInfo());
   rv = PrincipalToPrincipalInfo(principal, principalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(principalInfo->type() ==
-                        PrincipalInfo::TContentPrincipalInfo);
+  MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo);
 
   if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
     return NS_ERROR_FAILURE;
   }
 
   nsCString suffix;
   nsCString origin;
   rv = QuotaManager::GetInfoFromPrincipal(principal, &suffix, nullptr, &origin);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(originAttrSuffix == suffix);
+  MOZ_ASSERT(originAttrSuffix == suffix);
 
   uint32_t privateBrowsingId;
   rv = principal->GetPrivateBrowsingId(&privateBrowsingId);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   Maybe<ClientInfo> clientInfo = aWindow->GetClientInfo();
@@ -325,35 +324,34 @@ nsresult LSObject::CreateForWindow(nsPID
 }
 
 // static
 nsresult LSObject::CreateForPrincipal(nsPIDOMWindowInner* aWindow,
                                       nsIPrincipal* aPrincipal,
                                       const nsAString& aDocumentURI,
                                       bool aPrivate, LSObject** aObject) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPrincipal);
-  MOZ_DIAGNOSTIC_ASSERT(aObject);
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(aObject);
 
   nsCString originAttrSuffix;
   nsCString originKey;
   nsresult rv = GenerateOriginKey(aPrincipal, originAttrSuffix, originKey);
   if (NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsAutoPtr<PrincipalInfo> principalInfo(new PrincipalInfo());
   rv = PrincipalToPrincipalInfo(aPrincipal, principalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(
-      principalInfo->type() == PrincipalInfo::TContentPrincipalInfo ||
-      principalInfo->type() == PrincipalInfo::TSystemPrincipalInfo);
+  MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo ||
+             principalInfo->type() == PrincipalInfo::TSystemPrincipalInfo);
 
   if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
     return NS_ERROR_FAILURE;
   }
 
   nsCString suffix;
   nsCString origin;
 
@@ -362,17 +360,17 @@ nsresult LSObject::CreateForPrincipal(ns
   } else {
     rv = QuotaManager::GetInfoFromPrincipal(aPrincipal, &suffix, nullptr,
                                             &origin);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(originAttrSuffix == suffix);
+  MOZ_ASSERT(originAttrSuffix == suffix);
 
   Maybe<nsID> clientId;
   if (aWindow) {
     Maybe<ClientInfo> clientInfo = aWindow->GetClientInfo();
     if (clientInfo.isNothing()) {
       return NS_ERROR_FAILURE;
     }
 
@@ -453,17 +451,17 @@ LSRequestChild* LSObject::StartRequest(n
 Storage::StorageType LSObject::Type() const {
   AssertIsOnOwningThread();
 
   return eLocalStorage;
 }
 
 bool LSObject::IsForkOf(const Storage* aStorage) const {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aStorage);
+  MOZ_ASSERT(aStorage);
 
   if (aStorage->Type() != eLocalStorage) {
     return false;
   }
 
   return static_cast<const LSObject*>(aStorage)->mOrigin == mOrigin;
 }
 
@@ -793,17 +791,17 @@ nsresult LSObject::EnsureDatabase() {
 
   if (mDatabase && !mDatabase->IsAllowedToClose()) {
     return NS_OK;
   }
 
   mDatabase = LSDatabase::Get(mOrigin);
 
   if (mDatabase) {
-    MOZ_DIAGNOSTIC_ASSERT(!mDatabase->IsAllowedToClose());
+    MOZ_ASSERT(!mDatabase->IsAllowedToClose());
     return NS_OK;
   }
 
   // We don't need this yet, but once the request successfully finishes, it's
   // too late to initialize PBackground child on the owning thread, because
   // it can fail and parent would keep an extra strong ref to the datastore.
   PBackgroundChild* backgroundActor =
       BackgroundChild::GetOrCreateForCurrentThread();
@@ -821,18 +819,18 @@ nsresult LSObject::EnsureDatabase() {
 
   LSRequestResponse response;
 
   nsresult rv = DoRequestSynchronously(params, response);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(response.type() ==
-                        LSRequestResponse::TLSRequestPrepareDatastoreResponse);
+  MOZ_ASSERT(response.type() ==
+             LSRequestResponse::TLSRequestPrepareDatastoreResponse);
 
   const LSRequestPrepareDatastoreResponse& prepareDatastoreResponse =
       response.get_LSRequestPrepareDatastoreResponse();
 
   uint64_t datastoreId = prepareDatastoreResponse.datastoreId();
 
   // The datastore is now ready on the parent side (prepared by the asynchronous
   // request on the DOM File thread).
@@ -885,33 +883,33 @@ nsresult LSObject::EnsureObserver() {
 
   LSRequestResponse response;
 
   nsresult rv = DoRequestSynchronously(params, response);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(response.type() ==
-                        LSRequestResponse::TLSRequestPrepareObserverResponse);
+  MOZ_ASSERT(response.type() ==
+             LSRequestResponse::TLSRequestPrepareObserverResponse);
 
   const LSRequestPrepareObserverResponse& prepareObserverResponse =
       response.get_LSRequestPrepareObserverResponse();
 
   uint64_t observerId = prepareObserverResponse.observerId();
 
   // The obsserver is now ready on the parent side (prepared by the asynchronous
   // request on the DOM File thread).
   // Let's create a direct connection to the observer (through an observer
   // actor) from the owning thread.
   // Note that we now can't error out, otherwise parent will keep an extra
   // strong reference to the observer.
 
   PBackgroundChild* backgroundActor = BackgroundChild::GetForCurrentThread();
-  MOZ_DIAGNOSTIC_ASSERT(backgroundActor);
+  MOZ_ASSERT(backgroundActor);
 
   RefPtr<LSObserver> observer = new LSObserver(mOrigin);
 
   LSObserverChild* actor = new LSObserverChild(observer);
 
   MOZ_ALWAYS_TRUE(
       backgroundActor->SendPBackgroundLSObserverConstructor(actor, observerId));
 
@@ -940,30 +938,30 @@ void LSObject::OnChange(const nsAString&
                /* aImmediateDispatch */ false);
 }
 
 nsresult LSObject::EndExplicitSnapshotInternal() {
   AssertIsOnOwningThread();
 
   // Can be only called if the mInExplicitSnapshot flag is true.
   // An explicit snapshot must have been created.
-  MOZ_DIAGNOSTIC_ASSERT(mInExplicitSnapshot);
+  MOZ_ASSERT(mInExplicitSnapshot);
 
   // If an explicit snapshot have been created then mDatabase must be not null.
   // DropDatabase could be called in the meatime, but that would set
   // mInExplicitSnapshot to false. EnsureDatabase could be called in the
   // meantime too, but that can't set mDatabase to null or to a new value. See
   // the comment below.
-  MOZ_DIAGNOSTIC_ASSERT(mDatabase);
+  MOZ_ASSERT(mDatabase);
 
   // Existence of a snapshot prevents the database from allowing to close. See
   // LSDatabase::RequestAllowToClose and LSDatabase::NoteFinishedSnapshot.
   // If the database is not allowed to close then mDatabase could not have been
   // nulled out or set to a new value. See EnsureDatabase.
-  MOZ_DIAGNOSTIC_ASSERT(!mDatabase->IsAllowedToClose());
+  MOZ_ASSERT(!mDatabase->IsAllowedToClose());
 
   nsresult rv = mDatabase->EndExplicitSnapshot(this);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   mInExplicitSnapshot = false;
 
@@ -991,17 +989,17 @@ NestedEventTargetWrapper::IsOnCurrentThr
   MOZ_CRASH(
       "IsOnCurrentThread should never be called on "
       "NestedEventTargetWrapper");
 }
 
 NS_IMETHODIMP
 NestedEventTargetWrapper::Dispatch(already_AddRefed<nsIRunnable> aEvent,
                                    uint32_t aFlags) {
-  MOZ_DIAGNOSTIC_ASSERT(mNestedEventTarget);
+  MOZ_ASSERT(mNestedEventTarget);
 
   if (mDisconnected) {
     MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(std::move(aEvent), aFlags));
     return NS_OK;
   }
 
   nsCOMPtr<nsIRunnable> event(aEvent);
 
@@ -1054,17 +1052,17 @@ nsresult RequestHelper::StartAndReturnRe
   // event loop can't fire any other events.
   // This way the thread is synchronously blocked in a safe manner and the
   // runnable gets executed.
   {
     auto thread = static_cast<nsThread*>(NS_GetCurrentThread());
 
     const nsLocalExecutionGuard localExecution(thread->EnterLocalExecution());
     mNestedEventTarget = localExecution.GetEventTarget();
-    MOZ_DIAGNOSTIC_ASSERT(mNestedEventTarget);
+    MOZ_ASSERT(mNestedEventTarget);
 
     mNestedEventTargetWrapper =
         new NestedEventTargetWrapper(mNestedEventTarget);
 
     nsCOMPtr<nsIEventTarget> domFileThread =
         XRE_IsParentProcess() ? IPCBlobInputStreamThread::GetOrCreate()
                               : IPCBlobInputStreamThread::Get();
     if (NS_WARN_IF(!domFileThread)) {
@@ -1176,34 +1174,34 @@ nsresult RequestHelper::StartAndReturnRe
   }
 
   aResponse = std::move(mResponse);
   return NS_OK;
 }
 
 nsresult RequestHelper::Start() {
   AssertIsOnDOMFileThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Initial);
+  MOZ_ASSERT(mState == State::Initial);
 
   mState = State::ResponsePending;
 
   LSRequestChild* actor =
       mObject->StartRequest(mNestedEventTargetWrapper, mParams, this);
   if (NS_WARN_IF(!actor)) {
     return NS_ERROR_FAILURE;
   }
 
   mActor = actor;
 
   return NS_OK;
 }
 
 void RequestHelper::Finish() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::Finishing);
+  MOZ_ASSERT(mState == State::Finishing);
 
   mObject = nullptr;
 
   mWaiting = false;
 
   mState = State::Complete;
 }
 
@@ -1241,17 +1239,17 @@ RequestHelper::Run() {
     }
   }
 
   return NS_OK;
 }
 
 void RequestHelper::OnResponse(const LSRequestResponse& aResponse) {
   AssertIsOnDOMFileThread();
-  MOZ_DIAGNOSTIC_ASSERT(mState == State::ResponsePending);
+  MOZ_ASSERT(mState == State::ResponsePending);
 
   mActor = nullptr;
 
   mResponse = aResponse;
 
   mState = State::Finishing;
 
   MOZ_ALWAYS_SUCCEEDS(
--- a/dom/localstorage/LSObserver.cpp
+++ b/dom/localstorage/LSObserver.cpp
@@ -26,44 +26,44 @@ StaticAutoPtr<LSObserverHashtable> gLSOb
 LSObserver::LSObserver(const nsACString& aOrigin)
     : mActor(nullptr), mOrigin(aOrigin) {
   AssertIsOnOwningThread();
 
   if (!gLSObservers) {
     gLSObservers = new LSObserverHashtable();
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(!gLSObservers->Get(mOrigin));
+  MOZ_ASSERT(!gLSObservers->Get(mOrigin));
   gLSObservers->Put(mOrigin, this);
 }
 
 LSObserver::~LSObserver() {
   AssertIsOnOwningThread();
 
   if (mActor) {
     mActor->SendDeleteMeInternal();
-    MOZ_DIAGNOSTIC_ASSERT(!mActor, "SendDeleteMeInternal should have cleared!");
+    MOZ_ASSERT(!mActor, "SendDeleteMeInternal should have cleared!");
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(gLSObservers);
-  MOZ_DIAGNOSTIC_ASSERT(gLSObservers->Get(mOrigin));
+  MOZ_ASSERT(gLSObservers);
+  MOZ_ASSERT(gLSObservers->Get(mOrigin));
   gLSObservers->Remove(mOrigin);
 
   if (!gLSObservers->Count()) {
     gLSObservers = nullptr;
   }
 }
 
 // static
 LSObserver* LSObserver::Get(const nsACString& aOrigin) {
   return gLSObservers ? gLSObservers->Get(aOrigin) : nullptr;
 }
 
 void LSObserver::SetActor(LSObserverChild* aActor) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mActor);
+  MOZ_ASSERT(aActor);
+  MOZ_ASSERT(!mActor);
 
   mActor = aActor;
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/localstorage/LSObserver.h
+++ b/dom/localstorage/LSObserver.h
@@ -43,17 +43,17 @@ class LSObserver final {
   NS_INLINE_DECL_REFCOUNTING(LSObserver)
 
   void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(LSObserver); }
 
   void SetActor(LSObserverChild* aActor);
 
   void ClearActor() {
     AssertIsOnOwningThread();
-    MOZ_DIAGNOSTIC_ASSERT(mActor);
+    MOZ_ASSERT(mActor);
 
     mActor = nullptr;
   }
 
  private:
   // Only created by LSObject.
   explicit LSObserver(const nsACString& aOrigin);
 
--- a/dom/localstorage/LSSnapshot.cpp
+++ b/dom/localstorage/LSSnapshot.cpp
@@ -24,53 +24,53 @@ LSSnapshot::LSSnapshot(LSDatabase* aData
       mLength(0),
       mExactUsage(0),
       mPeakUsage(0),
       mLoadState(LoadState::Initial),
       mExplicit(false),
       mHasPendingStableStateCallback(false),
       mHasPendingTimerCallback(false),
       mDirty(false)
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
       ,
       mInitialized(false),
       mSentFinish(false)
 #endif
 {
   AssertIsOnOwningThread();
 }
 
 LSSnapshot::~LSSnapshot() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(!mHasPendingStableStateCallback);
-  MOZ_DIAGNOSTIC_ASSERT(!mHasPendingTimerCallback);
-  MOZ_DIAGNOSTIC_ASSERT_IF(mInitialized, mSentFinish);
+  MOZ_ASSERT(mDatabase);
+  MOZ_ASSERT(!mHasPendingStableStateCallback);
+  MOZ_ASSERT(!mHasPendingTimerCallback);
+  MOZ_ASSERT_IF(mInitialized, mSentFinish);
 
   if (mActor) {
     mActor->SendDeleteMeInternal();
-    MOZ_DIAGNOSTIC_ASSERT(!mActor, "SendDeleteMeInternal should have cleared!");
+    MOZ_ASSERT(!mActor, "SendDeleteMeInternal should have cleared!");
   }
 }
 
 void LSSnapshot::SetActor(LSSnapshotChild* aActor) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(aActor);
-  MOZ_DIAGNOSTIC_ASSERT(!mActor);
+  MOZ_ASSERT(aActor);
+  MOZ_ASSERT(!mActor);
 
   mActor = aActor;
 }
 
 nsresult LSSnapshot::Init(const LSSnapshotInitInfo& aInitInfo, bool aExplicit) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mSelfRef);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mLoadState == LoadState::Initial);
-  MOZ_DIAGNOSTIC_ASSERT(!mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(!mSelfRef);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mLoadState == LoadState::Initial);
+  MOZ_ASSERT(!mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   mSelfRef = this;
 
   LoadState loadState = aInitInfo.loadState();
 
   const nsTArray<LSItemInfo>& itemInfos = aInitInfo.itemInfos();
   for (uint32_t i = 0; i < itemInfos.Length(); i++) {
     const LSItemInfo& itemInfo = itemInfos[i];
@@ -85,62 +85,62 @@ nsresult LSSnapshot::Init(const LSSnapsh
   }
 
   if (loadState == LoadState::Partial) {
     mInitLength = aInitInfo.totalLength();
     mLength = mInitLength;
   } else if (loadState == LoadState::AllOrderedKeys) {
     mInitLength = aInitInfo.totalLength();
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(loadState == LoadState::AllOrderedItems);
+    MOZ_ASSERT(loadState == LoadState::AllOrderedItems);
   }
 
   mExactUsage = aInitInfo.initialUsage();
   mPeakUsage = aInitInfo.peakUsage();
 
   mLoadState = aInitInfo.loadState();
 
   mExplicit = aExplicit;
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   mInitialized = true;
 #endif
 
   if (!mExplicit) {
     mTimer = NS_NewTimer();
-    MOZ_DIAGNOSTIC_ASSERT(mTimer);
+    MOZ_ASSERT(mTimer);
 
     ScheduleStableStateCallback();
   }
 
   return NS_OK;
 }
 
 nsresult LSSnapshot::GetLength(uint32_t* aResult) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   MaybeScheduleStableStateCallback();
 
   if (mLoadState == LoadState::Partial) {
     *aResult = mLength;
   } else {
     *aResult = mValues.Count();
   }
 
   return NS_OK;
 }
 
 nsresult LSSnapshot::GetKey(uint32_t aIndex, nsAString& aResult) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   MaybeScheduleStableStateCallback();
 
   nsresult rv = EnsureAllKeys();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -153,37 +153,37 @@ nsresult LSSnapshot::GetKey(uint32_t aIn
     aIndex--;
   }
 
   return NS_OK;
 }
 
 nsresult LSSnapshot::GetItem(const nsAString& aKey, nsAString& aResult) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   MaybeScheduleStableStateCallback();
 
   nsString result;
   nsresult rv = GetItemInternal(aKey, Optional<nsString>(), result);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   aResult = result;
   return NS_OK;
 }
 
 nsresult LSSnapshot::GetKeys(nsTArray<nsString>& aKeys) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   MaybeScheduleStableStateCallback();
 
   nsresult rv = EnsureAllKeys();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -192,19 +192,19 @@ nsresult LSSnapshot::GetKeys(nsTArray<ns
   }
 
   return NS_OK;
 }
 
 nsresult LSSnapshot::SetItem(const nsAString& aKey, const nsAString& aValue,
                              LSNotifyInfo& aNotifyInfo) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   MaybeScheduleStableStateCallback();
 
   nsString oldValue;
   nsresult rv =
       GetItemInternal(aKey, Optional<nsString>(nsString(aValue)), oldValue);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -249,19 +249,19 @@ nsresult LSSnapshot::SetItem(const nsASt
   aNotifyInfo.oldValue() = oldValue;
 
   return NS_OK;
 }
 
 nsresult LSSnapshot::RemoveItem(const nsAString& aKey,
                                 LSNotifyInfo& aNotifyInfo) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   MaybeScheduleStableStateCallback();
 
   nsString oldValue;
   nsresult rv =
       GetItemInternal(aKey, Optional<nsString>(VoidString()), oldValue);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -271,22 +271,18 @@ nsresult LSSnapshot::RemoveItem(const ns
   if (oldValue.IsVoid()) {
     changed = false;
   } else {
     changed = true;
 
     int64_t delta = -(static_cast<int64_t>(aKey.Length()) +
                       static_cast<int64_t>(oldValue.Length()));
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-    nsresult rv = UpdateUsage(delta);
-    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
-#else
-    UpdateUsage(delta);
-#endif
+    DebugOnly<nsresult> rv = UpdateUsage(delta);
+    MOZ_ASSERT(NS_SUCCEEDED(rv));
 
     if (mLoadState == LoadState::Partial) {
       mLength--;
     }
 
     LSRemoveItemInfo removeItemInfo;
     removeItemInfo.key() = aKey;
     removeItemInfo.oldValue() = oldValue;
@@ -297,26 +293,26 @@ nsresult LSSnapshot::RemoveItem(const ns
   aNotifyInfo.changed() = changed;
   aNotifyInfo.oldValue() = oldValue;
 
   return NS_OK;
 }
 
 nsresult LSSnapshot::Clear(LSNotifyInfo& aNotifyInfo) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   MaybeScheduleStableStateCallback();
 
   uint32_t length;
   if (mLoadState == LoadState::Partial) {
     length = mLength;
-    MOZ_DIAGNOSTIC_ASSERT(length);
+    MOZ_ASSERT(length);
 
     MOZ_ALWAYS_TRUE(mActor->SendLoaded());
 
     mLoadedItems.Clear();
     mUnknownItems.Clear();
     mLength = 0;
     mLoadState = LoadState::AllOrderedItems;
   } else {
@@ -324,66 +320,62 @@ nsresult LSSnapshot::Clear(LSNotifyInfo&
   }
 
   bool changed;
   if (!length) {
     changed = false;
   } else {
     changed = true;
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-    nsresult rv = UpdateUsage(-mExactUsage);
-    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
-#else
-    UpdateUsage(-mExactUsage);
-#endif
+    DebugOnly<nsresult> rv = UpdateUsage(-mExactUsage);
+    MOZ_ASSERT(NS_SUCCEEDED(rv));
 
     mValues.Clear();
 
     LSClearInfo clearInfo;
 
     mWriteInfos.AppendElement(std::move(clearInfo));
   }
 
   aNotifyInfo.changed() = changed;
 
   return NS_OK;
 }
 
 void LSSnapshot::MarkDirty() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   if (mDirty) {
     return;
   }
 
   mDirty = true;
 
   if (!mExplicit && !mHasPendingStableStateCallback) {
     CancelTimer();
 
     MOZ_ALWAYS_SUCCEEDS(Checkpoint());
 
     MOZ_ALWAYS_SUCCEEDS(Finish());
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(!mHasPendingTimerCallback);
+    MOZ_ASSERT(!mHasPendingTimerCallback);
   }
 }
 
 nsresult LSSnapshot::End() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mExplicit);
-  MOZ_DIAGNOSTIC_ASSERT(!mHasPendingStableStateCallback);
-  MOZ_DIAGNOSTIC_ASSERT(!mHasPendingTimerCallback);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mExplicit);
+  MOZ_ASSERT(!mHasPendingStableStateCallback);
+  MOZ_ASSERT(!mHasPendingTimerCallback);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   nsresult rv = Checkpoint();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   RefPtr<LSSnapshot> kungFuDeathGrip = this;
 
@@ -396,52 +388,52 @@ nsresult LSSnapshot::End() {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 void LSSnapshot::ScheduleStableStateCallback() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mTimer);
-  MOZ_DIAGNOSTIC_ASSERT(!mExplicit);
-  MOZ_DIAGNOSTIC_ASSERT(!mHasPendingStableStateCallback);
+  MOZ_ASSERT(mTimer);
+  MOZ_ASSERT(!mExplicit);
+  MOZ_ASSERT(!mHasPendingStableStateCallback);
 
   CancelTimer();
 
   nsCOMPtr<nsIRunnable> runnable = this;
   nsContentUtils::RunInStableState(runnable.forget());
 
   mHasPendingStableStateCallback = true;
 }
 
 void LSSnapshot::MaybeScheduleStableStateCallback() {
   AssertIsOnOwningThread();
 
   if (!mExplicit && !mHasPendingStableStateCallback) {
     ScheduleStableStateCallback();
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(!mHasPendingTimerCallback);
+    MOZ_ASSERT(!mHasPendingTimerCallback);
   }
 }
 
 nsresult LSSnapshot::GetItemInternal(const nsAString& aKey,
                                      const Optional<nsString>& aValue,
                                      nsAString& aResult) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   nsString result;
 
   switch (mLoadState) {
     case LoadState::Partial: {
       if (mValues.Get(aKey, &result)) {
-        MOZ_DIAGNOSTIC_ASSERT(!result.IsVoid());
+        MOZ_ASSERT(!result.IsVoid());
       } else if (mLoadedItems.GetEntry(aKey) || mUnknownItems.GetEntry(aKey)) {
         result.SetIsVoid(true);
       } else {
         if (NS_WARN_IF(!mActor->SendLoadItem(nsString(aKey), &result))) {
           return NS_ERROR_FAILURE;
         }
 
         if (result.IsVoid()) {
@@ -473,24 +465,24 @@ nsresult LSSnapshot::GetItemInternal(con
 
     case LoadState::AllOrderedKeys: {
       if (mValues.Get(aKey, &result)) {
         if (result.IsVoid()) {
           if (NS_WARN_IF(!mActor->SendLoadItem(nsString(aKey), &result))) {
             return NS_ERROR_FAILURE;
           }
 
-          MOZ_DIAGNOSTIC_ASSERT(!result.IsVoid());
+          MOZ_ASSERT(!result.IsVoid());
 
           mLoadedItems.PutEntry(aKey);
           mValues.Put(aKey, result);
 
           if (mLoadedItems.Count() == mInitLength) {
             mLoadedItems.Clear();
-            MOZ_DIAGNOSTIC_ASSERT(mLength == 0);
+            MOZ_ASSERT(mLength == 0);
             mLoadState = LoadState::AllOrderedItems;
           }
         }
       } else {
         result.SetIsVoid(true);
       }
 
       if (aValue.WasPassed()) {
@@ -516,25 +508,25 @@ nsresult LSSnapshot::GetItemInternal(con
             entry.Data() = value;
           } else {
             result.SetIsVoid(true);
             entry.OrInsert([value]() { return value; });
           }
         } else {
           if (auto entry = mValues.Lookup(aKey)) {
             result = entry.Data();
-            MOZ_DIAGNOSTIC_ASSERT(!result.IsVoid());
+            MOZ_ASSERT(!result.IsVoid());
             entry.Remove();
           } else {
             result.SetIsVoid(true);
           }
         }
       } else {
         if (mValues.Get(aKey, &result)) {
-          MOZ_DIAGNOSTIC_ASSERT(!result.IsVoid());
+          MOZ_ASSERT(!result.IsVoid());
         } else {
           result.SetIsVoid(true);
         }
       }
 
       break;
     }
 
@@ -543,20 +535,20 @@ nsresult LSSnapshot::GetItemInternal(con
   }
 
   aResult = result;
   return NS_OK;
 }
 
 nsresult LSSnapshot::EnsureAllKeys() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
-  MOZ_DIAGNOSTIC_ASSERT(mLoadState != LoadState::Initial);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mLoadState != LoadState::Initial);
 
   if (mLoadState == LoadState::AllOrderedKeys ||
       mLoadState == LoadState::AllOrderedItems) {
     return NS_OK;
   }
 
   nsTArray<nsString> keys;
   if (NS_WARN_IF(!mActor->SendLoadKeys(&keys))) {
@@ -586,154 +578,154 @@ nsresult LSSnapshot::EnsureAllKeys() {
         break;
       }
 
       default:
         MOZ_CRASH("Should never get here!");
     }
   }
 
-  MOZ_DIAGNOSTIC_ASSERT_IF(mLoadState == LoadState::AllUnorderedItems,
-                           newValues.Count() == mValues.Count());
+  MOZ_ASSERT_IF(mLoadState == LoadState::AllUnorderedItems,
+                newValues.Count() == mValues.Count());
 
   for (auto iter = newValues.Iter(); !iter.Done(); iter.Next()) {
     nsString value;
     if (mValues.Get(iter.Key(), &value)) {
       iter.Data() = value;
     }
   }
 
   mValues.SwapElements(newValues);
 
   if (mLoadState == LoadState::Partial) {
     mUnknownItems.Clear();
     mLength = 0;
     mLoadState = LoadState::AllOrderedKeys;
   } else {
-    MOZ_DIAGNOSTIC_ASSERT(mLoadState == LoadState::AllUnorderedItems);
+    MOZ_ASSERT(mLoadState == LoadState::AllUnorderedItems);
 
-    MOZ_DIAGNOSTIC_ASSERT(mUnknownItems.Count() == 0);
-    MOZ_DIAGNOSTIC_ASSERT(mLength == 0);
+    MOZ_ASSERT(mUnknownItems.Count() == 0);
+    MOZ_ASSERT(mLength == 0);
     mLoadState = LoadState::AllOrderedItems;
   }
 
   return NS_OK;
 }
 
 nsresult LSSnapshot::UpdateUsage(int64_t aDelta) {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mPeakUsage >= mExactUsage);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mDatabase);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mPeakUsage >= mExactUsage);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   int64_t newExactUsage = mExactUsage + aDelta;
   if (newExactUsage > mPeakUsage) {
     int64_t minSize = newExactUsage - mPeakUsage;
     int64_t requestedSize = minSize + 4096;
     int64_t size;
     if (NS_WARN_IF(
             !mActor->SendIncreasePeakUsage(requestedSize, minSize, &size))) {
       return NS_ERROR_FAILURE;
     }
 
-    MOZ_DIAGNOSTIC_ASSERT(size >= 0);
+    MOZ_ASSERT(size >= 0);
 
     if (size == 0) {
       return NS_ERROR_FILE_NO_DEVICE_SPACE;
     }
 
     mPeakUsage += size;
   }
 
   mExactUsage = newExactUsage;
   return NS_OK;
 }
 
 nsresult LSSnapshot::Checkpoint() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   if (!mWriteInfos.IsEmpty()) {
     MOZ_ALWAYS_TRUE(mActor->SendCheckpoint(mWriteInfos));
 
     mWriteInfos.Clear();
   }
 
   return NS_OK;
 }
 
 nsresult LSSnapshot::Finish() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mDatabase);
-  MOZ_DIAGNOSTIC_ASSERT(mActor);
-  MOZ_DIAGNOSTIC_ASSERT(mInitialized);
-  MOZ_DIAGNOSTIC_ASSERT(!mSentFinish);
+  MOZ_ASSERT(mDatabase);
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(mInitialized);
+  MOZ_ASSERT(!mSentFinish);
 
   MOZ_ALWAYS_TRUE(mActor->SendFinish());
 
   mDatabase->NoteFinishedSnapshot(this);
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   mSentFinish = true;
 #endif
 
   // Clear the self reference added in Init method.
-  MOZ_DIAGNOSTIC_ASSERT(mSelfRef);
+  MOZ_ASSERT(mSelfRef);
   mSelfRef = nullptr;
 
   return NS_OK;
 }
 
 void LSSnapshot::CancelTimer() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(mTimer);
+  MOZ_ASSERT(mTimer);
 
   if (mHasPendingTimerCallback) {
     MOZ_ALWAYS_SUCCEEDS(mTimer->Cancel());
     mHasPendingTimerCallback = false;
   }
 }
 
 // static
 void LSSnapshot::TimerCallback(nsITimer* aTimer, void* aClosure) {
-  MOZ_DIAGNOSTIC_ASSERT(aTimer);
+  MOZ_ASSERT(aTimer);
 
   auto* self = static_cast<LSSnapshot*>(aClosure);
-  MOZ_DIAGNOSTIC_ASSERT(self);
-  MOZ_DIAGNOSTIC_ASSERT(self->mTimer);
-  MOZ_DIAGNOSTIC_ASSERT(SameCOMIdentity(self->mTimer, aTimer));
-  MOZ_DIAGNOSTIC_ASSERT(!self->mHasPendingStableStateCallback);
-  MOZ_DIAGNOSTIC_ASSERT(self->mHasPendingTimerCallback);
+  MOZ_ASSERT(self);
+  MOZ_ASSERT(self->mTimer);
+  MOZ_ASSERT(SameCOMIdentity(self->mTimer, aTimer));
+  MOZ_ASSERT(!self->mHasPendingStableStateCallback);
+  MOZ_ASSERT(self->mHasPendingTimerCallback);
 
   self->mHasPendingTimerCallback = false;
 
   MOZ_ALWAYS_SUCCEEDS(self->Finish());
 }
 
 NS_IMPL_ISUPPORTS(LSSnapshot, nsIRunnable)
 
 NS_IMETHODIMP
 LSSnapshot::Run() {
   AssertIsOnOwningThread();
-  MOZ_DIAGNOSTIC_ASSERT(!mExplicit);
-  MOZ_DIAGNOSTIC_ASSERT(mHasPendingStableStateCallback);
-  MOZ_DIAGNOSTIC_ASSERT(!mHasPendingTimerCallback);
+  MOZ_ASSERT(!mExplicit);
+  MOZ_ASSERT(mHasPendingStableStateCallback);
+  MOZ_ASSERT(!mHasPendingTimerCallback);
 
   mHasPendingStableStateCallback = false;
 
   MOZ_ALWAYS_SUCCEEDS(Checkpoint());
 
   if (mDirty || !Preferences::GetBool("dom.storage.snapshot_reusing")) {
     MOZ_ALWAYS_SUCCEEDS(Finish());
   } else if (!mExplicit) {
-    MOZ_DIAGNOSTIC_ASSERT(mTimer);
+    MOZ_ASSERT(mTimer);
 
     MOZ_ALWAYS_SUCCEEDS(mTimer->InitWithNamedFuncCallback(
         TimerCallback, this, kSnapshotTimeoutMs, nsITimer::TYPE_ONE_SHOT,
         "LSSnapshot::TimerCallback"));
 
     mHasPendingTimerCallback = true;
   }
 
--- a/dom/localstorage/LSSnapshot.h
+++ b/dom/localstorage/LSSnapshot.h
@@ -86,31 +86,31 @@ class LSSnapshot final : public nsIRunna
 
   LoadState mLoadState;
 
   bool mExplicit;
   bool mHasPendingStableStateCallback;
   bool mHasPendingTimerCallback;
   bool mDirty;
 
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+#ifdef DEBUG
   bool mInitialized;
   bool mSentFinish;
 #endif
 
  public:
   explicit LSSnapshot(LSDatabase* aDatabase);
 
   void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(LSSnapshot); }
 
   void SetActor(LSSnapshotChild* aActor);
 
   void ClearActor() {
     AssertIsOnOwningThread();
-    MOZ_DIAGNOSTIC_ASSERT(mActor);
+    MOZ_ASSERT(mActor);
 
     mActor = nullptr;
   }
 
   bool Explicit() const { return mExplicit; }
 
   nsresult Init(const LSSnapshotInitInfo& aInitInfo, bool aExplicit);
 
--- a/dom/localstorage/LocalStorageCommon.cpp
+++ b/dom/localstorage/LocalStorageCommon.cpp
@@ -42,17 +42,17 @@ bool NextGenLocalStorageEnabled() {
     bool enabled = Preferences::GetBool("dom.storage.next_gen", false);
     gNextGenLocalStorageEnabled = enabled ? 1 : 0;
   }
 
   return !!gNextGenLocalStorageEnabled;
 }
 
 bool CachedNextGenLocalStorageEnabled() {
-  MOZ_DIAGNOSTIC_ASSERT(gNextGenLocalStorageEnabled != -1);
+  MOZ_ASSERT(gNextGenLocalStorageEnabled != -1);
 
   return !!gNextGenLocalStorageEnabled;
 }
 
 nsresult GenerateOriginKey2(const PrincipalInfo& aPrincipalInfo,
                             nsACString& aOriginAttrSuffix,
                             nsACString& aOriginKey) {
   OriginAttributes attrs;
--- a/dom/localstorage/LocalStorageManager2.cpp
+++ b/dom/localstorage/LocalStorageManager2.cpp
@@ -49,17 +49,17 @@ class SimpleRequestResolver final : publ
   void HandleResponse(bool aResponse);
 
   // LSRequestChildCallback
   void OnResponse(const LSSimpleRequestResponse& aResponse) override;
 };
 
 nsresult CreatePromise(JSContext* aContext, Promise** aPromise) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aContext);
+  MOZ_ASSERT(aContext);
 
   nsIGlobalObject* global =
       xpc::NativeGlobal(JS::CurrentGlobalOrNull(aContext));
   if (NS_WARN_IF(!global)) {
     return NS_ERROR_FAILURE;
   }
 
   ErrorResult result;
@@ -70,17 +70,17 @@ nsresult CreatePromise(JSContext* aConte
 
   promise.forget(aPromise);
   return NS_OK;
 }
 
 nsresult CheckedPrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
                                          PrincipalInfo& aPrincipalInfo) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPrincipal);
+  MOZ_ASSERT(aPrincipal);
 
   nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &aPrincipalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
     return NS_ERROR_FAILURE;
@@ -93,47 +93,47 @@ nsresult CheckedPrincipalToPrincipalInfo
 
   return NS_OK;
 }
 
 }  // namespace
 
 LocalStorageManager2::LocalStorageManager2() {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(NextGenLocalStorageEnabled());
+  MOZ_ASSERT(NextGenLocalStorageEnabled());
 }
 
 LocalStorageManager2::~LocalStorageManager2() { MOZ_ASSERT(NS_IsMainThread()); }
 
 NS_IMPL_ISUPPORTS(LocalStorageManager2, nsIDOMStorageManager,
                   nsILocalStorageManager)
 
 NS_IMETHODIMP
 LocalStorageManager2::PrecacheStorage(nsIPrincipal* aPrincipal,
                                       Storage** _retval) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPrincipal);
-  MOZ_DIAGNOSTIC_ASSERT(_retval);
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(_retval);
 
   // This method was created as part of the e10s-ification of the old LS
   // implementation to perform a preload in the content/current process.  That's
   // not how things work in LSNG.  Instead everything happens in the parent
   // process, triggered by the official preloading spot,
   // ContentParent::AboutToLoadHttpFtpDocumentForChild.
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 LocalStorageManager2::CreateStorage(mozIDOMWindow* aWindow,
                                     nsIPrincipal* aPrincipal,
                                     const nsAString& aDocumentURI,
                                     bool aPrivate, Storage** _retval) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPrincipal);
-  MOZ_DIAGNOSTIC_ASSERT(_retval);
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(_retval);
 
   nsCOMPtr<nsPIDOMWindowInner> inner = nsPIDOMWindowInner::From(aWindow);
 
   RefPtr<LSObject> object;
   nsresult rv = LSObject::CreateForPrincipal(inner, aPrincipal, aDocumentURI,
                                              aPrivate, getter_AddRefs(object));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -143,59 +143,59 @@ LocalStorageManager2::CreateStorage(mozI
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LocalStorageManager2::GetStorage(mozIDOMWindow* aWindow,
                                  nsIPrincipal* aPrincipal, bool aPrivate,
                                  Storage** _retval) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPrincipal);
-  MOZ_DIAGNOSTIC_ASSERT(_retval);
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(_retval);
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 LocalStorageManager2::CloneStorage(Storage* aStorageToCloneFrom) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aStorageToCloneFrom);
+  MOZ_ASSERT(aStorageToCloneFrom);
 
   // Cloning is specific to sessionStorage; state is forked when a new tab is
   // opened from an existing tab.
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 LocalStorageManager2::CheckStorage(nsIPrincipal* aPrincipal, Storage* aStorage,
                                    bool* _retval) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPrincipal);
-  MOZ_DIAGNOSTIC_ASSERT(aStorage);
-  MOZ_DIAGNOSTIC_ASSERT(_retval);
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(aStorage);
+  MOZ_ASSERT(_retval);
 
   // Only used by sessionStorage.
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 LocalStorageManager2::GetNextGenLocalStorageEnabled(bool* aResult) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aResult);
+  MOZ_ASSERT(aResult);
 
   *aResult = NextGenLocalStorageEnabled();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LocalStorageManager2::Preload(nsIPrincipal* aPrincipal, JSContext* aContext,
                               nsISupports** _retval) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPrincipal);
-  MOZ_DIAGNOSTIC_ASSERT(_retval);
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(_retval);
 
   nsCString originAttrSuffix;
   nsCString originKey;
   nsresult rv = GenerateOriginKey(aPrincipal, originAttrSuffix, originKey);
   if (NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
@@ -228,18 +228,18 @@ LocalStorageManager2::Preload(nsIPrincip
   promise.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LocalStorageManager2::IsPreloaded(nsIPrincipal* aPrincipal, JSContext* aContext,
                                   nsISupports** _retval) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPrincipal);
-  MOZ_DIAGNOSTIC_ASSERT(_retval);
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(_retval);
 
   RefPtr<Promise> promise;
   nsresult rv = CreatePromise(aContext, getter_AddRefs(promise));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   LSSimpleRequestPreloadedParams params;
@@ -277,17 +277,17 @@ nsresult LocalStorageManager2::StartRequ
   }
 
   return NS_OK;
 }
 
 nsresult LocalStorageManager2::StartSimpleRequest(
     Promise* aPromise, const LSSimpleRequestParams& aParams) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aPromise);
+  MOZ_ASSERT(aPromise);
 
   PBackgroundChild* backgroundActor =
       BackgroundChild::GetOrCreateForCurrentThread();
   if (NS_WARN_IF(!backgroundActor)) {
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<SimpleRequestResolver> resolver = new SimpleRequestResolver(aPromise);
@@ -335,24 +335,24 @@ void RequestResolver::OnResponse(const L
       break;
     default:
       MOZ_CRASH("Unknown response type!");
   }
 }
 
 void SimpleRequestResolver::HandleResponse(nsresult aResponse) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(mPromise);
+  MOZ_ASSERT(mPromise);
 
   mPromise->MaybeReject(aResponse);
 }
 
 void SimpleRequestResolver::HandleResponse(bool aResponse) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(mPromise);
+  MOZ_ASSERT(mPromise);
 
   mPromise->MaybeResolve(aResponse);
 }
 
 void SimpleRequestResolver::OnResponse(
     const LSSimpleRequestResponse& aResponse) {
   MOZ_ASSERT(NS_IsMainThread());
 
--- a/js/src/doc/Debugger/Debugger-API.md
+++ b/js/src/doc/Debugger/Debugger-API.md
@@ -105,17 +105,18 @@ per-`Debugger`, tools can do so without 
 other tools that use their own `Debugger` instances.
 
 
 ## Examples
 
 Here are some things you can try out yourself that show off some of `Debugger`'s
 features:
 
-- [Evaluating an expression in a web page's stack frame when it executes a `debugger;` statement.][tut debugger]
+- [Setting a breakpoint][tut breakpoint] in a page, running a handler function
+  when it is hit that evaluates an expression in the page's context.
 
 - [Showing how many objects different call paths allocate.][tut alloc log]
 
 
 ## Gecko-specific features
 
 While the `Debugger` core API deals only with concepts common to any
 JavaScript implementation, it also includes some Gecko-specific features:
new file mode 100644
--- /dev/null
+++ b/js/src/doc/Debugger/Tutorial-Breakpoint.md
@@ -0,0 +1,126 @@
+Tutorial: Set a breakpoint using `Debugger`
+===========================================
+
+This page shows how you can try out the [`Debugger` API][debugger] yourself
+using Firefox's Scratchpad. We use `Debugger` to set a breakpoint in a function,
+and then evaluate an expression whenever it is hit.
+
+This tutorial was tested against Firefox 58 Beta and Nightly. It does not work in Firefox 57.
+
+1)  Since the `Debugger` API is only available to privileged JavaScript code,
+    you'll need to use the Browser Content Toolbox to try it out. To do this,
+    open the Firefox developer tools, click on the options gear at the upper
+    right of the toolbox, and make sure that both “Enable browser chrome and
+    add-on debugging toolboxes” and “Enable remote debugging” are checked. These
+    are located at the bottom right of the options panel; you may need to scroll
+    to see them. Once they're checked, you can close the developer tools.
+
+
+1)  Save the following text to an HTML file:
+
+    ```language-html
+    <div onclick="report('the best div');">Click me!</div>
+    <div onclick="report('another great div');">Or me!</div>
+    <script>
+    function report(what) {
+      console.log('clicked: ' + what);
+    }
+    </script>
+    ```
+
+1)  Visit the HTML file in your browser, and open the Browser Content Toolbox by
+    opening the Firefox menu, choosing “Web Developer”, and then “Browser
+    Content Toolbox”. If that item doesn't appear in the “Web Developer” menu,
+    make sure you checked both boxes to enable the Browser Content Toolbox as
+    explained in Step 1.
+
+1)  Our example code is long enough that the best way to run it is to use the
+    Scratchpad panel, which is not enabled by default. To enable it, click on
+    the options gear at the upper right of the Browser Content Toolbox, and make
+    sure the “Scratchpad” box in the “Default Developer Tools” section the left
+    is checked. The Scratchpad panel should appear at the top of the Toolbox
+    alongside the Console, Debugger, and Memory panels.
+
+1)  Click on the Scratchpad panel and enter the following code:
+
+    ```language-js
+    Components.utils.import("resource://gre/modules/jsdebugger.jsm");
+    Components.utils.import("resource://gre/modules/Console.jsm");
+
+    // This simply defines 'Debugger' in this Scratchpad;
+    // it doesn't actually start debugging anything.
+    addDebuggerToGlobal(this);
+
+    // Create a 'Debugger' instance.
+    var dbg = new Debugger;
+
+    // Make the tab's top window a debuggee, and get a
+    // Debugger.Object referring to the window.
+    var windowDO = dbg.addDebuggee(tabs[0].content);
+
+    // Get a Debugger.Object referring to the window's `report`
+    // function.
+    var reportDO = windowDO.getOwnPropertyDescriptor('report').value;
+
+    // Set a breakpoint at the entry point of `report`.
+    reportDO.script.setBreakpoint(0, {
+        hit: function (frame) {
+            console.log('hit breakpoint in ' + frame.callee.name);
+            console.log('what = ' + frame.eval('what').return);
+        }
+    });
+
+    console.log('Finished setting breakpoint!');
+    ```
+
+1)  In the Scratchpad, ensure that no text is selected, and press the "Run"
+    button.
+
+    Now, click on the text that says "Click me!" in the web page.
+    This runs the `div` element's `onclick` handler.
+    When control reaches the start of the `report` function,
+    `Debugger` calls the breakpoint handler's `hit` method,
+    passing a `Debugger.Frame` instance.
+    The `hit` method logs the breakpoint hit to the browser content toolbox's console.
+    Then it evaluates the expression `what` in the given stack frame, and logs its result.
+    The toolbox's console now looks like this:
+
+    ![The breakpoint handler's console output][img-example-console]
+    <!-- HTML comment prevents caption, which MDN styles poorly  -->
+
+    You can also click on the text that says “Or me!”, to see `report` called from a
+    different handler.
+
+    If `Debugger` is unable to find the `report` function, or the console output
+    does not appear, evaluate the expression `tabs[0].content.document.location`
+    in the console to make sure that `tabs[0]` indeed refers to the HTML file you
+    visited. If you have more than one tab visiting a `file:` URL, they all share
+    a single content process, so you may need to use a different element of the
+    array as the debuggee.
+
+1) Press "Run" in the Scratchpad again. Now, clicking on "Click me!" causes the
+    breakpoint hit to be logged twice---one for each `Debugger` instance.
+
+    Multiple `Debugger` instances can observe the same debuggee. Re-running the code
+    in the Scratchpad creates a fresh `Debugger` instance, adds the same web page as
+    its debuggee, and then sets a new breakpoint. When you click on the `div`
+    element, both `Debugger`s' breakpoints are hit, and both handlers run.
+
+    This shows how any number of `Debugger`-based tools can observe a single web
+    page simultaneously. In fact, you can use the Browser Content Toolbox's Debugger
+    panel to set its own breakpoint in `report`, and it will trigger along with the
+    first two. Keep in mind, however, that when multiple Debuggers share a debuggee,
+    the order in which their handlers run is not specified. If more than one tool
+    tries to influence the debuggee's behavior, their combined behavior could be
+    unpredictable.
+
+1)  Close the web page and the Browser Content Toolbox.
+
+    Since both the Scratchpad's global object and the debuggee window are
+    now gone, the `Debugger` instances will be garbage collected, since
+    they can no longer have any visible effect on Firefox's behavior. The
+    `Debugger` API tries to interact with garbage collection as
+    transparently as possible; for example, if both a `Debugger.Object`
+    instance and its referent are not reachable, they will both be
+    collected, even while the `Debugger` instance to which the shadow
+    belonged continues to exist.
--- a/js/src/doc/Debugger/Tutorial-Debugger-Statement.md
+++ b/js/src/doc/Debugger/Tutorial-Debugger-Statement.md
@@ -1,11 +1,14 @@
 Tutorial: Evaluate an Expression When a debugger; Statement Is Executed
 =======================================================================
 
+**NOTE: This tutorial no longer works in current versions of Firefox.**
+Instead, please try the updated and expanded [breakpoint tutorial][tut breakpoint].
+
 This page shows how you can try out the [`Debugger` API][debugger] yourself
 using Firefox's Scratchpad. We use the API to evaluate an expression in the web
 page whenever it executes a JavaScript `debugger;` statement.
 
 1)  Visit the URL `about:config`, and set the `devtools.chrome.enabled`
     preference to `true`:
 
     ![Setting the 'devtools.chrome.enabled' preference][img-chrome-pref]
--- a/js/src/doc/Debugger/config.sh
+++ b/js/src/doc/Debugger/config.sh
@@ -43,24 +43,39 @@ markdown Debugger.Memory.md Debugger-API
   label 'drain-alloc-log'            '#drain-alloc-log'            "Debugger.Memory: drainAllocationsLog"
   label 'max-alloc-log'              '#max-alloc-log'              "Debugger.Memory: maxAllocationsLogLength"
   label 'alloc-sampling-probability' '#alloc-sampling-probability' "Debugger.Memory: allocationSamplingProbability"
   label 'take-census'                '#take-census'                "Debugger.Memory: takeCensus"
 
 markdown Tutorial-Debugger-Statement.md Debugger-API/Tutorial-Debugger-Statement
   label 'tut debugger'                          "Tutorial: the debugger; statement"
 
+markdown Tutorial-Breakpoint.md Debugger-API/Tutorial-Breakpoint
+  label 'tut breakpoint'                        "Tutorial: Evaluate an expression when a breakpoint is hit"
+
 markdown Tutorial-Alloc-Log-Tree.md Debugger-API/Tutorial-Allocation-Log-Tree
   label 'tut alloc log'                         "Tutorial: the allocation log"
 
 # Images:
 RBASE=https://mdn.mozillademos.org/files
 resource 'img-shadows'            shadows.svg                        $RBASE/7225/shadows.svg
 resource 'img-chrome-pref'        enable-chrome-devtools.png         $RBASE/7233/enable-chrome-devtools.png
 resource 'img-scratchpad-browser' scratchpad-browser-environment.png $RBASE/7229/scratchpad-browser-environment.png
 resource 'img-example-alert'      debugger-alert.png                 $RBASE/7231/debugger-alert.png
+resource 'img-example-console'    console.png                        $RBASE/15721/console.png
 resource 'img-alloc-plot'         alloc-plot-console.png             $RBASE/8461/alloc-plot-console.png
 
 # External links:
-absolute-label 'protocol' https://wiki.mozilla.org/Remote_Debugging_Protocol "Remote Debugging Protocol"
-absolute-label 'saved-frame' https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/SavedFrame "SavedFrame"
-absolute-label 'bernoulli-trial' https://en.wikipedia.org/wiki/Bernoulli_trial "Bernoulli Trial"
-absolute-label 'promise' https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
+absolute-label 'protocol' \
+    https://wiki.mozilla.org/Remote_Debugging_Protocol \
+    "Remote Debugging Protocol"
+absolute-label 'saved-frame' \
+    https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/SavedFrame \
+    "SavedFrame"
+absolute-label 'bernoulli-trial' \
+    https://en.wikipedia.org/wiki/Bernoulli_trial \
+    "Bernoulli Trial"
+absolute-label 'promise' \
+    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise \
+    "Promise"
+absolute-label 'browser-content-toolbox' \
+    https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Debugging_frame_scripts \
+    "Browser Content Toolbox"
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9e9ce4ae74c14925b40de49aa05f78ab5a3b2cc9
GIT binary patch
literal 41695
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%0D4Pww`p<B{;yS`5i^
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
DdLt&}
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -193,17 +193,16 @@ pref("xpinstall.signatures.required", tr
 // constants in AddonManager.jsm for values to use here, and Bug 1405528 for a rationale).
 pref("extensions.autoDisableScopes", 15);
 
 pref("extensions.enabledScopes", 1);
 pref("extensions.autoupdate.enabled", true);
 pref("extensions.autoupdate.interval", 86400);
 pref("extensions.update.enabled", true);
 pref("extensions.update.interval", 86400);
-pref("lightweightThemes.update.enabled", true);
 pref("extensions.dss.enabled", false);
 pref("extensions.ignoreMTimeChanges", false);
 pref("extensions.logging.enabled", false);
 pref("extensions.hideInstallButton", true);
 pref("extensions.hideUpdateButton", false);
 pref("extensions.strictCompatibility", false);
 pref("extensions.minCompatibleAppVersion", "11.0");
 
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -6543,21 +6543,16 @@ var Distribution = {
           case "string":
           case "undefined":
             defaults.setCharPref(key, value);
             break;
         }
       } catch (e) { /* ignore bad prefs and move on */ }
     }
 
-    // Apply a lightweight theme if necessary
-    if (prefs && prefs["lightweightThemes.selectedThemeID"]) {
-      Services.obs.notifyObservers(null, "lightweight-theme-apply");
-    }
-
     let localizedString = Cc["@mozilla.org/pref-localizedstring;1"].createInstance(Ci.nsIPrefLocalizedString);
     let localizeablePrefs = aData["LocalizablePreferences"];
     for (let key in localizeablePrefs) {
       try {
         let value = localizeablePrefs[key];
         value = value.replace(/%LOCALE%/g, locale);
         localizedString.data = "data:text/plain," + key + "=" + value;
         defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedString);
--- a/mobile/android/modules/LightweightThemeConsumer.jsm
+++ b/mobile/android/modules/LightweightThemeConsumer.jsm
@@ -1,54 +1,77 @@
 /* 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/. */
 
 var EXPORTED_SYMBOLS = ["LightweightThemeConsumer"];
 
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {LightweightThemeManager} = ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm");
+const {ExtensionUtils} = ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "EventDispatcher",
                                "resource://gre/modules/Messaging.jsm");
-ChromeUtils.defineModuleGetter(this, "LightweightThemePersister",
-  "resource://gre/modules/addons/LightweightThemePersister.jsm");
 
 const DEFAULT_THEME_ID = "default-theme@mozilla.org";
 
-function LightweightThemeConsumer(aDocument) {
-  this._doc = aDocument;
-  Services.obs.addObserver(this, "lightweight-theme-styling-update");
-  Services.obs.addObserver(this, "lightweight-theme-apply");
+let RESOLVE_PROPERTIES = ["headerURL"];
+
+let handlers = new ExtensionUtils.DefaultMap(proto => {
+  try {
+    return Cc[`@mozilla.org/network/protocol;1?name=${proto}`]
+      .getService(Ci.nsISubstitutingProtocolHandler);
+  } catch (e) {
+    return null;
+  }
+});
 
-  this._update(LightweightThemeManager.currentThemeWithFallback);
+// The Java front-end code cannot understand internal protocols like
+// resource:, so resolve them to their underlying file: or jar: URIs
+// when possible.
+function maybeResolveURL(url) {
+  try {
+    let uri = Services.io.newURI(url);
+    let handler = handlers.get(uri.scheme);
+    if (handler) {
+      return handler.resolveURI(uri);
+    }
+  } catch (e) {
+    Cu.reportError(e);
+  }
+  return url;
 }
 
-LightweightThemeConsumer.prototype = {
-  observe: function(aSubject, aTopic, aData) {
+class LightweightThemeConsumer {
+  constructor(aDocument) {
+    this._doc = aDocument;
+    Services.obs.addObserver(this, "lightweight-theme-styling-update");
+
+    this._update(LightweightThemeManager.currentThemeWithFallback);
+  }
+
+  observe(aSubject, aTopic, aData) {
     if (aTopic == "lightweight-theme-styling-update") {
       this._update(aSubject.wrappedJSObject.theme);
-    } else if (aTopic == "lightweight-theme-apply") {
-      this._update(LightweightThemeManager.currentThemeWithFallback);
     }
-  },
+  }
 
-  destroy: function() {
+  destroy() {
     Services.obs.removeObserver(this, "lightweight-theme-styling-update");
-    Services.obs.removeObserver(this, "lightweight-theme-apply");
     this._doc = null;
-  },
+  }
 
-  _update: function(aData) {
+  _update(aData) {
     let active = aData && aData.id !== DEFAULT_THEME_ID;
-    let msg = active ? { type: "LightweightTheme:Update" } :
-                       { type: "LightweightTheme:Disable" };
+    let msg = { type: (active ? "LightweightTheme:Update"
+                              : "LightweightTheme:Disable") };
 
     if (active) {
-      LightweightThemePersister.persistImages(aData, () => {
-        msg.data = LightweightThemePersister.getPersistedData(aData);
-        EventDispatcher.instance.sendRequest(msg);
-      });
-    } else {
-      EventDispatcher.instance.sendRequest(msg);
+      msg.data = {...aData};
+      for (let prop of RESOLVE_PROPERTIES) {
+        if (msg.data[prop]) {
+          msg.data[prop] = maybeResolveURL(msg.data[prop]);
+        }
+      }
     }
-  },
-};
+    EventDispatcher.instance.sendRequest(msg);
+  }
+}
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testThemeInstall.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testThemeInstall.java
@@ -41,25 +41,20 @@ public class testThemeInstall extends Ja
             checkTestFinished();
             return;
         }
 
         mAsserter.is(event, "LightweightTheme:Update", "Received LightweightTheme:Update event");
         try {
             GeckoBundle themeData = message.getBundle("data");
             String headerURL = themeData.getString("headerURL");
-            mAsserter.ok(headerURL.contains("/lightweighttheme-header"),
+            mAsserter.ok(headerURL.endsWith("/testImage.png"),
                     "Theme update has the expected headerURL",null);
-            mAsserter.ok(headerURL.startsWith("file://"),
-                    "headerURL was transformed to file:// URL", null);
-            File themeFile = new File(new URI(headerURL).getPath());
-            mAsserter.ok(themeFile.exists(),
-                    "file pointed to by headerURL was successfully persisted", null);
-            mAsserter.ok(themeFile.length() > 0,
-                    "theme file is not empty", null);
+            mAsserter.ok(headerURL.startsWith("jar:file://"),
+                    "headerURL was transformed to jar:file:// URL", null);
         } catch (Exception e) {
             fFail("Event does not contain expected data: " + e.getMessage());
         }
 
         mFinished = true;
         checkTestFinished();
     }
 
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-67c41e385581
+e5e10a46b9ad
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc
@@ -477,16 +477,83 @@ TEST_P(TlsExtensionTestGeneric, Supporte
 
 TEST_P(TlsExtensionTestGeneric, SupportedCurvesTrailingData) {
   const uint8_t val[] = {0x00, 0x02, 0x00, 0x00, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
       client_, ssl_elliptic_curves_xtn, extension));
 }
 
+TEST_P(TlsExtensionTest12, SupportedCurvesDisableX25519) {
+  // Disable session resumption.
+  ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
+
+  // Ensure that we can enable its use in the key exchange.
+  SECStatus rv =
+      NSS_SetAlgorithmPolicy(SEC_OID_CURVE25519, NSS_USE_ALG_IN_SSL_KX, 0);
+  ASSERT_EQ(SECSuccess, rv);
+  rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
+                              0);
+  ASSERT_EQ(SECSuccess, rv);
+
+  auto capture1 =
+      MakeTlsFilter<TlsExtensionCapture>(client_, ssl_elliptic_curves_xtn);
+  Connect();
+
+  EXPECT_TRUE(capture1->captured());
+  const DataBuffer& ext1 = capture1->extension();
+
+  uint32_t count;
+  ASSERT_TRUE(ext1.Read(0, 2, &count));
+
+  // Whether or not we've seen x25519 offered in this handshake.
+  bool seen1_x25519 = false;
+  for (size_t offset = 2; offset <= count; offset++) {
+    uint32_t val;
+    ASSERT_TRUE(ext1.Read(offset, 2, &val));
+    if (val == ssl_grp_ec_curve25519) {
+      seen1_x25519 = true;
+      break;
+    }
+  }
+  ASSERT_TRUE(seen1_x25519);
+
+  // Ensure that we can disable its use in the key exchange.
+  rv = NSS_SetAlgorithmPolicy(SEC_OID_CURVE25519, 0, NSS_USE_ALG_IN_SSL_KX);
+  ASSERT_EQ(SECSuccess, rv);
+  rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
+                              0);
+  ASSERT_EQ(SECSuccess, rv);
+
+  // Clean up after the last run.
+  Reset();
+  auto capture2 =
+      MakeTlsFilter<TlsExtensionCapture>(client_, ssl_elliptic_curves_xtn);
+  Connect();
+
+  EXPECT_TRUE(capture2->captured());
+  const DataBuffer& ext2 = capture2->extension();
+
+  ASSERT_TRUE(ext2.Read(0, 2, &count));
+
+  // Whether or not we've seen x25519 offered in this handshake.
+  bool seen2_x25519 = false;
+  for (size_t offset = 2; offset <= count; offset++) {
+    uint32_t val;
+    ASSERT_TRUE(ext2.Read(offset, 2, &val));
+
+    if (val == ssl_grp_ec_curve25519) {
+      seen2_x25519 = true;
+      break;
+    }
+  }
+
+  ASSERT_FALSE(seen2_x25519);
+}
+
 TEST_P(TlsExtensionTestPre13, SupportedPointsEmpty) {
   const uint8_t val[] = {0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
       client_, ssl_ec_point_formats_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, SupportedPointsBadLength) {
--- a/security/nss/gtests/ssl_gtest/tls_connect.h
+++ b/security/nss/gtests/ssl_gtest/tls_connect.h
@@ -151,17 +151,18 @@ class TlsConnectTestBase : public ::test
   // which places the preferred (and default) entry at the end of the list.
   // NSS will move this final entry to the front when used with ALPN.
   const uint8_t alpn_dummy_val_[4] = {0x01, 0x62, 0x01, 0x61};
 
   // A list of algorithm IDs whose policies need to be preserved
   // around test cases.  In particular, DSA is checked in
   // ssl_extension_unittest.cc.
   const std::vector<SECOidTag> algorithms_ = {SEC_OID_APPLY_SSL_POLICY,
-                                              SEC_OID_ANSIX9_DSA_SIGNATURE};
+                                              SEC_OID_ANSIX9_DSA_SIGNATURE,
+                                              SEC_OID_CURVE25519};
   std::vector<std::tuple<SECOidTag, uint32_t>> saved_policies_;
 
  private:
   void CheckResumption(SessionResumptionMode expected);
   void CheckExtendedMasterSecret();
   void CheckEarlyDataAccepted();
 
   bool expect_extended_master_secret_;
--- a/security/nss/lib/freebl/chacha20poly1305.c
+++ b/security/nss/lib/freebl/chacha20poly1305.c
@@ -152,26 +152,28 @@ ChaCha20Poly1305_DestroyContext(ChaCha20
 #ifndef NSS_DISABLE_CHACHAPOLY
     PORT_Memset(ctx, 0, sizeof(*ctx));
     if (freeit) {
         PORT_Free(ctx);
     }
 #endif
 }
 
+#ifndef NSS_DISABLE_CHACHAPOLY
 void
 ChaCha20Xor(uint8_t *output, uint8_t *block, uint32_t len, uint8_t *k,
             uint8_t *nonce, uint32_t ctr)
 {
     if (ssse3_support() || arm_neon_support()) {
         Hacl_Chacha20_Vec128_chacha20(output, block, len, k, nonce, ctr);
     } else {
         Hacl_Chacha20_chacha20(output, block, len, k, nonce, ctr);
     }
 }
+#endif /* NSS_DISABLE_CHACHAPOLY */
 
 SECStatus
 ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
                       unsigned int *outputLen, unsigned int maxOutputLen,
                       const unsigned char *input, unsigned int inputLen,
                       const unsigned char *nonce, unsigned int nonceLen,
                       const unsigned char *ad, unsigned int adLen)
 {
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ b/security/nss/lib/pk11wrap/pk11pars.c
@@ -233,16 +233,18 @@ static const oidValDef curveOptList[] = 
     { CIPHER_NAME("SECP256K1"), SEC_OID_SECG_EC_SECP256K1,
       NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
     { CIPHER_NAME("SECP256R1"), SEC_OID_ANSIX962_EC_PRIME256V1,
       NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
     { CIPHER_NAME("SECP384R1"), SEC_OID_SECG_EC_SECP384R1,
       NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
     { CIPHER_NAME("SECP521R1"), SEC_OID_SECG_EC_SECP521R1,
       NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+    { CIPHER_NAME("CURVE25519"), SEC_OID_CURVE25519,
+      NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
     /* ANSI X9.62 named elliptic curves (characteristic two field) */
     { CIPHER_NAME("C2PNB163V1"), SEC_OID_ANSIX962_EC_C2PNB163V1,
       NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
     { CIPHER_NAME("C2PNB163V2"), SEC_OID_ANSIX962_EC_C2PNB163V2,
       NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
     { CIPHER_NAME("C2PNB163V3"), SEC_OID_ANSIX962_EC_C2PNB163V3,
       NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
     { CIPHER_NAME("C2PNB176V1"), SEC_OID_ANSIX962_EC_C2PNB176V1,
--- a/taskcluster/ci/beetmover-checksums/kind.yml
+++ b/taskcluster/ci/beetmover-checksums/kind.yml
@@ -21,16 +21,20 @@ job-template:
    attributes:
       artifact_prefix: public
       artifact_map:
          by-project:
             default:
                by-platform:
                   android.*: taskcluster/taskgraph/manifests/fennec_nightly_checksums.yml
                   default: taskcluster/taskgraph/manifests/firefox_nightly_checksums.yml
+            try:
+               by-platform:
+                  android.*: taskcluster/taskgraph/manifests/fennec_candidates_checksums.yml
+                  default: taskcluster/taskgraph/manifests/firefox_candidates_checksums.yml
             mozilla-beta:
                by-platform:
                   android.*: taskcluster/taskgraph/manifests/fennec_candidates_checksums.yml
                   default: taskcluster/taskgraph/manifests/firefox_candidates_checksums.yml
             mozilla-release:
                by-platform:
                   android.*: taskcluster/taskgraph/manifests/fennec_candidates_checksums.yml
                   default: taskcluster/taskgraph/manifests/firefox_candidates_checksums.yml
--- a/taskcluster/ci/beetmover-repackage/kind.yml
+++ b/taskcluster/ci/beetmover-repackage/kind.yml
@@ -53,11 +53,12 @@ only-for-build-platforms:
     - linux64-asan-reporter-nightly/opt
     - win64-asan-reporter-nightly/opt
 
 job-template:
     shipping-phase: promote
     attributes:
         artifact_map:
             by-project:
-                mozilla-release: taskcluster/taskgraph/manifests/firefox_candidates.yml
+                default: taskcluster/taskgraph/manifests/firefox_nightly.yml
+                try: taskcluster/taskgraph/manifests/firefox_candidates.yml
                 mozilla-beta: taskcluster/taskgraph/manifests/firefox_candidates.yml
-                default: taskcluster/taskgraph/manifests/firefox_nightly.yml
+                mozilla-release: taskcluster/taskgraph/manifests/firefox_candidates.yml
--- a/taskcluster/ci/release-beetmover-signed-langpacks-checksums/kind.yml
+++ b/taskcluster/ci/release-beetmover-signed-langpacks-checksums/kind.yml
@@ -9,8 +9,11 @@ transforms:
    - taskgraph.transforms.beetmover_langpack_checksums:transforms
    - taskgraph.transforms.task:transforms
 
 kind-dependencies:
    - release-beetmover-signed-langpacks
 
 job-template:
    shipping-phase: promote
+   attributes:
+      artifact_prefix: public
+      artifact_map: taskcluster/taskgraph/manifests/firefox_candidates_checksums.yml
--- a/taskcluster/ci/release-beetmover-signed-langpacks/kind.yml
+++ b/taskcluster/ci/release-beetmover-signed-langpacks/kind.yml
@@ -19,8 +19,10 @@ only-for-attributes:
 job-template:
    description: Beetmover submission for platform-independent langpacks {locales} in {platform} directory
    worker-type:
       by-release-level:
          production: scriptworker-prov-v1/beetmoverworker-v1
          staging: scriptworker-prov-v1/beetmoverworker-dev
    run-on-projects: []
    shipping-phase: promote
+   attributes:
+      artifact_map: taskcluster/taskgraph/manifests/firefox_candidates.yml
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/manifests/firefox_candidates.yml
@@ -0,0 +1,353 @@
+# This file contains exhaustive information about all the release artifacs that
+# are needed within a type of release.
+#
+# Structure
+# --------
+# `s3_bucket_paths`       -- prefix to be used per product to correctly access our S3 buckets
+# `default_locales`       -- list of locales to be used when composing upstream artifacts or the list of
+#                      destinations. If given an empty locale, it uses these locales instead.
+# `tasktype_map`          -- mapping between task reference and task type, particularly usefule when
+#                      composing the upstreamArtifacts for scriptworker.
+# `platform_names`        -- various platform mappings used in reckoning artifacts or other paths
+# `default`               -- a default entry, which the mappings extend and override in such a way that
+#                      final path full-destinations will be a concatenation of the following:
+#                      `s3_bucket_paths`, `destinations`, `locale_prefix`, `pretty_name`
+# `from`                  -- specifies the dependency(ies) from which to expect the particular artifact
+# `all_locales`           -- boolean argument to specify whether that particular artifact is to be expected
+#                      for all locales or just the default one
+# `description`           -- brief summary of what that artifact is
+# `locale_prefix`         -- prefix to be used in the final destination paths, whether that's for default locale or not
+# `source_path_modifier`  -- any parent dir that might be used in between artifact prefix and filename at source location
+#                            for example `public/build` vs `public/build/ach/`.
+# `destinations`          -- final list of directories where to push the artifacts in S3
+# `pretty_name`           -- the final name the artifact will have at destination
+# `checksums_path`        -- the name to identify one artifact within the checksums file
+# `not_for_platforms`     -- filtering option to avoid associating an artifact with a specific platform
+# `only_for_platforms`    -- filtering option to exclusively include the association of an artifact for a specific platform
+# `partials_only`         -- filtering option to avoid associating an artifact unless this flag is present
+# `update_balrog_manifest`-- flag needed downstream in beetmover jobs to reckon the balrog manifest
+# `from_buildid`          -- flag needed downstream in beetmover jobs to reckon the balrog manifest
+
+---
+s3_bucket_paths:
+  - pub/firefox/candidates
+default_locales:
+  - en-US
+tasktype_map:
+  build: build
+  signing: signing
+  mar-signing: signing
+  partials-signing: signing
+  repackage: repackage
+  repackage-signing: repackage
+  repackage-signing-msi: repackage
+  release-sign-and-push-langpacks: scriptworker
+platform_names:
+  path_platform:
+    by-platform:
+      linux-nightly: 'linux-i686'
+      linux64-nightly: 'linux-x86_64'
+      linux64-asan-reporter-nightly: 'linux-x86_64-asan-reporter'
+      macosx64-nightly: 'mac'
+      win32-nightly: 'win32'
+      win64-nightly: 'win64'
+      win64-aarch64-nightly: 'win64-aarch64'
+      win64-asan-reporter-nightly: 'win64-asan-reporter'
+  filename_platform:
+    by-platform:
+      linux-nightly: 'linux-i686'
+      linux64-nightly: 'linux-x86_64'
+      linux64-asan-reporter-nightly: 'linux-x86_64-asan-reporter'
+      macosx64-nightly: 'mac'
+      win32-nightly: 'win32'
+      win64-nightly: 'win64'
+      win64-aarch64-nightly: 'win64-aarch64'
+      win64-asan-reporter-nightly: 'win64-asan-reporter'
+  stage_platform:
+    by-platform:
+      linux-nightly: 'linux'
+      linux64-nightly: 'linux64'
+      linux64-asan-reporter-nightly: 'linux-x86_64-asan-reporter'
+      macosx64-nightly: 'macosx64'
+      win32-nightly: 'win32'
+      win64-nightly: 'win64'
+      win64-aarch64-nightly: 'win64-aarch64'
+      win64-asan-reporter-nightly: 'win64-asan-reporter'
+
+default: &default
+  from:
+    - build
+  all_locales: false
+  description: "TO_BE_OVERRIDDEN"
+  locale_prefix: '${locale}/'
+  source_path_modifier:
+    by-locale:
+      default: '${locale}'
+      en-US: ''
+  destinations:
+    - ${version}-candidates/build${build_number}/${path_platform}
+
+mapping:
+  buildhub.json:
+    <<: *default
+    all_locales: false
+    description: "Build related information to be consumed by Buildhub service"
+    pretty_name: buildhub.json
+    checksums_path: ${path_platform}/${locale}/buildhub.json
+  target.common.tests.tar.gz:
+    <<: *default
+    description: "Mixture of reftests, mochitests, UI and others, commonly bundled together in a test suite"
+    pretty_name: firefox-${version}.common.tests.tar.gz
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.common.tests.tar.gz
+  target.cppunittest.tests.tar.gz:
+    <<: *default
+    description: "C++ unittests related in-tree test infrastructure"
+    pretty_name: firefox-${version}.cppunittest.tests.tar.gz
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.cppunittest.tests.tar.gz
+  target.crashreporter-symbols.zip:
+    <<: *default
+    description: "Crashreporter symbols to be consumed by Socorro"
+    pretty_name: firefox-${version}.crashreporter-symbols.zip
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.crashreporter-symbols.zip
+  target.json:
+    <<: *default
+    description: "Various compile and moz_app flags baked together in a json file"
+    pretty_name: firefox-${version}.json
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.json
+  target.mochitest.tests.tar.gz:
+    <<: *default
+    description: "Results for running the mochitest testing framework via Javascript function calls"
+    pretty_name: firefox-${version}.mochitest.tests.tar.gz
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.mochitest.tests.tar.gz
+  target.mozinfo.json:
+    <<: *default
+    description: "Various compile and moz_app flags baked together in a json file"
+    pretty_name: firefox-${version}.mozinfo.json
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.mozinfo.json
+  target.reftest.tests.tar.gz:
+    <<: *default
+    description: "Results for running the reftest testing framework via display of two Web pages comparison"
+    pretty_name: firefox-${version}.reftest.tests.tar.gz
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.reftest.tests.tar.gz
+  target.talos.tests.tar.gz:
+    <<: *default
+    description: "Results for running the talos testing framework to measure performance"
+    pretty_name: firefox-${version}.talos.tests.tar.gz
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.talos.tests.tar.gz
+  target.awsy.tests.tar.gz:
+    <<: *default
+    description: "Results for running the awsy testing framework to track memory usage"
+    pretty_name: firefox-${version}.awsy.tests.tar.gz
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.awsy.tests.tar.gz
+  target.test_packages.json:
+    <<: *default
+    description: "File containing metadata about all other files and testing harnesses specifics"
+    pretty_name: firefox-${version}.test_packages.json
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.test_packages.json
+  target.txt:
+    <<: *default
+    description: "File containing buildid and revision"
+    pretty_name: firefox-${version}.txt
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.txt
+  target.web-platform.tests.tar.gz:
+    <<: *default
+    description: "Results for running the webplatform testing framework to cover standard Web platform features"
+    pretty_name: firefox-${version}.web-platform.tests.tar.gz
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.web-platform.tests.tar.gz
+  target.xpcshell.tests.tar.gz:
+    <<: *default
+    description: "Results for running the xpcshell testing framework to enable XPConnect console application"
+    pretty_name: firefox-${version}.xpcshell.tests.tar.gz
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.xpcshell.tests.tar.gz
+  target_info.txt:
+    <<: *default
+    description: "File containing the buildID"
+    locale_prefix: ''
+    pretty_name: ${stage_platform}_info.txt
+    checksums_path: ${stage_platform}_info.txt
+    destinations:
+      - ${version}-candidates/build${build_number}
+  mozharness.zip:
+    <<: *default
+    description: "File containing the mozharness set of scripts and configuration used by various automation tools"
+    pretty_name: mozharness.zip
+    checksums_path: ${path_platform}/${locale}/mozharness.zip
+  target.jsshell.zip:
+    <<: *default
+    description: "Set of shells to allow test snippets of Javascript code without needing to reload the page"
+    locale_prefix: ''
+    pretty_name: jsshell-${filename_platform}.zip
+    checksums_path: jsshell/jsshell-${filename_platform}.zip
+    destinations:
+      - ${version}-candidates/build${build_number}/jsshell
+  target.langpack.xpi:
+    <<: *default
+    all_locales: true
+    description: "Localized repack that grabs a packaged en-US Firefox and repackages it as locale-specific Firefox"
+    locale_prefix: ''
+    source_path_modifier: '${locale}'
+    from:
+      - release-sign-and-push-langpacks
+    only_for_platforms:
+      - linux-nightly
+      - linux64-nightly
+      - macosx64-nightly
+      - win32-nightly
+      - win64-nightly
+    pretty_name: ${locale}.xpi
+    checksums_path: ${path_platform}/xpi/${locale}.xpi
+    destinations:
+      - ${version}-candidates/build${build_number}/${path_platform}/xpi
+  mar:
+    <<: *default
+    description: "Alongside `mbsdiff`, a tool used to generate partials"
+    locale_prefix: ''
+    source_path_modifier: 'host/bin'
+    pretty_name: ${stage_platform}/mar
+    checksums_path: mar-tools/${stage_platform}/mar
+    not_for_platforms:
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+    destinations:
+      - ${version}-candidates/build${build_number}/mar-tools
+  mbsdiff:
+    <<: *default
+    description: "Alongside `mar`, a tool used to generate partials"
+    locale_prefix: ''
+    source_path_modifier: 'host/bin'
+    pretty_name: ${stage_platform}/mbsdiff
+    checksums_path: mar-tools/${stage_platform}/mbsdiff
+    not_for_platforms:
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+    destinations:
+      - ${version}-candidates/build${build_number}/mar-tools
+  mar.exe:
+    <<: *default
+    description: "Alongside `mbsdiff.exe`, a tool used to generate partials for Windows platforms"
+    locale_prefix: ''
+    source_path_modifier: 'host/bin'
+    pretty_name: ${stage_platform}/mar.exe
+    checksums_path: mar-tools/${stage_platform}/mar.exe
+    only_for_platforms:
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+    destinations:
+      - ${version}-candidates/build${build_number}/mar-tools
+  mbsdiff.exe:
+    <<: *default
+    locale_prefix: ''
+    description: "Alongside `mar.exe`, a tool used to generate partials for Windows platforms"
+    source_path_modifier: 'host/bin'
+    pretty_name: ${stage_platform}/mbsdiff.exe
+    checksums_path: mar-tools/${stage_platform}/mbsdiff.exe
+    only_for_platforms:
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+    destinations:
+      - ${version}-candidates/build${build_number}/mar-tools
+  target.tar.bz2:
+    <<: *default
+    description: "Main installer for Linux platforms"
+    all_locales: true
+    from:
+      - signing
+    only_for_platforms:
+      - linux-nightly
+      - linux64-nightly
+    pretty_name: firefox-${version}.tar.bz2
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.tar.bz2
+  target.tar.bz2.asc:
+    <<: *default
+    description: "Detached signature for the checksums file"
+    all_locales: true
+    from:
+      - signing
+    only_for_platforms:
+      - linux-nightly
+      - linux64-nightly
+    pretty_name: firefox-${version}.tar.bz2.asc
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.tar.bz2.asc
+  target.dmg:
+    <<: *default
+    description: "Main package installer for Mac OS X platforms"
+    all_locales: true
+    from:
+      - repackage
+    only_for_platforms:
+      - macosx64-nightly
+    pretty_name: Firefox ${version}.dmg
+    checksums_path: ${path_platform}/${locale}/Firefox ${version}.dmg
+  target.zip:
+    <<: *default
+    description: "Main package installer for Windows platforms"
+    all_locales: true
+    from:
+      - signing
+    only_for_platforms:
+      - win64-nightly
+      - win32-nightly
+      - win64-aarch64-nightly
+    pretty_name: firefox-${version}.zip
+    checksums_path: ${path_platform}/${locale}/firefox-${version}.zip
+  target.installer.exe:
+    <<: *default
+    description: "Main installer for Windows platforms"
+    all_locales: true
+    from:
+      - repackage-signing
+    only_for_platforms:
+      - win64-nightly
+      - win32-nightly
+      - win64-aarch64-nightly
+    pretty_name: Firefox Setup ${version}.exe
+    checksums_path: ${path_platform}/${locale}/Firefox Setup ${version}.exe
+  target.stub-installer.exe:
+    <<: *default
+    description: "Stub installer for Win32 platforms"
+    all_locales: true
+    from:
+      - repackage-signing
+    only_for_platforms:
+      - win32-nightly
+    pretty_name: Firefox Installer.exe
+    checksums_path: ${path_platform}/${locale}/Firefox Installer.exe
+  target.installer.msi:
+    <<: *default
+    description: "Windows installer for MSI platform"
+    all_locales: true
+    from:
+      - repackage-signing-msi
+    only_for_platforms:
+      - win64-nightly
+      - win32-nightly
+    pretty_name: Firefox Setup ${version}.msi
+    checksums_path: ${path_platform}/${locale}/Firefox Setup ${version}.msi
+  target.complete.mar:
+    <<: *default
+    description: "The main installer we ship our mobile products baked within"
+    all_locales: true
+    from:
+      - mar-signing
+    pretty_name: firefox-${version}.complete.mar
+    checksums_path: update/${path_platform}/${locale}/firefox-${version}.complete.mar
+    update_balrog_manifest: true
+    destinations:
+      - ${version}-candidates/build${build_number}/update/${path_platform}
+  ${partial}:
+    <<: *default
+    description: "Partials MAR files to serve as updates"
+    all_locales: true
+    from:
+      - partials-signing
+    partials_only: true
+    pretty_name: firefox-${previous_version}-${version}.partial.mar
+    checksums_path: update/${path_platform}/${locale}/firefox-${previous_version}-${version}.partial.mar
+    update_balrog_manifest: true
+    from_buildid: ${from_buildid}
+    destinations:
+      - ${version}-candidates/build${build_number}/update/${path_platform}
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/manifests/firefox_candidates_checksums.yml
@@ -0,0 +1,117 @@
+# This file contains exhaustive information about all the release artifacs that
+# are needed within a type of release.
+#
+# Structure
+# --------
+# `s3_bucket_paths`       -- prefix to be used per product to correctly access our S3 buckets
+# `default_locales`       -- list of locales to be used when composing upstream artifacts or the list of
+#                      destinations. If given an empty locale, it uses these locales instead.
+# `tasktype_map`          -- mapping between task reference and task type, particularly usefule when
+#                      composing the upstreamArtifacts for scriptworker.
+# `platform_names`        -- various platform mappings used in reckoning artifacts or other paths
+# `default`               -- a default entry, which the mappings extend and override in such a way that
+#                      final path full-destinations will be a concatenation of the following:
+#                      `s3_bucket_paths`, `destinations`, `locale_prefix`, `pretty_name`
+# `from`                  -- specifies the dependency(ies) from which to expect the particular artifact
+# `all_locales`           -- boolean argument to specify whether that particular artifact is to be expected
+#                      for all locales or just the default one
+# `description`           -- brief summary of what that artifact is
+# `locale_prefix`         -- prefix to be used in the final destination paths, whether that's for default locale or not
+# `source_path_modifier`  -- any parent dir that might be used in between artifact prefix and filename at source location
+#                            for example `public/build` vs `public/build/ach/`.
+# `destinations`          -- final list of directories where to push the artifacts in S3
+# `pretty_name`           -- the final name the artifact will have at destination
+# `checksums_path`        -- the name to identify one artifact within the checksums file
+# `not_for_platforms`     -- filtering option to avoid associating an artifact with a specific platform
+# `only_for_platforms`    -- filtering option to exclusively include the association of an artifact for a specific platform
+# `partials_only`         -- filtering option to avoid associating an artifact unless this flag is present
+# `update_balrog_manifest`-- flag needed downstream in beetmover jobs to reckon the balrog manifest
+# `from_buildid`          -- flag needed downstream in beetmover jobs to reckon the balrog manifest
+---
+s3_bucket_paths:
+  by-platform:
+    .*devedition.*:
+      - pub/devedition/candidates
+    default:
+      - pub/firefox/candidates
+default_locales:
+  - en-US
+tasktype_map:
+  checksums-signing: signing
+  release-beetmover-signed-langpacks: signing
+platform_names:
+  path_platform:
+    by-platform:
+      linux-nightly: 'linux-i686'
+      linux64-nightly: 'linux-x86_64'
+      linux64-asan-reporter-nightly: 'linux-x86_64-asan-reporter'
+      macosx64-nightly: 'mac'
+      win32-nightly: 'win32'
+      win64-nightly: 'win64'
+      win64-aarch64-nightly: 'win64-aarch64'
+      win64-asan-reporter-nightly: 'win64-asan-reporter'
+      linux-shippable: 'linux-i686'
+      linux64-shippable: 'linux-x86_64'
+      macosx64-shippable: 'mac'
+      win32-shippable: 'win32'
+      win64-shippable: 'win64'
+      win64-aarch64-shippable: 'win64-aarch64'
+      linux: 'linux-i686'
+      linux64: 'linux-x86_64'
+      macosx64: 'mac'
+      win32: 'win32'
+      win64: 'win64'
+  filename_platform:
+    by-platform:
+      linux-nightly: 'linux-i686'
+      linux64-nightly: 'linux-x86_64'
+      linux64-asan-reporter-nightly: 'linux-x86_64-asan-reporter'
+      macosx64-nightly: 'mac'
+      win32-nightly: 'win32'
+      win64-nightly: 'win64'
+      win64-aarch64-nightly: 'win64-aarch64'
+      win64-asan-reporter-nightly: 'win64-asan-reporter'
+      linux-shippable: 'linux-i686'
+      linux64-shippable: 'linux-x86_64'
+      macosx64-shippable: 'mac'
+      win32-shippable: 'win32'
+      win64-shippable: 'win64'
+      win64-aarch64-shippable: 'win64-aarch64'
+      linux: 'linux-i686'
+      linux64: 'linux-x86_64'
+      macosx64: 'mac'
+      win32: 'win32'
+      win64: 'win64'
+  stage_platform: ''
+
+default: &default
+  from:
+    - checksums-signing
+  all_locales: true
+  description: "TO_BE_OVERRIDDEN"
+  locale_prefix: '${locale}/'
+  source_path_modifier: ''
+  destinations:
+    - ${version}-candidates/build${build_number}/beetmover-checksums/${path_platform}
+
+mapping:
+  target.checksums:
+    <<: *default
+    description: "Checksums file containing size, hash, sha algorithm and filename"
+    pretty_name: firefox-${version}.checksums.beet
+    checksums_path: beetmover-checksums/${path_platform}/${locale}/firefox-${version}.checksums.beet
+  target.checksums.asc:
+    <<: *default
+    description: "Detached signature for the checksums file"
+    pretty_name: firefox-${version}.checksums.asc
+    checksums_path: beetmover-checksums/${path_platform}/${locale}/firefox-${version}.checksums.asc
+  target-langpack.checksums:
+    <<: *default
+    description: "Checksums file containing size, hash, sha algorithm and filename for the langpack"
+    locale_prefix: ''
+    from:
+      - release-beetmover-signed-langpacks
+    pretty_name: ${locale}.checksums.beet
+    checksums_path: beetmover-checksums/${path_platform}/xpi/${locale}.checksums.beet
+    destinations:
+      - ${version}-candidates/build${build_number}/beetmover-checksums/${path_platform}/xpi
--- a/taskcluster/taskgraph/transforms/beetmover_langpack_checksums.py
+++ b/taskcluster/taskgraph/transforms/beetmover_langpack_checksums.py
@@ -6,24 +6,28 @@ Transform release-beetmover-langpack-che
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.loader.single_dep import schema
 from taskgraph.transforms.base import TransformSequence
 from taskgraph.transforms.beetmover import craft_release_properties
 from taskgraph.util.attributes import copy_attributes_from_dependent_job
-from taskgraph.util.scriptworker import (get_beetmover_bucket_scope,
+from taskgraph.util.scriptworker import (generate_beetmover_artifact_map,
+                                         generate_beetmover_upstream_artifacts,
                                          get_beetmover_action_scope,
-                                         get_worker_type_for_scope)
+                                         get_beetmover_bucket_scope,
+                                         get_worker_type_for_scope,
+                                         should_use_artifact_map)
 from taskgraph.transforms.task import task_description_schema
 from voluptuous import Required, Optional
 
 beetmover_checksums_description_schema = schema.extend({
     Required('depname', default='build'): basestring,
+    Required('attributes'): {basestring: object},
     Optional('label'): basestring,
     Optional('treeherder'): task_description_schema['treeherder'],
     Optional('locale'): basestring,
     Optional('shipping-phase'): task_description_schema['shipping-phase'],
     Optional('shipping-product'): task_description_schema['shipping-product'],
 })
 
 transforms = TransformSequence()
@@ -62,16 +66,17 @@ def make_beetmover_checksums_description
         dependencies = {dep_job.kind: dep_job.label}
         for k, v in dep_job.dependencies.items():
             if k.startswith('beetmover'):
                 dependencies[k] = v
 
         attributes = copy_attributes_from_dependent_job(dep_job)
         if 'chunk_locales' in dep_job.attributes:
             attributes['chunk_locales'] = dep_job.attributes['chunk_locales']
+        attributes.update(job.get('attributes', {}))
 
         bucket_scope = get_beetmover_bucket_scope(config)
         action_scope = get_beetmover_action_scope(config)
 
         task = {
             'label': label,
             'description': description,
             'worker-type': get_worker_type_for_scope(config, bucket_scope),
@@ -131,16 +136,25 @@ def make_beetmover_checksums_worker(conf
                 refs['beetmover'] = "<{}>".format(dependency)
         if None in refs.values():
             raise NotImplementedError(
                 "Beetmover checksums must have a beetmover dependency!")
 
         worker = {
             'implementation': 'beetmover',
             'release-properties': craft_release_properties(config, job),
-            'upstream-artifacts': generate_upstream_artifacts(
-                refs, platform, locales
-            ),
         }
 
+        if should_use_artifact_map(platform, config.params['project']):
+            upstream_artifacts = generate_beetmover_upstream_artifacts(
+                config, job, platform, locales
+            )
+            worker['artifact-map'] = generate_beetmover_artifact_map(
+                config, job, platform=platform, locale=locales)
+        else:
+            upstream_artifacts = generate_upstream_artifacts(
+                refs, platform, locales
+            )
+
+        worker['upstream-artifacts'] = upstream_artifacts
         job["worker"] = worker
 
         yield job
--- a/taskcluster/taskgraph/transforms/release_beetmover_signed_addons.py
+++ b/taskcluster/taskgraph/transforms/release_beetmover_signed_addons.py
@@ -8,17 +8,20 @@ Transform the beetmover task into an act
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.loader.single_dep import schema
 from taskgraph.transforms.base import TransformSequence
 from taskgraph.transforms.beetmover import craft_release_properties
 from taskgraph.util.attributes import copy_attributes_from_dependent_job
 from taskgraph.util.schema import optionally_keyed_by, resolve_keyed_by
 from taskgraph.util.scriptworker import (get_beetmover_bucket_scope,
-                                         get_beetmover_action_scope)
+                                         get_beetmover_action_scope,
+                                         generate_beetmover_upstream_artifacts,
+                                         generate_beetmover_artifact_map,
+                                         should_use_artifact_map)
 from taskgraph.transforms.task import task_description_schema
 from taskgraph.transforms.release_sign_and_push_langpacks import get_upstream_task_ref
 from voluptuous import Required, Optional
 
 import logging
 import copy
 
 logger = logging.getLogger(__name__)
@@ -26,16 +29,19 @@ logger = logging.getLogger(__name__)
 
 transforms = TransformSequence()
 
 
 beetmover_description_schema = schema.extend({
     # depname is used in taskref's to identify the taskID of the unsigned things
     Required('depname', default='build'): basestring,
 
+    # attributes is used for enabling artifact-map by declarative artifacts
+    Required('attributes'): {basestring: object},
+
     # unique label to describe this beetmover task, defaults to {dep.label}-beetmover
     Optional('label'): basestring,
 
     # treeherder is allowed here to override any defaults we use for beetmover.  See
     # taskcluster/taskgraph/transforms/task.py for the schema details, and the
     # below transforms for defaults of various values.
     Optional('treeherder'): task_description_schema['treeherder'],
 
@@ -61,20 +67,24 @@ def set_label(config, jobs):
 
 
 transforms.add_validate(beetmover_description_schema)
 
 
 @transforms.add
 def resolve_keys(config, jobs):
     for job in jobs:
-        resolve_keyed_by(
-            job, 'worker-type', item_name=job['label'],
-            **{'release-level': config.params.release_level()}
-        )
+        for field in ('worker-type', 'attributes.artifact_map'):
+            resolve_keyed_by(
+                job, field, item_name=job['label'],
+                **{
+                    'release-level': config.params.release_level(),
+                    'project': config.params['project']
+                }
+            )
         yield job
 
 
 @transforms.add
 def make_task_description(config, jobs):
     for job in jobs:
         dep_job = job['primary-dependency']
         attributes = dep_job.attributes
@@ -83,17 +93,17 @@ def make_task_description(config, jobs):
         treeherder.setdefault('symbol', 'langpack(BM{})'.format(attributes.get('l10n_chunk', '')))
         dep_th_platform = dep_job.task.get('extra', {}).get(
             'treeherder', {}).get('machine', {}).get('platform', '')
         treeherder.setdefault('platform',
                               "{}/opt".format(dep_th_platform))
         treeherder.setdefault('tier', 1)
         treeherder.setdefault('kind', 'build')
 
-        job['attributes'] = copy_attributes_from_dependent_job(dep_job)
+        job['attributes'].update(copy_attributes_from_dependent_job(dep_job))
         job['attributes']['chunk_locales'] = dep_job.attributes['chunk_locales']
 
         job['description'] = job['description'].format(
             locales='/'.join(job['attributes']['chunk_locales']),
             platform=job['attributes']['build_platform']
         )
 
         job['scopes'] = [
@@ -113,24 +123,36 @@ def make_task_description(config, jobs):
 
 @transforms.add
 def make_task_worker(config, jobs):
     for job in jobs:
         signing_task_ref = get_upstream_task_ref(
             job, expected_kinds=('release-sign-and-push-langpacks',)
         )
 
+        platform = job["attributes"]["build_platform"]
+        locale = job["attributes"]["chunk_locales"]
+        if should_use_artifact_map(platform, config.params['project']):
+            upstream_artifacts = generate_beetmover_upstream_artifacts(
+                config, job, platform, locale,
+            )
+        else:
+            upstream_artifacts = generate_upstream_artifacts(
+                signing_task_ref, job['attributes']['chunk_locales']
+            )
         job['worker'] = {
             'implementation': 'beetmover',
             'release-properties': craft_release_properties(config, job),
-            'upstream-artifacts': generate_upstream_artifacts(
-                signing_task_ref, job['attributes']['chunk_locales']
-            ),
+            'upstream-artifacts': upstream_artifacts,
         }
 
+        if should_use_artifact_map(platform, config.params['project']):
+            job['worker']['artifact-map'] = generate_beetmover_artifact_map(
+                config, job, platform=platform, locale=locale)
+
         yield job
 
 
 def generate_upstream_artifacts(upstream_task_ref, locales):
     return [{
         'taskId': {'task-reference': upstream_task_ref},
         'taskType': 'scriptworker',
         'locale': locale,
@@ -162,17 +184,17 @@ def yield_all_platform_jobs(config, jobs
             if 'devedition' in job['attributes']['build_platform']:
                 platforms = ('{}-devedition'.format(plat) for plat in platforms)
             for platform in platforms:
                 platform_job = copy.deepcopy(job)
                 if 'ja' in platform_job['attributes']['chunk_locales'] and \
                         platform in ('macosx64', 'macosx64-devedition'):
                     platform_job = _strip_ja_data_from_linux_job(platform_job)
 
-                platform_job = _change_platform_data(platform_job, platform)
+                platform_job = _change_platform_data(config, platform_job, platform)
 
                 yield platform_job
 
 
 def _strip_ja_data_from_linux_job(platform_job):
     # Let's take "ja" out the description. This locale is in a substring like "aa/bb/cc/dd", where
     # "ja" could be any of "aa", "bb", "cc", "dd"
     platform_job['description'] = platform_job['description'].replace('ja/', '')
@@ -182,21 +204,57 @@ def _strip_ja_data_from_linux_job(platfo
         artifact
         for artifact in platform_job['worker']['upstream-artifacts']
         if artifact['locale'] != 'ja'
     ]
 
     return platform_job
 
 
-def _change_platform_data(platform_job, platform):
+def _change_platform_in_artifact_map_paths(paths, orig_platform, new_platform):
+    amended_paths = {}
+    for artifact, artifact_info in paths.iteritems():
+        amended_artifact_info = {
+            'checksums_path': artifact_info['checksums_path'].replace(orig_platform, new_platform),
+            'destinations': [
+                d.replace(orig_platform, new_platform) for d in artifact_info['destinations']
+            ]
+        }
+        amended_paths[artifact] = amended_artifact_info
+
+    return amended_paths
+
+
+def _change_platform_data(config, platform_job, platform):
     orig_platform = 'linux64'
     if 'devedition' in platform:
         orig_platform = 'linux64-devedition'
+    backup_platform = platform_job['attributes']['build_platform']
     platform_job['attributes']['build_platform'] = platform
     platform_job['label'] = platform_job['label'].replace(orig_platform, platform)
     platform_job['description'] = platform_job['description'].replace(orig_platform, platform)
     platform_job['treeherder']['platform'] = platform_job['treeherder']['platform'].replace(
         orig_platform, platform
     )
     platform_job['worker']['release-properties']['platform'] = platform
 
+    # amend artifactMap entries as well
+    if should_use_artifact_map(backup_platform, config.params['project']):
+        platform_mapping = {
+            'linux64': 'linux-x86_64',
+            'linux': 'linux-i686',
+            'macosx64': 'mac',
+            'win32': 'win32',
+            'win64': 'win64',
+        }
+        orig_platform = platform_mapping.get(orig_platform, orig_platform)
+        platform = platform_mapping.get(platform, platform)
+        platform_job['worker']['artifact-map'] = [
+            {
+                'locale': entry['locale'],
+                'taskId': entry['taskId'],
+                'paths': _change_platform_in_artifact_map_paths(entry['paths'],
+                                                                orig_platform,
+                                                                platform)
+            } for entry in platform_job['worker']['artifact-map']
+        ]
+
     return platform_job
--- a/taskcluster/taskgraph/util/scriptworker.py
+++ b/taskcluster/taskgraph/util/scriptworker.py
@@ -427,16 +427,18 @@ def generate_beetmover_upstream_artifact
         project=config.params['project'],
         platform=platform
     )
     map_config = cached_load_yaml(job['attributes']['artifact_map'])
     upstream_artifacts = list()
 
     if not locale:
         locales = map_config['default_locales']
+    elif isinstance(locale, list):
+        locales = locale
     else:
         locales = [locale]
 
     if not dependencies:
         dependencies = job['dependencies'].keys()
 
     for locale, dep in itertools.product(locales, dependencies):
         paths = list()
@@ -557,17 +559,20 @@ def generate_beetmover_artifact_map(conf
     map_config = cached_load_yaml(job['attributes']['artifact_map'])
     base_artifact_prefix = map_config.get('base_artifact_prefix', get_artifact_prefix(job))
 
     artifacts = list()
 
     dependencies = job['dependencies'].keys()
 
     if kwargs.get('locale'):
-        locales = [kwargs['locale']]
+        if isinstance(kwargs['locale'], list):
+            locales = kwargs['locale']
+        else:
+            locales = [kwargs['locale']]
     else:
         locales = map_config['default_locales']
 
     resolve_keyed_by(map_config, 's3_bucket_paths', 's3_bucket_paths', platform=platform)
 
     for locale, dep in itertools.product(locales, dependencies):
         paths = dict()
         for filename in map_config['mapping']:
@@ -775,16 +780,17 @@ def generate_beetmover_partials_artifact
                 # optional flag: from_buildid
                 if file_config.get('from_buildid'):
                     partials_paths[key]['from_buildid'] = file_config['from_buildid']
 
                 # render buildid
                 kwargs.update({
                     'partial': pname,
                     'from_buildid': info['buildid'],
+                    'previous_version': info.get('previousVersion'),
                     'buildid': str(config.params['moz_build_date']),
                     'locale': locale,
                     'version': config.params['version'],
                     'branch': config.params['project'],
                     'build_number': config.params['build_number'],
                     'filename_platform': platforms['filename_platform'],
                     'path_platform': platforms['path_platform'],
                     'stage_platform': platforms['stage_platform'],
@@ -821,26 +827,33 @@ def should_use_artifact_map(platform, pr
     # FIXME: once we're ready to switch fully to declarative artifacts on other
     # branches, we can expand this; for now, Fennec is rolled-out to all
     # release branches, while Firefox only to mozilla-central
     platforms = [
         'android',
         'fennec'
     ]
     projects = ['mozilla-central', 'mozilla-beta', 'mozilla-release']
-    if any([pl in platform for pl in platforms]) and any([pj in project for pj in projects]):
+    if any([pl in platform for pl in platforms]) and any([pj == project for pj in projects]):
         return True
 
     platforms = [
+        'linux',    # needed for beetmover-langpacks-checksums
+        'linux64',  # which inherit amended platform from their beetmover counterpart
+        'win32',
+        'win64',
+        'macosx64',
         'linux-shippable',
         'linux64-shippable',
         'macosx64-shippable',
         'win32-shippable',
         'win64-shippable',
         'win64-aarch64-shippable',
         'win64-asan-reporter-nightly',
         'linux64-asan-reporter-nightly',
+        'firefox-source',
+        'firefox-release',
     ]
-    projects = ['mozilla-central']
-    if any([pl in platform for pl in platforms]) and any([pj in project for pj in projects]):
+    projects = ['try', 'mozilla-central', 'mozilla-beta', 'mozilla-release']
+    if any([pl == platform for pl in platforms]) and any([pj == project for pj in projects]):
         return True
 
     return False
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -7,16 +7,18 @@
 // Test timeout (seconds)
 var gTimeoutSeconds = 45;
 var gConfig;
 var gSaveInstrumentationData = null;
 
 var {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
+ChromeUtils.defineModuleGetter(this, "AddonManager",
+  "resource://gre/modules/AddonManager.jsm");
 ChromeUtils.defineModuleGetter(this, "ContentSearch",
   "resource:///modules/ContentSearch.jsm");
 
 const SIMPLETEST_OVERRIDES =
   ["ok", "record", "is", "isnot", "todo", "todo_is", "todo_isnot", "info", "expectAssertions", "requestCompleteLog"];
 
 setTimeout(testInit, 0);
 
@@ -517,27 +519,35 @@ Tester.prototype = {
         this.nextTest();
       });
     } else {
       this.finish();
     }
   },
 
   async waitForWindowsReady() {
+    await this.setupDefaultTheme();
     await new Promise(resolve => this.waitForGraphicsTestWindowToBeGone(resolve));
     await this.promiseMainWindowReady();
   },
 
   async promiseMainWindowReady() {
     if (window.gBrowserInit && !gBrowserInit.idleTasksFinished) {
       await this.TestUtils.topicObserved("browser-idle-startup-tasks-finished",
                                          subject => subject === window);
     }
   },
 
+  async setupDefaultTheme() {
+    // Developer Edition enables the wrong theme by default. Make sure
+    // the ordinary default theme is enabled.
+    let theme = await AddonManager.getAddonByID("default-theme@mozilla.org");
+    await theme.enable();
+  },
+
   waitForGraphicsTestWindowToBeGone(aCallback) {
     for (let win of Services.wm.getEnumerator(null)) {
       if (win != window && !win.closed &&
           win.document.documentURI == "chrome://gfxsanity/content/sanityparent.html") {
         this.BrowserTestUtils.domWindowClosed(win).then(aCallback);
         return;
       }
     }
--- a/testing/profiles/perf/user.js
+++ b/testing/profiles/perf/user.js
@@ -61,19 +61,16 @@ user_pref("extensions.update.background.
 user_pref("extensions.update.notifyUser", false);
 user_pref("extensions.update.url", "http://127.0.0.1/extensions-dummy/updateURL");
 user_pref("extensions.webservice.discoverURL", "http://127.0.0.1/extensions-dummy/discoveryURL");
 user_pref("identity.fxaccounts.auth.uri", "https://127.0.0.1/fxa-dummy/");
 user_pref("identity.fxaccounts.migrateToDevEdition", false);
 // Avoid idle-daily notifications, to avoid expensive operations that may
 // cause unexpected test timeouts.
 user_pref("idle.lastDailyNotification", -1);
-// Make tests run consistently on DevEdition (which has a lightweight theme
-// selected by default).
-user_pref("lightweightThemes.selectedThemeID", "");
 user_pref("media.capturestream_hints.enabled", true);
 user_pref("media.gmp-manager.url", "http://127.0.0.1/gmpmanager-dummy/update.xml");
 // Don't block old libavcodec libraries when testing, because our test systems
 // cannot easily be upgraded.
 user_pref("media.libavcodec.allow-obsolete", true);
 user_pref("media.navigator.enabled", true);
 user_pref("media.navigator.permission.disabled", true);
 user_pref("media.peerconnection.enabled", true);
--- a/testing/profiles/unittest-required/user.js
+++ b/testing/profiles/unittest-required/user.js
@@ -153,19 +153,16 @@ user_pref("identity.fxaccounts.remote.ro
 // Avoid idle-daily notifications, to avoid expensive operations that may
 // cause unexpected test timeouts.
 user_pref("idle.lastDailyNotification", -1);
 user_pref("javascript.options.showInConsole", true);
 // Make sure CSS error reporting is enabled for tests
 user_pref("layout.css.report_errors", true);
 // Disable spammy layout warnings because they pollute test logs
 user_pref("layout.spammy_warnings.enabled", false);
-// Make tests run consistently on DevEdition (which has a lightweight theme
-// selected by default).
-user_pref("lightweightThemes.selectedThemeID", "");
 // Disable all recommended Marionette preferences for Gecko tests.
 // The prefs recommended by Marionette are typically geared towards
 // consumer automation; not vendor testing.
 user_pref("marionette.prefs.recommended", false);
 user_pref("media.cache_size", 1000);
 user_pref("media.dormant-on-pause-timeout-ms", 0); // Enter dormant immediately without waiting for timeout.
 // Set the number of shmems the PChromiumCDM protocol pre-allocates to 0,
 // so that we test the case where we under-estimate how many shmems we need
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -1474,21 +1474,16 @@ function run_next_test() {
 
 try {
   // Set global preferences
   if (runningInParent) {
     let prefsFile = Cc["@mozilla.org/file/local;1"]
       .createInstance(Ci.nsIFile);
     prefsFile.initWithPath(_PREFS_FILE);
     _Services.prefs.readUserPrefsFromFile(prefsFile);
-
-    // Make tests run consistently on DevEdition (which has a lightweight theme
-    // selected by default).
-    _Services.prefs.deleteBranch("lightweightThemes.selectedThemeID");
-    _Services.prefs.deleteBranch("browser.devedition.theme.enabled");
   }
 } catch (e) {
   do_throw(e);
 }
 
 function _load_mozinfo() {
   let mozinfoFile = Cc["@mozilla.org/file/local;1"]
     .createInstance(Ci.nsIFile);
--- a/third_party/rust/cssparser/.cargo-checksum.json
+++ b/third_party/rust/cssparser/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"47497bde56f31c8a24665d840fbe5b03f14324dd06a68f907e419f8e7a855186","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"c5781e673335f37ed3d7acb119f8ed33efdf6eb75a7094b7da2abe0c3230adb8","build.rs":"310d6d7b1931ff783a8aa1a4c6baee87b4c9130c858e4694ef69cc96df5e38dc","build/match_byte.rs":"31905ae3dba69fa82c1f13069df4cd056bb340d59ee5d177679425f105f203cf","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"c60f1b0ab7a2a6213e434604ee33f78e7ef74347f325d86d0b9192d8225ae1cc","src/cow_rc_str.rs":"541216f8ef74ee3cc5cbbc1347e5f32ed66588c401851c9a7d68b867aede1de0","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"a474ee88ef8f73fcb7b7272d426e5eafb4ad10d104797a5a188d1676c8180972","src/macros.rs":"adb9773c157890381556ea83d7942dcc676f99eea71abbb6afeffee1e3f28960","src/nth.rs":"5c70fb542d1376cddab69922eeb4c05e4fcf8f413f27563a2af50f72a47c8f8c","src/parser.rs":"a4ec0bd1b5eab6632cf1985701a7ea641fe7f7bbcc0a2bd33f924ae6228591a5","src/rules_and_declarations.rs":"622ce07c117a511d40ce595602d4f4730659a59273388f28553d1a2b0fac92ce","src/serializer.rs":"3e2dfc60613f885cb6f99abfc854fde2a1e00de507431bd2e51178b61abfd69b","src/size_of_tests.rs":"e5f63c8c18721cc3ff7a5407e84f9889ffa10e66da96e8510a696c3e00ad72d5","src/tests.rs":"9d08b3943d453664e01d58e307f79345e240f9f9ce6f8d36a842eff37155563e","src/tokenizer.rs":"adcf5811955e8df57a519e3d1e44fe3afeb5afeb1076daeb8d36fed1abcf1327","src/unicode_range.rs":"ae159d2ebe4123a6666e18dc0362f89b475240a6b7ed5fb6fe21b9e7a4139da8"},"package":"730363a45c4e248d4f21d3e5c1156d1a9cdec0855056c0d9539e814bc59865c3"}
\ No newline at end of file
+{"files":{"Cargo.toml":"150d450e43bcb9e523941408be883997ecffce7ff5f224329372edfe56334a55","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"b9d6c5dc56ccc267db9e0e2389061dc2524daefa4baed88b36c98efc7a51c2a9","build.rs":"310d6d7b1931ff783a8aa1a4c6baee87b4c9130c858e4694ef69cc96df5e38dc","build/match_byte.rs":"6f7ec4235c9f2da403ea0be9339661ecd8e1f5e1c788cf88a41448b1080c59b8","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"43f996fbd8da54bd8ffa870f5e3610e5ba6e61543f92a129fa6c850e9b10db7e","src/cow_rc_str.rs":"541216f8ef74ee3cc5cbbc1347e5f32ed66588c401851c9a7d68b867aede1de0","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"a474ee88ef8f73fcb7b7272d426e5eafb4ad10d104797a5a188d1676c8180972","src/macros.rs":"adb9773c157890381556ea83d7942dcc676f99eea71abbb6afeffee1e3f28960","src/nth.rs":"5c70fb542d1376cddab69922eeb4c05e4fcf8f413f27563a2af50f72a47c8f8c","src/parser.rs":"22067562160a1294fa92779b66c25cbccf259a2ef7dcf687c791fecdd020ce7f","src/rules_and_declarations.rs":"622ce07c117a511d40ce595602d4f4730659a59273388f28553d1a2b0fac92ce","src/serializer.rs":"3e2dfc60613f885cb6f99abfc854fde2a1e00de507431bd2e51178b61abfd69b","src/size_of_tests.rs":"385a0d77fbd6f86cb8013fd8d7541886980876a9da1da714bf175954c0e726cf","src/tests.rs":"9d08b3943d453664e01d58e307f79345e240f9f9ce6f8d36a842eff37155563e","src/tokenizer.rs":"adcf5811955e8df57a519e3d1e44fe3afeb5afeb1076daeb8d36fed1abcf1327","src/unicode_range.rs":"ae159d2ebe4123a6666e18dc0362f89b475240a6b7ed5fb6fe21b9e7a4139da8"},"package":"ba1ab4e1814be64bf6b6064ff532db0e34087f11b37706d6c96a21d32478761d"}
\ No newline at end of file
--- a/third_party/rust/cssparser/Cargo.toml
+++ b/third_party/rust/cssparser/Cargo.toml
@@ -1,23 +1,23 @@
 # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
 #
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
+# to registry (e.g., crates.io) dependencies
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cssparser"
-version = "0.25.0"
+version = "0.25.3"
 authors = ["Simon Sapin <simon.sapin@exyr.org>"]
 build = "build.rs"
 exclude = ["src/css-parsing-tests/**", "src/big-data-url.css"]
 description = "Rust implementation of CSS Syntax Level 3"
 documentation = "https://docs.rs/cssparser/"
 readme = "README.md"
 keywords = ["css", "syntax", "parser"]
 license = "MPL-2.0"
@@ -49,25 +49,25 @@ version = "1.0"
 optional = true
 
 [dependencies.smallvec]
 version = "0.6"
 [dev-dependencies.difference]
 version = "2.0"
 
 [dev-dependencies.encoding_rs]
-version = "0.7"
+version = "0.8"
 
 [dev-dependencies.rustc-serialize]
 version = "0.3"
 [build-dependencies.proc-macro2]
 version = "0.4"
 
 [build-dependencies.quote]
 version = "0.6"
 
 [build-dependencies.syn]
-version = "0.14"
+version = "0.15.12"
 features = ["extra-traits", "fold", "full"]
 
 [features]
 bench = []
 dummy_match_byte = []
--- a/third_party/rust/cssparser/README.md
+++ b/third_party/rust/cssparser/README.md
@@ -34,17 +34,17 @@ Parsing CSS involves a series of steps:
   that contain more component values.
 
   rust-cssparser does this at the same time as tokenization:
   raw tokens are never materialized, you only get component values.
 
 * Component values can then be parsed into generic rules or declarations.
   The header and body of rules as well as the value of declarations
   are still just lists of component values at this point.
-  See [the `ast` module](src/ast.rs) for the data structures.
+  See [the `Token` enum](src/tokenizer.rs) for the data structure.
 
 * The last step of a full CSS parser is
   parsing the remaining component values
   into [Selectors](https://drafts.csswg.org/selectors/),
   specific CSS properties, etc.
 
   By design, rust-cssparser does not do this last step
   which depends a lot on what you want to do:
--- a/third_party/rust/cssparser/build/match_byte.rs
+++ b/third_party/rust/cssparser/build/match_byte.rs
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use quote::ToTokens;
 use std::fs::File;
 use std::io::{Read, Write};
 use std::path::Path;
 use syn;
 use syn::fold::Fold;
+use syn::parse::{Parse, ParseStream, Result};
 
 use proc_macro2::{Span, TokenStream};
 
 struct MatchByteParser {
 }
 
 pub fn expand(from: &Path, to: &Path) {
     let mut source = String::new();
@@ -25,27 +26,33 @@ pub fn expand(from: &Path, to: &Path) {
     File::create(to).unwrap().write_all(code.as_bytes()).unwrap();
 }
 
 struct MatchByte {
     expr: syn::Expr,
     arms: Vec<syn::Arm>,
 }
 
-impl syn::synom::Synom for MatchByte {
-    named!(parse -> Self, do_parse!(
-        expr: syn!(syn::Expr) >>
-        punct!(,) >>
-        arms: many0!(syn!(syn::Arm)) >> (
-            MatchByte {
-                expr,
+impl Parse for MatchByte {
+    fn parse(input: ParseStream) -> Result<Self> {
+        Ok(MatchByte {
+            expr: {
+                let expr = input.parse()?;
+                input.parse::<Token![,]>()?;
+                expr
+            },
+            arms: {
+                let mut arms = Vec::new();
+                while !input.is_empty() {
+                    arms.push(input.call(syn::Arm::parse)?);
+                }
                 arms
             }
-        )
-    ));
+        })
+    }
 }
 
 fn get_byte_from_expr_lit(expr: &Box<syn::Expr>) -> u8 {
     match **expr {
         syn::Expr::Lit(syn::ExprLit { ref lit, .. }) => {
             if let syn::Lit::Byte(ref byte) = *lit {
                 byte.value()
             }
--- a/third_party/rust/cssparser/src/color.rs
+++ b/third_party/rust/cssparser/src/color.rs
@@ -7,16 +7,17 @@ use std::f32::consts::PI;
 
 use super::{Token, Parser, ToCss, ParseError, BasicParseError};
 
 #[cfg(feature = "serde")]
 use serde::{Deserialize, Deserializer, Serialize, Serializer};
 
 /// A color with red, green, blue, and alpha components, in a byte each.
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[repr(C)]
 pub struct RGBA {
     /// The red component.
     pub red: u8,
     /// The green component.
     pub green: u8,
     /// The blue component.
     pub blue: u8,
     /// The alpha component.
--- a/third_party/rust/cssparser/src/parser.rs
+++ b/third_party/rust/cssparser/src/parser.rs
@@ -416,16 +416,26 @@ impl<'i: 't, 't> Parser<'i, 't> {
     }
 
     /// Create a new unexpected token ParseError at the current location
     #[inline]
     pub fn new_unexpected_token_error<E>(&self, token: Token<'i>) -> ParseError<'i, E> {
         self.new_error(BasicParseErrorKind::UnexpectedToken(token))
     }
 
+    /// Create a new unexpected token or EOF ParseError at the current location
+    #[inline]
+    pub fn new_error_for_next_token<E>(&mut self) -> ParseError<'i, E> {
+        let token = match self.next() {
+            Ok(token) => token.clone(),
+            Err(e) => return e.into()
+        };
+        self.new_error(BasicParseErrorKind::UnexpectedToken(token))
+    }
+
     /// Return the current internal state of the parser (including position within the input).
     ///
     /// This state can later be restored with the `Parser::reset` method.
     #[inline]
     pub fn state(&self) -> ParserState {
         ParserState {
             at_start_of: self.at_start_of,
             .. self.input.tokenizer.state()
--- a/third_party/rust/cssparser/src/size_of_tests.rs
+++ b/third_party/rust/cssparser/src/size_of_tests.rs
@@ -1,17 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use cow_rc_str::CowRcStr;
 use std::borrow::Cow;
 use tokenizer::Token;
 
-#[macro_export]
 macro_rules! size_of_test {
     ($testname: ident, $t: ty, $expected_size: expr) => {
         #[test]
         fn $testname() {
             let new = ::std::mem::size_of::<$t>();
             let old = $expected_size;
             if new < old {
                 panic!(
--- a/toolkit/crashreporter/CrashAnnotations.yaml
+++ b/toolkit/crashreporter/CrashAnnotations.yaml
@@ -495,16 +495,25 @@ JSOutOfMemory:
 
 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
 
+LocalStorageShutdownTimeout:
+  description: >
+    This annotation is present if LocalStorage shutdown was not finished in time
+    and the browser was crashed instead of waiting for LocalStorage shutdown to
+    finish. The condition that caused the hang is contained in the annotation.
+  type: string
+  content: false
+  ping: true
+
 LowCommitSpaceEvents:
   description: >
     Number of times the available memory tracker has detected a that
     commit-space was running low. This is a Windows-specific annotation.
   type: integer
   ping: true
 
 MarshalActCtxManifestPath:
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -2535,17 +2535,17 @@ var AddonManagerInternal = {
 
       // All installs end up in this callback when the add-on is available
       // for installation.  There are numerous different things that can
       // happen from here though.  For webextensions, if the application
       // implements webextension permission prompts, those always take
       // precedence.
       // If this add-on is not a webextension or if the application does not
       // implement permission prompts, no confirmation is displayed for
-      // installs created with mozAddonManager (in which case requireConfirm
+      // installs created from about:addons (in which case requireConfirm
       // is false).
       // In the remaining cases, a confirmation prompt is displayed but the
       // application may override it either by implementing the
       // "@mozilla.org/addons/web-install-prompt;1" contract or by setting
       // the customConfirmationUI preference and responding to the
       // "addon-install-confirmation" notification.  If the application
       // does not implement its own prompt, use the built-in xul dialog.
       if (info.addon.userPermissions && WEBEXT_PERMISSION_PROMPTS) {
@@ -2700,17 +2700,22 @@ var AddonManagerInternal = {
         browser: target,
         triggeringPrincipal: options.triggeringPrincipal,
         hash: options.hash,
         telemetryInfo: {
           source: AddonManager.getInstallSourceFromHost(options.sourceHost),
           method: "amWebAPI",
         },
       }).then(install => {
-        AddonManagerInternal.setupPromptHandler(target, null, install, false, "AMO");
+        let requireConfirm = true;
+        if (target.contentDocument &&
+            target.contentDocument.nodePrincipal.isSystemPrincipal) {
+          requireConfirm = false;
+        }
+        AddonManagerInternal.setupPromptHandler(target, null, install, requireConfirm, "AMO");
 
         let id = this.nextInstall++;
         let {listener, installPromise} = makeListener(id, target.messageManager);
         install.addListener(listener);
 
         this.installs.set(id, {install, target, listener, installPromise});
 
         let result = {id};
deleted file mode 100644
--- a/toolkit/mozapps/extensions/internal/LightweightThemePersister.jsm
+++ /dev/null
@@ -1,130 +0,0 @@
-/* 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";
-
-var EXPORTED_SYMBOLS = ["LightweightThemePersister"];
-
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-let _prefs = Services.prefs.getBranch("lightweightThemes.");
-
-ChromeUtils.defineModuleGetter(this, "LightweightThemeManager",
-  "resource://gre/modules/LightweightThemeManager.jsm");
-
-const PERSIST_FILES = {
-  headerURL: "lightweighttheme-header",
-};
-
-var LightweightThemePersister = {
-  getPersistedData(aData) {
-    for (let key in PERSIST_FILES) {
-      try {
-        if (aData[key] && _prefs.getBoolPref("persisted." + key))
-          aData[key] = _getLocalImageURI(PERSIST_FILES[key]).spec
-                       + `?${aData.id};${aData.version}`;
-      } catch (e) {}
-    }
-    return aData;
-  },
-
-  persistImages(aData, aCallback) {
-    function onSuccess(key) {
-      return function() {
-        let current = LightweightThemeManager.currentThemeWithFallback;
-        if (current && current.id == aData.id) {
-          _prefs.setBoolPref("persisted." + key, true);
-        } else {
-          themeStillCurrent = false;
-        }
-        if (--numFilesToPersist == 0) {
-          if (themeStillCurrent) {
-            _prefs.setStringPref("persistedThemeID", _versionCode(aData));
-          }
-          if (aCallback) {
-            aCallback();
-          }
-        }
-      };
-    }
-
-    if (_prefs.getStringPref("persistedThemeID", "") == _versionCode(aData)) {
-      if (aCallback) {
-        aCallback();
-      }
-      return;
-    }
-
-    let numFilesToPersist = 0;
-    let themeStillCurrent = true;
-    for (let key in PERSIST_FILES) {
-      _prefs.setBoolPref("persisted." + key, false);
-      if (aData[key]) {
-        numFilesToPersist++;
-        _persistImage(aData[key], PERSIST_FILES[key], onSuccess(key));
-      }
-    }
-  },
-};
-
-Object.freeze(LightweightThemePersister);
-
-
-function _persistImage(sourceURL, localFileName, successCallback) {
-  if (/^(file|resource):/.test(sourceURL))
-    return;
-
-  var targetURI = _getLocalImageURI(localFileName);
-  var sourceURI = Services.io.newURI(sourceURL);
-
-  var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
-                  .createInstance(Ci.nsIWebBrowserPersist);
-
-  persist.persistFlags =
-    Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
-    Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
-
-  persist.progressListener = new _persistProgressListener(successCallback);
-
-  let sourcePrincipal = Services.scriptSecurityManager.createCodebasePrincipal(sourceURI, {});
-  persist.saveURI(sourceURI, sourcePrincipal, 0,
-                  null, Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
-                  null, null, targetURI, null);
-}
-
-function _persistProgressListener(successCallback) {
-  this.onLocationChange = function() {};
-  this.onProgressChange = function() {};
-  this.onStatusChange = function() {};
-  this.onSecurityChange = function() {};
-  this.onContentBlockingEvent = function() {};
-  this.onStateChange = function(aWebProgress, aRequest, aStateFlags, aStatus) {
-    if (aRequest &&
-        aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
-        aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
-      // LWTs used to get their image files from the network…
-      if (aRequest instanceof Ci.nsIHttpChannel &&
-          aRequest.QueryInterface(Ci.nsIHttpChannel).requestSucceeded ||
-          // … but static themes usually include the image data inside the
-          // extension package.
-          aRequest instanceof Ci.nsIChannel &&
-          aRequest.originalURI.schemeIs("moz-extension") &&
-          aRequest.QueryInterface(Ci.nsIChannel).contentLength > 0) {
-        // success
-        successCallback();
-      }
-      // failure
-    }
-  };
-}
-
-function _getLocalImageURI(localFileName) {
-  let localFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
-  localFile.append(localFileName);
-  return Services.io.newFileURI(localFile);
-}
-
-function _versionCode(aThemeData) {
-  return `${aThemeData.id}-${aThemeData.version}`;
-}
--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -1619,16 +1619,18 @@ this.XPIDatabase = {
    * @param {string} aType
    *        The type of the newly enabled add-on
    */
   async addonChanged(aId, aType) {
     // We only care about themes in this provider
     if (aType !== "theme")
       return;
 
+    Services.prefs.setCharPref("extensions.activeThemeID", aId || DEFAULT_THEME_ID);
+
     let enableTheme;
 
     let addons = this.getAddonsByType("theme");
     for (let theme of addons) {
       if (theme.visible) {
         if (!aId && theme.id == DEFAULT_THEME_ID) {
           enableTheme = theme;
         } else if (theme.id != aId) {
--- a/toolkit/mozapps/extensions/internal/moz.build
+++ b/toolkit/mozapps/extensions/internal/moz.build
@@ -11,20 +11,16 @@ EXTRA_JS_MODULES.addons += [
     'Content.js',
     'GMPProvider.jsm',
     'ProductAddonChecker.jsm',
     'XPIDatabase.jsm',
     'XPIInstall.jsm',
     'XPIProvider.jsm',
 ]
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
-    EXTRA_JS_MODULES.addons += [
-        'LightweightThemePersister.jsm',
-    ]
-else:
+if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
     EXTRA_JS_MODULES.addons += [
         'PluginProvider.jsm',
     ]
 
 TESTING_JS_MODULES += [
     'AddonTestUtils.jsm',
 ]
--- a/toolkit/mozapps/extensions/test/browser/browser_webapi_theme.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_webapi_theme.js
@@ -16,24 +16,31 @@ add_task(async function test_theme_insta
     function observer(subject, topic, data) {
       updates.push(JSON.stringify(subject.wrappedJSObject));
     }
     Services.obs.addObserver(observer, "lightweight-theme-styling-update");
     registerCleanupFunction(() => {
       Services.obs.removeObserver(observer, "lightweight-theme-styling-update");
     });
 
+    let sawConfirm = false;
+    promisePopupNotificationShown("addon-install-confirmation").then(panel => {
+      sawConfirm = true;
+      panel.button.click();
+    });
 
     let prompt1 = waitAppMenuNotificationShown("addon-installed", "theme@tests.mozilla.org", false);
     let installPromise = ContentTask.spawn(browser, URL, async (url) => {
       let install = await content.navigator.mozAddonManager.createInstall({url});
       return install.install();
     });
     await prompt1;
 
+    ok(sawConfirm, "Confirm notification was displayed before installation");
+
     // Open a new window and test the app menu panel from there.  This verifies the
     // incognito checkbox as well as finishing install in this case.
     let newWin = await BrowserTestUtils.openNewBrowserWindow();
     await waitAppMenuNotificationShown("addon-installed", "theme@tests.mozilla.org", true, newWin);
     await installPromise;
     ok(true, "Theme install completed");
 
     await BrowserTestUtils.closeWindow(newWin);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_update.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_update.js
@@ -2,20 +2,16 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // This verifies that add-on update checks work
 
 // The test extension uses an insecure update url.
 Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
 
-// This test requires lightweight themes update to be enabled even if the app
-// doesn't support lightweight themes.
-Services.prefs.setBoolPref("lightweightThemes.update.enabled", true);
-
 const updateFile = "test_update.json";
 
 const profileDir = gProfD.clone();
 profileDir.append("extensions");
 
 const ADDONS = {
   test_update: {
     id: "addon1@tests.mozilla.org",
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_theme.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_theme.js
@@ -38,16 +38,22 @@ add_task(async function setup_to_default
       gecko: {
         id: THEME_IDS[0],
       },
     },
   }, profileDir);
 
   await promiseStartupManager();
 
+  if (AppConstants.MOZ_DEV_EDITION) {
+    // Developer Edition selects the wrong theme by default.
+    let defaultTheme = await AddonManager.getAddonByID("default-theme@mozilla.org");
+    await defaultTheme.enable();
+  }
+
   let [ t1, t2, d ] = await promiseAddonsByIDs(THEME_IDS);
   Assert.ok(t1, "Theme addon should exist");
   Assert.equal(t2, null, "Theme addon is not a thing anymore");
   Assert.ok(d, "Theme addon should exist");
 
   await t1.disable();
   await new Promise(executeSoon);
   Assert.ok(!t1.isActive, "Theme should be disabled");