Merge inbound to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Mon, 31 Jul 2017 17:43:38 -0700
changeset 420797 44121dbcac6a9d3ff18ed087a09b3205e5a04db1
parent 420765 8b19670d12fde57d3aee50a5a7d1c734d9b709d5 (current diff)
parent 420796 a431c842cc50cfd446af8d48593bfda68a9e127f (diff)
child 420825 3093ee7b4f98be42cace4d1402506b3616061449
child 420865 805352a14fc52645529fde20b2d5c8dcdf99c27e
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to central, a=merge MozReview-Commit-ID: Dg4fbH8wbXt
browser/base/content/browser.js
browser/components/distribution.js
browser/components/nsBrowserGlue.js
browser/components/uitour/UITour.jsm
browser/extensions/shield-recipe-client/test/browser/browser_RecipeRunner.js
layout/base/nsPresContext.cpp
modules/libpref/init/all.js
testing/marionette/event.js
testing/marionette/reftest.js
toolkit/components/telemetry/TelemetrySession.jsm
--- a/browser/base/content/abouthealthreport/abouthealth.js
+++ b/browser/base/content/abouthealthreport/abouthealth.js
@@ -1,34 +1,29 @@
 /* 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 {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
-Cu.import("resource://gre/modules/Preferences.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-const prefs = new Preferences("datareporting.healthreport.");
-
-const PREF_UNIFIED = "toolkit.telemetry.unified";
 const PREF_REPORTING_URL = "datareporting.healthreport.about.reportUrl";
 
 var healthReportWrapper = {
   init() {
     let iframe = document.getElementById("remote-report");
     iframe.addEventListener("load", healthReportWrapper.initRemotePage);
     iframe.src = this._getReportURI().spec;
-    prefs.observe("uploadEnabled", this.updatePrefState, healthReportWrapper);
-  },
-
-  uninit() {
-    prefs.ignore("uploadEnabled", this.updatePrefState, healthReportWrapper);
+    XPCOMUtils.defineLazyPreferenceGetter(this, /* unused */ "_isUploadEnabled",
+                                          "datareporting.healthreport.uploadEnabled",
+                                          false, () => this.updatePrefState());
   },
 
   _getReportURI() {
     let url = Services.urlFormatter.formatURLPref(PREF_REPORTING_URL);
     return Services.io.newURI(url);
   },
 
   setDataSubmission(enabled) {
@@ -170,9 +165,8 @@ var healthReportWrapper = {
   },
 
   handlePayloadFailure() {
     healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PAYLOAD_FAILED);
   },
 }
 
 window.addEventListener("load", function() { healthReportWrapper.init(); });
-window.addEventListener("unload", function() { healthReportWrapper.uninit(); });
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -322,17 +322,17 @@ var gXPInstallObserver = {
       options.contentWindow = browser.contentWindow;
       options.sourceURI = browser.currentURI;
       options.eventCallback = function(aEvent) {
         switch (aEvent) {
           case "shown":
             let notificationElement = [...this.owner.panel.childNodes]
                                       .find(n => n.notification == this);
             if (notificationElement) {
-              if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+              if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
                 notificationElement.setAttribute("mainactiondisabled", "true");
               } else {
                 notificationElement.button.hidden = true;
               }
             }
             break;
           case "removed":
             options.contentWindow = null;
--- a/browser/base/content/browser-captivePortal.js
+++ b/browser/base/content/browser-captivePortal.js
@@ -7,17 +7,17 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "nsICaptivePortalService");
 
 var CaptivePortalWatcher = {
   /**
    * This constant is chosen to be large enough for a portal recheck to complete,
    * and small enough that the delay in opening a tab isn't too noticeable.
    * Please see comments for _delayedCaptivePortalDetected for more details.
    */
-  PORTAL_RECHECK_DELAY_MS: Preferences.get("captivedetect.portalRecheckDelayMS", 500),
+  PORTAL_RECHECK_DELAY_MS: Services.prefs.getIntPref("captivedetect.portalRecheckDelayMS", 500),
 
   // This is the value used to identify the captive portal notification.
   PORTAL_NOTIFICATION_VALUE: "captive-portal-detected",
 
   // This holds a weak reference to the captive portal tab so that we
   // don't leak it if the user closes it.
   _captivePortalTab: null,
 
@@ -63,16 +63,19 @@ var CaptivePortalWatcher = {
         this.ensureCaptivePortalTab();
       }
     } else if (cps.state == cps.UNKNOWN) {
       // We trigger a portal check after delayed startup to avoid doing a network
       // request before first paint.
       this._delayedRecheckPending = true;
       Services.obs.addObserver(this, "browser-delayed-startup-finished");
     }
+
+    XPCOMUtils.defineLazyPreferenceGetter(this, "PORTAL_RECHECK_DELAY_MS",
+                                          "captivedetect.portalRecheckDelayMS", 500);
   },
 
   uninit() {
     Services.obs.removeObserver(this, "captive-portal-login");
     Services.obs.removeObserver(this, "captive-portal-login-abort");
     Services.obs.removeObserver(this, "captive-portal-login-success");
 
     if (this._delayedRecheckPending) {
--- a/browser/base/content/browser-data-submission-info-bar.js
+++ b/browser/base/content/browser-data-submission-info-bar.js
@@ -1,17 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const LOGGER_NAME = "Toolkit.Telemetry";
 const LOGGER_PREFIX = "DataNotificationInfoBar::";
-
-XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
-                                  "resource://gre/modules/Preferences.jsm");
 /**
  * Represents an info bar that shows a data submission notification.
  */
 var gDataNotificationInfoBar = {
   _OBSERVERS: [
     "datareporting:notify-data-policy:request",
     "datareporting:notify-data-policy:close",
   ],
@@ -63,17 +60,17 @@ var gDataNotificationInfoBar = {
     let buttons = [{
       label: gNavigatorBundle.getString("dataReportingNotification.button.label"),
       accessKey: gNavigatorBundle.getString("dataReportingNotification.button.accessKey"),
       popup: null,
       callback: () => {
         this._actionTaken = true;
         // The advanced subpanes are only supported in the old organization, which will
         // be removed by bug 1349689.
-        if (Preferences.get("browser.preferences.useOldOrganization")) {
+        if (Services.prefs.getBoolPref("browser.preferences.useOldOrganization")) {
           window.openAdvancedPreferences("dataChoicesTab", {origin: "dataReporting"});
         } else {
           window.openPreferences("privacy-reports", {origin: "dataReporting"});
         }
       },
     }];
 
     this._log.info("Creating data reporting policy notification.");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -26,17 +26,17 @@ XPCOMUtils.defineLazyPreferenceGetter(th
 
 /* global AboutHome:false,
           BrowserUITelemetry:false, BrowserUsageTelemetry:false, BrowserUtils:false,
           CastingApps:false, CharsetMenu:false, Color:false, ContentSearch:false,
           CustomizableUI: false, DownloadsCommon: false,
           Deprecated:false, E10SUtils:false, ExtensionsUI: false, FormValidationHandler:false,
           GMPInstallManager:false, LightweightThemeManager:false, Log:false,
           LoginManagerParent:false, NewTabUtils:false, PageThumbs:false,
-          PluralForm:false, Preferences:false, PrivateBrowsingUtils:false,
+          PluralForm:false, PrivateBrowsingUtils:false,
           ProcessHangMonitor:false, PromiseUtils:false, ReaderMode:false,
           ReaderParent:false, RecentWindow:false, SafeBrowsing: false,
           SessionStore:false,
           ShortcutUtils:false, SimpleServiceDiscovery:false, SitePermissions:false,
           Social:false, TabCrashHandler:false, TelemetryStopwatch:false,
           Translation:false, UITour:false, Utils:false, UpdateUtils:false,
           Weave:false,
           WebNavigationFrames: false, fxAccounts:false, gDevTools:false,
@@ -67,17 +67,16 @@ XPCOMUtils.defineLazyPreferenceGetter(th
   ["GMPInstallManager", "resource://gre/modules/GMPInstallManager.jsm"],
   ["LightweightThemeManager", "resource://gre/modules/LightweightThemeManager.jsm"],
   ["Log", "resource://gre/modules/Log.jsm"],
   ["LoginManagerParent", "resource://gre/modules/LoginManagerParent.jsm"],
   ["NewTabUtils", "resource://gre/modules/NewTabUtils.jsm"],
   ["PageActions", "resource:///modules/PageActions.jsm"],
   ["PageThumbs", "resource://gre/modules/PageThumbs.jsm"],
   ["PluralForm", "resource://gre/modules/PluralForm.jsm"],
-  ["Preferences", "resource://gre/modules/Preferences.jsm"],
   ["PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"],
   ["ProcessHangMonitor", "resource:///modules/ProcessHangMonitor.jsm"],
   ["PromiseUtils", "resource://gre/modules/PromiseUtils.jsm"],
   ["ReaderMode", "resource://gre/modules/ReaderMode.jsm"],
   ["ReaderParent", "resource:///modules/ReaderParent.jsm"],
   ["RecentWindow", "resource:///modules/RecentWindow.jsm"],
   ["SafeBrowsing", "resource://gre/modules/SafeBrowsing.jsm"],
   ["SessionStore", "resource:///modules/sessionstore/SessionStore.jsm"],
@@ -581,17 +580,17 @@ const gStoragePressureObserver = {
       msg = prefStrBundle.getFormattedString(descriptionStringID, [brandShortName]);
       buttons.push({
         label: prefStrBundle.getString(prefButtonLabelStringID),
         accessKey: prefStrBundle.getString(prefButtonAccesskeyStringID),
         callback(notificationBar, button) {
           // The advanced subpanes are only supported in the old organization, which will
           // be removed by bug 1349689.
           let win = gBrowser.ownerGlobal;
-          if (Preferences.get("browser.preferences.useOldOrganization")) {
+          if (Services.prefs.getBoolPref("browser.preferences.useOldOrganization")) {
             win.openAdvancedPreferences("networkTab", {origin: "storagePressure"});
           } else {
             win.openPreferences("panePrivacy", {origin: "storagePressure"});
           }
         }
       });
     }
 
@@ -6512,17 +6511,17 @@ var OfflineApps = {
         docId,
       });
     }
   },
 
   manage() {
     // The advanced subpanes are only supported in the old organization, which will
     // be removed by bug 1349689.
-    if (Preferences.get("browser.preferences.useOldOrganization")) {
+    if (Services.prefs.getBoolPref("browser.preferences.useOldOrganization")) {
       openAdvancedPreferences("networkTab", {origin: "offlineApps"});
     } else {
       openPreferences("panePrivacy", {origin: "offlineApps"});
     }
   },
 
   receiveMessage(msg) {
     switch (msg.name) {
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -16,18 +16,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                                   "resource://gre/modules/Downloads.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
                                   "resource:///modules/DownloadsCommon.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
                                   "resource://gre/modules/TelemetryStopwatch.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "console",
                                   "resource://gre/modules/Console.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
-                                  "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "setTimeout",
                                   "resource://gre/modules/Timer.jsm");
 
 var {classes: Cc, interfaces: Ci} = Components;
 
 /**
  * A number of iterations after which to yield time back
  * to the system.
@@ -105,18 +103,18 @@ Sanitizer.prototype = {
         } catch (ex) {
           return false;
         }
       });
     }
 
     // Store the list of items to clear, in case we are killed before we
     // get a chance to complete.
-    Preferences.set(Sanitizer.PREF_SANITIZE_IN_PROGRESS,
-                    JSON.stringify(itemsToClear));
+    Services.prefs.setStringPref(Sanitizer.PREF_SANITIZE_IN_PROGRESS,
+                                 JSON.stringify(itemsToClear));
 
     // Store the list of items to clear, for debugging/forensics purposes
     for (let k of itemsToClear) {
       progress[k] = "ready";
     }
 
     // Ensure open windows get cleared first, if they're in our list, so that they don't stick
     // around in the recently closed windows list, and so we can cancel the whole thing
@@ -172,17 +170,17 @@ Sanitizer.prototype = {
       progress[handle.name] = "blocking";
       await handle.promise;
     }
 
     // Sanitization is complete.
     TelemetryStopwatch.finish("FX_SANITIZE_TOTAL", refObj);
     // Reset the inProgress preference since we were not killed during
     // sanitization.
-    Preferences.reset(Sanitizer.PREF_SANITIZE_IN_PROGRESS);
+    Services.prefs.clearUserPref(Sanitizer.PREF_SANITIZE_IN_PROGRESS);
     progress = {};
     if (seenError) {
       throw new Error("Error sanitizing");
     }
   },
 
   // Time span only makes sense in certain cases.  Consumers who want
   // to only clear some private data can opt in by setting this to false,
@@ -802,24 +800,24 @@ Sanitizer.showUI = function(aParentWindo
  */
 Sanitizer.sanitize = function(aParentWindow) {
   Sanitizer.showUI(aParentWindow);
 };
 
 Sanitizer.onStartup = async function() {
   // Check if we were interrupted during the last shutdown sanitization.
   let shutownSanitizationWasInterrupted =
-    Preferences.get(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, false) &&
-    !Preferences.has(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN);
+    Services.prefs.getBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, false) &&
+    Services.prefs.getPrefType(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN) == Ci.nsIPrefBranch.PREF_INVALID;
 
-  if (Preferences.has(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN)) {
+  if (Services.prefs.prefHasUserValue(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN)) {
     // Reset the pref, so that if we crash before having a chance to
     // sanitize on shutdown, we will do at the next startup.
     // Flushing prefs has a cost, so do this only if necessary.
-    Preferences.reset(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN);
+    Services.prefs.clearUserPref(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN);
     Services.prefs.savePrefFile(null);
   }
 
   // Make sure that we are triggered during shutdown.
   let shutdownClient = Cc["@mozilla.org/browser/nav-history-service;1"]
                          .getService(Ci.nsPIPlacesDatabase)
                          .shutdownClient
                          .jsclient;
@@ -832,35 +830,35 @@ Sanitizer.onStartup = async function() {
   shutdownClient.addBlocker("sanitize.js: Sanitize on shutdown",
     () => sanitizeOnShutdown({ progress }),
     {
       fetchState: () => ({ progress })
     }
   );
 
   // Check if Firefox crashed during a sanitization.
-  let lastInterruptedSanitization = Preferences.get(Sanitizer.PREF_SANITIZE_IN_PROGRESS, "");
+  let lastInterruptedSanitization = Services.prefs.getStringPref(Sanitizer.PREF_SANITIZE_IN_PROGRESS, "");
   if (lastInterruptedSanitization) {
     let s = new Sanitizer();
     // If the json is invalid this will just throw and reject the Task.
     let itemsToClear = JSON.parse(lastInterruptedSanitization);
     await s.sanitize(itemsToClear);
   } else if (shutownSanitizationWasInterrupted) {
     // Otherwise, could be we were supposed to sanitize on shutdown but we
     // didn't have a chance, due to an earlier crash.
     // In such a case, just redo a shutdown sanitize now, during startup.
     await sanitizeOnShutdown();
   }
 };
 
 var sanitizeOnShutdown = async function(options = {}) {
-  if (!Preferences.get(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN)) {
+  if (!Services.prefs.getBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN)) {
     return;
   }
   // Need to sanitize upon shutdown
   let s = new Sanitizer();
   s.prefDomain = "privacy.clearOnShutdown.";
   await s.sanitize(null, options);
   // We didn't crash during shutdown sanitization, so annotate it to avoid
   // sanitizing again on startup.
-  Preferences.set(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN, true);
+  Services.prefs.setBoolPref(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN, true);
   Services.prefs.savePrefFile(null);
 };
--- a/browser/base/content/test/about/browser_aboutHealthReport.js
+++ b/browser/base/content/test/about/browser_aboutHealthReport.js
@@ -2,26 +2,26 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 
 const CHROME_BASE = "chrome://mochitests/content/browser/browser/base/content/test/about/";
 const HTTPS_BASE = "https://example.com/browser/browser/base/content/test/about/";
 
 const TELEMETRY_LOG_PREF = "toolkit.telemetry.log.level";
-const telemetryOriginalLogPref = Preferences.get(TELEMETRY_LOG_PREF, null);
+const telemetryOriginalLogPref = Services.prefs.getStringPref(TELEMETRY_LOG_PREF, null);
 
 const originalReportUrl = Services.prefs.getCharPref("datareporting.healthreport.about.reportUrl");
 
 registerCleanupFunction(function() {
   // Ensure we don't pollute prefs for next tests.
   if (telemetryOriginalLogPref) {
-    Preferences.set(TELEMETRY_LOG_PREF, telemetryOriginalLogPref);
+    Services.prefs.setStringPref(TELEMETRY_LOG_PREF, telemetryOriginalLogPref);
   } else {
-    Preferences.reset(TELEMETRY_LOG_PREF);
+    Services.prefs.clearUserPref(TELEMETRY_LOG_PREF);
   }
 
   try {
     Services.prefs.setCharPref("datareporting.healthreport.about.reportUrl", originalReportUrl);
     Services.prefs.setBoolPref("datareporting.healthreport.uploadEnabled", true);
   } catch (ex) {}
 });
 
@@ -53,20 +53,20 @@ async function setupPingArchive() {
   }
 }
 
 var gTests = [
 
 {
   desc: "Test the remote commands",
   async setup() {
-    Preferences.set(TELEMETRY_LOG_PREF, "Trace");
+    Services.prefs.setStringPref(TELEMETRY_LOG_PREF, "Trace");
     await setupPingArchive();
-    Preferences.set("datareporting.healthreport.about.reportUrl",
-                    HTTPS_BASE + "healthreport_testRemoteCommands.html");
+    Services.prefs.setCharPref("datareporting.healthreport.about.reportUrl",
+                               HTTPS_BASE + "healthreport_testRemoteCommands.html");
   },
   run(iframe) {
     return new Promise((resolve, reject) => {
       let results = 0;
       try {
         iframe.contentWindow.addEventListener("FirefoxHealthReportTestResponse", function evtHandler(event) {
           let data = event.detail.data;
           if (data.type == "testResult") {
--- a/browser/base/content/test/captivePortal/head.js
+++ b/browser/base/content/test/captivePortal/head.js
@@ -59,17 +59,17 @@ async function freePortal(aSuccess) {
 async function focusWindowAndWaitForPortalUI(aLongRecheck, win) {
   // CaptivePortalWatcher triggers a recheck when a window gains focus. If
   // the time taken for the check to complete is under PORTAL_RECHECK_DELAY_MS,
   // a tab with the login page is opened and selected. If it took longer,
   // no tab is opened. It's not reliable to time things in an async test,
   // so use a delay threshold of -1 to simulate a long recheck (so that any
   // amount of time is considered excessive), and a very large threshold to
   // simulate a short recheck.
-  Preferences.set("captivedetect.portalRecheckDelayMS", aLongRecheck ? -1 : 1000000);
+  Services.prefs.setIntPref("captivedetect.portalRecheckDelayMS", aLongRecheck ? -1 : 1000000);
 
   if (!win) {
     win = await BrowserTestUtils.openNewBrowserWindow();
   }
   await SimpleTest.promiseFocus(win);
 
   // After a new window is opened, CaptivePortalWatcher asks for a recheck, and
   // waits for it to complete. We need to manually tell it a recheck completed.
--- a/browser/base/content/test/general/browser_bug553455.js
+++ b/browser/base/content/test/general/browser_bug553455.js
@@ -132,17 +132,17 @@ function waitForNotificationClose() {
     info("Waiting for notification to close");
     PopupNotifications.panel.addEventListener("popuphidden", function() {
       resolve();
     }, {once: true});
   });
 }
 
 async function waitForInstallDialog() {
-  if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     let panel = await waitForNotification("addon-install-confirmation");
     return panel.childNodes[0];
   }
 
   info("Waiting for install dialog");
 
   let window = await new Promise(resolve => {
     Services.wm.addListener({
@@ -178,26 +178,26 @@ async function waitForInstallDialog() {
 function removeTab() {
   return Promise.all([
     waitForNotificationClose(),
     BrowserTestUtils.removeTab(gBrowser.selectedTab)
   ]);
 }
 
 function acceptInstallDialog(installDialog) {
-  if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     installDialog.button.click();
   } else {
     let win = Services.wm.getMostRecentWindow("Addons:Install");
     win.document.documentElement.acceptDialog();
   }
 }
 
 function cancelInstallDialog(installDialog) {
-  if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     installDialog.secondaryButton.click();
   } else {
     let win = Services.wm.getMostRecentWindow("Addons:Install");
     win.document.documentElement.cancelDialog();
   }
 }
 
 async function waitForSingleNotification(aCallback) {
@@ -441,17 +441,17 @@ async function test_restartless() {
   gBrowser.removeTab(gBrowser.selectedTab);
   await closePromise;
 },
 
 async function test_sequential() {
   // This test is only relevant if using the new doorhanger UI
   // TODO: this subtest is disabled until multiple notification prompts are
   // reworked in bug 1188152
-  if (true || !Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (true || !Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     return;
   }
   let pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   let progressPromise = waitForProgressNotification();
   let dialogPromise = waitForInstallDialog();
   let triggers = encodeURIComponent(JSON.stringify({
@@ -514,18 +514,18 @@ async function test_sequential() {
   cancelInstallDialog(installDialog);
   await closePromise;
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 },
 
 async function test_allUnverified() {
   // This test is only relevant if using the new doorhanger UI and allowing
   // unsigned add-ons
-  if (!Preferences.get("xpinstall.customConfirmationUI", false) ||
-      Preferences.get("xpinstall.signatures.required", true) ||
+  if (!Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false) ||
+      Services.prefs.getBoolPref("xpinstall.signatures.required", true) ||
       AppConstants.MOZ_REQUIRE_SIGNING) {
         return;
   }
   let pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   let progressPromise = waitForProgressNotification();
   let dialogPromise = waitForInstallDialog();
@@ -615,17 +615,17 @@ async function test_localFile() {
   is(notification.getAttribute("label"),
      "This add-on could not be installed because it appears to be corrupt.",
      "Should have seen the right message");
 
   await removeTab();
 },
 
 async function test_tabClose() {
-  if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (!Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     info("Test skipped due to xpinstall.customConfirmationUI being false.");
     return;
   }
 
   let progressPromise = waitForProgressNotification();
   let dialogPromise = waitForInstallDialog();
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
@@ -642,17 +642,17 @@ async function test_tabClose() {
 
   installs = await getInstalls();
   is(installs.length, 0, "Should be no pending install since the tab is closed");
 },
 
 // Add-ons should be cancelled and the install notification destroyed when
 // navigating to a new origin
 async function test_tabNavigate() {
-  if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (!Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     return;
   }
   let pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   let progressPromise = waitForProgressNotification();
   let dialogPromise = waitForInstallDialog();
   let triggers = encodeURIComponent(JSON.stringify({
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
@@ -200,29 +200,29 @@ var tests = [
       ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
       ok(!this.notifyObj.secondaryActionClicked, "secondary action not clicked");
     }
   },
   // Test that notification close button calls secondary action instead of
   // dismissal callback if privacy.permissionPrompts.showCloseButton is set.
   { id: "Test#10",
     run() {
-      Preferences.set("privacy.permissionPrompts.showCloseButton", true);
+      Services.prefs.setBoolPref("privacy.permissionPrompts.showCloseButton", true);
       this.notifyObj = new BasicNotification(this.id);
       this.notification = showNotification(this.notifyObj);
     },
     onShown(popup) {
       checkPopup(popup, this.notifyObj);
       let notification = popup.childNodes[0];
       EventUtils.synthesizeMouseAtCenter(notification.closebutton, {});
     },
     onHidden(popup) {
       ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback not triggered");
       ok(this.notifyObj.secondaryActionClicked, "secondary action clicked");
-      Preferences.reset("privacy.permissionPrompts.showCloseButton");
+      Services.prefs.clearUserPref("privacy.permissionPrompts.showCloseButton");
       this.notification.remove();
       ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
     }
   },
   // Test notification when chrome is hidden
   { id: "Test#11",
     run() {
       window.locationbar.visible = false;
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -2449,17 +2449,17 @@ file, You can obtain one at http://mozil
             if (maxProgress >= 0)
               maxProgress += aInstall.maxProgress;
             if (aInstall.state < AddonManager.STATE_DOWNLOADED)
               downloadingCount++;
           });
 
           if (downloadingCount == 0) {
             this.destroy();
-            if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+            if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
               this.progressmeter.setAttribute("mode", "undetermined");
               let status = gNavigatorBundle.getString("addonDownloadVerifying");
               this.progresstext.setAttribute("value", status);
               this.progresstext.setAttribute("tooltiptext", status);
             } else {
               PopupNotifications.remove(this.notification);
             }
           } else {
--- a/browser/components/distribution.js
+++ b/browser/components/distribution.js
@@ -9,17 +9,18 @@ var Cc = Components.classes;
 var Cr = Components.results;
 var Cu = Components.utils;
 
 const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC =
   "distribution-customization-complete";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+                                  "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 
 this.DistributionCustomizer = function DistributionCustomizer() {
   // For parallel xpcshell testing purposes allow loading the distribution.ini
   // file from the profile folder through an hidden pref.
   let loadFromProfile = Services.prefs.getBoolPref("distribution.testing.loadFromProfile", false);
   let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -29,16 +29,17 @@
 //       should use "expectUncaughtRejection" to flag individual failures.
 const {PromiseTestUtils} = Cu.import("resource://testing-common/PromiseTestUtils.jsm", {});
 PromiseTestUtils.whitelistRejectionsGlobally(/Message manager disconnected/);
 PromiseTestUtils.whitelistRejectionsGlobally(/No matching message handler/);
 PromiseTestUtils.whitelistRejectionsGlobally(/Receiving end does not exist/);
 
 const {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm", {});
 const {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", {});
+const {Preferences} = Cu.import("resource://gre/modules/Preferences.jsm", {});
 
 // We run tests under two different configurations, from browser.ini and
 // browser-remote.ini. When running from browser-remote.ini, the tests are
 // copied to the sub-directory "test-oop-extensions", which we detect here, and
 // use to select our configuration.
 let remote = gTestPath.includes("test-oop-extensions");
 SpecialPowers.pushPrefEnv({set: [
   ["extensions.webextensions.remote", remote],
--- a/browser/components/newtab/NewTabPrefsProvider.jsm
+++ b/browser/components/newtab/NewTabPrefsProvider.jsm
@@ -1,15 +1,14 @@
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["NewTabPrefsProvider"];
 
 const {interfaces: Ci, utils: Cu} = Components;
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
   const {EventEmitter} = Cu.import("resource://gre/modules/EventEmitter.jsm", {});
   return EventEmitter;
 });
 
 // Supported prefs and data type
@@ -41,26 +40,30 @@ let PrefsProvider = function PrefsProvid
 
 PrefsProvider.prototype = {
 
   observe(subject, topic, data) { // jshint ignore:line
     if (topic === "nsPref:changed") {
       if (gPrefsMap.has(data)) {
         switch (gPrefsMap.get(data)) {
           case "bool":
-            this.emit(data, Preferences.get(data, false));
+            this.emit(data, Services.prefs.getBoolPref(data, false));
             break;
           case "str":
-            this.emit(data, Preferences.get(data, ""));
+            this.emit(data, Services.prefs.getStringPref(data, ""));
             break;
           case "localized":
-            try {
-              this.emit(data, Preferences.get(data, "", Ci.nsIPrefLocalizedString));
-            } catch (e) {
-              this.emit(data, Preferences.get(data, ""));
+            if (Services.prefs.getPrefType(data) == Ci.nsIPrefBranch.PREF_INVALID) {
+              this.emit(data, "");
+            } else {
+              try {
+                this.emit(data, Services.prefs.getComplexValue(data, Ci.nsIPrefLocalizedString));
+              } catch (e) {
+                this.emit(data, Services.prefs.getStringPref(data));
+              }
             }
             break;
           default:
             this.emit(data);
             break;
         }
       }
     } else {
@@ -69,17 +72,35 @@ PrefsProvider.prototype = {
   },
 
   /*
    * Return the preferences that are important to the newtab page
    */
   get newtabPagePrefs() {
     let results = {};
     for (let pref of gNewtabPagePrefs) {
-      results[pref] = Preferences.get(pref, null);
+      results[pref] = null;
+
+      if (Services.prefs.getPrefType(pref) != Ci.nsIPrefBranch.PREF_INVALID) {
+        switch (gPrefsMap.get(pref)) {
+          case "bool":
+            results[pref] = Services.prefs.getBoolPref(pref);
+            break;
+          case "str":
+            results[pref] = Services.prefs.getStringPref(pref);
+            break;
+          case "localized":
+            try {
+              results[pref] = Services.prefs.getComplexValue(pref, Ci.nsIPrefLocalizedString);
+            } catch (e) {
+              results[pref] = Services.prefs.getStringPref(pref);
+            }
+            break;
+        }
+      }
     }
     return results;
   },
 
   get prefsMap() {
     return gPrefsMap;
   },
 
--- a/browser/components/newtab/NewTabWebChannel.jsm
+++ b/browser/components/newtab/NewTabWebChannel.jsm
@@ -1,16 +1,15 @@
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["NewTabWebChannel"];
 
 const {utils: Cu} = Components;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
                                   "resource:///modules/NewTabPrefsProvider.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NewTabRemoteResources",
                                   "resource:///modules/NewTabRemoteResources.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "WebChannel",
                                   "resource://gre/modules/WebChannel.jsm");
 XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
@@ -240,19 +239,19 @@ NewTabWebChannelImpl.prototype = {
         break;
     }
   },
 
   /*
    * Sets up the internal state
    */
   setupState() {
-    this._prefs.enabled = Preferences.get(PREF_ENABLED, false);
+    this._prefs.enabled = Services.prefs.getBoolPref(PREF_ENABLED, false);
 
-    let mode = Preferences.get(PREF_MODE, "production");
+    let mode = Services.prefs.getStringPref(PREF_MODE, "production");
     if (!(mode in NewTabRemoteResources.MODE_CHANNEL_MAP)) {
       mode = "production";
     }
     this._prefs.mode = mode;
     this._principals = new WeakMap();
     this._browsers = new Set();
 
     if (this._prefs.enabled) {
--- a/browser/components/newtab/aboutNewTabService.js
+++ b/browser/components/newtab/aboutNewTabService.js
@@ -5,17 +5,18 @@
 */
 
 "use strict";
 
 const {utils: Cu, interfaces: Ci} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+                                  "resource://gre/modules/Preferences.jsm");
 
 const LOCAL_NEWTAB_URL = "chrome://browser/content/newtab/newTab.xhtml";
 
 const ACTIVITY_STREAM_URL = "resource://activity-stream/data/content/activity-stream.html";
 
 const ABOUT_URL = "about:newtab";
 
 // Pref that tells if activity stream is enabled
--- a/browser/components/newtab/tests/browser/browser_newtab_overrides.js
+++ b/browser/components/newtab/tests/browser/browser_newtab_overrides.js
@@ -1,14 +1,13 @@
 "use strict";
 
 let Cu = Components.utils;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 const PREF_NEWTAB_ACTIVITY_STREAM = "browser.newtabpage.activity-stream.enabled";
 
 Services.prefs.setBoolPref(PREF_NEWTAB_ACTIVITY_STREAM, false);
 
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -473,23 +473,20 @@ BrowserGlue.prototype = {
         let win = RecentWindow.getMostRecentBrowserWindow();
         win.BrowserSearch.recordSearchInTelemetry(engine, "urlbar");
         break;
       case "browser-search-engine-modified":
         // Ensure we cleanup the hiddenOneOffs pref when removing
         // an engine, and that newly added engines are visible.
         if (data == "engine-added" || data == "engine-removed") {
           let engineName = subject.QueryInterface(Ci.nsISearchEngine).name;
-          let Preferences =
-            Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
-          let pref = Preferences.get("browser.search.hiddenOneOffs");
+          let pref = Services.prefs.getStringPref("browser.search.hiddenOneOffs");
           let hiddenList = pref ? pref.split(",") : [];
           hiddenList = hiddenList.filter(x => x !== engineName);
-          Preferences.set("browser.search.hiddenOneOffs",
-                          hiddenList.join(","));
+          Services.prefs.setStringPref("browser.search.hiddenOneOffs", hiddenList.join(","));
         }
         break;
       case "flash-plugin-hang":
         this._handleFlashHang();
         break;
       case "xpi-signature-changed":
         let disabledAddons = JSON.parse(data).disabled;
         AddonManager.getAddonsByIDs(disabledAddons, (addons) => {
--- a/browser/components/originattributes/test/browser/browser_imageCacheIsolation.js
+++ b/browser/components/originattributes/test/browser/browser_imageCacheIsolation.js
@@ -13,21 +13,21 @@ const NUM_CACHED_LOADS = 1;
 let gHits = 0;
 
 let server = new HttpServer();
 server.registerPathHandler("/image.png", imageHandler);
 server.registerPathHandler("/file.html", fileHandler);
 server.start(-1);
 
 // Disable rcwn to make cache behavior deterministic.
-let rcwnEnabled = Preferences.get("network.http.rcwn.enabled");
-Preferences.set("network.http.rcwn.enabled", false);
+let rcwnEnabled = Services.prefs.getBoolPref("network.http.rcwn.enabled");
+Services.prefs.setBoolPref("network.http.rcwn.enabled", false);
 
 registerCleanupFunction(() => {
-  Preferences.set("network.http.rcwn.enabled", rcwnEnabled);
+  Services.prefs.setBoolPref("network.http.rcwn.enabled", rcwnEnabled);
 
   server.stop(() => {
     server = null;
   });
 });
 
 let BASE_URI = "http://localhost:" + server.identity.primaryPort;
 let IMAGE_URI = BASE_URI + "/image.png";
--- a/browser/components/selfsupport/SelfSupportService.js
+++ b/browser/components/selfsupport/SelfSupportService.js
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 
 const PREF_FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
 
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryArchive",
                                   "resource://gre/modules/TelemetryArchive.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryEnvironment",
                                   "resource://gre/modules/TelemetryEnvironment.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryController",
@@ -30,21 +29,21 @@ MozSelfSupportInterface.prototype = {
 
   _window: null,
 
   init(window) {
     this._window = window;
   },
 
   get healthReportDataSubmissionEnabled() {
-    return Preferences.get(PREF_FHR_UPLOAD_ENABLED, false);
+    return Services.prefs.getBoolPref(PREF_FHR_UPLOAD_ENABLED, false);
   },
 
   set healthReportDataSubmissionEnabled(enabled) {
-    Preferences.set(PREF_FHR_UPLOAD_ENABLED, enabled);
+    Services.prefs.setBoolPref(PREF_FHR_UPLOAD_ENABLED, enabled);
   },
 
   resetPref(name) {
     Services.prefs.clearUserPref(name);
   },
 
   resetSearchEngines() {
     Services.search.restoreDefaultEngines();
--- a/browser/components/selfsupport/test/browser_selfsupportAPI.js
+++ b/browser/components/selfsupport/test/browser_selfsupportAPI.js
@@ -1,49 +1,55 @@
-Cu.import("resource://gre/modules/Preferences.jsm");
+function prefHas(pref) {
+  return Services.prefs.getPrefType(pref) != Ci.nsIPrefBranch.PREF_INVALID;
+}
+
+function prefIsSet(pref) {
+  return Services.prefs.prefHasUserValue(pref);
+}
 
 function test_resetPref() {
   const prefNewName = "browser.newpref.fake";
-  Assert.ok(!Preferences.has(prefNewName), "pref should not exist");
+  Assert.ok(!prefHas(prefNewName), "pref should not exist");
 
   const prefExistingName = "extensions.hotfix.id";
-  Assert.ok(Preferences.has(prefExistingName), "pref should exist");
-  Assert.ok(!Preferences.isSet(prefExistingName), "pref should not be user-set");
-  let prefExistingOriginalValue = Preferences.get(prefExistingName);
+  Assert.ok(prefHas(prefExistingName), "pref should exist");
+  Assert.ok(!prefIsSet(prefExistingName), "pref should not be user-set");
+  let prefExistingOriginalValue = Services.prefs.getStringPref(prefExistingName);
 
   registerCleanupFunction(function() {
-    Preferences.set(prefExistingName, prefExistingOriginalValue);
+    Services.prefs.setStringPref(prefExistingName, prefExistingOriginalValue);
     Services.prefs.deleteBranch(prefNewName);
   });
 
   // 1. do nothing on an inexistent pref
   MozSelfSupport.resetPref(prefNewName);
-  Assert.ok(!Preferences.has(prefNewName), "pref should still not exist");
+  Assert.ok(!prefHas(prefNewName), "pref should still not exist");
 
   // 2. creation of a new pref
-  Preferences.set(prefNewName, 10);
-  Assert.ok(Preferences.has(prefNewName), "pref should exist");
-  Assert.equal(Preferences.get(prefNewName), 10, "pref value should be 10");
+  Services.prefs.setIntPref(prefNewName, 10);
+  Assert.ok(prefHas(prefNewName), "pref should exist");
+  Assert.equal(Services.prefs.getIntPref(prefNewName), 10, "pref value should be 10");
 
   MozSelfSupport.resetPref(prefNewName);
-  Assert.ok(!Preferences.has(prefNewName), "pref should not exist any more");
+  Assert.ok(!prefHas(prefNewName), "pref should not exist any more");
 
   // 3. do nothing on an unchanged existing pref
   MozSelfSupport.resetPref(prefExistingName);
-  Assert.ok(Preferences.has(prefExistingName), "pref should still exist");
-  Assert.equal(Preferences.get(prefExistingName), prefExistingOriginalValue, "pref value should be the same as original");
+  Assert.ok(prefHas(prefExistingName), "pref should still exist");
+  Assert.equal(Services.prefs.getStringPref(prefExistingName), prefExistingOriginalValue, "pref value should be the same as original");
 
   // 4. change the value of an existing pref
-  Preferences.set(prefExistingName, "anyone@mozilla.org");
-  Assert.ok(Preferences.has(prefExistingName), "pref should exist");
-  Assert.equal(Preferences.get(prefExistingName), "anyone@mozilla.org", "pref value should have changed");
+  Services.prefs.setStringPref(prefExistingName, "anyone@mozilla.org");
+  Assert.ok(prefHas(prefExistingName), "pref should exist");
+  Assert.equal(Services.prefs.getStringPref(prefExistingName), "anyone@mozilla.org", "pref value should have changed");
 
   MozSelfSupport.resetPref(prefExistingName);
-  Assert.ok(Preferences.has(prefExistingName), "pref should still exist");
-  Assert.equal(Preferences.get(prefExistingName), prefExistingOriginalValue, "pref value should be the same as original");
+  Assert.ok(prefHas(prefExistingName), "pref should still exist");
+  Assert.equal(Services.prefs.getStringPref(prefExistingName), prefExistingOriginalValue, "pref value should be the same as original");
 
   // 5. delete an existing pref
   // deleteBranch is implemented in such a way that
   // clearUserPref can't undo its action
   // see discussion in bug 1075160
 }
 
 function test_resetSearchEngines() {
--- a/browser/components/sessionstore/SessionFile.jsm
+++ b/browser/components/sessionstore/SessionFile.jsm
@@ -29,17 +29,16 @@ const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://gre/modules/AsyncShutdown.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "console",
   "resource://gre/modules/Console.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
   "resource://gre/modules/PromiseUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "RunState",
   "resource:///modules/sessionstore/RunState.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
@@ -298,19 +297,19 @@ var SessionFileInternal = {
       };
     }
 
     result.noFilesFound = noFilesFound;
 
     // Initialize the worker (in the background) to let it handle backups and also
     // as a workaround for bug 964531.
     let promiseInitialized = SessionWorker.post("init", [result.origin, result.useOldExtension, this.Paths, {
-      maxUpgradeBackups: Preferences.get(PREF_MAX_UPGRADE_BACKUPS, 3),
-      maxSerializeBack: Preferences.get(PREF_MAX_SERIALIZE_BACK, 10),
-      maxSerializeForward: Preferences.get(PREF_MAX_SERIALIZE_FWD, -1)
+      maxUpgradeBackups: Services.prefs.getIntPref(PREF_MAX_UPGRADE_BACKUPS, 3),
+      maxSerializeBack: Services.prefs.getIntPref(PREF_MAX_SERIALIZE_BACK, 10),
+      maxSerializeForward: Services.prefs.getIntPref(PREF_MAX_SERIALIZE_FWD, -1)
     }]);
 
     promiseInitialized.catch(err => {
       // Ensure that we report errors but that they do not stop us.
       Promise.reject(err);
     }).then(() => this._deferredInitialized.resolve());
 
     return result;
--- a/browser/components/sessionstore/content/content-sessionStore.js
+++ b/browser/components/sessionstore/content/content-sessionStore.js
@@ -19,18 +19,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
   "resource://gre/modules/TelemetryStopwatch.jsm");
 
 function debug(msg) {
   Services.console.logStringMessage("SessionStoreContent: " + msg);
 }
 
 XPCOMUtils.defineLazyModuleGetter(this, "FormData",
   "resource://gre/modules/FormData.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
-  "resource://gre/modules/Preferences.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "DocShellCapabilities",
   "resource:///modules/sessionstore/DocShellCapabilities.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ScrollPosition",
   "resource://gre/modules/ScrollPosition.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "SessionHistory",
   "resource://gre/modules/sessionstore/SessionHistory.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
@@ -560,17 +558,17 @@ var SessionStorageListener = {
     // How much data does DOMSessionStorage contain?
     let usage = content.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIDOMWindowUtils)
                        .getStorageUsage(event.storageArea);
     Services.telemetry.getHistogramById("FX_SESSION_RESTORE_DOM_STORAGE_SIZE_ESTIMATE_CHARS").add(usage);
 
     // Don't store any data if we exceed the limit. Wipe any data we previously
     // collected so that we don't confuse websites with partial state.
-    if (usage > Preferences.get(DOM_STORAGE_LIMIT_PREF)) {
+    if (usage > Services.prefs.getIntPref(DOM_STORAGE_LIMIT_PREF)) {
       MessageQueue.push("storage", () => null);
       return;
     }
 
     let {url, key, newValue} = event;
     let uri = Services.io.newURI(url);
     let domain = uri.prePath;
     if (!this._changes) {
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -6,17 +6,16 @@
 
 this.EXPORTED_SYMBOLS = ["UITour"];
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/TelemetryController.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 
 Cu.importGlobalProperties(["URL"]);
 
 XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
   "resource://gre/modules/LightweightThemeManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ResetProfile",
@@ -1536,19 +1535,19 @@ this.UITour = {
             data = {engines: [], searchEngineIdentifier: ""};
           }
           this.sendPageCallback(aMessageManager, aCallbackID, data);
         });
         break;
       case "sync":
         this.sendPageCallback(aMessageManager, aCallbackID, {
           setup: Services.prefs.prefHasUserValue("services.sync.username"),
-          desktopDevices: Preferences.get("services.sync.clients.devices.desktop", 0),
-          mobileDevices: Preferences.get("services.sync.clients.devices.mobile", 0),
-          totalDevices: Preferences.get("services.sync.numClients", 0),
+          desktopDevices: Services.prefs.getIntPref("services.sync.clients.devices.desktop", 0),
+          mobileDevices: Services.prefs.getIntPref("services.sync.clients.devices.mobile", 0),
+          totalDevices: Services.prefs.getIntPref("services.sync.numClients", 0),
         });
         break;
       case "canReset":
         this.sendPageCallback(aMessageManager, aCallbackID, ResetProfile.resetSupported());
         break;
       default:
         log.error("getConfiguration: Unknown configuration requested: " + aConfiguration);
         break;
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -9,17 +9,16 @@ this.EXPORTED_SYMBOLS = [
 ];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/AsyncShutdown.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
                                   "resource://gre/modules/UpdateUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
                                   "resource://gre/modules/AddonManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
                                   "resource://gre/modules/AddonManager.jsm");
@@ -33,32 +32,32 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://services-common/utils.js");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
                                    "@mozilla.org/xre/app-info;1",
                                    "nsICrashReporter");
 
 const FILE_CACHE                = "experiments.json";
 const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed";
+const PREF_CHANGED_TOPIC        = "nsPref:changed";
 const MANIFEST_VERSION          = 1;
 const CACHE_VERSION             = 1;
 
 const KEEP_HISTORY_N_DAYS       = 180;
 
 const PREF_BRANCH               = "experiments.";
 const PREF_ENABLED              = "enabled"; // experiments.enabled
 const PREF_ACTIVE_EXPERIMENT    = "activeExperiment"; // whether we have an active experiment
 const PREF_LOGGING              = "logging";
 const PREF_LOGGING_LEVEL        = PREF_LOGGING + ".level"; // experiments.logging.level
 const PREF_LOGGING_DUMP         = PREF_LOGGING + ".dump"; // experiments.logging.dump
 const PREF_MANIFEST_URI         = "manifest.uri"; // experiments.logging.manifest.uri
 const PREF_FORCE_SAMPLE         = "force-sample-value"; // experiments.force-sample-value
 
-const PREF_BRANCH_TELEMETRY     = "toolkit.telemetry.";
-const PREF_TELEMETRY_ENABLED    = "enabled";
+const PREF_TELEMETRY_ENABLED      = "toolkit.telemetry.enabled";
 
 const URI_EXTENSION_STRINGS     = "chrome://mozapps/locale/extensions/extensions.properties";
 const STRING_TYPE_NAME          = "type.%ID%.name";
 
 const CACHE_WRITE_RETRY_DELAY_SEC = 60 * 3;
 const MANIFEST_FETCH_TIMEOUT_MSEC = 60 * 3 * 1000; // 3 minutes
 
 const TELEMETRY_LOG = {
@@ -87,18 +86,17 @@ const TELEMETRY_LOG = {
     EXPIRED: "EXPIRED",
     // Disabled after re-evaluating conditions. If this is specified,
     // details will be provided.
     RECHECK: "RECHECK",
   },
 };
 XPCOMUtils.defineConstant(this, "TELEMETRY_LOG", TELEMETRY_LOG);
 
-const gPrefs = new Preferences(PREF_BRANCH);
-const gPrefsTelemetry = new Preferences(PREF_BRANCH_TELEMETRY);
+const gPrefs = Services.prefs.getBranch(PREF_BRANCH);
 var gExperimentsEnabled = false;
 var gAddonProvider = null;
 var gExperiments = null;
 var gLogAppenderDump = null;
 var gPolicyCounter = 0;
 var gExperimentsCounter = 0;
 var gExperimentEntryCounter = 0;
 var gPreviousProviderCounter = 0;
@@ -114,19 +112,19 @@ var gActiveUninstallAddonIDs = new Set()
 var gLogger;
 var gLogDumping = false;
 
 function configureLogging() {
   if (!gLogger) {
     gLogger = Log.repository.getLogger("Browser.Experiments");
     gLogger.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()));
   }
-  gLogger.level = gPrefs.get(PREF_LOGGING_LEVEL, Log.Level.Warn);
+  gLogger.level = gPrefs.getIntPref(PREF_LOGGING_LEVEL, Log.Level.Warn);
 
-  let logDumping = gPrefs.get(PREF_LOGGING_DUMP, false);
+  let logDumping = gPrefs.getBoolPref(PREF_LOGGING_DUMP, false);
   if (logDumping != gLogDumping) {
     if (logDumping) {
       gLogAppenderDump = new Log.DumpAppender(new Log.BasicFormatter());
       gLogger.addAppender(gLogAppenderDump);
     } else {
       gLogger.removeAppender(gLogAppenderDump);
       gLogAppenderDump = null;
     }
@@ -246,17 +244,17 @@ Experiments.Policy = function() {
 };
 
 Experiments.Policy.prototype = {
   now() {
     return new Date();
   },
 
   random() {
-    let pref = gPrefs.get(PREF_FORCE_SAMPLE);
+    let pref = gPrefs.getStringPref(PREF_FORCE_SAMPLE, undefined);
     if (pref !== undefined) {
       let val = Number.parseFloat(pref);
       this._log.debug("random sample forced: " + val);
       if (isNaN(val) || val < 0) {
         return 0;
       }
       if (val > 1) {
         return 1;
@@ -367,38 +365,52 @@ Experiments.Experiments = function(polic
   // We need to tell when we first evaluated the experiments to fire an
   // experiments-changed notification when we only loaded completed experiments.
   this._firstEvaluate = true;
 
   this.init();
 };
 
 Experiments.Experiments.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback, Ci.nsIObserver]),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback, Ci.nsIObserver, Ci.nsISupportsWeakReference]),
 
   /**
    * `true` if the experiments manager is currently setup (has been fully initialized
    * and not uninitialized yet).
    */
   get isReady() {
     return !this._shutdown;
   },
 
+  observe(subject, topic, data) {
+    switch (topic) {
+      case PREF_CHANGED_TOPIC:
+        if (data == PREF_BRANCH + PREF_MANIFEST_URI) {
+          this.updateManifest();
+        } else if (data == PREF_BRANCH + PREF_ENABLED) {
+          this._toggleExperimentsEnabled(gPrefs.getBoolPref(PREF_ENABLED, false));
+        } else if (data == PREF_TELEMETRY_ENABLED) {
+          this._telemetryStatusChanged();
+        }
+        break;
+    }
+  },
+
   init() {
     this._shutdown = false;
     configureLogging();
 
-    gExperimentsEnabled = gPrefs.get(PREF_ENABLED, false) && TelemetryUtils.isTelemetryEnabled;
+    gExperimentsEnabled = gPrefs.getBoolPref(PREF_ENABLED, false) && TelemetryUtils.isTelemetryEnabled;
     this._log.trace("enabled=" + gExperimentsEnabled + ", " + this.enabled);
 
-    gPrefs.observe(PREF_LOGGING, configureLogging);
-    gPrefs.observe(PREF_MANIFEST_URI, this.updateManifest, this);
-    gPrefs.observe(PREF_ENABLED, this._toggleExperimentsEnabled, this);
+    Services.prefs.addObserver(PREF_BRANCH + PREF_LOGGING, configureLogging);
+    Services.prefs.addObserver(PREF_BRANCH + PREF_MANIFEST_URI, this, true);
+    Services.prefs.addObserver(PREF_BRANCH + PREF_ENABLED, this, true);
 
-    gPrefsTelemetry.observe(PREF_TELEMETRY_ENABLED, this._telemetryStatusChanged, this);
+    Services.prefs.addObserver(PREF_TELEMETRY_ENABLED, this, true);
 
     AddonManager.shutdown.addBlocker("Experiments.jsm shutdown",
       this.uninit.bind(this),
       this._getState.bind(this)
     );
 
     this._registerWithAddonManager();
 
@@ -433,21 +445,21 @@ Experiments.Experiments.prototype = {
     this._log.trace("uninit: started");
     await this._loadTask;
     this._log.trace("uninit: finished with _loadTask");
 
     if (!this._shutdown) {
       this._log.trace("uninit: no previous shutdown");
       this._unregisterWithAddonManager();
 
-      gPrefs.ignore(PREF_LOGGING, configureLogging);
-      gPrefs.ignore(PREF_MANIFEST_URI, this.updateManifest, this);
-      gPrefs.ignore(PREF_ENABLED, this._toggleExperimentsEnabled, this);
+      Services.prefs.removeObserver(PREF_BRANCH + PREF_LOGGING, configureLogging);
+      Services.prefs.removeObserver(PREF_BRANCH + PREF_MANIFEST_URI, this);
+      Services.prefs.removeObserver(PREF_BRANCH + PREF_ENABLED, this);
 
-      gPrefsTelemetry.ignore(PREF_TELEMETRY_ENABLED, this._telemetryStatusChanged, this);
+      Services.prefs.removeObserver(PREF_TELEMETRY_ENABLED, this);
 
       if (this._timer) {
         this._timer.clear();
       }
     }
 
     this._shutdown = true;
     if (this._mainTask) {
@@ -576,17 +588,17 @@ Experiments.Experiments.prototype = {
     return gExperimentsEnabled;
   },
 
   /**
    * Toggle whether the experiments feature is enabled or not.
    */
   set enabled(enabled) {
     this._log.trace("set enabled(" + enabled + ")");
-    gPrefs.set(PREF_ENABLED, enabled);
+    gPrefs.setBoolPref(PREF_ENABLED, enabled);
   },
 
   async _toggleExperimentsEnabled(enabled) {
     this._log.trace("_toggleExperimentsEnabled(" + enabled + ")");
     let wasEnabled = gExperimentsEnabled;
     gExperimentsEnabled = enabled && TelemetryUtils.isTelemetryEnabled;
 
     if (wasEnabled == gExperimentsEnabled) {
@@ -599,17 +611,17 @@ Experiments.Experiments.prototype = {
       await this.disableExperiment(TELEMETRY_LOG.TERMINATION.SERVICE_DISABLED);
       if (this._timer) {
         this._timer.clear();
       }
     }
   },
 
   _telemetryStatusChanged() {
-    this._toggleExperimentsEnabled(gPrefs.get(PREF_ENABLED, false));
+    this._toggleExperimentsEnabled(gPrefs.getBoolPref(PREF_ENABLED, false));
   },
 
   /**
    * Returns a promise that is resolved with an array of `ExperimentInfo` objects,
    * which provide info on the currently and recently active experiments.
    * The array is in chronological order.
    *
    * The experiment info is of the form:
@@ -1218,17 +1230,17 @@ Experiments.Experiments.prototype = {
       await uninstallAddons(unknownAddons);
     }
 
     let activeExperiment = this._getActiveExperiment();
     let activeChanged = false;
 
     if (!activeExperiment) {
       // Avoid this pref staying out of sync if there were e.g. crashes.
-      gPrefs.set(PREF_ACTIVE_EXPERIMENT, false);
+      gPrefs.setBoolPref(PREF_ACTIVE_EXPERIMENT, false);
     }
 
     // Ensure the active experiment is in the proper state. This may install,
     // uninstall, upgrade, or enable the experiment add-on. What exactly is
     // abstracted away from us by design.
     if (activeExperiment) {
       let changes;
       let shouldStopResult = await activeExperiment.shouldStop();
@@ -1298,17 +1310,17 @@ Experiments.Experiments.prototype = {
           // On failure, clean up the best we can and try the next experiment.
           this._log.error("evaluateExperiments() - Unable to start experiment: " + e.message);
           experiment._enabled = false;
           await experiment.reconcileAddonState();
         }
       }
     }
 
-    gPrefs.set(PREF_ACTIVE_EXPERIMENT, activeExperiment != null);
+    gPrefs.setBoolPref(PREF_ACTIVE_EXPERIMENT, activeExperiment != null);
 
     if (activeChanged || this._firstEvaluate) {
       Services.obs.notifyObservers(null, EXPERIMENTS_CHANGED_TOPIC);
       this._firstEvaluate = false;
     }
 
     if ("@mozilla.org/toolkit/crash-reporter;1" in Cc && activeExperiment) {
       try {
--- a/browser/experiments/ExperimentsService.js
+++ b/browser/experiments/ExperimentsService.js
@@ -3,55 +3,44 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Experiments",
                                   "resource:///modules/experiments/Experiments.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",
                                   "resource://services-common/utils.js");
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryUtils",
                                   "resource://gre/modules/TelemetryUtils.jsm");
 
 
 const PREF_EXPERIMENTS_ENABLED  = "experiments.enabled";
 const PREF_ACTIVE_EXPERIMENT    = "experiments.activeExperiment"; // whether we have an active experiment
 const DELAY_INIT_MS             = 30 * 1000;
 
-XPCOMUtils.defineLazyGetter(
-  this, "gPrefs", () => {
-    return new Preferences();
-  });
-
-XPCOMUtils.defineLazyGetter(
-  this, "gActiveExperiment", () => {
-    return gPrefs.get(PREF_ACTIVE_EXPERIMENT);
-  });
-
 function ExperimentsService() {
   this._initialized = false;
   this._delayedInitTimer = null;
 }
 
 ExperimentsService.prototype = {
   classID: Components.ID("{f7800463-3b97-47f9-9341-b7617e6d8d49}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback, Ci.nsIObserver]),
 
   get _experimentsEnabled() {
     // We can enable experiments if either unified Telemetry or FHR is on, and the user
     // has opted into Telemetry.
-    return gPrefs.get(PREF_EXPERIMENTS_ENABLED, false) &&
+    return Services.prefs.getBoolPref(PREF_EXPERIMENTS_ENABLED, false) &&
            TelemetryUtils.isTelemetryEnabled;
   },
 
   notify(timer) {
     if (!this._experimentsEnabled) {
       return;
     }
     if (OS.Constants.Path.profileDir === undefined) {
@@ -77,17 +66,17 @@ ExperimentsService.prototype = {
   observe(subject, topic, data) {
     switch (topic) {
       case "profile-after-change":
         if (this._experimentsEnabled) {
           Services.obs.addObserver(this, "quit-application");
           Services.obs.addObserver(this, "sessionstore-state-finalized");
           Services.obs.addObserver(this, "EM-loaded");
 
-          if (gActiveExperiment) {
+          if (Services.prefs.getBoolPref(PREF_ACTIVE_EXPERIMENT, false)) {
             this._initialized = true;
             Experiments.instance(); // for side effects
           }
         }
         break;
       case "sessionstore-state-finalized":
         if (!this._initialized) {
           CommonUtils.namedTimer(this._delayedInit, DELAY_INIT_MS, this, "_delayedInitTimer");
--- a/browser/extensions/shield-recipe-client/test/browser/browser_ClientEnvironment.js
+++ b/browser/extensions/shield-recipe-client/test/browser/browser_ClientEnvironment.js
@@ -1,17 +1,14 @@
 "use strict";
 
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/TelemetryController.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/ClientEnvironment.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/PreferenceExperiments.jsm", this);
 
-
 add_task(async function testTelemetry() {
   // setup
   await TelemetryController.submitExternalPing("testfoo", {foo: 1});
   await TelemetryController.submitExternalPing("testbar", {bar: 2});
   const environment = ClientEnvironment.getEnvironment();
 
   // Test it can access telemetry
   const telemetry = await environment.telemetry;
--- a/browser/extensions/shield-recipe-client/test/browser/browser_RecipeRunner.js
+++ b/browser/extensions/shield-recipe-client/test/browser/browser_RecipeRunner.js
@@ -1,11 +1,10 @@
 "use strict";
 
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://shield-recipe-client/lib/RecipeRunner.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/ClientEnvironment.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/CleanupManager.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/NormandyApi.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/ActionSandboxManager.jsm", this);
 
 add_task(async function getFilterContext() {
   const recipe = {id: 17, arguments: {foo: "bar"}, unrelated: false};
--- a/browser/extensions/shield-recipe-client/test/browser/head.js
+++ b/browser/extensions/shield-recipe-client/test/browser/head.js
@@ -1,12 +1,12 @@
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 
-Cu.import("resource://gre/modules/Preferences.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/SandboxManager.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/NormandyDriver.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/NormandyApi.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/Utils.jsm", this);
 
 // Load mocking/stubbing library, sinon
 // docs: http://sinonjs.org/docs/
 const loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -1637,35 +1637,39 @@ nsScriptSecurityManager::EnsureFileURIWh
 
     //
     // Rebuild the set of principals for which we allow file:// URI loads. This
     // implements a small subset of an old pref-based CAPS people that people
     // have come to depend on. See bug 995943.
     //
 
     mFileURIWhitelist.emplace();
-    auto policies = mozilla::Preferences::GetCString("capability.policy.policynames");
+    nsAutoCString policies;
+    mozilla::Preferences::GetCString("capability.policy.policynames", policies);
     for (uint32_t base = SkipPast<IsWhitespaceOrComma>(policies, 0), bound = 0;
          base < policies.Length();
          base = SkipPast<IsWhitespaceOrComma>(policies, bound))
     {
         // Grab the current policy name.
         bound = SkipUntil<IsWhitespaceOrComma>(policies, base);
         auto policyName = Substring(policies, base, bound - base);
 
         // Figure out if this policy allows loading file:// URIs. If not, we can skip it.
         nsCString checkLoadURIPrefName = NS_LITERAL_CSTRING("capability.policy.") +
                                          policyName +
                                          NS_LITERAL_CSTRING(".checkloaduri.enabled");
-        if (!Preferences::GetString(checkLoadURIPrefName.get()).LowerCaseEqualsLiteral("allaccess")) {
+        nsAutoString value;
+        nsresult rv = Preferences::GetString(checkLoadURIPrefName.get(), value);
+        if (NS_FAILED(rv) || !value.LowerCaseEqualsLiteral("allaccess")) {
             continue;
         }
 
         // Grab the list of domains associated with this policy.
         nsCString domainPrefName = NS_LITERAL_CSTRING("capability.policy.") +
                                    policyName +
                                    NS_LITERAL_CSTRING(".sites");
-        auto siteList = Preferences::GetCString(domainPrefName.get());
+        nsAutoCString siteList;
+        Preferences::GetCString(domainPrefName.get(), siteList);
         AddSitesToFileURIWhitelist(siteList);
     }
 
     return mFileURIWhitelist.ref();
 }
--- a/chrome/nsChromeRegistryChrome.cpp
+++ b/chrome/nsChromeRegistryChrome.cpp
@@ -246,21 +246,22 @@ nsChromeRegistryChrome::GetSelectedLocal
   return NS_OK;
 }
 
 nsresult
 nsChromeRegistryChrome::OverrideLocalePackage(const nsACString& aPackage,
                                               nsACString& aOverride)
 {
   const nsACString& pref = NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
-  nsAdoptingCString override = mozilla::Preferences::GetCString(PromiseFlatCString(pref).get());
-  if (override) {
+  nsAutoCString override;
+  nsresult rv =
+    mozilla::Preferences::GetCString(PromiseFlatCString(pref).get(), override);
+  if (NS_SUCCEEDED(rv)) {
     aOverride = override;
-  }
-  else {
+  } else {
     aOverride = aPackage;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsChromeRegistryChrome::Observe(nsISupports *aSubject, const char *aTopic,
                                 const char16_t *someData)
--- a/docshell/base/nsDefaultURIFixup.cpp
+++ b/docshell/base/nsDefaultURIFixup.cpp
@@ -573,26 +573,27 @@ nsDefaultURIFixup::MakeAlternateURI(nsIU
     }
     ++iter;
   }
 
   // Get the prefix and suffix to stick onto the new hostname. By default these
   // are www. & .com but they could be any other value, e.g. www. & .org
 
   nsAutoCString prefix("www.");
-  nsAdoptingCString prefPrefix =
-    Preferences::GetCString("browser.fixup.alternate.prefix");
-  if (prefPrefix) {
+  nsAutoCString prefPrefix;
+  nsresult rv =
+    Preferences::GetCString("browser.fixup.alternate.prefix", prefPrefix);
+  if (NS_SUCCEEDED(rv)) {
     prefix.Assign(prefPrefix);
   }
 
   nsAutoCString suffix(".com");
-  nsAdoptingCString prefSuffix =
-    Preferences::GetCString("browser.fixup.alternate.suffix");
-  if (prefSuffix) {
+  nsAutoCString prefSuffix;
+  rv = Preferences::GetCString("browser.fixup.alternate.suffix", prefSuffix);
+  if (NS_SUCCEEDED(rv)) {
     suffix.Assign(prefSuffix);
   }
 
   if (numDots == 0) {
     newHost.Assign(prefix);
     newHost.Append(oldHost);
     newHost.Append(suffix);
   } else if (numDots == 1) {
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -5094,19 +5094,21 @@ nsDocShell::DisplayLoadError(nsresult aE
           // measuring STS separately allows us to measure click through
           // rates easily
           bucketId = nsISecurityUITelemetry::WARNING_BAD_CERT_TOP_STS;
         } else {
           bucketId = nsISecurityUITelemetry::WARNING_BAD_CERT_TOP;
         }
 
         // See if an alternate cert error page is registered
-        nsAdoptingCString alternateErrorPage =
-          Preferences::GetCString("security.alternate_certificate_error_page");
-        if (alternateErrorPage) {
+        nsAutoCString alternateErrorPage;
+        nsresult rv =
+          Preferences::GetCString("security.alternate_certificate_error_page",
+                                  alternateErrorPage);
+        if (NS_SUCCEEDED(rv)) {
           errorPage.Assign(alternateErrorPage);
         }
 
         if (!IsFrame() && errorPage.EqualsIgnoreCase("certerror")) {
           Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, bucketId);
         }
 
       } else {
@@ -5118,19 +5120,20 @@ nsDocShell::DisplayLoadError(nsresult aE
              NS_ERROR_UNWANTED_URI == aError) {
     nsAutoCString host;
     aURI->GetHost(host);
     CopyUTF8toUTF16(host, formatStrs[0]);
     formatStrCount = 1;
 
     // Malware and phishing detectors may want to use an alternate error
     // page, but if the pref's not set, we'll fall back on the standard page
-    nsAdoptingCString alternateErrorPage =
-      Preferences::GetCString("urlclassifier.alternate_error_page");
-    if (alternateErrorPage) {
+    nsAutoCString alternateErrorPage;
+    nsresult rv = Preferences::GetCString("urlclassifier.alternate_error_page",
+                                          alternateErrorPage);
+    if (NS_SUCCEEDED(rv)) {
       errorPage.Assign(alternateErrorPage);
     }
 
     uint32_t bucketId;
     bool sendTelemetry = false;
     if (NS_ERROR_PHISHING_URI == aError) {
       sendTelemetry = true;
       error = "deceptiveBlocked";
--- a/dom/audiochannel/AudioChannelAgent.cpp
+++ b/dom/audiochannel/AudioChannelAgent.cpp
@@ -113,19 +113,20 @@ AudioChannelAgent::FindCorrectWindow(nsP
   if (!doc) {
     return NS_OK;
   }
 
   if (nsContentUtils::IsChromeDoc(doc)) {
     return NS_OK;
   }
 
-  nsAdoptingCString systemAppUrl =
-    mozilla::Preferences::GetCString("b2g.system_startup_url");
-  if (!systemAppUrl) {
+  nsAutoCString systemAppUrl;
+  nsresult rv =
+    mozilla::Preferences::GetCString("b2g.system_startup_url", systemAppUrl);
+  if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
   nsCOMPtr<nsIURI> uri;
   principal->GetURI(getter_AddRefs(uri));
 
   if (uri) {
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -558,17 +558,18 @@ AudioChannelService::GetAudioChannel(con
   }
 
   return AudioChannel::Normal;
 }
 
 /* static */ AudioChannel
 AudioChannelService::GetDefaultAudioChannel()
 {
-  nsAutoString audioChannel(Preferences::GetString("media.defaultAudioChannel"));
+  nsAutoString audioChannel;
+  Preferences::GetString("media.defaultAudioChannel", audioChannel);
   if (audioChannel.IsEmpty()) {
     return AudioChannel::Normal;
   }
 
   for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].tag; ++i) {
     if (audioChannel.EqualsASCII(kMozAudioChannelAttributeTable[i].tag)) {
       return static_cast<AudioChannel>(kMozAudioChannelAttributeTable[i].value);
     }
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -374,18 +374,18 @@ Navigator::GetAppName(nsAString& aAppNam
 /* static */ void
 Navigator::GetAcceptLanguages(nsTArray<nsString>& aLanguages)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   aLanguages.Clear();
 
   // E.g. "de-de, en-us,en".
-  const nsAdoptingString& acceptLang =
-    Preferences::GetLocalizedString("intl.accept_languages");
+  nsAutoString acceptLang;
+  Preferences::GetLocalizedString("intl.accept_languages", acceptLang);
 
   // Split values on commas.
   nsCharSeparatedTokenizer langTokenizer(acceptLang, ',');
   while (langTokenizer.hasMoreTokens()) {
     nsDependentSubstring lang = langTokenizer.nextToken();
 
     // Replace "_" with "-" to avoid POSIX/Windows "en_US" notation.
     // NOTE: we should probably rely on the pref being set correctly.
@@ -468,20 +468,19 @@ Navigator::GetOscpu(nsAString& aOSCPU, C
   if (aCallerType != CallerType::System) {
     // If fingerprinting resistance is on, we will spoof this value. See nsRFPService.h
     // for details about spoofed values.
     if (nsContentUtils::ShouldResistFingerprinting()) {
       aOSCPU.AssignLiteral(SPOOFED_OSCPU);
       return;
     }
 
-    const nsAdoptingString& override =
-      Preferences::GetString("general.oscpu.override");
-
-    if (override) {
+    nsAutoString override;
+    nsresult rv = Preferences::GetString("general.oscpu.override", override);
+    if (NS_SUCCEEDED(rv)) {
       aOSCPU = override;
       return;
     }
   }
 
   nsresult rv;
   nsCOMPtr<nsIHttpProtocolHandler>
     service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
@@ -648,20 +647,19 @@ Navigator::GetBuildID(nsAString& aBuildI
 {
   if (aCallerType != CallerType::System) {
     // If fingerprinting resistance is on, we will spoof this value. See nsRFPService.h
     // for details about spoofed values.
     if (nsContentUtils::ShouldResistFingerprinting()) {
       aBuildID.AssignLiteral(LEGACY_BUILD_ID);
       return;
     }
-    const nsAdoptingString& override =
-      Preferences::GetString("general.buildID.override");
-
-    if (override) {
+    nsAutoString override;
+    nsresult rv = Preferences::GetString("general.buildID.override", override);
+    if (NS_SUCCEEDED(rv)) {
       aBuildID = override;
       return;
     }
   }
 
   nsCOMPtr<nsIXULAppInfo> appInfo =
     do_GetService("@mozilla.org/xre/app-info;1");
   if (!appInfo) {
@@ -699,17 +697,18 @@ Navigator::GetDoNotTrack(nsAString &aRes
 }
 
 bool
 Navigator::JavaEnabled(CallerType aCallerType, ErrorResult& aRv)
 {
   Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer;
 
   // Return true if we have a handler for the java mime
-  nsAdoptingString javaMIME = Preferences::GetString("plugin.java.mime");
+  nsAutoString javaMIME;
+  Preferences::GetString("plugin.java.mime", javaMIME);
   NS_ENSURE_TRUE(!javaMIME.IsEmpty(), false);
 
   if (!mMimeTypes) {
     if (!mWindow) {
       aRv.Throw(NS_ERROR_UNEXPECTED);
       return false;
     }
     mMimeTypes = new nsMimeTypeArray(mWindow);
@@ -1778,20 +1777,21 @@ Navigator::GetPlatform(nsAString& aPlatf
 
   if (aUsePrefOverriddenValue) {
     // If fingerprinting resistance is on, we will spoof this value. See nsRFPService.h
     // for details about spoofed values.
     if (nsContentUtils::ShouldResistFingerprinting()) {
       aPlatform.AssignLiteral(SPOOFED_PLATFORM);
       return NS_OK;
     }
-    const nsAdoptingString& override =
-      mozilla::Preferences::GetString("general.platform.override");
+    nsAutoString override;
+    nsresult rv =
+      mozilla::Preferences::GetString("general.platform.override", override);
 
-    if (override) {
+    if (NS_SUCCEEDED(rv)) {
       aPlatform = override;
       return NS_OK;
     }
   }
 
   nsresult rv;
 
   nsCOMPtr<nsIHttpProtocolHandler>
@@ -1829,20 +1829,21 @@ Navigator::GetAppVersion(nsAString& aApp
 
   if (aUsePrefOverriddenValue) {
     // If fingerprinting resistance is on, we will spoof this value. See nsRFPService.h
     // for details about spoofed values.
     if (nsContentUtils::ShouldResistFingerprinting()) {
       aAppVersion.AssignLiteral(SPOOFED_APPVERSION);
       return NS_OK;
     }
-    const nsAdoptingString& override =
-      mozilla::Preferences::GetString("general.appversion.override");
+    nsAutoString override;
+    nsresult rv =
+      mozilla::Preferences::GetString("general.appversion.override", override);
 
-    if (override) {
+    if (NS_SUCCEEDED(rv)) {
       aAppVersion = override;
       return NS_OK;
     }
   }
 
   nsresult rv;
 
   nsCOMPtr<nsIHttpProtocolHandler>
@@ -1873,20 +1874,21 @@ Navigator::AppName(nsAString& aAppName, 
   if (aUsePrefOverriddenValue) {
     // If fingerprinting resistance is on, we will spoof this value. See nsRFPService.h
     // for details about spoofed values.
     if (nsContentUtils::ShouldResistFingerprinting()) {
       aAppName.AssignLiteral(SPOOFED_APPNAME);
       return;
     }
 
-    const nsAdoptingString& override =
-      mozilla::Preferences::GetString("general.appname.override");
+    nsAutoString override;
+    nsresult rv =
+      mozilla::Preferences::GetString("general.appname.override", override);
 
-    if (override) {
+    if (NS_SUCCEEDED(rv)) {
       aAppName = override;
       return;
     }
   }
 
   aAppName.AssignLiteral("Netscape");
 }
 
@@ -1902,20 +1904,21 @@ Navigator::GetUserAgent(nsPIDOMWindowInn
                         nsAString& aUserAgent)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // We will skip the override and pass to httpHandler to get spoofed userAgent
   // when 'privacy.resistFingerprinting' is true.
   if (!aIsCallerChrome &&
       !nsContentUtils::ShouldResistFingerprinting()) {
-    const nsAdoptingString& override =
-      mozilla::Preferences::GetString("general.useragent.override");
+    nsAutoString override;
+    nsresult rv =
+      mozilla::Preferences::GetString("general.useragent.override", override);
 
-    if (override) {
+    if (NS_SUCCEEDED(rv)) {
       aUserAgent = override;
       return NS_OK;
     }
   }
 
   nsresult rv;
   nsCOMPtr<nsIHttpProtocolHandler>
     service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2701,19 +2701,17 @@ nsContentUtils::GetCommonAncestor(nsIDOM
 }
 
 template <typename Node, typename GetParentFunc>
 static Node*
 GetCommonAncestorInternal(Node* aNode1,
                           Node* aNode2,
                           GetParentFunc aGetParentFunc)
 {
-  if (aNode1 == aNode2) {
-    return aNode1;
-  }
+  MOZ_ASSERT(aNode1 != aNode2);
 
   // Build the chain of parents
   AutoTArray<Node*, 30> parents1, parents2;
   do {
     parents1.AppendElement(aNode1);
     aNode1 = aGetParentFunc(aNode1);
   } while (aNode1);
   do {
@@ -2735,27 +2733,27 @@ GetCommonAncestorInternal(Node* aNode1,
     parent = child1;
   }
 
   return parent;
 }
 
 /* static */
 nsINode*
-nsContentUtils::GetCommonAncestor(nsINode* aNode1, nsINode* aNode2)
+nsContentUtils::GetCommonAncestorHelper(nsINode* aNode1, nsINode* aNode2)
 {
   return GetCommonAncestorInternal(aNode1, aNode2, [](nsINode* aNode) {
     return aNode->GetParentNode();
   });
 }
 
 /* static */
 nsIContent*
-nsContentUtils::GetCommonFlattenedTreeAncestor(nsIContent* aContent1,
-                                               nsIContent* aContent2)
+nsContentUtils::GetCommonFlattenedTreeAncestorHelper(nsIContent* aContent1,
+                                                     nsIContent* aContent2)
 {
   return GetCommonAncestorInternal(aContent1, aContent2, [](nsIContent* aContent) {
     return aContent->GetFlattenedTreeParent();
   });
 }
 
 /* static */
 bool
@@ -5572,17 +5570,18 @@ nsContentUtils::GetTopLevelWidget(nsIWid
 }
 
 /* static */
 const nsDependentString
 nsContentUtils::GetLocalizedEllipsis()
 {
   static char16_t sBuf[4] = { 0, 0, 0, 0 };
   if (!sBuf[0]) {
-    nsAdoptingString tmp = Preferences::GetLocalizedString("intl.ellipsis");
+    nsAutoString tmp;
+    Preferences::GetLocalizedString("intl.ellipsis", tmp);
     uint32_t len = std::min(uint32_t(tmp.Length()),
                           uint32_t(ArrayLength(sBuf) - 1));
     CopyUnicodeTo(tmp, 0, sBuf, len);
     if (!sBuf[0])
       sBuf[0] = char16_t(0x2026);
   }
   return nsDependentString(sBuf);
 }
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -378,24 +378,38 @@ public:
                                     nsIDOMNode *aOther,
                                     nsIDOMNode** aCommonAncestor);
 
   /**
    * Returns the common ancestor, if any, for two nodes.
    *
    * Returns null if the nodes are disconnected.
    */
-  static nsINode* GetCommonAncestor(nsINode* aNode1, nsINode* aNode2);
+  static nsINode* GetCommonAncestor(nsINode* aNode1, nsINode* aNode2)
+  {
+    if (aNode1 == aNode2) {
+      return aNode1;
+    }
+
+    return GetCommonAncestorHelper(aNode1, aNode2);
+  }
 
   /**
    * Returns the common flattened tree ancestor, if any, for two given content
    * nodes.
    */
   static nsIContent* GetCommonFlattenedTreeAncestor(nsIContent* aContent1,
-                                                    nsIContent* aContent2);
+                                                    nsIContent* aContent2)
+  {
+    if (aContent1 == aContent2) {
+      return aContent1;
+    }
+
+    return GetCommonFlattenedTreeAncestorHelper(aContent1, aContent2);
+  }
 
   /**
    * Returns true if aNode1 is before aNode2 in the same connected
    * tree.
    */
   static bool PositionIsBefore(nsINode* aNode1, nsINode* aNode2);
 
   /**
@@ -3176,16 +3190,20 @@ private:
    * are also checked.
    *
    * Used in the implementation of StorageAllowedForWindow and
    * StorageAllowedForPrincipal.
    */
   static StorageAccess InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
                                                           nsPIDOMWindowInner* aWindow);
 
+  static nsINode* GetCommonAncestorHelper(nsINode* aNode1, nsINode* aNode2);
+  static nsIContent* GetCommonFlattenedTreeAncestorHelper(nsIContent* aContent1,
+                                                          nsIContent* aContent2);
+
   static nsIXPConnect *sXPConnect;
 
   static nsIScriptSecurityManager *sSecurityManager;
   static nsIPrincipal *sSystemPrincipal;
   static nsIPrincipal *sNullSubjectPrincipal;
 
   static nsIParserService *sParserService;
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -2759,18 +2759,19 @@ nsDocument::InitCSP(nsIChannel* aChannel
       csp->AppendPolicy(addonCSP, false, false);
     }
   }
 
   // ----- if the doc is a signed content, apply the default CSP.
   // Note that when the content signing becomes a standard, we might have
   // to restrict this enforcement to "remote content" only.
   if (applySignedContentCSP) {
-    nsAdoptingString signedContentCSP =
-      Preferences::GetString("security.signed_content.CSP.default");
+    nsAutoString signedContentCSP;
+    Preferences::GetString("security.signed_content.CSP.default",
+                           signedContentCSP);
     csp->AppendPolicy(signedContentCSP, false, false);
   }
 
   // ----- if there's a full-strength CSP header, apply it.
   if (!cspHeaderValue.IsEmpty()) {
     rv = CSP_AppendCSPFromHeader(csp, cspHeaderValue, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -13286,34 +13287,34 @@ nsDocument::PrincipalFlashClassification
   if (!flashBlock) {
     return FlashClassification::Unknown;
   }
 
   nsAutoCString allowTables, allowExceptionsTables,
                 denyTables, denyExceptionsTables,
                 subDocDenyTables, subDocDenyExceptionsTables,
                 tables;
-  Preferences::GetCString("urlclassifier.flashAllowTable", &allowTables);
+  Preferences::GetCString("urlclassifier.flashAllowTable", allowTables);
   MaybeAddTableToTableList(allowTables, tables);
   Preferences::GetCString("urlclassifier.flashAllowExceptTable",
-                          &allowExceptionsTables);
+                          allowExceptionsTables);
   MaybeAddTableToTableList(allowExceptionsTables, tables);
-  Preferences::GetCString("urlclassifier.flashTable", &denyTables);
+  Preferences::GetCString("urlclassifier.flashTable", denyTables);
   MaybeAddTableToTableList(denyTables, tables);
   Preferences::GetCString("urlclassifier.flashExceptTable",
-                          &denyExceptionsTables);
+                          denyExceptionsTables);
   MaybeAddTableToTableList(denyExceptionsTables, tables);
 
   bool isThirdPartyDoc = IsThirdParty();
   if (isThirdPartyDoc) {
     Preferences::GetCString("urlclassifier.flashSubDocTable",
-                            &subDocDenyTables);
+                            subDocDenyTables);
     MaybeAddTableToTableList(subDocDenyTables, tables);
     Preferences::GetCString("urlclassifier.flashSubDocExceptTable",
-                            &subDocDenyExceptionsTables);
+                            subDocDenyExceptionsTables);
     MaybeAddTableToTableList(subDocDenyExceptionsTables, tables);
   }
 
   if (tables.IsEmpty()) {
     return FlashClassification::Unknown;
   }
 
   nsCOMPtr<nsIURIClassifier> uriClassifier =
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1700,22 +1700,21 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
 
     Preferences::AddUintVarCache(&gThrottledIdlePeriodLength,
                                  "dom.idle_period.throttled_length",
                                  DEFAULT_THROTTLED_IDLE_PERIOD_LENGTH);
     sFirstTime = false;
   }
 
   if (gDumpFile == nullptr) {
-    const nsAdoptingCString& fname =
-      Preferences::GetCString("browser.dom.window.dump.file");
+    nsAutoCString fname;
+    Preferences::GetCString("browser.dom.window.dump.file", fname);
     if (!fname.IsEmpty()) {
-      // if this fails to open, Dump() knows to just go to stdout
-      // on null.
-      gDumpFile = fopen(fname, "wb+");
+      // If this fails to open, Dump() knows to just go to stdout on null.
+      gDumpFile = fopen(fname.get(), "wb+");
     } else {
       gDumpFile = stdout;
     }
   }
 
   mSerial = ++gSerialCounter;
 
 #ifdef DEBUG
@@ -6936,17 +6935,18 @@ struct FullscreenTransitionDuration
 
 static void
 GetFullscreenTransitionDuration(bool aEnterFullscreen,
                                 FullscreenTransitionDuration* aDuration)
 {
   const char* pref = aEnterFullscreen ?
     "full-screen-api.transition-duration.enter" :
     "full-screen-api.transition-duration.leave";
-  nsAdoptingCString prefValue = Preferences::GetCString(pref);
+  nsAutoCString prefValue;
+  Preferences::GetCString(pref, prefValue);
   if (!prefValue.IsEmpty()) {
     sscanf(prefValue.get(), "%hu%hu",
            &aDuration->mFadeIn, &aDuration->mFadeOut);
   }
 }
 
 class FullscreenTransitionTask : public Runnable
 {
@@ -8041,18 +8041,18 @@ void
 nsGlobalWindow::HomeOuter(nsIPrincipal& aSubjectPrincipal, ErrorResult& aError)
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
 
   if (!mDocShell) {
     return;
   }
 
-  nsAdoptingString homeURL =
-    Preferences::GetLocalizedString(PREF_BROWSER_STARTUP_HOMEPAGE);
+  nsAutoString homeURL;
+  Preferences::GetLocalizedString(PREF_BROWSER_STARTUP_HOMEPAGE, homeURL);
 
   if (homeURL.IsEmpty()) {
     // if all else fails, use this
 #ifdef DEBUG_seth
     printf("all else failed.  using %s as the home page\n", DEFAULT_HOME_PAGE);
 #endif
     CopyASCIItoUTF16(DEFAULT_HOME_PAGE, homeURL);
   }
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -928,17 +928,19 @@ nsObjectLoadingContent::BuildParametersA
     MozPluginParameter param;
     const nsAttrName* attrName = content->GetAttrNameAt(i);
     nsIAtom* atom = attrName->LocalName();
     content->GetAttr(attrName->NamespaceID(), atom, param.mValue);
     atom->ToString(param.mName);
     mCachedAttributes.AppendElement(param);
   }
 
-  nsAdoptingCString wmodeOverride = Preferences::GetCString("plugins.force.wmode");
+  nsAutoCString wmodeOverride;
+  Preferences::GetCString("plugins.force.wmode", wmodeOverride);
+
   for (uint32_t i = 0; i < mCachedAttributes.Length(); i++) {
     if (!wmodeOverride.IsEmpty() && mCachedAttributes[i].mName.EqualsIgnoreCase("wmode")) {
       CopyASCIItoUTF16(wmodeOverride, mCachedAttributes[i].mValue);
       wmodeOverride.Truncate();
     }
   }
 
   if (!wmodeOverride.IsEmpty()) {
@@ -3363,18 +3365,18 @@ nsObjectLoadingContent::ShouldPlay(Fallb
 }
 
 bool
 nsObjectLoadingContent::FavorFallbackMode(bool aIsPluginClickToPlay) {
   if (!IsFlashMIME(mContentType)) {
     return false;
   }
 
-  nsCString prefString;
-  if (NS_SUCCEEDED(Preferences::GetCString(kPrefFavorFallbackMode, &prefString))) {
+  nsAutoCString prefString;
+  if (NS_SUCCEEDED(Preferences::GetCString(kPrefFavorFallbackMode, prefString))) {
     if (aIsPluginClickToPlay &&
         prefString.EqualsLiteral("follow-ctp")) {
       return true;
     }
 
     if (prefString.EqualsLiteral("always")) {
       return true;
     }
@@ -3390,18 +3392,18 @@ nsObjectLoadingContent::HasGoodFallback(
   NS_ASSERTION(thisContent, "must be a content");
 
   if (!thisContent->IsHTMLElement(nsGkAtoms::object) ||
       mContentType.IsEmpty()) {
     return false;
   }
 
   nsTArray<nsCString> rulesList;
-  nsCString prefString;
-  if (NS_SUCCEEDED(Preferences::GetCString(kPrefFavorFallbackRules, &prefString))) {
+  nsAutoCString prefString;
+  if (NS_SUCCEEDED(Preferences::GetCString(kPrefFavorFallbackRules, prefString))) {
       ParseString(prefString, ',', rulesList);
   }
 
   for (uint32_t i = 0; i < rulesList.Length(); ++i) {
     // RULE "embed":
     // Don't use fallback content if the object contains an <embed> inside its
     // fallback content.
     if (rulesList[i].EqualsLiteral("embed")) {
--- a/dom/base/nsPluginArray.cpp
+++ b/dom/base/nsPluginArray.cpp
@@ -328,17 +328,19 @@ operator<(const RefPtr<nsPluginElement>&
 {
   // Sort plugins alphabetically by name.
   return lhs->PluginTag()->Name() < rhs->PluginTag()->Name();
 }
 
 static bool
 PluginShouldBeHidden(const nsCString& aName) {
   // This only supports one hidden plugin
-  return Preferences::GetCString("plugins.navigator.hidden_ctp_plugin").Equals(aName);
+  nsAutoCString value;
+  Preferences::GetCString("plugins.navigator.hidden_ctp_plugin", value);
+  return value.Equals(aName);
 }
 
 void
 nsPluginArray::EnsurePlugins()
 {
   if (!mPlugins.IsEmpty() || !mCTPPlugins.IsEmpty()) {
     // We already have an array of plugin elements.
     return;
--- a/dom/canvas/WebGLContextState.cpp
+++ b/dom/canvas/WebGLContextState.cpp
@@ -302,17 +302,17 @@ WebGLContext::GetParameter(JSContext* cx
                 default:
                     MOZ_CRASH("GFX: bad `pname`");
                 }
 
                 bool hasRetVal = false;
 
                 nsAutoString ret;
                 if (overridePref) {
-                    nsresult res = Preferences::GetString(overridePref, &ret);
+                    nsresult res = Preferences::GetString(overridePref, ret);
                     if (NS_SUCCEEDED(res) && ret.Length() > 0)
                         hasRetVal = true;
                 }
 
                 if (!hasRetVal) {
                     const char* chars = reinterpret_cast<const char*>(gl->fGetString(driverEnum));
                     ret = NS_ConvertASCIItoUTF16(chars);
                     hasRetVal = true;
--- a/dom/encoding/FallbackEncoding.cpp
+++ b/dom/encoding/FallbackEncoding.cpp
@@ -44,18 +44,18 @@ FallbackEncoding::FallbackEncoding()
 
 NotNull<const Encoding*>
 FallbackEncoding::Get()
 {
   if (mFallback) {
     return WrapNotNull(mFallback);
   }
 
-  const nsAdoptingCString& override =
-    Preferences::GetCString("intl.charset.fallback.override");
+  nsAutoCString override;
+  Preferences::GetCString("intl.charset.fallback.override", override);
   // Don't let the user break things by setting the override to unreasonable
   // values via about:config
   auto encoding = Encoding::ForLabel(override);
   if (!encoding || !encoding->IsAsciiCompatible() ||
       encoding == UTF_8_ENCODING) {
     mFallback = nullptr;
   } else {
     mFallback = encoding;
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -895,17 +895,18 @@ Event::GetEventPopupControlState(WidgetE
 // static
 void
 Event::PopupAllowedEventsChanged()
 {
   if (sPopupAllowedEvents) {
     free(sPopupAllowedEvents);
   }
 
-  nsAdoptingCString str = Preferences::GetCString("dom.popup_allowed_events");
+  nsAutoCString str;
+  Preferences::GetCString("dom.popup_allowed_events", str);
 
   // We'll want to do this even if str is empty to avoid looking up
   // this pref all the time if it's not set.
   sPopupAllowedEvents = ToNewCString(str);
 }
 
 // static
 void
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -479,17 +479,17 @@ NS_IMPL_ISUPPORTS(UploadLastDir::Content
 
 NS_IMETHODIMP
 UploadLastDir::ContentPrefCallback::HandleCompletion(uint16_t aReason)
 {
   nsCOMPtr<nsIFile> localFile;
   nsAutoString prefStr;
 
   if (aReason == nsIContentPrefCallback2::COMPLETE_ERROR || !mResult) {
-    prefStr = Preferences::GetString("dom.input.fallbackUploadDir");
+    Preferences::GetString("dom.input.fallbackUploadDir", prefStr);
   }
 
   if (prefStr.IsEmpty() && mResult) {
     nsCOMPtr<nsIVariant> pref;
     mResult->GetValue(getter_AddRefs(pref));
     pref->GetAsAString(prefStr);
   }
 
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -426,18 +426,18 @@ IndexedDatabaseManager::Init()
 
   Preferences::RegisterCallbackAndCall(DataThresholdPrefChangedCallback,
                                        kDataThresholdPref);
 
   Preferences::RegisterCallbackAndCall(MaxSerializedMsgSizePrefChangeCallback,
                                        kPrefMaxSerilizedMsgSize);
 
 #ifdef ENABLE_INTL_API
-  const nsAdoptingCString& acceptLang =
-    Preferences::GetLocalizedCString("intl.accept_languages");
+  nsAutoCString acceptLang;
+  Preferences::GetLocalizedCString("intl.accept_languages", acceptLang);
 
   // Split values on commas.
   nsCCharSeparatedTokenizer langTokenizer(acceptLang, ',');
   while (langTokenizer.hasMoreTokens()) {
     nsAutoCString lang(langTokenizer.nextToken());
     icu::Locale locale = icu::Locale::createCanonical(lang.get());
     if (!locale.isBogus()) {
       // icu::Locale::getBaseName is always ASCII as per BCP 47
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1506,23 +1506,25 @@ StartMacOSContentSandbox()
   info.appPath.assign(appPath.get());
   info.appBinaryPath.assign(appBinaryPath.get());
   info.appDir.assign(appDir.get());
   info.appTempDir.assign(tempDirPath.get());
 
   // These paths are used to whitelist certain directories used by the testing
   // system. They should not be considered a public API, and are only intended
   // for use in automation.
-  nsAdoptingCString testingReadPath1 =
-    Preferences::GetCString("security.sandbox.content.mac.testing_read_path1");
+  nsAutoCString testingReadPath1;
+  Preferences::GetCString("security.sandbox.content.mac.testing_read_path1",
+                          testingReadPath1);
   if (!testingReadPath1.IsEmpty()) {
     info.testingReadPath1.assign(testingReadPath1.get());
   }
-  nsAdoptingCString testingReadPath2 =
-    Preferences::GetCString("security.sandbox.content.mac.testing_read_path2");
+  nsAutoCString testingReadPath2;
+  Preferences::GetCString("security.sandbox.content.mac.testing_read_path2",
+                          testingReadPath2);
   if (!testingReadPath2.IsEmpty()) {
     info.testingReadPath2.assign(testingReadPath2.get());
   }
 
   if (mozilla::IsDevelopmentBuild()) {
     nsCOMPtr<nsIFile> repoDir;
     rv = mozilla::GetRepoDir(getter_AddRefs(repoDir));
     if (NS_FAILED(rv)) {
@@ -1600,21 +1602,22 @@ ContentChild::RecvSetProcessSandbox(cons
       brokerFd = fd.release();
       // brokerFd < 0 means to allow direct filesystem access, so
       // make absolutely sure that doesn't happen if the parent
       // didn't intend it.
       MOZ_RELEASE_ASSERT(brokerFd >= 0);
     }
     // Allow user overrides of seccomp-bpf syscall filtering
     std::vector<int> syscallWhitelist;
-    nsAdoptingCString extraSyscalls =
-      Preferences::GetCString("security.sandbox.content.syscall_whitelist");
-    if (extraSyscalls) {
+    nsAutoCString extraSyscalls;
+    nsresult rv =
+      Preferences::GetCString("security.sandbox.content.syscall_whitelist",
+                              extraSyscalls);
+    if (NS_SUCCEEDED(rv)) {
       for (const nsACString& callNrString : extraSyscalls.Split(',')) {
-        nsresult rv;
         int callNr = PromiseFlatCString(callNrString).ToInteger(&rv);
         if (NS_SUCCEEDED(rv)) {
           syscallWhitelist.push_back(callNr);
         }
       }
     }
     ContentChild* cc = ContentChild::GetSingleton();
     bool isFileProcess = cc->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2035,17 +2035,18 @@ ContentParent::LaunchSubprocess(ProcessP
     switch (Preferences::GetType(ContentPrefs::GetContentPref(i))) {
     case nsIPrefBranch::PREF_INT:
       intPrefs.Append(nsPrintfCString("%u:%d|", i, Preferences::GetInt(ContentPrefs::GetContentPref(i))));
       break;
     case nsIPrefBranch::PREF_BOOL:
       boolPrefs.Append(nsPrintfCString("%u:%d|", i, Preferences::GetBool(ContentPrefs::GetContentPref(i))));
       break;
     case nsIPrefBranch::PREF_STRING: {
-      nsAdoptingCString value(Preferences::GetCString(ContentPrefs::GetContentPref(i)));
+      nsAutoCString value;
+      Preferences::GetCString(ContentPrefs::GetContentPref(i), value);
       stringPrefs.Append(nsPrintfCString("%u:%d;%s|", i, value.Length(), value.get()));
 
     }
       break;
     case nsIPrefBranch::PREF_INVALID:
       break;
     default:
       printf("preference type: %x\n", Preferences::GetType(ContentPrefs::GetContentPref(i)));
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -157,23 +157,23 @@ static const uint32_t CUBEB_NORMAL_LATEN
 // Consevative default that can work on all platforms.
 static const uint32_t CUBEB_NORMAL_LATENCY_FRAMES = 1024;
 
 namespace CubebUtils {
 
 void PrefChanged(const char* aPref, void* aClosure)
 {
   if (strcmp(aPref, PREF_VOLUME_SCALE) == 0) {
-    nsAdoptingString value = Preferences::GetString(aPref);
+    nsAutoCString value;
+    Preferences::GetCString(aPref, value);
     StaticMutexAutoLock lock(sMutex);
     if (value.IsEmpty()) {
       sVolumeScale = 1.0;
     } else {
-      NS_ConvertUTF16toUTF8 utf8(value);
-      sVolumeScale = std::max<double>(0, PR_strtod(utf8.get(), nullptr));
+      sVolumeScale = std::max<double>(0, PR_strtod(value.get(), nullptr));
     }
   } else if (strcmp(aPref, PREF_CUBEB_LATENCY_PLAYBACK) == 0) {
     // Arbitrary default stream latency of 100ms.  The higher this
     // value, the longer stream volume changes will take to become
     // audible.
     sCubebPlaybackLatencyPrefSet = Preferences::HasUserValue(aPref);
     uint32_t value = Preferences::GetUint(aPref, CUBEB_NORMAL_LATENCY_MS);
     StaticMutexAutoLock lock(sMutex);
@@ -183,38 +183,38 @@ void PrefChanged(const char* aPref, void
     uint32_t value = Preferences::GetUint(aPref, CUBEB_NORMAL_LATENCY_FRAMES);
     StaticMutexAutoLock lock(sMutex);
     // 128 is the block size for the Web Audio API, which limits how low the
     // latency can be here.
     // We don't want to limit the upper limit too much, so that people can
     // experiment.
     sCubebMSGLatencyInFrames = std::min<uint32_t>(std::max<uint32_t>(value, 128), 1e6);
   } else if (strcmp(aPref, PREF_CUBEB_LOGGING_LEVEL) == 0) {
-    nsAdoptingString value = Preferences::GetString(aPref);
-    NS_ConvertUTF16toUTF8 utf8(value);
+    nsAutoCString value;
+    Preferences::GetCString(aPref, value);
     LogModule* cubebLog = LogModule::Get("cubeb");
-    if (strcmp(utf8.get(), "verbose") == 0) {
+    if (value.EqualsLiteral("verbose")) {
       cubeb_set_log_callback(CUBEB_LOG_VERBOSE, CubebLogCallback);
       cubebLog->SetLevel(LogLevel::Verbose);
-    } else if (strcmp(utf8.get(), "normal") == 0) {
+    } else if (value.EqualsLiteral("normal")) {
       cubeb_set_log_callback(CUBEB_LOG_NORMAL, CubebLogCallback);
       cubebLog->SetLevel(LogLevel::Error);
-    } else if (utf8.IsEmpty()) {
+    } else if (value.IsEmpty()) {
       cubeb_set_log_callback(CUBEB_LOG_DISABLED, nullptr);
       cubebLog->SetLevel(LogLevel::Disabled);
     }
   } else if (strcmp(aPref, PREF_CUBEB_BACKEND) == 0) {
-    nsAdoptingString value = Preferences::GetString(aPref);
+    nsAutoCString value;
+    Preferences::GetCString(aPref, value);
     if (value.IsEmpty()) {
       sCubebBackendName = nullptr;
     } else {
-      NS_LossyConvertUTF16toASCII ascii(value);
-      sCubebBackendName = new char[ascii.Length() + 1];
-      PodCopy(sCubebBackendName.get(), ascii.get(), ascii.Length());
-      sCubebBackendName[ascii.Length()] = 0;
+      sCubebBackendName = new char[value.Length() + 1];
+      PodCopy(sCubebBackendName.get(), value.get(), value.Length());
+      sCubebBackendName[value.Length()] = 0;
     }
   }
 }
 
 bool GetFirstStream()
 {
   static bool sFirstStream = true;
 
--- a/dom/media/DecoderDoctorDiagnostics.cpp
+++ b/dom/media/DecoderDoctorDiagnostics.cpp
@@ -399,18 +399,18 @@ static bool
 AllowNotification(const NotificationAndReportStringId& aNotification)
 {
   // "media.decoder-doctor.notifications-allowed" controls which notifications
   // may be dispatched to the front-end. It either contains:
   // - '*' -> Allow everything.
   // - Comma-separater list of ids -> Allow if aReportStringId (from
   //                                  dom.properties) is one of them.
   // - Nothing (missing or empty) -> Disable everything.
-  nsAdoptingCString filter =
-    Preferences::GetCString("media.decoder-doctor.notifications-allowed");
+  nsAutoCString filter;
+  Preferences::GetCString("media.decoder-doctor.notifications-allowed", filter);
   return filter.EqualsLiteral("*") ||
          StringListContains(filter, aNotification.mReportStringId);
 }
 
 static bool
 AllowDecodeIssue(const MediaResult& aDecodeIssue, bool aDecodeIssueIsError)
 {
   if (aDecodeIssue == NS_OK) {
@@ -419,20 +419,21 @@ AllowDecodeIssue(const MediaResult& aDec
     return true;
   }
 
   // "media.decoder-doctor.decode-{errors,warnings}-allowed" controls which
   // decode issues may be dispatched to the front-end. It either contains:
   // - '*' -> Allow everything.
   // - Comma-separater list of ids -> Allow if the issue name is one of them.
   // - Nothing (missing or empty) -> Disable everything.
-  nsAdoptingCString filter =
-    Preferences::GetCString(aDecodeIssueIsError
-                            ? "media.decoder-doctor.decode-errors-allowed"
-                            : "media.decoder-doctor.decode-warnings-allowed");
+  nsAutoCString filter;
+  Preferences::GetCString(aDecodeIssueIsError
+                          ? "media.decoder-doctor.decode-errors-allowed"
+                          : "media.decoder-doctor.decode-warnings-allowed",
+                          filter);
   if (filter.EqualsLiteral("*")) {
     return true;
   }
 
   nsCString decodeIssueName;
   GetErrorName(aDecodeIssue.Code(), static_cast<nsACString&>(decodeIssueName));
   return StringListContains(filter, decodeIssueName);
 }
@@ -623,18 +624,18 @@ DecoderDoctorDocumentWatcher::Synthesize
       { &supportedKeySystems, &playableFormats };
     // For each type of notification, retrieve the pref that contains formats/
     // key systems with issues.
     for (const NotificationAndReportStringId* id :
            sAllNotificationsAndReportStringIds) {
       nsAutoCString formatsPref("media.decoder-doctor.");
       formatsPref += id->mReportStringId;
       formatsPref += ".formats";
-      nsAdoptingString formatsWithIssues =
-        Preferences::GetString(formatsPref.Data());
+      nsAutoString formatsWithIssues;
+      Preferences::GetString(formatsPref.Data(), formatsWithIssues);
       if (formatsWithIssues.IsEmpty()) {
         continue;
       }
       // See if that list of formats-with-issues contains any formats that are
       // now playable/supported.
       bool solved = false;
       for (const nsAString* workingFormats : workingFormatsArray) {
         for (const auto& workingFormat : MakeStringListRange(*workingFormats)) {
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1696,26 +1696,26 @@ MediaManager::EnumerateRawDevices(uint64
                                   bool aFake)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aVideoType != MediaSourceEnum::Other ||
              aAudioType != MediaSourceEnum::Other);
   RefPtr<PledgeSourceSet> p = new PledgeSourceSet();
   uint32_t id = mOutstandingPledges.Append(*p);
 
-  nsAdoptingCString audioLoopDev, videoLoopDev;
+  nsAutoCString audioLoopDev, videoLoopDev;
   if (!aFake) {
     // Fake stream not requested. The entire device stack is available.
     // Loop in loopback devices if they are set, and their respective type is
     // requested. This is currently used for automated media tests only.
     if (aVideoType == MediaSourceEnum::Camera) {
-      videoLoopDev = Preferences::GetCString("media.video_loopback_dev");
+      Preferences::GetCString("media.video_loopback_dev", videoLoopDev);
     }
     if (aAudioType == MediaSourceEnum::Microphone) {
-      audioLoopDev = Preferences::GetCString("media.audio_loopback_dev");
+      Preferences::GetCString("media.audio_loopback_dev", audioLoopDev);
     }
   }
 
   RefPtr<Runnable> task = NewTaskFrom([id, aWindowId, audioLoopDev,
                                        videoLoopDev, aVideoType,
                                        aAudioType, aFake]() mutable {
     // Only enumerate what's asked for, and only fake cams and mics.
     bool hasVideo = aVideoType != MediaSourceEnum::Other;
@@ -1734,25 +1734,27 @@ MediaManager::EnumerateRawDevices(uint64
       realBackend->AddDeviceChangeCallback(manager);
     }
 
     auto result = MakeUnique<SourceSet>();
 
     if (hasVideo) {
       nsTArray<RefPtr<VideoDevice>> videos;
       GetSources(fakeCams? fakeBackend : realBackend, aVideoType,
-                 &MediaEngine::EnumerateVideoDevices, videos, videoLoopDev);
+                 &MediaEngine::EnumerateVideoDevices, videos,
+                 videoLoopDev.get());
       for (auto& source : videos) {
         result->AppendElement(source);
       }
     }
     if (hasAudio) {
       nsTArray<RefPtr<AudioDevice>> audios;
       GetSources(fakeMics? fakeBackend : realBackend, aAudioType,
-                 &MediaEngine::EnumerateAudioDevices, audios, audioLoopDev);
+                 &MediaEngine::EnumerateAudioDevices, audios,
+                 audioLoopDev.get());
       for (auto& source : audios) {
         result->AppendElement(source);
       }
     }
     SourceSet* handoff = result.release();
     NS_DispatchToMainThread(NewRunnableFrom([id, handoff]() mutable {
       UniquePtr<SourceSet> result(handoff); // grab result
       RefPtr<MediaManager> mgr = MediaManager_GetInstance();
--- a/dom/media/webspeech/recognition/SpeechRecognition.cpp
+++ b/dom/media/webspeech/recognition/SpeechRecognition.cpp
@@ -67,18 +67,18 @@ GetSpeechRecognitionLog()
 }
 #define SR_LOG(...) MOZ_LOG(GetSpeechRecognitionLog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
 
 already_AddRefed<nsISpeechRecognitionService>
 GetSpeechRecognitionService(const nsAString& aLang)
 {
   nsAutoCString speechRecognitionServiceCID;
 
-  nsAdoptingCString prefValue =
-    Preferences::GetCString(PREFERENCE_DEFAULT_RECOGNITION_SERVICE);
+  nsAutoCString prefValue;
+  Preferences::GetCString(PREFERENCE_DEFAULT_RECOGNITION_SERVICE, prefValue);
   nsAutoCString speechRecognitionService;
 
   if (!aLang.IsEmpty()) {
     speechRecognitionService =
       NS_LITERAL_CSTRING(DEFAULT_RECOGNITION_SERVICE_PREFIX) +
       NS_ConvertUTF16toUTF8(aLang);
   } else if (!prefValue.IsEmpty()) {
     speechRecognitionService = prefValue;
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -1547,18 +1547,18 @@ nsPluginHost::RegisterFakePlugin(JS::Han
   for (const auto& existingTag : mFakePlugins) {
     if (newTag->HandlerURIMatches(existingTag->HandlerURI())) {
       return NS_ERROR_UNEXPECTED;
     }
   }
 
   mFakePlugins.AppendElement(newTag);
 
-  nsAdoptingCString disableFullPage =
-    Preferences::GetCString(kPrefDisableFullPage);
+  nsAutoCString disableFullPage;
+  Preferences::GetCString(kPrefDisableFullPage, disableFullPage);
   for (uint32_t i = 0; i < newTag->MimeTypes().Length(); i++) {
     if (!IsTypeInList(newTag->MimeTypes()[i], disableFullPage)) {
       RegisterWithCategoryManager(newTag->MimeTypes()[i],
                                   ePluginRegister);
     }
   }
 
   newTag.forget(aResult);
@@ -1991,18 +1991,18 @@ ShouldAddPlugin(const nsPluginInfo& info
 
 void
 nsPluginHost::AddPluginTag(nsPluginTag* aPluginTag)
 {
   aPluginTag->mNext = mPlugins;
   mPlugins = aPluginTag;
 
   if (aPluginTag->IsActive()) {
-    nsAdoptingCString disableFullPage =
-      Preferences::GetCString(kPrefDisableFullPage);
+    nsAutoCString disableFullPage;
+    Preferences::GetCString(kPrefDisableFullPage, disableFullPage);
     for (uint32_t i = 0; i < aPluginTag->MimeTypes().Length(); i++) {
       if (!IsTypeInList(aPluginTag->MimeTypes()[i], disableFullPage)) {
         RegisterWithCategoryManager(aPluginTag->MimeTypes()[i],
                                     ePluginRegister);
       }
     }
   }
 }
@@ -2384,18 +2384,18 @@ nsPluginHost::SetPluginsInContent(uint32
                                                       mozilla::ipc::DeserializeURI(tag.handlerURI()),
                                                       tag.name().get(),
                                                       tag.description().get(),
                                                       tag.mimeTypes(),
                                                       tag.mimeDescriptions(),
                                                       tag.extensions(),
                                                       tag.niceName(),
                                                       tag.sandboxScript()));
-      nsAdoptingCString disableFullPage =
-        Preferences::GetCString(kPrefDisableFullPage);
+      nsAutoCString disableFullPage;
+      Preferences::GetCString(kPrefDisableFullPage, disableFullPage);
       for (uint32_t i = 0; i < pluginTag->MimeTypes().Length(); i++) {
         if (!IsTypeInList(pluginTag->MimeTypes()[i], disableFullPage)) {
           RegisterWithCategoryManager(pluginTag->MimeTypes()[i],
                                       ePluginRegister);
         }
       }
     }
 
@@ -2631,18 +2631,18 @@ nsPluginHost::UpdateInMemoryPluginInfo(n
   NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
   NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
 
   if (!aPluginTag) {
     return;
   }
 
   // Update types with category manager
-  nsAdoptingCString disableFullPage =
-    Preferences::GetCString(kPrefDisableFullPage);
+  nsAutoCString disableFullPage;
+  Preferences::GetCString(kPrefDisableFullPage, disableFullPage);
   for (uint32_t i = 0; i < aPluginTag->MimeTypes().Length(); i++) {
     nsRegisterType shouldRegister;
 
     if (IsTypeInList(aPluginTag->MimeTypes()[i], disableFullPage)) {
       shouldRegister = ePluginUnregister;
     } else {
       nsPluginTag *plugin = FindNativePluginForType(aPluginTag->MimeTypes()[i],
                                                     true);
@@ -2670,18 +2670,19 @@ nsPluginHost::UpdatePluginInfo(nsPluginT
   IncrementChromeEpoch();
 
   UpdateInMemoryPluginInfo(aPluginTag);
 }
 
 /* static */ bool
 nsPluginHost::IsTypeWhitelisted(const char *aMimeType)
 {
-  nsAdoptingCString whitelist = Preferences::GetCString(kPrefWhitelist);
-  if (!whitelist.Length()) {
+  nsAutoCString whitelist;
+  Preferences::GetCString(kPrefWhitelist, whitelist);
+  if (whitelist.IsEmpty()) {
     return true;
   }
   nsDependentCString wrap(aMimeType);
   return IsTypeInList(wrap, whitelist);
 }
 
 /* static */ bool
 nsPluginHost::ShouldLoadTypeInParent(const nsACString& aMimeType)
--- a/dom/presentation/provider/MulticastDNSDeviceProvider.cpp
+++ b/dom/presentation/provider/MulticastDNSDeviceProvider.cpp
@@ -155,17 +155,18 @@ MulticastDNSDeviceProvider::Init()
   }
   Preferences::AddStrongObservers(this, kObservedPrefs);
 
   mDiscoveryEnabled = Preferences::GetBool(PREF_PRESENTATION_DISCOVERY);
   mDiscoveryTimeoutMs = Preferences::GetUint(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS);
   mDiscoverable = Preferences::GetBool(PREF_PRESENTATION_DISCOVERABLE);
   mDiscoverableEncrypted = Preferences::GetBool(PREF_PRESENTATION_DISCOVERABLE_ENCRYPTED);
   mServerRetryMs = Preferences::GetUint(PREF_PRESENTATION_DISCOVERABLE_RETRY_MS);
-  mServiceName = Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME);
+  mServiceName.Truncate();
+  Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME, mServiceName);
 
 #ifdef MOZ_WIDGET_ANDROID
   // FIXME: Bug 1185806 - Provide a common device name setting.
   if (mServiceName.IsEmpty()) {
     GetAndroidDeviceName(mServiceName);
     Unused << Preferences::SetCString(PREF_PRESENTATION_DEVICE_NAME, mServiceName);
   }
 #endif // MOZ_WIDGET_ANDROID
@@ -1093,17 +1094,18 @@ MulticastDNSDeviceProvider::Observe(nsIS
   if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
     if (data.EqualsLiteral(PREF_PRESENTATION_DISCOVERY)) {
       OnDiscoveryChanged(Preferences::GetBool(PREF_PRESENTATION_DISCOVERY));
     } else if (data.EqualsLiteral(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS)) {
       OnDiscoveryTimeoutChanged(Preferences::GetUint(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS));
     } else if (data.EqualsLiteral(PREF_PRESENTATION_DISCOVERABLE)) {
       OnDiscoverableChanged(Preferences::GetBool(PREF_PRESENTATION_DISCOVERABLE));
     } else if (data.EqualsLiteral(PREF_PRESENTATION_DEVICE_NAME)) {
-      nsAdoptingCString newServiceName = Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME);
+      nsAutoCString newServiceName;
+      Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME, newServiceName);
       if (!mServiceName.Equals(newServiceName)) {
         OnServiceNameChanged(newServiceName);
       }
     }
   } else if (!strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC)) {
     nsCOMPtr<nsITimer> timer = do_QueryInterface(aSubject);
     if (!timer) {
       return NS_ERROR_UNEXPECTED;
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -709,18 +709,20 @@ nsContentSecurityManager::IsOriginPotent
     return NS_OK;
   }
 
   // If a host is not considered secure according to the default algorithm, then
   // check to see if it has been whitelisted by the user.  We only apply this
   // whitelist for network resources, i.e., those with scheme "http" or "ws".
   // The pref should contain a comma-separated list of hostnames.
   if (scheme.EqualsLiteral("http") || scheme.EqualsLiteral("ws")) {
-    nsAdoptingCString whitelist = Preferences::GetCString("dom.securecontext.whitelist");
-    if (whitelist) {
+    nsAutoCString whitelist;
+    nsresult rv =
+      Preferences::GetCString("dom.securecontext.whitelist", whitelist);
+    if (NS_SUCCEEDED(rv)) {
       nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
       while (tokenizer.hasMoreTokens()) {
         const nsACString& allowedHost = tokenizer.nextToken();
         if (host.Equals(allowedHost)) {
           *aIsTrustWorthy = true;
           return NS_OK;
         }
       }
--- a/dom/svg/SVGSwitchElement.cpp
+++ b/dom/svg/SVGSwitchElement.cpp
@@ -122,18 +122,18 @@ SVGSwitchElement::IsAttributeMapped(cons
 }
 
 //----------------------------------------------------------------------
 // Implementation Helpers:
 
 nsIContent *
 SVGSwitchElement::FindActiveChild() const
 {
-  const nsAdoptingString& acceptLangs =
-    Preferences::GetLocalizedString("intl.accept_languages");
+  nsAutoString acceptLangs;
+  Preferences::GetLocalizedString("intl.accept_languages", acceptLangs);
 
   if (!acceptLangs.IsEmpty()) {
     int32_t bestLanguagePreferenceRank = -1;
     nsIContent *bestChild = nullptr;
     nsIContent *defaultChild = nullptr;
     for (nsIContent* child = nsINode::GetFirstChild();
          child;
          child = child->GetNextSibling()) {
--- a/dom/svg/SVGTests.cpp
+++ b/dom/svg/SVGTests.cpp
@@ -142,18 +142,22 @@ SVGTests::PassesConditionalProcessingTes
   // prefix of one of the languages given in the value of this parameter such
   // that the first tag character following the prefix is "-".
   if (mStringListAttributes[LANGUAGE].IsExplicitlySet()) {
     if (mStringListAttributes[LANGUAGE].IsEmpty()) {
       return false;
     }
 
     // Get our language preferences
-    const nsAutoString acceptLangs(aAcceptLangs ? *aAcceptLangs :
-      Preferences::GetLocalizedString("intl.accept_languages"));
+    nsAutoString acceptLangs;
+    if (aAcceptLangs) {
+      acceptLangs.Assign(*aAcceptLangs);
+    } else {
+      Preferences::GetLocalizedString("intl.accept_languages", acceptLangs);
+    }
 
     if (acceptLangs.IsEmpty()) {
       NS_WARNING("no default language specified for systemLanguage conditional test");
       return false;
     }
 
     const nsDefaultStringComparator defaultComparator;
 
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -1319,46 +1319,46 @@ PrefLanguagesChanged(const char* /* aPre
   }
 }
 
 void
 AppNameOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
 {
   AssertIsOnMainThread();
 
-  const nsAdoptingString& override =
-    mozilla::Preferences::GetString("general.appname.override");
+  nsAutoString override;
+  Preferences::GetString("general.appname.override", override);
 
   RuntimeService* runtime = RuntimeService::GetService();
   if (runtime) {
     runtime->UpdateAppNameOverridePreference(override);
   }
 }
 
 void
 AppVersionOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
 {
   AssertIsOnMainThread();
 
-  const nsAdoptingString& override =
-    mozilla::Preferences::GetString("general.appversion.override");
+  nsAutoString override;
+  Preferences::GetString("general.appversion.override", override);
 
   RuntimeService* runtime = RuntimeService::GetService();
   if (runtime) {
     runtime->UpdateAppVersionOverridePreference(override);
   }
 }
 
 void
 PlatformOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
 {
   AssertIsOnMainThread();
 
-  const nsAdoptingString& override =
-    mozilla::Preferences::GetString("general.platform.override");
+  nsAutoString override;
+  Preferences::GetString("general.platform.override", override);
 
   RuntimeService* runtime = RuntimeService::GetService();
   if (runtime) {
     runtime->UpdatePlatformOverridePreference(override);
   }
 }
 
 class BackgroundChildCallback final
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -899,17 +899,17 @@ nsEditorSpellCheck::SetFallbackDictionar
   nsAutoString dictName(mPreferredLang);
 #ifdef DEBUG_DICT
   printf("***** Assigned from element/doc |%s|\n",
          NS_ConvertUTF16toUTF8(dictName).get());
 #endif
 
   // Get the preference value.
   nsAutoString preferredDict;
-  preferredDict = Preferences::GetLocalizedString("spellchecker.dictionary");
+  Preferences::GetLocalizedString("spellchecker.dictionary", preferredDict);
 
   if (!dictName.IsEmpty()) {
     // RFC 5646 explicitly states that matches should be case-insensitive.
     BuildDictionaryList(dictName, dictList, DICT_COMPARE_CASE_INSENSITIVE,
                         tryDictList);
 
 #ifdef DEBUG_DICT
     printf("***** Trying from element/doc |%s| \n",
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -608,44 +608,44 @@ CSSEditUtils::IsCSSInvertible(nsIAtom& a
   return nsGkAtoms::b == &aProperty;
 }
 
 // Get the default browser background color if we need it for GetCSSBackgroundColorState
 void
 CSSEditUtils::GetDefaultBackgroundColor(nsAString& aColor)
 {
   if (Preferences::GetBool("editor.use_custom_colors", false)) {
-    nsresult rv = Preferences::GetString("editor.background_color", &aColor);
+    nsresult rv = Preferences::GetString("editor.background_color", aColor);
     // XXX Why don't you validate the pref value?
     if (NS_FAILED(rv)) {
       NS_WARNING("failed to get editor.background_color");
       aColor.AssignLiteral("#ffffff");  // Default to white
     }
     return;
   }
 
   if (Preferences::GetBool("browser.display.use_system_colors", false)) {
     return;
   }
 
   nsresult rv =
-    Preferences::GetString("browser.display.background_color", &aColor);
+    Preferences::GetString("browser.display.background_color", aColor);
   // XXX Why don't you validate the pref value?
   if (NS_FAILED(rv)) {
     NS_WARNING("failed to get browser.display.background_color");
     aColor.AssignLiteral("#ffffff");  // Default to white
   }
 }
 
 // Get the default length unit used for CSS Indent/Outdent
 void
 CSSEditUtils::GetDefaultLengthUnit(nsAString& aLengthUnit)
 {
   nsresult rv =
-    Preferences::GetString("editor.css.default_length_unit", &aLengthUnit);
+    Preferences::GetString("editor.css.default_length_unit", aLengthUnit);
   // XXX Why don't you validate the pref value?
   if (NS_FAILED(rv)) {
     aLengthUnit.AssignLiteral("px");
   }
 }
 
 // Unfortunately, CSSStyleDeclaration::GetPropertyCSSValue is not yet
 // implemented... We need then a way to determine the number part and the unit
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -170,16 +170,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Ed
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mInlineSpellChecker)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTxnMgr)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mIMETextNode)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mActionListeners)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorObservers)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocStateListeners)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventTarget)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventListener)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mPlaceholderTransaction)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSavedSel);
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mRangeUpdater);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(EditorBase)
  nsIDocument* currentDoc =
    tmp->mRootElement ? tmp->mRootElement->GetUncomposedDoc() : nullptr;
  if (currentDoc &&
@@ -190,16 +191,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInlineSpellChecker)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTxnMgr)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIMETextNode)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mActionListeners)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditorObservers)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocStateListeners)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventTarget)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventListener)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlaceholderTransaction)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSavedSel);
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRangeUpdater);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(EditorBase)
  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
  NS_INTERFACE_MAP_ENTRY(nsIEditor)
  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditor)
@@ -683,39 +685,42 @@ EditorBase::GetSelection(SelectionType a
   }
 
   return sel->AsSelection();
 }
 
 NS_IMETHODIMP
 EditorBase::DoTransaction(nsITransaction* aTxn)
 {
-  if (mPlaceholderBatch && !mPlaceholderTransactionWeak) {
-    RefPtr<PlaceholderTransaction> placeholderTransaction =
+  return DoTransaction(nullptr, aTxn);
+}
+
+nsresult
+EditorBase::DoTransaction(Selection* aSelection, nsITransaction* aTxn)
+{
+  if (mPlaceholderBatch && !mPlaceholderTransaction) {
+    mPlaceholderTransaction =
       new PlaceholderTransaction(*this, mPlaceholderName, Move(mSelState));
 
-    // Save off weak reference to placeholder transaction
-    mPlaceholderTransactionWeak = placeholderTransaction;
-
     // We will recurse, but will not hit this case in the nested call
-    DoTransaction(placeholderTransaction);
+    DoTransaction(mPlaceholderTransaction);
 
     if (mTxnMgr) {
       nsCOMPtr<nsITransaction> topTransaction = mTxnMgr->PeekUndoStack();
       nsCOMPtr<nsIAbsorbingTransaction> topAbsorbingTransaction =
         do_QueryInterface(topTransaction);
       if (topAbsorbingTransaction) {
         RefPtr<PlaceholderTransaction> topPlaceholderTransaction =
           topAbsorbingTransaction->AsPlaceholderTransaction();
         if (topPlaceholderTransaction) {
           // there is a placeholder transaction on top of the undo stack.  It
           // is either the one we just created, or an earlier one that we are
           // now merging into.  From here on out remember this placeholder
           // instead of the one we just created.
-          mPlaceholderTransactionWeak = topPlaceholderTransaction;
+          mPlaceholderTransaction = topPlaceholderTransaction;
         }
       }
     }
   }
 
   if (aTxn) {
     // XXX: Why are we doing selection specific batching stuff here?
     // XXX: Most entry points into the editor have auto variables that
@@ -732,17 +737,17 @@ EditorBase::DoTransaction(nsITransaction
     // XXX: selection listeners have access to accurate frame data?
     // XXX:
     // XXX: Note that if we did add Begin/EndUpdateViewBatch() calls
     // XXX: we will need to make sure that they are disabled during
     // XXX: the init of the editor for text widgets to avoid layout
     // XXX: re-entry during initial reflow. - kin
 
     // get the selection and start a batch change
-    RefPtr<Selection> selection = GetSelection();
+    RefPtr<Selection> selection = aSelection ? aSelection : GetSelection();
     NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
 
     selection->StartBatchChanges();
 
     nsresult rv;
     if (mTxnMgr) {
       RefPtr<nsTransactionManager> txnMgr = mTxnMgr;
       rv = txnMgr->DoTransaction(aTxn);
@@ -960,17 +965,17 @@ EditorBase::EndTransaction()
 NS_IMETHODIMP
 EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName)
 {
   MOZ_ASSERT(mPlaceholderBatch >= 0, "negative placeholder batch count!");
   if (!mPlaceholderBatch) {
     NotifyEditorObservers(eNotifyEditorObserversOfBefore);
     // time to turn on the batch
     BeginUpdateViewBatch();
-    mPlaceholderTransactionWeak = nullptr;
+    mPlaceholderTransaction = nullptr;
     mPlaceholderName = aName;
     RefPtr<Selection> selection = GetSelection();
     if (selection) {
       mSelState = MakeUnique<SelectionState>();
       mSelState->SaveSelection(selection);
       // Composition transaction can modify multiple nodes and it merges text
       // node for ime into single text node.
       // So if current selection is into IME text node, it might be failed
@@ -1032,25 +1037,24 @@ EditorBase::EndPlaceHolderTransaction()
       // we saved the selection state, but never got to hand it to placeholder
       // (else we ould have nulled out this pointer), so destroy it to prevent leaks.
       if (mPlaceholderName == nsGkAtoms::IMETxnName) {
         mRangeUpdater.DropSelectionState(*mSelState);
       }
       mSelState = nullptr;
     }
     // We might have never made a placeholder if no action took place.
-    if (mPlaceholderTransactionWeak) {
-      RefPtr<PlaceholderTransaction> placeholderTransaction =
-        mPlaceholderTransactionWeak.get();
-      placeholderTransaction->EndPlaceHolderBatch();
+    if (mPlaceholderTransaction) {
+      mPlaceholderTransaction->EndPlaceHolderBatch();
       // notify editor observers of action but if composing, it's done by
       // compositionchange event handler.
       if (!mComposition) {
         NotifyEditorObservers(eNotifyEditorObserversOfEnd);
       }
+      mPlaceholderTransaction = nullptr;
     } else {
       NotifyEditorObservers(eNotifyEditorObserversOfCancel);
     }
   }
   mPlaceholderBatch--;
 
   return NS_OK;
 }
@@ -2711,17 +2715,18 @@ EditorBase::NotifyDocumentListeners(
     default:
       NS_NOTREACHED("Unknown notification");
   }
 
   return rv;
 }
 
 nsresult
-EditorBase::SetTextImpl(const nsAString& aString, Text& aCharData)
+EditorBase::SetTextImpl(Selection& aSelection, const nsAString& aString,
+                        Text& aCharData)
 {
   RefPtr<SetTextTransaction> transaction =
     CreateTxnForSetText(aString, aCharData);
   if (NS_WARN_IF(!transaction)) {
     return NS_ERROR_FAILURE;
   }
 
   uint32_t length = aCharData.Length();
@@ -2741,17 +2746,17 @@ EditorBase::SetTextImpl(const nsAString&
       if (!aString.IsEmpty()) {
         listener->WillInsertText(
           static_cast<nsIDOMCharacterData*>(aCharData.AsDOMNode()), 0,
           aString);
       }
     }
   }
 
-  nsresult rv = DoTransaction(transaction);
+  nsresult rv = DoTransaction(&aSelection, transaction);
 
   // Let listeners know what happened
   {
     AutoActionListenerArray listeners(mActionListeners);
     for (auto& listener : listeners) {
       if (length) {
         listener->DidDeleteText(
           static_cast<nsIDOMCharacterData*>(aCharData.AsDOMNode()), 0,
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -274,17 +274,18 @@ public:
   virtual nsresult InsertTextImpl(const nsAString& aStringToInsert,
                                   nsCOMPtr<nsINode>* aInOutNode,
                                   int32_t* aInOutOffset,
                                   nsIDocument* aDoc);
   nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
                                       Text& aTextNode, int32_t aOffset,
                                       bool aSuppressIME = false);
 
-  nsresult SetTextImpl(const nsAString& aString,
+  nsresult SetTextImpl(Selection& aSelection,
+                       const nsAString& aString,
                        Text& aTextNode);
 
   NS_IMETHOD DeleteSelectionImpl(EDirection aAction,
                                  EStripWrappers aStripWrappers);
 
   already_AddRefed<Element> DeleteSelectionAndCreateElement(nsIAtom& aTag);
 
   /**
@@ -490,16 +491,20 @@ protected:
 
   void DoAfterUndoTransaction();
 
   /**
    * Called after a transaction is redone successfully.
    */
   void DoAfterRedoTransaction();
 
+  // Note that aSelection is optional and can be nullptr.
+  nsresult DoTransaction(Selection* aSelection,
+                         nsITransaction* aTxn);
+
   enum TDocumentListenerNotification
   {
     eDocumentCreated,
     eDocumentToBeDestroyed,
     eDocumentStateChanged
   };
 
   /**
@@ -1121,18 +1126,18 @@ protected:
   RefPtr<nsTransactionManager> mTxnMgr;
   // Cached root node.
   nsCOMPtr<Element> mRootElement;
   // Current IME text node.
   RefPtr<Text> mIMETextNode;
   // The form field as an event receiver.
   nsCOMPtr<dom::EventTarget> mEventTarget;
   nsCOMPtr<nsIDOMEventListener> mEventListener;
-  // Weak reference to placeholder for begin/end batch purposes.
-  WeakPtr<PlaceholderTransaction> mPlaceholderTransactionWeak;
+  // Strong reference to placeholder for begin/end batch purposes.
+  RefPtr<PlaceholderTransaction> mPlaceholderTransaction;
   // Name of placeholder transaction.
   nsIAtom* mPlaceholderName;
   // Saved selection state for placeholder transaction batching.
   mozilla::UniquePtr<SelectionState> mSelState;
   // IME composition this is not null between compositionstart and
   // compositionend.
   RefPtr<TextComposition> mComposition;
 
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -271,18 +271,18 @@ HTMLEditRules::Init(TextEditor* aTextEdi
 
   // call through to base class Init
   nsresult rv = TextEditRules::Init(aTextEditor);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // cache any prefs we care about
   static const char kPrefName[] =
     "editor.html.typing.returnInEmptyListItemClosesList";
-  nsAdoptingCString returnInEmptyLIKillsList =
-    Preferences::GetCString(kPrefName);
+  nsAutoCString returnInEmptyLIKillsList;
+  Preferences::GetCString(kPrefName, returnInEmptyLIKillsList);
 
   // only when "false", becomes FALSE.  Otherwise (including empty), TRUE.
   // XXX Why was this pref designed as a string and not bool?
   mReturnInEmptyLIKillsList = !returnInEmptyLIKillsList.EqualsLiteral("false");
 
   // make a utility range for use by the listenter
   nsCOMPtr<nsINode> node = mHTMLEditor->GetRoot();
   if (!node) {
@@ -471,17 +471,17 @@ HTMLEditRules::AfterEditInner(EditAction
     }
   }
 
   if (bDamagedRange && !((action == EditAction::undo) ||
                          (action == EditAction::redo))) {
     // don't let any txns in here move the selection around behind our back.
     // Note that this won't prevent explicit selection setting from working.
     NS_ENSURE_STATE(mHTMLEditor);
-    AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
 
     // expand the "changed doc range" as needed
     PromoteRange(*mDocChangeRange, action);
 
     // if we did a ranged deletion or handling backspace key, make sure we have
     // a place to put caret.
     // Note we only want to do this if the overall operation was deletion,
     // not if deletion was done along the way for EditAction::loadHTML, EditAction::insertText, etc.
@@ -1346,19 +1346,19 @@ HTMLEditRules::WillInsertText(EditAction
     NS_ENSURE_SUCCESS(rv, rv);
 
     // turn off the edit listener: we know how to
     // build the "doc changed range" ourselves, and it's
     // must faster to do it once here than to track all
     // the changes one at a time.
     AutoLockListener lockit(&mListenerEnabled);
 
-    // don't spaz my selection in subtransactions
+    // don't change my selection in subtransactions
     NS_ENSURE_STATE(mHTMLEditor);
-    AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
     nsAutoString tString(*inString);
     const char16_t *unicodeBuf = tString.get();
     int32_t pos = 0;
     NS_NAMED_LITERAL_STRING(newlineStr, LFSTR);
 
     {
       NS_ENSURE_STATE(mHTMLEditor);
       AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater,
@@ -2377,17 +2377,17 @@ HTMLEditRules::WillDeleteSelection(Selec
   nsCOMPtr<nsINode> endNode = aSelection->GetRangeAt(0)->GetEndContainer();
   int32_t endOffset = aSelection->GetRangeAt(0)->EndOffset();
   NS_ENSURE_TRUE(endNode, NS_ERROR_FAILURE);
 
   // Figure out if the endpoints are in nodes that can be merged.  Adjust
   // surrounding whitespace in preparation to delete selection.
   if (!IsPlaintextEditor()) {
     NS_ENSURE_STATE(mHTMLEditor);
-    AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
     rv = WSRunObject::PrepareToDeleteRange(mHTMLEditor,
                                            address_of(startNode), &startOffset,
                                            address_of(endNode), &endOffset);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   {
     // Track location of where we are deleting
@@ -2750,17 +2750,17 @@ HTMLEditRules::TryToJoinBlocks(nsIConten
       // sublists in our implementation.
       leftBlock = leftList;
       rightBlock = rightList;
       mergeLists = true;
       existingList = leftList->NodeInfo()->NameAtom();
     }
   }
 
-  AutoTransactionsConserveSelection dontSpazMySelection(htmlEditor);
+  AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
 
   int32_t rightOffset = 0;
   int32_t leftOffset = -1;
 
   // offset below is where you find yourself in rightBlock when you traverse
   // upwards from leftBlock
   if (EditorUtils::IsDescendantOf(leftBlock, rightBlock, &rightOffset)) {
     // Tricky case.  Left block is inside right block.  Do ws adjustment.  This
@@ -3559,17 +3559,17 @@ nsresult
 HTMLEditRules::MakeBasicBlock(Selection& aSelection, nsIAtom& blockType)
 {
   NS_ENSURE_STATE(mHTMLEditor);
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
 
   nsresult rv = NormalizeSelection(&aSelection);
   NS_ENSURE_SUCCESS(rv, rv);
   AutoSelectionRestorer selectionRestorer(&aSelection, htmlEditor);
-  AutoTransactionsConserveSelection dontSpazMySelection(htmlEditor);
+  AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
 
   // Contruct a list of nodes to act on.
   nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
   rv = GetNodesFromSelection(aSelection, EditAction::makeBasicBlock,
                              arrayOfNodes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // If nothing visible in list, make an empty block
@@ -5979,17 +5979,17 @@ HTMLEditRules::GetListActionNodes(
     // the selection spans multiple lists but with no common list parent.
     if (!aOutArrayOfNodes.IsEmpty()) {
       return NS_OK;
     }
   }
 
   {
     // We don't like other people messing with our selection!
-    AutoTransactionsConserveSelection dontSpazMySelection(htmlEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
 
     // contruct a list of nodes to act on.
     nsresult rv = GetNodesFromSelection(*selection, EditAction::makeList,
                                         aOutArrayOfNodes, aTouchContent);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Pre-process our list of nodes
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -3769,17 +3769,17 @@ HTMLEditor::GetEnclosingTable(nsIDOMNode
  * "adjacent" means literally adjacent siblings of the same parent.
  * Uses EditorBase::JoinNodes so action is undoable.
  * Should be called within the context of a batch transaction.
  */
 nsresult
 HTMLEditor::CollapseAdjacentTextNodes(nsRange* aInRange)
 {
   NS_ENSURE_TRUE(aInRange, NS_ERROR_NULL_POINTER);
-  AutoTransactionsConserveSelection dontSpazMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(this);
   nsTArray<nsCOMPtr<nsIDOMNode> > textNodes;
   // we can't actually do anything during iteration, so store the text nodes in an array
   // don't bother ref counting them because we know we can hold them for the
   // lifetime of this method
 
 
   // build a list of editable text nodes
   nsresult rv = NS_ERROR_UNEXPECTED;
@@ -4552,17 +4552,17 @@ HTMLEditor::SetCSSBackgroundColor(const 
   NS_ENSURE_STATE(selection);
 
   bool isCollapsed = selection->Collapsed();
 
   AutoEditBatch batchIt(this);
   AutoRules beginRulesSniffing(this, EditAction::insertElement,
                                nsIEditor::eNext);
   AutoSelectionRestorer selectionRestorer(selection, this);
-  AutoTransactionsConserveSelection dontSpazMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(this);
 
   bool cancel, handled;
   TextRulesInfo ruleInfo(EditAction::setTextProperty);
   nsresult rv = rules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!cancel && !handled) {
     // Loop through the ranges in the selection
     for (uint32_t i = 0; i < selection->RangeCount(); i++) {
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -1146,17 +1146,17 @@ HTMLEditor::InsertFromTransferable(nsITr
   nsresult rv = NS_OK;
   nsAutoCString bestFlavor;
   nsCOMPtr<nsISupports> genericDataObj;
   uint32_t len = 0;
   if (NS_SUCCEEDED(
         transferable->GetAnyTransferData(bestFlavor,
                                          getter_AddRefs(genericDataObj),
                                          &len))) {
-    AutoTransactionsConserveSelection dontSpazMySelection(this);
+    AutoTransactionsConserveSelection dontChangeMySelection(this);
     nsAutoString flavor;
     CopyASCIItoUTF16(bestFlavor, flavor);
     nsAutoString stuffToPaste;
     bool isSafe = IsSafeToInsertData(aSourceDoc);
 
     if (bestFlavor.EqualsLiteral(kFileMime) ||
         bestFlavor.EqualsLiteral(kJPEGImageMime) ||
         bestFlavor.EqualsLiteral(kJPGImageMime) ||
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -121,17 +121,17 @@ HTMLEditor::SetInlineProperty(nsIAtom* a
     mTypeInState->SetProp(aProperty, aAttribute, aValue);
     return NS_OK;
   }
 
   AutoEditBatch batchIt(this);
   AutoRules beginRulesSniffing(this, EditAction::insertElement,
                                nsIEditor::eNext);
   AutoSelectionRestorer selectionRestorer(selection, this);
-  AutoTransactionsConserveSelection dontSpazMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(this);
 
   bool cancel, handled;
   TextRulesInfo ruleInfo(EditAction::setTextProperty);
   // Protect the edit rules object from dying
   nsresult rv = rules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!cancel && !handled) {
     // Loop through the ranges in the selection
@@ -1223,17 +1223,17 @@ HTMLEditor::RemoveInlinePropertyImpl(nsI
     }
     return NS_OK;
   }
 
   AutoEditBatch batchIt(this);
   AutoRules beginRulesSniffing(this, EditAction::removeTextProperty,
                                nsIEditor::eNext);
   AutoSelectionRestorer selectionRestorer(selection, this);
-  AutoTransactionsConserveSelection dontSpazMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(this);
 
   bool cancel, handled;
   TextRulesInfo ruleInfo(EditAction::removeTextProperty);
   // Protect the edit rules object from dying
   nsCOMPtr<nsIEditRules> rules(mRules);
   nsresult rv = rules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!cancel && !handled) {
@@ -1380,17 +1380,17 @@ HTMLEditor::RelativeFontChange(FontSize 
     return NS_OK;
   }
 
   // Wrap with txn batching, rules sniffing, and selection preservation code
   AutoEditBatch batchIt(this);
   AutoRules beginRulesSniffing(this, EditAction::setTextProperty,
                                nsIEditor::eNext);
   AutoSelectionRestorer selectionRestorer(selection, this);
-  AutoTransactionsConserveSelection dontSpazMySelection(this);
+  AutoTransactionsConserveSelection dontChangeMySelection(this);
 
   // Loop through the ranges in the selection
   AutoRangeArray arrayOfRanges(selection);
   for (auto& range : arrayOfRanges.mRanges) {
     // Adjust range to include any ancestors with entirely selected children
     nsresult rv = PromoteInlineRange(*range);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/editor/libeditor/PlaceholderTransaction.h
+++ b/editor/libeditor/PlaceholderTransaction.h
@@ -4,42 +4,37 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef PlaceholderTransaction_h
 #define PlaceholderTransaction_h
 
 #include "EditAggregateTransaction.h"
 #include "mozilla/EditorUtils.h"
 #include "mozilla/UniquePtr.h"
-#include "mozilla/WeakPtr.h"
 #include "nsIAbsorbingTransaction.h"
 #include "nsIDOMNode.h"
 #include "nsCOMPtr.h"
 #include "nsWeakPtr.h"
-#include "nsWeakReference.h"
 
 namespace mozilla {
 
 class CompositionTransaction;
 
 /**
  * An aggregate transaction that knows how to absorb all subsequent
  * transactions with the same name.  This transaction does not "Do" anything.
  * But it absorbs other transactions via merge, and can undo/redo the
  * transactions it has absorbed.
  */
 
 class PlaceholderTransaction final
  : public EditAggregateTransaction
  , public nsIAbsorbingTransaction
- , public SupportsWeakPtr<PlaceholderTransaction>
 {
 public:
-  MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PlaceholderTransaction)
-
   NS_DECL_ISUPPORTS_INHERITED
 
   PlaceholderTransaction(EditorBase& aEditorBase, nsIAtom* aName,
                          UniquePtr<SelectionState> aSelState);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaceholderTransaction,
                                            EditAggregateTransaction)
 // ------------ EditAggregateTransaction -----------------------
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -312,17 +312,17 @@ TextEditRules::WillDoAction(Selection* a
 NS_IMETHODIMP
 TextEditRules::DidDoAction(Selection* aSelection,
                            RulesInfo* aInfo,
                            nsresult aResult)
 {
   NS_ENSURE_STATE(mTextEditor);
   // don't let any txns in here move the selection around behind our back.
   // Note that this won't prevent explicit selection setting from working.
-  AutoTransactionsConserveSelection dontSpazMySelection(mTextEditor);
+  AutoTransactionsConserveSelection dontChangeMySelection(mTextEditor);
 
   NS_ENSURE_TRUE(aSelection && aInfo, NS_ERROR_NULL_POINTER);
 
   // my kingdom for dynamic cast
   TextRulesInfo* info = static_cast<TextRulesInfo*>(aInfo);
 
   switch (info->action) {
     case EditAction::insertBreak:
@@ -783,19 +783,19 @@ TextEditRules::WillInsertText(EditAction
     rv = mTextEditor->InsertTextImpl(*outString, address_of(selNode),
                                      &selOffset, doc);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     // aAction == EditAction::insertText; find where we are
     nsCOMPtr<nsINode> curNode = selNode;
     int32_t curOffset = selOffset;
 
-    // don't spaz my selection in subtransactions
+    // don't change my selection in subtransactions
     NS_ENSURE_STATE(mTextEditor);
-    AutoTransactionsConserveSelection dontSpazMySelection(mTextEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(mTextEditor);
 
     rv = mTextEditor->InsertTextImpl(*outString, address_of(curNode),
                                      &curOffset, doc);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (curNode) {
       // Make the caret attach to the inserted text, unless this text ends with a LF,
       // in which case make the caret attach to the next line.
@@ -896,19 +896,23 @@ TextEditRules::WillSetText(Selection& aS
     return NS_OK;
   }
 
   nsINode* curNode = rootElement->GetFirstChild();
   if (NS_WARN_IF(!EditorBase::IsTextNode(curNode))) {
     return NS_OK;
   }
 
+  // don't change my selection in subtransactions
+  AutoTransactionsConserveSelection dontChangeMySelection(textEditor);
+
   // Even if empty text, we don't remove text node and set empty text
   // for performance
-  nsresult rv = textEditor->SetTextImpl(tString, *curNode->GetAsText());
+  nsresult rv = textEditor->SetTextImpl(aSelection, tString,
+                                        *curNode->GetAsText());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   *aHandled = true;
 
   ASSERT_PASSWORD_LENGTHS_EQUAL();
 
@@ -1386,17 +1390,17 @@ TextEditRules::CreateTrailingBRIfNeeded(
   dom::Element* body = mTextEditor->GetRoot();
   NS_ENSURE_TRUE(body, NS_ERROR_NULL_POINTER);
 
   nsIContent* lastChild = body->GetLastChild();
   // assuming CreateBogusNodeIfNeeded() has been called first
   NS_ENSURE_TRUE(lastChild, NS_ERROR_NULL_POINTER);
 
   if (!lastChild->IsHTMLElement(nsGkAtoms::br)) {
-    AutoTransactionsConserveSelection dontSpazMySelection(mTextEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(mTextEditor);
     nsCOMPtr<nsIDOMNode> domBody = do_QueryInterface(body);
     return CreateMozBR(domBody, body->Length());
   }
 
   // Check to see if the trailing BR is a former bogus node - this will have
   // stuck around if we previously morphed a trailing node into a bogus node.
   if (!mTextEditor->IsMozEditorBogusNode(lastChild)) {
     return NS_OK;
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -723,18 +723,18 @@ TextEditor::InsertLineBreak()
                                                *nsGkAtoms::textTagName)) {
       return NS_ERROR_FAILURE;
     }
 
     // we need to get the doc
     nsCOMPtr<nsIDocument> doc = GetDocument();
     NS_ENSURE_TRUE(doc, NS_ERROR_NOT_INITIALIZED);
 
-    // don't spaz my selection in subtransactions
-    AutoTransactionsConserveSelection dontSpazMySelection(this);
+    // don't change my selection in subtransactions
+    AutoTransactionsConserveSelection dontChangeMySelection(this);
 
     // insert a linefeed character
     rv = InsertTextImpl(NS_LITERAL_STRING("\n"), address_of(selNode),
                         &selOffset, doc);
     if (!selNode) {
       rv = NS_ERROR_NULL_POINTER; // don't return here, so DidDoAction is called
     }
     if (NS_SUCCEEDED(rv)) {
--- a/editor/libeditor/TextEditorDataTransfer.cpp
+++ b/editor/libeditor/TextEditorDataTransfer.cpp
@@ -108,17 +108,17 @@ TextEditor::InsertTextFromTransferable(n
   nsCOMPtr<nsISupports> genericDataObj;
   uint32_t len = 0;
   if (NS_SUCCEEDED(
         aTransferable->GetAnyTransferData(bestFlavor,
                                           getter_AddRefs(genericDataObj),
                                           &len)) &&
       (bestFlavor.EqualsLiteral(kUnicodeMime) ||
        bestFlavor.EqualsLiteral(kMozTextInternal))) {
-    AutoTransactionsConserveSelection dontSpazMySelection(this);
+    AutoTransactionsConserveSelection dontChangeMySelection(this);
     nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
     if (textDataObj && len > 0) {
       nsAutoString stuffToPaste;
       textDataObj->GetData(stuffToPaste);
       NS_ASSERTION(stuffToPaste.Length() <= (len/2), "Invalid length!");
 
       // Sanitize possible carriage returns in the string to be inserted
       nsContentUtils::PlatformToDOMLineBreaks(stuffToPaste);
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -1419,17 +1419,17 @@ WSRunObject::GetCharBefore(const WSPoint
 nsresult
 WSRunObject::ConvertToNBSP(WSPoint aPoint)
 {
   // MOOSE: this routine needs to be modified to preserve the integrity of the
   // wsFragment info.
   NS_ENSURE_TRUE(aPoint.mTextNode, NS_ERROR_NULL_POINTER);
 
   // First, insert an nbsp
-  AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
+  AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
   nsAutoString nbspStr(nbsp);
   nsresult rv =
     mHTMLEditor->InsertTextIntoTextNodeImpl(nbspStr, *aPoint.mTextNode,
                                             aPoint.mOffset, true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Next, find range of ws it will replace
   RefPtr<Text> startNode, endNode;
@@ -1743,17 +1743,17 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
         // Refresh thePoint, prevPoint
         thePoint = GetCharBefore(aRun->mEndNode, aRun->mEndOffset);
         prevPoint = GetCharBefore(thePoint);
         rightCheck = true;
       }
     }
     if (leftCheck && rightCheck) {
       // Now replace nbsp with space.  First, insert a space
-      AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
+      AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
       nsAutoString spaceStr(char16_t(32));
       nsresult rv =
         mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr, *thePoint.mTextNode,
                                                 thePoint.mOffset, true);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Finally, delete that nbsp
       rv = DeleteChars(thePoint.mTextNode, thePoint.mOffset + 1,
@@ -1774,17 +1774,17 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
                        getter_AddRefs(endNode), &endOffset);
 
       // Delete that nbsp
       nsresult rv = DeleteChars(thePoint.mTextNode, thePoint.mOffset,
                                 thePoint.mTextNode, thePoint.mOffset + 1);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Finally, insert that nbsp before the ASCII ws run
-      AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
+      AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
       nsAutoString nbspStr(nbsp);
       rv = mHTMLEditor->InsertTextIntoTextNodeImpl(nbspStr, *startNode,
                                                    startOffset, true);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
   return NS_OK;
 }
@@ -1810,17 +1810,17 @@ WSRunObject::CheckTrailingNBSP(WSFragmen
       }
     } else if (aRun->mLeftType == WSType::text ||
                aRun->mLeftType == WSType::special) {
       canConvert = true;
     }
   }
   if (canConvert) {
     // First, insert a space
-    AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
     nsAutoString spaceStr(char16_t(32));
     nsresult rv =
       mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr, *thePoint.mTextNode,
                                               thePoint.mOffset, true);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Finally, delete that nbsp
     rv = DeleteChars(thePoint.mTextNode, thePoint.mOffset + 1,
@@ -1853,17 +1853,17 @@ WSRunObject::CheckLeadingNBSP(WSFragment
     } else if (aRun->mRightType == WSType::text ||
                aRun->mRightType == WSType::special ||
                aRun->mRightType == WSType::br) {
       canConvert = true;
     }
   }
   if (canConvert) {
     // First, insert a space
-    AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
+    AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
     nsAutoString spaceStr(char16_t(32));
     nsresult rv =
       mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr, *thePoint.mTextNode,
                                               thePoint.mOffset, true);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Finally, delete that nbsp
     rv = DeleteChars(thePoint.mTextNode, thePoint.mOffset + 1,
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -2852,17 +2852,18 @@ nsPermissionManager::Import()
   return NS_OK;
 }
 
 // ImportDefaults will read a URL with default permissions and add them to the
 // in-memory copy of permissions.  The database is *not* written to.
 nsresult
 nsPermissionManager::ImportDefaults()
 {
-  nsCString defaultsURL = mozilla::Preferences::GetCString(kDefaultsUrlPrefName);
+  nsAutoCString defaultsURL;
+  mozilla::Preferences::GetCString(kDefaultsUrlPrefName, defaultsURL);
   if (defaultsURL.IsEmpty()) { // == Don't use built-in permissions.
     return NS_OK;
   }
 
   nsCOMPtr<nsIURI> defaultsURI;
   nsresult rv = NS_NewURI(getter_AddRefs(defaultsURI), defaultsURL);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -73,18 +73,18 @@ static PRLibrary* LoadApitraceLibrary()
         return nullptr;
     }
 
     static PRLibrary* sApitraceLibrary = nullptr;
 
     if (sApitraceLibrary)
         return sApitraceLibrary;
 
-    nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
-
+    nsAutoCString logFile;
+    Preferences::GetCString("gfx.apitrace.logfile", logFile);
     if (logFile.IsEmpty()) {
         logFile = "firefox.trace";
     }
 
     // The firefox process can't write to /data/local, but it can write
     // to $GRE_HOME/
     nsAutoCString logPath;
     logPath.AppendPrintf("%s/%s", getenv("GRE_HOME"), logFile.get());
--- a/gfx/src/DriverCrashGuard.cpp
+++ b/gfx/src/DriverCrashGuard.cpp
@@ -346,17 +346,18 @@ DriverCrashGuard::CheckAndUpdateBoolPref
   return true;
 }
 
 bool
 DriverCrashGuard::CheckAndUpdatePref(const char* aPrefName, const nsAString& aCurrentValue)
 {
   std::string pref = GetFullPrefName(aPrefName);
 
-  nsAdoptingString oldValue = Preferences::GetString(pref.c_str());
+  nsAutoString oldValue;
+  Preferences::GetString(pref.c_str(), oldValue);
   if (oldValue == aCurrentValue) {
     return false;
   }
   Preferences::SetString(pref.c_str(), aCurrentValue);
   return true;
 }
 
 std::string
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -986,19 +986,21 @@ gfxDWriteFontList::InitFontListForPlatfo
                 }
             }
 
             // remove Gills Sans
             mFontFamilies.Remove(nameGillSans);
         }
     }
 
-    nsAdoptingCString classicFamilies =
-        Preferences::GetCString("gfx.font_rendering.cleartype_params.force_gdi_classic_for_families");
-    if (classicFamilies) {
+    nsAutoCString classicFamilies;
+    nsresult rv = Preferences::GetCString(
+      "gfx.font_rendering.cleartype_params.force_gdi_classic_for_families",
+      classicFamilies);
+    if (NS_SUCCEEDED(rv)) {
         nsCCharSeparatedTokenizer tokenizer(classicFamilies, ',');
         while (tokenizer.hasMoreTokens()) {
             NS_ConvertUTF8toUTF16 name(tokenizer.nextToken());
             BuildKeyNameFromFontName(name);
             gfxFontFamily *family = mFontFamilies.GetWeak(name);
             if (family) {
                 static_cast<gfxDWriteFontFamily*>(family)->SetForceGDIClassic(true);
             }
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -1693,27 +1693,31 @@ gfxFcPlatformFontList::AddGenericFonts(m
 
     // By default, most font prefs on Linux map to "use fontconfig"
     // keywords. So only need to explicitly lookup font pref if
     // non-default settings exist
     NS_ConvertASCIItoUTF16 genericToLookup(generic);
     if ((!mAlwaysUseFontconfigGenerics && aLanguage) ||
         aLanguage == nsGkAtoms::x_math) {
         nsIAtom* langGroup = GetLangGroup(aLanguage);
-        nsAdoptingString fontlistValue =
-            Preferences::GetString(NamePref(generic, langGroup).get());
+        nsAutoString fontlistValue;
+        Preferences::GetString(NamePref(generic, langGroup).get(),
+                               fontlistValue);
+        nsresult rv;
         if (fontlistValue.IsEmpty()) {
             // The font name list may have two or more family names as comma
             // separated list.  In such case, not matching with generic font
             // name is fine because if the list prefers specific font, we
             // should try to use the pref with complicated path.
-            fontlistValue =
-                 Preferences::GetString(NameListPref(generic, langGroup).get());
+            rv = Preferences::GetString(NameListPref(generic, langGroup).get(),
+                                        fontlistValue);
+        } else {
+            rv = NS_OK;
         }
-        if (fontlistValue) {
+        if (NS_SUCCEEDED(rv)) {
             if (!fontlistValue.EqualsLiteral("serif") &&
                 !fontlistValue.EqualsLiteral("sans-serif") &&
                 !fontlistValue.EqualsLiteral("monospace")) {
                 usePrefFontList = true;
             } else {
                 // serif, sans-serif or monospace was specified
                 genericToLookup.Assign(fontlistValue);
             }
@@ -1893,25 +1897,25 @@ gfxFcPlatformFontList::PrefFontListsUseO
             //       font.name-list.serif.ar ==> "Something, serif"
             //                                           (return false)
 
             nsDependentCString prefName(names[i] +
                                         ArrayLength(kFontNamePrefix) - 1);
             nsCCharSeparatedTokenizer tokenizer(prefName, '.');
             const nsDependentCSubstring& generic = tokenizer.nextToken();
             const nsDependentCSubstring& langGroup = tokenizer.nextToken();
-            nsAdoptingCString fontPrefValue = Preferences::GetCString(names[i]);
+            nsAutoCString fontPrefValue;
+            Preferences::GetCString(names[i], fontPrefValue);
             if (fontPrefValue.IsEmpty()) {
                 // The font name list may have two or more family names as comma
                 // separated list.  In such case, not matching with generic font
                 // name is fine because if the list prefers specific font, this
                 // should return false.
-                fontPrefValue =
-                    Preferences::GetCString(NameListPref(generic,
-                                                         langGroup).get());
+                Preferences::GetCString(NameListPref(generic, langGroup).get(),
+                                        fontPrefValue);
             }
 
             if (!langGroup.EqualsLiteral("x-math") &&
                 !generic.Equals(fontPrefValue)) {
                 prefFontsUseOnlyGenerics = false;
                 break;
             }
         }
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -855,18 +855,19 @@ void gfxFontUtils::ParseFontList(const n
         ++p;
     }
 }
 
 void gfxFontUtils::AppendPrefsFontList(const char *aPrefName,
                                        nsTArray<nsString>& aFontList)
 {
     // get the list of single-face font families
-    nsAdoptingString fontlistValue = Preferences::GetString(aPrefName);
-    if (!fontlistValue) {
+    nsAutoString fontlistValue;
+    nsresult rv = Preferences::GetString(aPrefName, fontlistValue);
+    if (NS_FAILED(rv)) {
         return;
     }
 
     ParseFontList(fontlistValue, aFontList);
 }
 
 void gfxFontUtils::GetPrefsFontList(const char *aPrefName,
                                     nsTArray<nsString>& aFontList)
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -565,19 +565,19 @@ gfxPlatform::InitChild(const ContentDevi
   Init();
   gContentDeviceInitData = nullptr;
 }
 
 void RecordingPrefChanged(const char *aPrefName, void *aClosure)
 {
   if (Preferences::GetBool("gfx.2d.recording", false)) {
     nsAutoCString fileName;
-    nsAdoptingString prefFileName = Preferences::GetString("gfx.2d.recordingfile");
-
-    if (prefFileName) {
+    nsAutoString prefFileName;
+    nsresult rv = Preferences::GetString("gfx.2d.recordingfile", prefFileName);
+    if (NS_SUCCEEDED(rv)) {
       fileName.Append(NS_ConvertUTF16toUTF8(prefFileName));
     } else {
       nsCOMPtr<nsIFile> tmpFile;
       if (NS_FAILED(NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpFile)))) {
         return;
       }
       fileName.AppendPrintf("moz2drec_%i_%i.aer", XRE_GetProcessType(), getpid());
 
@@ -640,18 +640,22 @@ gfxPlatform::Init()
 
     if (XRE_IsParentProcess()) {
       GPUProcessManager::Initialize();
 
       if (Preferences::GetBool("media.wmf.skip-blacklist")) {
         gfxVars::SetPDMWMFDisableD3D11Dlls(nsCString());
         gfxVars::SetPDMWMFDisableD3D9Dlls(nsCString());
       } else {
-        gfxVars::SetPDMWMFDisableD3D11Dlls(Preferences::GetCString("media.wmf.disable-d3d11-for-dlls"));
-        gfxVars::SetPDMWMFDisableD3D9Dlls(Preferences::GetCString("media.wmf.disable-d3d9-for-dlls"));
+        nsAutoCString d3d11;
+        Preferences::GetCString("media.wmf.disable-d3d11-for-dlls", d3d11);
+        gfxVars::SetPDMWMFDisableD3D11Dlls(d3d11);
+        nsAutoCString d3d9;
+        Preferences::GetCString("media.wmf.disable-d3d9-for-dlls", d3d9);
+        gfxVars::SetPDMWMFDisableD3D9Dlls(d3d9);
       }
 
       nsCOMPtr<nsIFile> file;
       nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file));
       if (NS_FAILED(rv)) {
         gfxVars::SetGREDirectory(nsCString());
       } else {
         nsAutoCString nativePath;
@@ -1820,18 +1824,18 @@ gfxPlatform::GetContentBackendPref(uint3
 {
     return GetBackendPref("gfx.content.azure.backends", aBackendBitmask);
 }
 
 /* static */ BackendType
 gfxPlatform::GetBackendPref(const char* aBackendPrefName, uint32_t &aBackendBitmask)
 {
     nsTArray<nsCString> backendList;
-    nsCString prefString;
-    if (NS_SUCCEEDED(Preferences::GetCString(aBackendPrefName, &prefString))) {
+    nsAutoCString prefString;
+    if (NS_SUCCEEDED(Preferences::GetCString(aBackendPrefName, prefString))) {
         ParseString(prefString, ',', backendList);
     }
 
     uint32_t allowedBackends = 0;
     BackendType result = BackendType::NONE;
     for (uint32_t i = 0; i < backendList.Length(); ++i) {
         BackendType type = BackendTypeForName(backendList[i]);
         if (BackendTypeBit(type) & aBackendBitmask) {
@@ -1937,19 +1941,20 @@ gfxPlatform::GetPlatformCMSOutputProfile
 {
     mem = nullptr;
     size = 0;
 }
 
 void
 gfxPlatform::GetCMSOutputProfileData(void *&mem, size_t &size)
 {
-    nsAdoptingCString fname = Preferences::GetCString("gfx.color_management.display_profile");
+    nsAutoCString fname;
+    Preferences::GetCString("gfx.color_management.display_profile", fname);
     if (!fname.IsEmpty()) {
-        qcms_data_from_path(fname, &mem, &size);
+        qcms_data_from_path(fname.get(), &mem, &size);
     }
     else {
         gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfile(mem, size);
     }
 }
 
 void
 gfxPlatform::CreateCMSOutputProfile()
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -1084,17 +1084,18 @@ gfxPlatformFontList::AppendCJKPrefLangs(
     // if not set up, set up the default CJK order, based on accept lang settings and locale
     if (mCJKPrefLangs.Length() == 0) {
 
         // temp array
         eFontPrefLang tempPrefLangs[kMaxLenPrefLangList];
         uint32_t tempLen = 0;
 
         // Add the CJK pref fonts from accept languages, the order should be same order
-        nsAdoptingCString list = Preferences::GetLocalizedCString("intl.accept_languages");
+        nsAutoCString list;
+        Preferences::GetLocalizedCString("intl.accept_languages", list);
         if (!list.IsEmpty()) {
             const char kComma = ',';
             const char *p, *p_end;
             list.BeginReading(p);
             list.EndReading(p_end);
             while (p < p_end) {
                 while (nsCRT::IsAsciiSpace(*p)) {
                     if (++p == p_end)
@@ -1210,18 +1211,18 @@ mozilla::FontFamilyType
 gfxPlatformFontList::GetDefaultGeneric(eFontPrefLang aLang)
 {
     // initialize lang group pref font defaults (i.e. serif/sans-serif)
     if (MOZ_UNLIKELY(mDefaultGenericsLangGroup.IsEmpty())) {
         mDefaultGenericsLangGroup.AppendElements(ArrayLength(gPrefLangNames));
         for (uint32_t i = 0; i < ArrayLength(gPrefLangNames); i++) {
             nsAutoCString prefDefaultFontType("font.default.");
             prefDefaultFontType.Append(GetPrefLangName(eFontPrefLang(i)));
-            nsAdoptingCString serifOrSans =
-                Preferences::GetCString(prefDefaultFontType.get());
+            nsAutoCString serifOrSans;
+            Preferences::GetCString(prefDefaultFontType.get(), serifOrSans);
             if (serifOrSans.EqualsLiteral("sans-serif")) {
                 mDefaultGenericsLangGroup[i] = eFamily_sans_serif;
             } else {
                 mDefaultGenericsLangGroup[i] = eFamily_serif;
             }
         }
     }
 
--- a/gfx/thebes/gfxPrefs.cpp
+++ b/gfx/thebes/gfxPrefs.cpp
@@ -193,17 +193,17 @@ float gfxPrefs::PrefGet(const char* aPre
   return Preferences::GetFloat(aPref, aDefault);
 }
 
 std::string gfxPrefs::PrefGet(const char* aPref, std::string aDefault)
 {
   MOZ_ASSERT(IsPrefsServiceAvailable());
 
   nsAdoptingCString result;
-  Preferences::GetCString(aPref, &result);
+  Preferences::GetCString(aPref, result);
 
   if (result.IsEmpty()) {
     return aDefault;
   }
 
   return result.get();
 }
 
--- a/gfx/vr/gfxVROSVR.cpp
+++ b/gfx/vr/gfxVROSVR.cpp
@@ -110,28 +110,26 @@ static pfn_osvrClientSetRoomRotationUsin
 bool
 LoadOSVRRuntime()
 {
   static PRLibrary* osvrUtilLib = nullptr;
   static PRLibrary* osvrCommonLib = nullptr;
   static PRLibrary* osvrClientLib = nullptr;
   static PRLibrary* osvrClientKitLib = nullptr;
   //this looks up the path in the about:config setting, from greprefs.js or modules\libpref\init\all.js
-  nsAdoptingCString osvrUtilPath =
-    mozilla::Preferences::GetCString("gfx.vr.osvr.utilLibPath");
-  nsAdoptingCString osvrCommonPath =
-    mozilla::Preferences::GetCString("gfx.vr.osvr.commonLibPath");
-  nsAdoptingCString osvrClientPath =
-    mozilla::Preferences::GetCString("gfx.vr.osvr.clientLibPath");
-  nsAdoptingCString osvrClientKitPath =
-    mozilla::Preferences::GetCString("gfx.vr.osvr.clientKitLibPath");
-
   //we need all the libs to be valid
-  if ((!osvrUtilPath) || (!osvrCommonPath) || (!osvrClientPath) ||
-      (!osvrClientKitPath)) {
+  nsAutoCString osvrUtilPath, osvrCommonPath, osvrClientPath, osvrClientKitPath;
+  if (NS_FAILED(mozilla::Preferences::GetCString("gfx.vr.osvr.utilLibPath",
+                                                 osvrUtilPath)) ||
+      NS_FAILED(mozilla::Preferences::GetCString("gfx.vr.osvr.commonLibPath",
+                                                 osvrCommonPath)) ||
+      NS_FAILED(mozilla::Preferences::GetCString("gfx.vr.osvr.clientLibPath",
+                                                 osvrClientPath)) ||
+      NS_FAILED(mozilla::Preferences::GetCString("gfx.vr.osvr.clientKitLibPath",
+                                                 osvrClientKitPath))) {
     return false;
   }
 
   osvrUtilLib = PR_LoadLibrary(osvrUtilPath.BeginReading());
   osvrCommonLib = PR_LoadLibrary(osvrCommonPath.BeginReading());
   osvrClientLib = PR_LoadLibrary(osvrClientPath.BeginReading());
   osvrClientKitLib = PR_LoadLibrary(osvrClientKitPath.BeginReading());
 
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -1341,22 +1341,23 @@ imgLoader::Observe(nsISupports* aSubject
     MOZ_ASSERT(0, "Invalid topic received");
   }
 
   return NS_OK;
 }
 
 void imgLoader::ReadAcceptHeaderPref()
 {
-  nsAdoptingCString accept = Preferences::GetCString("image.http.accept");
-  if (accept) {
+  nsAutoCString accept;
+  nsresult rv = Preferences::GetCString("image.http.accept", accept);
+  if (NS_SUCCEEDED(rv)) {
     mAcceptHeader = accept;
   } else {
     mAcceptHeader =
-        IMAGE_PNG "," IMAGE_WILDCARD ";q=0.8," ANY_WILDCARD ";q=0.5";
+      IMAGE_PNG "," IMAGE_WILDCARD ";q=0.8," ANY_WILDCARD ";q=0.5";
   }
 }
 
 NS_IMETHODIMP
 imgLoader::ClearCache(bool chrome)
 {
   if (XRE_IsParentProcess()) {
     bool privateLoader = this == gPrivateBrowsingLoader;
--- a/intl/hyphenation/glue/nsHyphenationManager.cpp
+++ b/intl/hyphenation/glue/nsHyphenationManager.cpp
@@ -300,18 +300,19 @@ nsHyphenationManager::LoadAliases()
     return;
   }
   uint32_t prefCount;
   char **prefNames;
   nsresult rv = prefRootBranch->GetChildList(kIntlHyphenationAliasPrefix,
                                              &prefCount, &prefNames);
   if (NS_SUCCEEDED(rv) && prefCount > 0) {
     for (uint32_t i = 0; i < prefCount; ++i) {
-      nsAdoptingCString value = Preferences::GetCString(prefNames[i]);
-      if (value) {
+      nsAutoCString value;
+      rv = Preferences::GetCString(prefNames[i], value);
+      if (NS_SUCCEEDED(rv)) {
         nsAutoCString alias(prefNames[i]);
         alias.Cut(0, sizeof(kIntlHyphenationAliasPrefix) - 1);
         ToLowerCase(alias);
         ToLowerCase(value);
         nsCOMPtr<nsIAtom> aliasAtom = NS_Atomize(alias);
         nsCOMPtr<nsIAtom> valueAtom = NS_Atomize(value);
         mHyphAliases.Put(aliasAtom, valueAtom);
       }
--- a/intl/locale/LocaleService.cpp
+++ b/intl/locale/LocaleService.cpp
@@ -90,17 +90,17 @@ ReadRequestedLocales(nsTArray<nsCString>
     // If he has, we'll pick the locale from the system
     if (OSPreferences::GetInstance()->GetSystemLocales(aRetVal)) {
       // If we succeeded, return.
       return true;
     }
   }
 
   // Otherwise, we'll try to get the requested locale from the prefs.
-  if (!NS_SUCCEEDED(Preferences::GetCString(SELECTED_LOCALE_PREF, &locale))) {
+  if (!NS_SUCCEEDED(Preferences::GetCString(SELECTED_LOCALE_PREF, locale))) {
     return false;
   }
 
   // At the moment we just take a single locale, but in the future
   // we'll want to allow user to specify a list of requested locales.
   aRetVal.AppendElement(locale);
   return true;
 }
@@ -507,22 +507,22 @@ LocaleService::IsAppLocaleRTL()
   }
   return uloc_isRightToLeft(locale.get());
 #else
   // first check the intl.uidirection.<locale> preference, and if that is not
   // set, check the same preference but with just the first two characters of
   // the locale. If that isn't set, default to left-to-right.
   nsAutoCString prefString = NS_LITERAL_CSTRING("intl.uidirection.") + locale;
   nsAutoCString dir;
-  Preferences::GetCString(prefString.get(), &dir);
+  Preferences::GetCString(prefString.get(), dir);
   if (dir.IsEmpty()) {
     int32_t hyphen = prefString.FindChar('-');
     if (hyphen >= 1) {
       prefString.Truncate(hyphen);
-      Preferences::GetCString(prefString.get(), &dir);
+      Preferences::GetCString(prefString.get(), dir);
     }
   }
   return dir.EqualsLiteral("rtl");
 #endif
 }
 
 NS_IMETHODIMP
 LocaleService::Observe(nsISupports *aSubject, const char *aTopic,
--- a/intl/locale/android/OSPreferences_android.cpp
+++ b/intl/locale/android/OSPreferences_android.cpp
@@ -14,17 +14,18 @@ OSPreferences::ReadSystemLocales(nsTArra
 {
   //XXX: This is a quite sizable hack to work around the fact that we cannot
   //     retrieve OS locale in C++ without reaching out to JNI.
   //     Once we fix this (bug 1337078), this hack should not be necessary.
   //
   //XXX: Notice, this value may be empty on an early read. In that case
   //     we won't add anything to the return list so that it doesn't get
   //     cached in mSystemLocales.
-  nsAdoptingCString locale = Preferences::GetCString("intl.locale.os");
+  nsAutoCString locale;
+  Preferences::GetCString("intl.locale.os", locale);
   if (!locale.IsEmpty()) {
     aLocaleList.AppendElement(locale);
     return true;
   }
   return false;
 }
 
 bool
--- a/intl/uconv/nsTextToSubURI.cpp
+++ b/intl/uconv/nsTextToSubURI.cpp
@@ -149,17 +149,17 @@ NS_IMETHODIMP  nsTextToSubURI::UnEscapeU
     // assume UTF-8 instead of ASCII  because hostname (IDN) may be in UTF-8
     CopyUTF8toUTF16(aURIFragment, _retval);
   }
 
   // If there are any characters that are unsafe for URIs, reescape those.
   if (mUnsafeChars.IsEmpty()) {
     nsAdoptingString blacklist;
     nsresult rv = mozilla::Preferences::GetString("network.IDN.blacklist_chars",
-                                                  &blacklist);
+                                                  blacklist);
     if (NS_SUCCEEDED(rv)) {
       // we allow SPACE and IDEOGRAPHIC SPACE in this method
       blacklist.StripChars(u" \u3000");
       mUnsafeChars.AppendElements(static_cast<const char16_t*>(blacklist.Data()),
                                   blacklist.Length());
     } else {
       NS_WARNING("Failed to get the 'network.IDN.blacklist_chars' preference");
     }
--- a/js/ipc/JavaScriptParent.cpp
+++ b/js/ipc/JavaScriptParent.cpp
@@ -68,19 +68,21 @@ ForbidUnsafeBrowserCPOWs()
 static bool
 ForbidCPOWsInCompatibleAddon(const nsACString& aAddonId)
 {
     bool forbid = Preferences::GetBool("dom.ipc.cpows.forbid-cpows-in-compat-addons", false);
     if (!forbid) {
         return false;
     }
 
-    nsCString allow;
+    nsAutoCString allow;
     allow.Assign(',');
-    allow.Append(Preferences::GetCString("dom.ipc.cpows.allow-cpows-in-compat-addons"));
+    nsAutoCString pref;
+    Preferences::GetCString("dom.ipc.cpows.allow-cpows-in-compat-addons", pref);
+    allow.Append(pref);
     allow.Append(',');
 
     nsCString searchString(",");
     searchString.Append(aAddonId);
     searchString.Append(',');
     return allow.Find(searchString) == kNotFound;
 }
 
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -483,16 +483,64 @@ GetBuiltinTagSlow(JSContext* cx, HandleO
                 return true;
             }
         }
         builtinTag.set(nullptr);
         return true;
     }
 }
 
+static MOZ_ALWAYS_INLINE JSString*
+GetBuiltinTagFast(JSObject* obj, const Class* clasp, JSContext* cx)
+{
+    MOZ_ASSERT(clasp == obj->getClass());
+    MOZ_ASSERT(!clasp->isProxy());
+
+    // Optimize the non-proxy case to bypass GetBuiltinClass.
+    if (clasp == &PlainObject::class_ || clasp == &UnboxedPlainObject::class_) {
+        // This is not handled by GetBuiltinTagSlow, but this case is by far
+        // the most common so we optimize it here.
+        return cx->names().objectObject;
+    }
+
+    if (clasp == &ArrayObject::class_ || clasp == &UnboxedArrayObject::class_)
+        return cx->names().objectArray;
+
+    if (clasp == &JSFunction::class_)
+        return cx->names().objectFunction;
+
+    if (clasp == &StringObject::class_)
+        return cx->names().objectString;
+
+    if (clasp == &NumberObject::class_)
+        return cx->names().objectNumber;
+
+    if (clasp == &BooleanObject::class_)
+        return cx->names().objectBoolean;
+
+    if (clasp == &DateObject::class_)
+        return cx->names().objectDate;
+
+    if (clasp == &RegExpObject::class_)
+        return cx->names().objectRegExp;
+
+    if (obj->is<ArgumentsObject>())
+        return cx->names().objectArguments;
+
+    if (obj->is<ErrorObject>())
+        return cx->names().objectError;
+
+    if (obj->isCallable() && !obj->getClass()->isDOMClass()) {
+        // Non-standard: Prevent <object> from showing up as Function.
+        return cx->names().objectFunction;
+    }
+
+    return nullptr;
+}
+
 // ES6 19.1.3.6
 bool
 js::obj_toString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     // Step 1.
     if (args.thisv().isUndefined()) {
@@ -512,53 +560,17 @@ js::obj_toString(JSContext* cx, unsigned
         return false;
 
     RootedString builtinTag(cx);
     const Class* clasp = obj->getClass();
     if (MOZ_UNLIKELY(clasp->isProxy())) {
         if (!GetBuiltinTagSlow(cx, obj, &builtinTag))
             return false;
     } else {
-        // Optimize the non-proxy case to bypass GetBuiltinClass.
-        if (clasp == &PlainObject::class_ || clasp == &UnboxedPlainObject::class_) {
-            // This is not handled by GetBuiltinTagSlow, but this case is by far
-            // the most common so we optimize it here.
-            builtinTag = cx->names().objectObject;
-
-        } else if (clasp == &ArrayObject::class_ || clasp == &UnboxedArrayObject::class_) {
-            builtinTag = cx->names().objectArray;
-
-        } else if (clasp == &JSFunction::class_) {
-            builtinTag = cx->names().objectFunction;
-
-        } else if (clasp == &StringObject::class_) {
-            builtinTag = cx->names().objectString;
-
-        } else if (clasp == &NumberObject::class_) {
-            builtinTag = cx->names().objectNumber;
-
-        } else if (clasp == &BooleanObject::class_) {
-            builtinTag = cx->names().objectBoolean;
-
-        } else if (clasp == &DateObject::class_) {
-            builtinTag = cx->names().objectDate;
-
-        } else if (clasp == &RegExpObject::class_) {
-            builtinTag = cx->names().objectRegExp;
-
-        } else if (obj->is<ArgumentsObject>()) {
-            builtinTag = cx->names().objectArguments;
-
-        } else if (obj->is<ErrorObject>()) {
-            builtinTag = cx->names().objectError;
-
-        } else if (obj->isCallable() && !obj->getClass()->isDOMClass()) {
-            // Non-standard: Prevent <object> from showing up as Function.
-            builtinTag = cx->names().objectFunction;
-        }
+        builtinTag = GetBuiltinTagFast(obj, clasp, cx);
 #ifdef DEBUG
         // Assert this fast path is correct and matches BuiltinTagSlow. The
         // only exception is the PlainObject case: we special-case it here
         // because it's so common, but BuiltinTagSlow doesn't handle this.
         RootedString builtinTagSlow(cx);
         if (!GetBuiltinTagSlow(cx, obj, &builtinTagSlow))
             return false;
         if (clasp == &PlainObject::class_ || clasp == &UnboxedPlainObject::class_)
@@ -605,16 +617,36 @@ js::obj_toString(JSContext* cx, unsigned
     JSString* str = sb.finishAtom();
     if (!str)
         return false;
 
     args.rval().setString(str);
     return true;
 }
 
+JSString*
+js::ObjectClassToString(JSContext* cx, HandleObject obj)
+{
+    const Class* clasp = obj->getClass();
+
+    if (JSString* tag = GetBuiltinTagFast(obj, clasp, cx))
+        return tag;
+
+    const char* className = clasp->name;
+    StringBuffer sb(cx);
+    if (!sb.append("[object ") ||
+        !sb.append(className, strlen(className)) ||
+        !sb.append(']'))
+    {
+        return nullptr;
+    }
+
+    return sb.finishAtom();
+}
+
 static bool
 obj_setPrototypeOf(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     if (args.length() < 2) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                                   "Object.setPrototypeOf", "1", "");
@@ -1504,17 +1536,17 @@ ProtoSetter(JSContext* cx, unsigned argc
     args.rval().setUndefined();
     return true;
 }
 
 static const JSFunctionSpec object_methods[] = {
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str,             obj_toSource,                0,0),
 #endif
-    JS_FN(js_toString_str,             obj_toString,                0,0),
+    JS_INLINABLE_FN(js_toString_str,   obj_toString,                0,0, ObjectToString),
     JS_SELF_HOSTED_FN(js_toLocaleString_str, "Object_toLocaleString", 0, 0),
     JS_SELF_HOSTED_FN(js_valueOf_str,  "Object_valueOf",            0,0),
 #if JS_HAS_OBJ_WATCHPOINT
     JS_FN(js_watch_str,                obj_watch,                   2,0),
     JS_FN(js_unwatch_str,              obj_unwatch,                 1,0),
 #endif
     JS_SELF_HOSTED_FN(js_hasOwnProperty_str, "Object_hasOwnProperty", 1,0),
     JS_FN(js_isPrototypeOf_str,        obj_isPrototypeOf,           1,0),
--- a/js/src/builtin/Object.h
+++ b/js/src/builtin/Object.h
@@ -50,16 +50,19 @@ obj_getPrototypeOf(JSContext* cx, unsign
 
 
 MOZ_MUST_USE bool
 obj_isExtensible(JSContext* cx, unsigned argc, JS::Value* vp);
 
 MOZ_MUST_USE bool
 obj_toString(JSContext* cx, unsigned argc, JS::Value* vp);
 
+JSString*
+ObjectClassToString(JSContext* cx, HandleObject obj);
+
 // Exposed so SelfHosting.cpp can use it in the OwnPropertyKeys intrinsic
 MOZ_MUST_USE bool
 GetOwnPropertyKeys(JSContext* cx, const JS::CallArgs& args, unsigned flags);
 
 /*
  * Like IdToValue, but convert int jsids to strings. This is used when
  * exposing a jsid to script for Object.getOwnProperty{Names,Symbols}
  * or scriptable proxy traps.
--- a/js/src/builtin/RegExpGlobalReplaceOpt.h.js
+++ b/js/src/builtin/RegExpGlobalReplaceOpt.h.js
@@ -58,20 +58,20 @@ function FUNC_NAME(rx, S, lengthS, repla
         assert(result.length >= 1, "RegExpMatcher doesn't return an empty array");
         var nCaptures = result.length - 1;
 #endif
 
         // Step 14.c.
         var matched = result[0];
 
         // Step 14.d.
-        var matchLength = matched.length;
+        var matchLength = matched.length | 0;
 
         // Steps 14.e-f.
-        var position = result.index;
+        var position = result.index | 0;
         lastIndex = position + matchLength;
 
         // Steps g-k.
         var replacement;
 #if defined(FUNCTIONAL)
         replacement = RegExpGetFunctionalReplacement(result, S, position, replaceValue);
 #elif defined(SUBSTITUTION)
         replacement = RegExpGetComplexReplacement(result, matched, S, position,
@@ -102,16 +102,17 @@ function FUNC_NAME(rx, S, lengthS, repla
         // Step 14.l.iii.
         nextSourcePosition = lastIndex;
 
         // Step 11.c.iii.2.
         if (matchLength === 0) {
             lastIndex = fullUnicode ? AdvanceStringIndex(S, lastIndex) : lastIndex + 1;
             if (lastIndex > lengthS)
                 break;
+            lastIndex |= 0;
         }
 
 #if defined(FUNCTIONAL) || defined(ELEMBASE)
         // Ensure the current source and flags match the original regexp, the
         // replaceValue function may have called RegExp#compile.
         if (UnsafeGetStringFromReservedSlot(rx, REGEXP_SOURCE_SLOT) !== originalSource ||
             UnsafeGetInt32FromReservedSlot(rx, REGEXP_FLAGS_SLOT) !== originalFlags)
         {
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -511,17 +511,17 @@ FOR_EACH_NURSERY_PROFILE_TIME(EXTRACT_NA
     json.endObject(); // timings value
 
     json.endObject();
 }
 
 /* static */ void
 js::Nursery::printProfileHeader()
 {
-    fprintf(stderr, "MinorGC:               Reason  PRate Size ");
+    fprintf(stderr, "MinorGC:               Reason  PRate Size        ");
 #define PRINT_HEADER(name, text)                                              \
     fprintf(stderr, " %6s", text);
 FOR_EACH_NURSERY_PROFILE_TIME(PRINT_HEADER)
 #undef PRINT_HEADER
     fprintf(stderr, "\n");
 }
 
 /* static */ void
@@ -531,17 +531,17 @@ js::Nursery::printProfileDurations(const
         fprintf(stderr, " %6" PRIi64, static_cast<int64_t>(time.ToMicroseconds()));
     fprintf(stderr, "\n");
 }
 
 void
 js::Nursery::printTotalProfileTimes()
 {
     if (enableProfiling_) {
-        fprintf(stderr, "MinorGC TOTALS: %7" PRIu64 " collections:      ", minorGcCount_);
+        fprintf(stderr, "MinorGC TOTALS: %7" PRIu64 " collections:             ", minorGcCount_);
         printProfileDurations(totalDurations_);
     }
 }
 
 void
 js::Nursery::maybeClearProfileDurations()
 {
     for (auto& duration : profileDurations_)
@@ -664,17 +664,17 @@ js::Nursery::collect(JS::gcreason::Reaso
     rt->addTelemetry(JS_TELEMETRY_GC_PRETENURE_COUNT, pretenureCount);
 
     rt->gc.stats().endNurseryCollection(reason);
     TraceMinorGCEnd();
 
     if (enableProfiling_ && totalTime >= profileThreshold_) {
         rt->gc.stats().maybePrintProfileHeaders();
 
-        fprintf(stderr, "MinorGC: %20s %5.1f%% %4u ",
+        fprintf(stderr, "MinorGC: %20s %5.1f%% %4u        ",
                 JS::gcreason::ExplainReason(reason),
                 promotionRate * 100,
                 numChunks());
         printProfileDurations(profileDurations_);
 
         if (reportTenurings_) {
             for (auto& entry : tenureCounts.entries) {
                 if (entry.count >= reportTenurings_) {
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -457,36 +457,43 @@ Statistics::formatDetailedSliceDescripti
                    slice.wasReset() ? "yes - " : "no",
                    slice.wasReset() ? ExplainAbortReason(slice.resetReason) : "",
                    gc::StateName(slice.initialState), gc::StateName(slice.finalState),
                    uint64_t(slice.endFaults - slice.startFaults),
                    t(slice.duration()), budgetDescription, t(slice.start - slices_[0].start));
     return DuplicateString(buffer);
 }
 
+static bool
+IncludePhase(TimeDuration duration)
+{
+    // Don't include durations that will print as "0.000ms".
+    return duration.ToMilliseconds() >= 0.001;
+}
+
 UniqueChars
 Statistics::formatDetailedPhaseTimes(const PhaseTimeTable& phaseTimes) const
 {
     static const TimeDuration MaxUnaccountedChildTime = TimeDuration::FromMicroseconds(50);
 
     FragmentVector fragments;
     char buffer[128];
     for (auto phase : AllPhases()) {
         uint8_t level = phases[phase].depth;
         TimeDuration ownTime = phaseTimes[phase];
         TimeDuration childTime = SumChildTimes(phase, phaseTimes);
-        if (!ownTime.IsZero()) {
-            SprintfLiteral(buffer, "      %*s: %.3fms\n",
-                           level * 2, phases[phase].name, t(ownTime));
+        if (IncludePhase(ownTime)) {
+            SprintfLiteral(buffer, "      %*s%s: %.3fms\n",
+                           level * 2, "", phases[phase].name, t(ownTime));
             if (!fragments.append(DuplicateString(buffer)))
                 return UniqueChars(nullptr);
 
             if (childTime && (ownTime - childTime) > MaxUnaccountedChildTime) {
-                SprintfLiteral(buffer, "      %*s: %.3fms\n",
-                               (level + 1) * 2, "Other", t(ownTime - childTime));
+                SprintfLiteral(buffer, "      %*s%s: %.3fms\n",
+                               (level + 1) * 2, "", "Other", t(ownTime - childTime));
                 if (!fragments.append(DuplicateString(buffer)))
                     return UniqueChars(nullptr);
             }
         }
     }
     return Join(fragments);
 }
 
@@ -1293,32 +1300,29 @@ Statistics::computeMMU(TimeDuration wind
 }
 
 void
 Statistics::maybePrintProfileHeaders()
 {
     static int printedHeader = 0;
     if ((printedHeader++ % 200) == 0) {
         printProfileHeader();
-        for (ZoneGroupsIter group(runtime); !group.done(); group.next()) {
-            if (group->nursery().enableProfiling()) {
-                Nursery::printProfileHeader();
-                break;
-            }
-        }
+        if (runtime->gc.nursery().enableProfiling())
+            Nursery::printProfileHeader();
     }
 }
 
 void
 Statistics::printProfileHeader()
 {
     if (!enableProfiling_)
         return;
 
-    fprintf(stderr, "MajorGC:               Reason States      ");
+    fprintf(stderr, "MajorGC:               Reason States SRN  ");
+    fprintf(stderr, " %6s", "budget");
     fprintf(stderr, " %6s", "total");
 #define PRINT_PROFILE_HEADER(name, text, phase)                               \
     fprintf(stderr, " %6s", text);
 FOR_EACH_GC_PROFILE_TIME(PRINT_PROFILE_HEADER)
 #undef PRINT_PROFILE_HEADER
     fprintf(stderr, "\n");
 }
 
@@ -1332,18 +1336,31 @@ Statistics::printProfileTimes(const Prof
 
 void
 Statistics::printSliceProfile()
 {
     const SliceData& slice = slices_.back();
 
     maybePrintProfileHeaders();
 
-    fprintf(stderr, "MajorGC: %20s %1d -> %1d      ",
-            ExplainReason(slice.reason), int(slice.initialState), int(slice.finalState));
+    bool shrinking = gckind == GC_SHRINK;
+    bool reset = slice.resetReason != AbortReason::None;
+    bool nonIncremental = nonincrementalReason_ != AbortReason::None;
+
+    fprintf(stderr, "MajorGC: %20s %1d -> %1d %1s%1s%1s  ",
+            ExplainReason(slice.reason),
+            int(slice.initialState), int(slice.finalState),
+            shrinking ? "S" : "",
+            reset ? "R" : "",
+            nonIncremental ? "N" : "");
+
+    if (!nonIncremental && !slice.budget.isUnlimited() && slice.budget.isTimeBudget())
+        fprintf(stderr, " %6" PRIi64, static_cast<int64_t>(slice.budget.timeBudget.budget));
+    else
+        fprintf(stderr, "       ");
 
     ProfileDurations times;
     times[ProfileKey::Total] = slice.duration();
     totalTimes_[ProfileKey::Total] += times[ProfileKey::Total];
 
 #define GET_PROFILE_TIME(name, text, phase)                                   \
     times[ProfileKey::name] = SumPhase(phase, slice.phaseTimes);              \
     totalTimes_[ProfileKey::name] += times[ProfileKey::name];
@@ -1352,13 +1369,13 @@ FOR_EACH_GC_PROFILE_TIME(GET_PROFILE_TIM
 
     printProfileTimes(times);
 }
 
 void
 Statistics::printTotalProfileTimes()
 {
     if (enableProfiling_) {
-        fprintf(stderr, "MajorGC TOTALS: %7" PRIu64 " slices:           ", sliceCount_);
+        fprintf(stderr, "MajorGC TOTALS: %7" PRIu64 " slices:                  ", sliceCount_);
         printProfileTimes(totalTimes_);
     }
 }
 
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -75,25 +75,25 @@ struct ZoneGCStats
     ZoneGCStats()
       : collectedZoneCount(0), zoneCount(0), sweptZoneCount(0),
         collectedCompartmentCount(0), compartmentCount(0), sweptCompartmentCount(0)
     {}
 };
 
 #define FOR_EACH_GC_PROFILE_TIME(_)                                           \
     _(BeginCallback, "bgnCB",  PhaseKind::GC_BEGIN)                           \
+    _(MinorForMajor, "evct4m", PhaseKind::EVICT_NURSERY_FOR_MAJOR_GC)         \
     _(WaitBgThread,  "waitBG", PhaseKind::WAIT_BACKGROUND_THREAD)             \
-    _(DiscardCode,   "discrd", PhaseKind::MARK_DISCARD_CODE)                  \
-    _(RelazifyFunc,  "relzfy", PhaseKind::RELAZIFY_FUNCTIONS)                 \
-    _(PurgeTables,   "prgTbl", PhaseKind::PURGE_SHAPE_TABLES)                 \
-    _(Purge,         "purge",  PhaseKind::PURGE)                              \
+    _(Prepare,       "prep",   PhaseKind::PREPARE)                            \
     _(Mark,          "mark",   PhaseKind::MARK)                               \
     _(Sweep,         "sweep",  PhaseKind::SWEEP)                              \
     _(Compact,       "cmpct",  PhaseKind::COMPACT)                            \
     _(EndCallback,   "endCB",  PhaseKind::GC_END)                             \
+    _(MinorGC,       "minor",  PhaseKind::MINOR_GC)                           \
+    _(EvictNursery,  "evict",  PhaseKind::EVICT_NURSERY)                      \
     _(Barriers,      "brrier", PhaseKind::BARRIER)
 
 const char* ExplainAbortReason(gc::AbortReason reason);
 const char* ExplainInvocationKind(JSGCInvocationKind gckind);
 
 /*
  * Struct for collecting timing statistics on a "phase tree". The tree is
  * specified as a limited DAG, but the timings are collected for the whole tree
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/object-prototype-tostring.js
@@ -0,0 +1,45 @@
+var toString = Object.prototype.toString;
+var iter = 500;
+
+function testConstant() {
+    for (var i = 0; i < iter; i++) {
+        assertEq(({}).toString(), "[object Object]");
+        assertEq(toString.call([]), "[object Array]");
+        assertEq(toString.call(Math.abs), "[object Function]");
+    }
+}
+testConstant();
+
+function testOwnToStringTag() {
+    var stringify = o => toString.call(o);
+    var o = {};
+    for (var i = 0; i < iter; i++)
+        assertEq(stringify(o), "[object Object]");
+    o[Symbol.toStringTag] = "foo";
+    for (var i = 0; i < iter; i++)
+        assertEq(stringify(o), "[object foo]");
+}
+testOwnToStringTag();
+
+function testDynamic() {
+    var arr = [{}, [], new Date, /a/];
+    var expected = ["[object Object]", "[object Array]", "[object Date]", "[object RegExp]"];
+    for (var i = 0; i < iter; i++) {
+        for (var j = 0; j < arr.length; j++)
+            assertEq(toString.call(arr[j]), expected[j]);
+    }
+}
+testDynamic();
+
+function testToStringTagProto() {
+    var c = 0;
+    Object.defineProperty(Date.prototype, Symbol.toStringTag, {get() { c++; return "evil"; }});
+    var arr = [{}, [], new Date, /a/];
+    var expected = ["[object Object]", "[object Array]", "[object evil]", "[object RegExp]"];
+    for (var i = 0; i < iter; i++) {
+        for (var j = 0; j < arr.length; j++)
+            assertEq(toString.call(arr[j]), expected[j]);
+    }
+    assertEq(c, iter);
+}
+testToStringTagProto();
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -12126,16 +12126,27 @@ CodeGenerator::visitHasClass(LHasClass* 
 {
     Register lhs = ToRegister(ins->lhs());
     Register output = ToRegister(ins->output());
 
     masm.loadObjClass(lhs, output);
     masm.cmpPtrSet(Assembler::Equal, output, ImmPtr(ins->mir()->getClass()), output);
 }
 
+typedef JSString* (*ObjectClassToStringFn)(JSContext*, HandleObject);
+static const VMFunction ObjectClassToStringInfo =
+    FunctionInfo<ObjectClassToStringFn>(js::ObjectClassToString, "ObjectClassToString");
+
+void
+CodeGenerator::visitObjectClassToString(LObjectClassToString* lir)
+{
+    pushArg(ToRegister(lir->object()));
+    callVM(ObjectClassToStringInfo, lir);
+}
+
 void
 CodeGenerator::visitWasmParameter(LWasmParameter* lir)
 {
 }
 
 void
 CodeGenerator::visitWasmParameterI64(LWasmParameterI64* lir)
 {
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -389,16 +389,17 @@ class CodeGenerator final : public CodeG
     void visitIsConstructor(LIsConstructor* lir);
     void visitOutOfLineIsConstructor(OutOfLineIsConstructor* ool);
     void visitIsArrayO(LIsArrayO* lir);
     void visitIsArrayV(LIsArrayV* lir);
     void visitIsTypedArray(LIsTypedArray* lir);
     void visitIsObject(LIsObject* lir);
     void visitIsObjectAndBranch(LIsObjectAndBranch* lir);
     void visitHasClass(LHasClass* lir);
+    void visitObjectClassToString(LObjectClassToString* lir);
     void visitWasmParameter(LWasmParameter* lir);
     void visitWasmParameterI64(LWasmParameterI64* lir);
     void visitWasmReturn(LWasmReturn* ret);
     void visitWasmReturnI64(LWasmReturnI64* ret);
     void visitWasmReturnVoid(LWasmReturnVoid* ret);
     void visitLexicalCheck(LLexicalCheck* ins);
     void visitThrowRuntimeLexicalError(LThrowRuntimeLexicalError* ins);
     void visitGlobalNameConflictsCheck(LGlobalNameConflictsCheck* ins);
--- a/js/src/jit/InlinableNatives.h
+++ b/js/src/jit/InlinableNatives.h
@@ -83,16 +83,17 @@
     _(StringFromCharCode)           \
     _(StringFromCodePoint)          \
     _(StringCharAt)                 \
                                     \
     _(IntrinsicStringReplaceString) \
     _(IntrinsicStringSplitString)   \
                                     \
     _(ObjectCreate)                 \
+    _(ObjectToString)               \
                                     \
     _(SimdInt32x4)                  \
     _(SimdUint32x4)                 \
     _(SimdInt16x8)                  \
     _(SimdUint16x8)                 \
     _(SimdInt8x16)                  \
     _(SimdUint8x16)                 \
     _(SimdFloat32x4)                \
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -5086,24 +5086,23 @@ IonBuilder::jsop_funcall(uint32_t argc)
     if (!zeroArguments) {
         InliningDecision decision = makeInliningDecision(target, callInfo);
         switch (decision) {
           case InliningDecision_Error:
             return abort(AbortReason::Alloc);
           case InliningDecision_DontInline:
           case InliningDecision_WarmUpCountTooLow:
             break;
-          case InliningDecision_Inline:
-            if (target->isInterpreted()) {
-                InliningStatus status;
-                MOZ_TRY_VAR(status, inlineScriptedCall(callInfo, target));
-                if (status == InliningStatus_Inlined)
-                    return Ok();
-            }
+          case InliningDecision_Inline: {
+            InliningStatus status;
+            MOZ_TRY_VAR(status, inlineSingleCall(callInfo, target));
+            if (status == InliningStatus_Inlined)
+                return Ok();
             break;
+          }
         }
     }
 
     // Call without inlining.
     return makeCall(target, callInfo);
 }
 
 AbortReasonOr<Ok>
@@ -5319,23 +5318,22 @@ IonBuilder::jsop_funapplyarguments(uint3
     // Try to inline the call.
     InliningDecision decision = makeInliningDecision(target, callInfo);
     switch (decision) {
       case InliningDecision_Error:
         return abort(AbortReason::Alloc);
       case InliningDecision_DontInline:
       case InliningDecision_WarmUpCountTooLow:
         break;
-      case InliningDecision_Inline:
-        if (target->isInterpreted()) {
-            InliningStatus status;
-            MOZ_TRY_VAR(status, inlineScriptedCall(callInfo, target));
-            if (status == InliningStatus_Inlined)
-                return Ok();
-        }
+      case InliningDecision_Inline: {
+        InliningStatus status;
+        MOZ_TRY_VAR(status, inlineSingleCall(callInfo, target));
+        if (status == InliningStatus_Inlined)
+            return Ok();
+      }
     }
 
     return makeCall(target, callInfo);
 }
 
 AbortReasonOr<Ok>
 IonBuilder::jsop_call(uint32_t argc, bool constructing, bool ignoresReturnValue)
 {
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -678,16 +678,17 @@ class IonBuilder
     InliningResult inlineRegExpTester(CallInfo& callInfo);
     InliningResult inlineIsRegExpObject(CallInfo& callInfo);
     InliningResult inlineRegExpPrototypeOptimizable(CallInfo& callInfo);
     InliningResult inlineRegExpInstanceOptimizable(CallInfo& callInfo);
     InliningResult inlineGetFirstDollarIndex(CallInfo& callInfo);
 
     // Object natives and intrinsics.
     InliningResult inlineObjectCreate(CallInfo& callInfo);
+    InliningResult inlineObjectToString(CallInfo& callInfo);
     InliningResult inlineDefineDataProperty(CallInfo& callInfo);
 
     // Atomics natives.
     InliningResult inlineAtomicsCompareExchange(CallInfo& callInfo);
     InliningResult inlineAtomicsExchange(CallInfo& callInfo);
     InliningResult inlineAtomicsLoad(CallInfo& callInfo);
     InliningResult inlineAtomicsStore(CallInfo& callInfo);
     InliningResult inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target);
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4386,16 +4386,26 @@ void
 LIRGenerator::visitHasClass(MHasClass* ins)
 {
     MOZ_ASSERT(ins->object()->type() == MIRType::Object);
     MOZ_ASSERT(ins->type() == MIRType::Boolean);
     define(new(alloc()) LHasClass(useRegister(ins->object())), ins);
 }
 
 void
+LIRGenerator::visitObjectClassToString(MObjectClassToString* ins)
+{
+    MOZ_ASSERT(ins->object()->type() == MIRType::Object);
+    MOZ_ASSERT(ins->type() == MIRType::String);
+    auto lir = new(alloc()) LObjectClassToString(useRegisterAtStart(ins->object()));
+    defineReturn(lir, ins);
+    assignSafepoint(lir, ins);
+}
+
+void
 LIRGenerator::visitWasmAddOffset(MWasmAddOffset* ins)
 {
     MOZ_ASSERT(ins->base()->type() == MIRType::Int32);
     MOZ_ASSERT(ins->type() == MIRType::Int32);
     define(new(alloc()) LWasmAddOffset(useRegisterAtStart(ins->base())), ins);
 }
 
 void
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -293,16 +293,17 @@ class LIRGenerator : public LIRGenerator
     void visitInstanceOf(MInstanceOf* ins);
     void visitCallInstanceOf(MCallInstanceOf* ins);
     void visitIsCallable(MIsCallable* ins);
     void visitIsConstructor(MIsConstructor* ins);
     void visitIsArray(MIsArray* ins);
     void visitIsTypedArray(MIsTypedArray* ins);
     void visitIsObject(MIsObject* ins);
     void visitHasClass(MHasClass* ins);
+    void visitObjectClassToString(MObjectClassToString* ins);
     void visitWasmAddOffset(MWasmAddOffset* ins);
     void visitWasmLoadTls(MWasmLoadTls* ins);
     void visitWasmBoundsCheck(MWasmBoundsCheck* ins);
     void visitWasmLoadGlobalVar(MWasmLoadGlobalVar* ins);
     void visitWasmStoreGlobalVar(MWasmStoreGlobalVar* ins);
     void visitWasmParameter(MWasmParameter* ins);
     void visitWasmReturn(MWasmReturn* ins);
     void visitWasmReturnVoid(MWasmReturnVoid* ins);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -231,16 +231,18 @@ IonBuilder::inlineNativeCall(CallInfo& c
       case InlinableNative::IntrinsicStringSplitString:
         return inlineStringSplitString(callInfo);
       case InlinableNative::IntrinsicNewStringIterator:
         return inlineNewIterator(callInfo, MNewIterator::StringIterator);
 
       // Object natives.
       case InlinableNative::ObjectCreate:
         return inlineObjectCreate(callInfo);
+      case InlinableNative::ObjectToString:
+        return inlineObjectToString(callInfo);
 
       // SIMD natives.
       case InlinableNative::SimdInt32x4:
         return inlineSimd(callInfo, target, SimdType::Int32x4);
       case InlinableNative::SimdUint32x4:
         return inlineSimd(callInfo, target, SimdType::Uint32x4);
       case InlinableNative::SimdInt16x8:
         return inlineSimd(callInfo, target, SimdType::Int16x8);
@@ -1951,17 +1953,17 @@ IonBuilder::inlineRegExpMatcher(CallInfo
         trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
         return InliningStatus_NotInlined;
     }
 
     MDefinition* rxArg = callInfo.getArg(0);
     MDefinition* strArg = callInfo.getArg(1);
     MDefinition* lastIndexArg = callInfo.getArg(2);
 
-    if (rxArg->type() != MIRType::Object)
+    if (rxArg->type() != MIRType::Object && rxArg->type() != MIRType::Value)
         return InliningStatus_NotInlined;
 
     TemporaryTypeSet* rxTypes = rxArg->resultTypeSet();
     const Class* clasp = rxTypes ? rxTypes->getKnownClass(constraints()) : nullptr;
     if (clasp != &RegExpObject::class_)
         return InliningStatus_NotInlined;
 
     if (strArg->mightBeType(MIRType::Object))
@@ -1997,17 +1999,17 @@ IonBuilder::inlineRegExpSearcher(CallInf
         trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
         return InliningStatus_NotInlined;
     }
 
     MDefinition* rxArg = callInfo.getArg(0);
     MDefinition* strArg = callInfo.getArg(1);
     MDefinition* lastIndexArg = callInfo.getArg(2);
 
-    if (rxArg->type() != MIRType::Object)
+    if (rxArg->type() != MIRType::Object && rxArg->type() != MIRType::Value)
         return InliningStatus_NotInlined;
 
     TemporaryTypeSet* regexpTypes = rxArg->resultTypeSet();
     const Class* clasp = regexpTypes ? regexpTypes->getKnownClass(constraints()) : nullptr;
     if (clasp != &RegExpObject::class_)
         return InliningStatus_NotInlined;
 
     if (strArg->mightBeType(MIRType::Object))
@@ -2043,17 +2045,17 @@ IonBuilder::inlineRegExpTester(CallInfo&
         trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
         return InliningStatus_NotInlined;
     }
 
     MDefinition* rxArg = callInfo.getArg(0);
     MDefinition* strArg = callInfo.getArg(1);
     MDefinition* lastIndexArg = callInfo.getArg(2);
 
-    if (rxArg->type() != MIRType::Object)
+    if (rxArg->type() != MIRType::Object && rxArg->type() != MIRType::Value)
         return InliningStatus_NotInlined;
 
     TemporaryTypeSet* rxTypes = rxArg->resultTypeSet();
     const Class* clasp = rxTypes ? rxTypes->getKnownClass(constraints()) : nullptr;
     if (clasp != &RegExpObject::class_)
         return InliningStatus_NotInlined;
 
     if (strArg->mightBeType(MIRType::Object))
@@ -2291,16 +2293,73 @@ IonBuilder::inlineObjectCreate(CallInfo&
     bool emitted = false;
     MOZ_TRY(newObjectTryTemplateObject(&emitted, templateObject));
 
     MOZ_ASSERT(emitted);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningResult
+IonBuilder::inlineObjectToString(CallInfo& callInfo)
+{
+    if (callInfo.constructing() || callInfo.argc() != 0) {
+        trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
+        return InliningStatus_NotInlined;
+    }
+
+    if (getInlineReturnType() != MIRType::String)
+        return InliningStatus_NotInlined;
+
+    MDefinition* arg = callInfo.thisArg();
+    if (arg->type() != MIRType::Object)
+        return InliningStatus_NotInlined;
+
+    TemporaryTypeSet* types = arg->resultTypeSet();
+    if (!types || types->unknownObject())
+        return InliningStatus_NotInlined;
+
+    // Don't optimize if this might be a proxy.
+    using ForAllResult = TemporaryTypeSet::ForAllResult;
+    if (types->forAllClasses(constraints(), IsProxyClass) != ForAllResult::ALL_FALSE)
+        return InliningStatus_NotInlined;
+
+    // Make sure there's no Symbol.toStringTag property.
+    jsid toStringTag = SYMBOL_TO_JSID(compartment->runtime()->wellKnownSymbols().toStringTag);
+    bool res;
+    MOZ_TRY_VAR(res, testNotDefinedProperty(arg, toStringTag));
+    if (!res)
+        return InliningStatus_NotInlined;
+
+    // At this point we know we're going to inline this.
+    callInfo.setImplicitlyUsedUnchecked();
+
+    // Try to constant fold some common cases.
+    if (const Class* knownClass = types->getKnownClass(constraints())) {
+        if (knownClass == &PlainObject::class_ || knownClass == &UnboxedPlainObject::class_) {
+            pushConstant(StringValue(names().objectObject));
+            return InliningStatus_Inlined;
+        }
+        if (IsArrayClass(knownClass)) {
+            pushConstant(StringValue(names().objectArray));
+            return InliningStatus_Inlined;
+        }
+        if (knownClass == &JSFunction::class_) {
+            pushConstant(StringValue(names().objectFunction));
+            return InliningStatus_Inlined;
+        }
+    }
+
+    MObjectClassToString* toString = MObjectClassToString::New(alloc(), arg);
+    current->add(toString);
+    current->push(toString);
+
+    return InliningStatus_Inlined;
+}
+
+IonBuilder::InliningResult
 IonBuilder::inlineHasClass(CallInfo& callInfo,
                            const Class* clasp1, const Class* clasp2,
                            const Class* clasp3, const Class* clasp4)
 {
     if (callInfo.constructing() || callInfo.argc() != 1) {
         trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
         return InliningStatus_NotInlined;
     }
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -13500,16 +13500,40 @@ class MIsTypedArray
     TRIVIAL_NEW_WRAPPERS
     NAMED_OPERANDS((0, value))
 
     AliasSet getAliasSet() const override {
         return AliasSet::None();
     }
 };
 
+class MObjectClassToString
+  : public MUnaryInstruction,
+    public SingleObjectPolicy::Data
+{
+    explicit MObjectClassToString(MDefinition* obj)
+      : MUnaryInstruction(obj)
+    {
+        setMovable();
+        setResultType(MIRType::String);
+    }
+
+  public:
+    INSTRUCTION_HEADER(ObjectClassToString)
+    TRIVIAL_NEW_WRAPPERS
+    NAMED_OPERANDS((0, object))
+
+    AliasSet getAliasSet() const override {
+        return AliasSet::None();
+    }
+    bool congruentTo(const MDefinition* ins) const override {
+        return congruentIfOperandsEqual(ins);
+    }
+};
+
 class MCheckReturn
   : public MBinaryInstruction,
     public BoxInputsPolicy::Data
 {
     explicit MCheckReturn(MDefinition* retVal, MDefinition* thisVal)
       : MBinaryInstruction(retVal, thisVal)
     {
         setGuard();
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -277,16 +277,17 @@ namespace jit {
     _(GetDOMMember)                                                         \
     _(SetDOMProperty)                                                       \
     _(IsConstructor)                                                        \
     _(IsCallable)                                                           \
     _(IsArray)                                                              \
     _(IsTypedArray)                                                         \
     _(IsObject)                                                             \
     _(HasClass)                                                             \
+    _(ObjectClassToString)                                                  \
     _(CopySign)                                                             \
     _(Rotate)                                                               \
     _(NewDerivedTypedObject)                                                \
     _(RecompileCheck)                                                       \
     _(UnknownValue)                                                         \
     _(LexicalCheck)                                                         \
     _(ThrowRuntimeLexicalError)                                             \
     _(GlobalNameConflictsCheck)                                             \
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -8092,16 +8092,32 @@ class LHasClass : public LInstructionHel
     const LAllocation* lhs() {
         return getOperand(0);
     }
     MHasClass* mir() const {
         return mir_->toHasClass();
     }
 };
 
+class LObjectClassToString : public LCallInstructionHelper<1, 1, 0>
+{
+  public:
+    LIR_HEADER(ObjectClassToString);
+
+    explicit LObjectClassToString(const LAllocation& lhs) {
+        setOperand(0, lhs);
+    }
+    const LAllocation* object() {
+        return getOperand(0);
+    }
+    MObjectClassToString* mir() const {
+        return mir_->toObjectClassToString();
+    }
+};
+
 template<size_t Defs, size_t Ops>
 class LWasmSelectBase : public LInstructionHelper<Defs, Ops, 0>
 {
     typedef LInstructionHelper<Defs, Ops, 0> Base;
   public:
 
     MWasmSelect* mir() const {
         return Base::mir_->toWasmSelect();
--- a/js/src/jit/shared/LOpcodes-shared.h
+++ b/js/src/jit/shared/LOpcodes-shared.h
@@ -391,16 +391,17 @@
     _(IsCallable)                   \
     _(IsConstructor)                \
     _(IsArrayO)                     \
     _(IsArrayV)                     \
     _(IsTypedArray)                 \
     _(IsObject)                     \
     _(IsObjectAndBranch)            \
     _(HasClass)                     \
+    _(ObjectClassToString)          \
     _(RecompileCheck)               \
     _(MemoryBarrier)                \
     _(AssertRangeI)                 \
     _(AssertRangeD)                 \
     _(AssertRangeF)                 \
     _(AssertRangeV)                 \
     _(AssertResultV)                \
     _(AssertResultT)                \
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -429,26 +429,27 @@ ArgumentsObject::obj_delProperty(JSConte
         argsobj.markIteratorOverridden();
     }
     return result.succeed();
 }
 
 /* static */ bool
 ArgumentsObject::obj_mayResolve(const JSAtomState& names, jsid id, JSObject*)
 {
-    // Arguments might resolve indexes or Symbol.iterator.
-    if (!JSID_IS_ATOM(id))
-        return true;
-
-    JSAtom* atom = JSID_TO_ATOM(id);
-    uint32_t index;
-    if (atom->isIndex(&index))
-        return true;
-
-    return atom == names.length || atom == names.callee;
+    // Arguments might resolve indexes, Symbol.iterator, or length/callee.
+    if (JSID_IS_ATOM(id)) {
+        JSAtom* atom = JSID_TO_ATOM(id);
+        uint32_t index;
+        if (atom->isIndex(&index))
+            return true;
+        return atom == names.length || atom == names.callee;
+    }
+    if (JSID_IS_SYMBOL(id))
+        return JSID_TO_SYMBOL(id)->code() == JS::SymbolCode::iterator;
+    return true;
 }
 
 static bool
 MappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
 {
     MappedArgumentsObject& argsobj = obj->as<MappedArgumentsObject>();
     if (JSID_IS_INT(id)) {
         /*
--- a/layout/base/StaticPresData.cpp
+++ b/layout/base/StaticPresData.cpp
@@ -98,18 +98,18 @@ LangGroupFontPrefs::Initialize(nsIAtom* 
   mDefaultFixedFont.size = nsPresContext::CSSPixelsToAppUnits(13);
 
   nsAutoCString pref;
 
   // get the current applicable font-size unit
   enum {eUnit_unknown = -1, eUnit_px, eUnit_pt};
   int32_t unit = eUnit_px;
 
-  nsAdoptingCString cvalue =
-    Preferences::GetCString("font.size.unit");
+  nsAutoCString cvalue;
+  Preferences::GetCString("font.size.unit", cvalue);
 
   if (!cvalue.IsEmpty()) {
     if (cvalue.EqualsLiteral("px")) {
       unit = eUnit_px;
     }
     else if (cvalue.EqualsLiteral("pt")) {
       unit = eUnit_pt;
     }
@@ -158,28 +158,29 @@ LangGroupFontPrefs::Initialize(nsIAtom* 
     nsFont* font = fontTypes[eType];
 
     // set the default variable font (the other fonts are seen as 'generic' fonts
     // in GFX and will be queried there when hunting for alternative fonts)
     if (eType == eDefaultFont_Variable) {
       // XXX "font.name.variable."?  There is no such pref...
       MAKE_FONT_PREF_KEY(pref, "font.name.variable.", langGroup);
 
-      nsAdoptingString value = Preferences::GetString(pref.get());
+      nsAutoString value;
+      Preferences::GetString(pref.get(), value);
       if (!value.IsEmpty()) {
         FontFamilyName defaultVariableName = FontFamilyName::Convert(value);
         FontFamilyType defaultType = defaultVariableName.mType;
         NS_ASSERTION(defaultType == eFamily_serif ||
                      defaultType == eFamily_sans_serif,
                      "default type must be serif or sans-serif");
         mDefaultVariableFont.fontlist = FontFamilyList(defaultType);
       }
       else {
         MAKE_FONT_PREF_KEY(pref, "font.default.", langGroup);
-        value = Preferences::GetString(pref.get());
+        Preferences::GetString(pref.get(), value);
         if (!value.IsEmpty()) {
           FontFamilyName defaultVariableName = FontFamilyName::Convert(value);
           FontFamilyType defaultType = defaultVariableName.mType;
           NS_ASSERTION(defaultType == eFamily_serif ||
                        defaultType == eFamily_sans_serif,
                        "default type must be serif or sans-serif");
           mDefaultVariableFont.fontlist = FontFamilyList(defaultType);
         }
@@ -216,17 +217,18 @@ LangGroupFontPrefs::Initialize(nsIAtom* 
       else if (unit == eUnit_pt) {
         font->size = nsPresContext::CSSPointsToAppUnits(size);
       }
     }
 
     // get font.size-adjust.[generic].[langGroup]
     // XXX only applicable on GFX ports that handle |font-size-adjust|
     MAKE_FONT_PREF_KEY(pref, "font.size-adjust", generic_dot_langGroup);
-    cvalue = Preferences::GetCString(pref.get());
+    cvalue.Truncate();
+    Preferences::GetCString(pref.get(), cvalue);
     if (!cvalue.IsEmpty()) {
       font->sizeAdjust = (float)atof(cvalue.get());
     }
 
 #ifdef DEBUG_rbs
     printf("%s Family-list:%s size:%d sizeAdjust:%.2f\n",
            generic_dot_langGroup.get(),
            NS_ConvertUTF16toUTF8(font->name).get(), font->size,
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -511,25 +511,24 @@ nsPresContext::GetDocumentColorPreferenc
   if (sUseStandinsForNativeColors) {
     // Once the preference "ui.use_standins_for_native_colors" is enabled,
     // use fixed color values instead of prefered colors and system colors.
     mDefaultColor = LookAndFeel::GetColorUsingStandins(
         LookAndFeel::eColorID_windowtext, NS_RGB(0x00, 0x00, 0x00));
     mBackgroundColor = LookAndFeel::GetColorUsingStandins(
         LookAndFeel::eColorID_window, NS_RGB(0xff, 0xff, 0xff));
   } else if (usePrefColors) {
-    nsAdoptingString colorStr =
-      Preferences::GetString("browser.display.foreground_color");
-
+    nsAutoString colorStr;
+    Preferences::GetString("browser.display.foreground_color", colorStr);
     if (!colorStr.IsEmpty()) {
       mDefaultColor = MakeColorPref(colorStr);
     }
 
-    colorStr = Preferences::GetString("browser.display.background_color");
-
+    colorStr.Truncate();
+    Preferences::GetString("browser.display.background_color", colorStr);
     if (!colorStr.IsEmpty()) {
       mBackgroundColor = MakeColorPref(colorStr);
     }
   }
   else {
     mDefaultColor =
       LookAndFeel::GetColor(LookAndFeel::eColorID_WindowForeground,
                             NS_RGB(0x00, 0x00, 0x00));
@@ -578,48 +577,48 @@ nsPresContext::GetUserPreferences()
   mSendAfterPaintToContent =
     Preferences::GetBool("dom.send_after_paint_to_content",
                          mSendAfterPaintToContent);
 
   // * link colors
   mUnderlineLinks =
     Preferences::GetBool("browser.underline_anchors", mUnderlineLinks);
 
-  nsAdoptingString colorStr = Preferences::GetString("browser.anchor_color");
-
+  nsAutoString colorStr;
+  Preferences::GetString("browser.anchor_color", colorStr);
   if (!colorStr.IsEmpty()) {
     mLinkColor = MakeColorPref(colorStr);
   }
 
-  colorStr = Preferences::GetString("browser.active_color");
-
+  colorStr.Truncate();
+  Preferences::GetString("browser.active_color", colorStr);
   if (!colorStr.IsEmpty()) {
     mActiveLinkColor = MakeColorPref(colorStr);
   }
 
-  colorStr = Preferences::GetString("browser.visited_color");
-
+  colorStr.Truncate();
+  Preferences::GetString("browser.visited_color", colorStr);
   if (!colorStr.IsEmpty()) {
     mVisitedLinkColor = MakeColorPref(colorStr);
   }
 
   mUseFocusColors =
     Preferences::GetBool("browser.display.use_focus_colors", mUseFocusColors);
 
   mFocusTextColor = mDefaultColor;
   mFocusBackgroundColor = mBackgroundColor;
 
-  colorStr = Preferences::GetString("browser.display.focus_text_color");
-
+  colorStr.Truncate();
+  Preferences::GetString("browser.display.focus_text_color", colorStr);
   if (!colorStr.IsEmpty()) {
     mFocusTextColor = MakeColorPref(colorStr);
   }
 
-  colorStr = Preferences::GetString("browser.display.focus_background_color");
-
+  colorStr.Truncate();
+  Preferences::GetString("browser.display.focus_background_color", colorStr);
   if (!colorStr.IsEmpty()) {
     mFocusBackgroundColor = MakeColorPref(colorStr);
   }
 
   mFocusRingWidth =
     Preferences::GetInt("browser.display.focus_ring_width", mFocusRingWidth);
 
   mFocusRingOnAnything =
@@ -637,18 +636,18 @@ nsPresContext::GetUserPreferences()
 
   mPrefScrollbarSide = Preferences::GetInt("layout.scrollbar.side");
 
   mLangGroupFontPrefs.Reset();
   mFontGroupCacheDirty = true;
   StaticPresData::Get()->ResetCachedFontPrefs();
 
   // * image animation
-  const nsAdoptingCString& animatePref =
-    Preferences::GetCString("image.animation_mode");
+  nsAutoCString animatePref;
+  Preferences::GetCString("image.animation_mode", animatePref);
   if (animatePref.EqualsLiteral("normal"))
     mImageAnimationModePref = imgIContainer::kNormalAnimMode;
   else if (animatePref.EqualsLiteral("none"))
     mImageAnimationModePref = imgIContainer::kDontAnimMode;
   else if (animatePref.EqualsLiteral("once"))
     mImageAnimationModePref = imgIContainer::kLoopOnceAnimMode;
   else // dynamic change to invalid value should act like it does initially
     mImageAnimationModePref = imgIContainer::kNormalAnimMode;
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -222,16 +222,18 @@ public:
     for (nsRefreshDriver* driver : mRootRefreshDrivers) {
       aNewTimer->AddRefreshDriver(driver);
       driver->mActiveTimer = aNewTimer;
     }
     mRootRefreshDrivers.Clear();
 
     aNewTimer->mLastFireEpoch = mLastFireEpoch;
     aNewTimer->mLastFireTime = mLastFireTime;
+
+    StopTimer();
   }
 
   virtual TimeDuration GetTimerRate() = 0;
 
   bool LastTickSkippedAnyPaints() const
   {
     return mLastFireSkipped;
   }
@@ -360,17 +362,17 @@ public:
    * aRate -- the delay, in milliseconds, requested between timer firings
    */
   explicit SimpleTimerBasedRefreshDriverTimer(double aRate)
   {
     SetRate(aRate);
     mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
   }
 
-  ~SimpleTimerBasedRefreshDriverTimer() override
+  virtual ~SimpleTimerBasedRefreshDriverTimer() override
   {
     StopTimer();
   }
 
   // will take effect at next timer tick
   virtual void SetRate(double aNewRate)
   {
     mRateMilliseconds = aNewRate;
--- a/layout/xul/nsTextBoxFrame.cpp
+++ b/layout/xul/nsTextBoxFrame.cpp
@@ -141,31 +141,33 @@ nsTextBoxFrame::DestroyFrom(nsIFrame* aD
 bool
 nsTextBoxFrame::AlwaysAppendAccessKey()
 {
   if (!gAccessKeyPrefInitialized)
   {
     gAccessKeyPrefInitialized = true;
 
     const char* prefName = "intl.menuitems.alwaysappendaccesskeys";
-    nsAdoptingString val = Preferences::GetLocalizedString(prefName);
+    nsAutoString val;
+    Preferences::GetLocalizedString(prefName, val);
     gAlwaysAppendAccessKey = val.EqualsLiteral("true");
   }
   return gAlwaysAppendAccessKey;
 }
 
 bool
 nsTextBoxFrame::InsertSeparatorBeforeAccessKey()
 {
   if (!gInsertSeparatorPrefInitialized)
   {
     gInsertSeparatorPrefInitialized = true;
 
     const char* prefName = "intl.menuitems.insertseparatorbeforeaccesskeys";
-    nsAdoptingString val = Preferences::GetLocalizedString(prefName);
+    nsAutoString val;
+    Preferences::GetLocalizedString(prefName, val);
     gInsertSeparatorBeforeAccessKey = val.EqualsLiteral("true");
   }
   return gInsertSeparatorBeforeAccessKey;
 }
 
 class nsAsyncAccesskeyUpdate final : public nsIReflowCallback
 {
 public:
--- a/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
+++ b/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
@@ -54,17 +54,19 @@ private:
   }
 };
 
 // For WEBRTC_TRACE()
 static WebRtcTraceCallback gWebRtcCallback;
 // For LOG()
 static mozilla::StaticAutoPtr<LogSinkImpl> sSink;
 
-void GetWebRtcLogPrefs(uint32_t *aTraceMask, nsACString* aLogFile, nsACString *aAECLogDir, bool *aMultiLog)
+void
+GetWebRtcLogPrefs(uint32_t *aTraceMask, nsACString& aLogFile,
+                  nsACString& aAECLogDir, bool *aMultiLog)
 {
   *aMultiLog = mozilla::Preferences::GetBool("media.webrtc.debug.multi_log");
   *aTraceMask = mozilla::Preferences::GetUint("media.webrtc.debug.trace_mask");
   mozilla::Preferences::GetCString("media.webrtc.debug.log_file", aLogFile);
   mozilla::Preferences::GetCString("media.webrtc.debug.aec_log_dir", aAECLogDir);
   webrtc::Trace::set_aec_debug_size(mozilla::Preferences::GetUint("media.webrtc.debug.aec_dump_max_size"));
 }
 
@@ -212,17 +214,17 @@ void StartWebRtcLog(uint32_t log_level)
     return;
   }
 
   uint32_t trace_mask = 0;
   bool multi_log = false;
   nsAutoCString log_file;
   nsAutoCString aec_log_dir;
 
-  GetWebRtcLogPrefs(&trace_mask, &log_file, &aec_log_dir, &multi_log);
+  GetWebRtcLogPrefs(&trace_mask, log_file, aec_log_dir, &multi_log);
   mozilla::LogLevel level = CheckOverrides(&trace_mask, &log_file, &multi_log);
 
   if (trace_mask == 0) {
     trace_mask = log_level;
   }
 
   ConfigWebRtcLog(level, trace_mask, log_file, aec_log_dir, multi_log);
 
@@ -234,17 +236,17 @@ void EnableWebRtcLog()
     return;
   }
 
   uint32_t trace_mask = 0;
   bool multi_log = false;
   nsAutoCString log_file;
   nsAutoCString aec_log_dir;
 
-  GetWebRtcLogPrefs(&trace_mask, &log_file, &aec_log_dir, &multi_log);
+  GetWebRtcLogPrefs(&trace_mask, log_file, aec_log_dir, &multi_log);
   mozilla::LogLevel level = CheckOverrides(&trace_mask, &log_file, &multi_log);
   ConfigWebRtcLog(level, trace_mask, log_file, aec_log_dir, multi_log);
 }
 
 // Called when we destroy the singletons from PeerConnectionCtx or if the
 // user changes logging in about:webrtc
 void StopWebRtcLog()
 {
@@ -290,17 +292,17 @@ void StartAecLog()
   if (webrtc::Trace::aec_debug()) {
     return;
   }
   uint32_t trace_mask = 0;
   bool multi_log = false;
   nsAutoCString log_file;
   nsAutoCString aec_log_dir;
 
-  GetWebRtcLogPrefs(&trace_mask, &log_file, &aec_log_dir, &multi_log);
+  GetWebRtcLogPrefs(&trace_mask, log_file, aec_log_dir, &multi_log);
   CheckOverrides(&trace_mask, &log_file, &multi_log);
   ConfigAecLog(aec_log_dir);
 
   webrtc::Trace::set_aec_debug(true);
 }
 
 void StopAecLog()
 {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java
@@ -116,17 +116,17 @@ public class LayerView extends FrameLayo
         @WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
         @Override protected native void disposeNative();
 
         // Gecko thread sets its Java instances; does not block UI thread.
         @WrapForJNI(calledFrom = "any", dispatchTo = "gecko")
         /* package */ native void attachToJava(GeckoLayerClient layerClient,
                                                NativePanZoomController npzc);
 
-        @WrapForJNI(calledFrom = "any", dispatchTo = "gecko_priority")
+        @WrapForJNI(calledFrom = "any", dispatchTo = "gecko")
         /* package */ native void onSizeChanged(int windowWidth, int windowHeight,
                                                 int screenWidth, int screenHeight);
 
         // Gecko thread creates compositor; blocks UI thread.
         @WrapForJNI(calledFrom = "ui", dispatchTo = "proxy")
         /* package */ native void createCompositor(int width, int height, Object surface);
 
         // Gecko thread pauses compositor; blocks UI thread.
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -1600,17 +1600,19 @@ static nsresult pref_InitInitialObjects(
   // channel, telemetry is on by default, otherwise not. This is necessary
   // so that beta users who are testing final release builds don't flipflop
   // defaults.
   if (Preferences::GetDefaultType(kTelemetryPref) == nsIPrefBranch::PREF_INVALID) {
     bool prerelease = false;
 #ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
     prerelease = true;
 #else
-    if (Preferences::GetDefaultCString(kChannelPref).EqualsLiteral("beta")) {
+    nsAutoCString prefValue;
+    Preferences::GetDefaultCString(kChannelPref, prefValue);
+    if (prefValue.EqualsLiteral("beta")) {
       prerelease = true;
     }
 #endif
     PREF_SetBoolPref(kTelemetryPref, prerelease, true);
   }
 
   NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID,
                                 nullptr, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID);
@@ -1661,105 +1663,65 @@ Preferences::GetFloat(const char* aPref,
   if (NS_SUCCEEDED(rv)) {
     *aResult = result.ToFloat(&rv);
   }
 
   return rv;
 }
 
 // static
-nsAdoptingCString
-Preferences::GetCString(const char* aPref)
-{
-  nsAdoptingCString result;
-  PREF_CopyCharPref(aPref, getter_Copies(result), false);
-  return result;
-}
-
-// static
-nsAdoptingString
-Preferences::GetString(const char* aPref)
+nsresult
+Preferences::GetCString(const char* aPref, nsACString& aResult)
 {
-  nsAdoptingString result;
-  GetString(aPref, &result);
-  return result;
-}
-
-// static
-nsresult
-Preferences::GetCString(const char* aPref, nsACString* aResult)
-{
-  NS_PRECONDITION(aResult, "aResult must not be NULL");
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
-  nsAutoCString result;
-  nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), false);
+  char* result;
+  nsresult rv = PREF_CopyCharPref(aPref, &result, false);
   if (NS_SUCCEEDED(rv)) {
-    *aResult = result;
+    aResult.Adopt(result);
   }
   return rv;
 }
 
 // static
 nsresult
-Preferences::GetString(const char* aPref, nsAString* aResult)
+Preferences::GetString(const char* aPref, nsAString& aResult)
 {
-  NS_PRECONDITION(aResult, "aResult must not be NULL");
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
   nsAutoCString result;
   nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), false);
   if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(result, *aResult);
-  }
-  return rv;
-}
-
-// static
-nsAdoptingCString
-Preferences::GetLocalizedCString(const char* aPref)
-{
-  nsAdoptingCString result;
-  GetLocalizedCString(aPref, &result);
-  return result;
-}
-
-// static
-nsAdoptingString
-Preferences::GetLocalizedString(const char* aPref)
-{
-  nsAdoptingString result;
-  GetLocalizedString(aPref, &result);
-  return result;
-}
-
-// static
-nsresult
-Preferences::GetLocalizedCString(const char* aPref, nsACString* aResult)
-{
-  NS_PRECONDITION(aResult, "aResult must not be NULL");
-  nsAutoString result;
-  nsresult rv = GetLocalizedString(aPref, &result);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF16toUTF8(result, *aResult);
+    CopyUTF8toUTF16(result, aResult);
   }
   return rv;
 }
 
 // static
 nsresult
-Preferences::GetLocalizedString(const char* aPref, nsAString* aResult)
+Preferences::GetLocalizedCString(const char* aPref, nsACString& aResult)
 {
-  NS_PRECONDITION(aResult, "aResult must not be NULL");
+  nsAutoString result;
+  nsresult rv = GetLocalizedString(aPref, result);
+  if (NS_SUCCEEDED(rv)) {
+    CopyUTF16toUTF8(result, aResult);
+  }
+  return rv;
+}
+
+// static
+nsresult
+Preferences::GetLocalizedString(const char* aPref, nsAString& aResult)
+{
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
   nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
   nsresult rv = sRootBranch->GetComplexValue(aPref,
                                              NS_GET_IID(nsIPrefLocalizedString),
                                              getter_AddRefs(prefLocalString));
   if (NS_SUCCEEDED(rv)) {
     NS_ASSERTION(prefLocalString, "Succeeded but the result is NULL");
-    prefLocalString->GetData(getter_Copies(*aResult));
+    prefLocalString->GetData(getter_Copies(aResult));
   }
   return rv;
 }
 
 // static
 nsresult
 Preferences::GetComplex(const char* aPref, const nsIID &aType, void** aResult)
 {
@@ -2193,110 +2155,72 @@ Preferences::GetDefaultInt(const char* a
 {
   NS_PRECONDITION(aResult, "aResult must not be NULL");
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
   return PREF_GetIntPref(aPref, aResult, true);
 }
 
 // static
 nsresult
-Preferences::GetDefaultCString(const char* aPref, nsACString* aResult)
+Preferences::GetDefaultCString(const char* aPref, nsACString& aResult)
 {
-  NS_PRECONDITION(aResult, "aResult must not be NULL");
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
-  nsAutoCString result;
-  nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), true);
+  char* result;
+  nsresult rv = PREF_CopyCharPref(aPref, &result, true);
   if (NS_SUCCEEDED(rv)) {
-    *aResult = result;
+    aResult.Adopt(result);
   }
   return rv;
 }
 
 // static
 nsresult
-Preferences::GetDefaultString(const char* aPref, nsAString* aResult)
+Preferences::GetDefaultString(const char* aPref, nsAString& aResult)
 {
-  NS_PRECONDITION(aResult, "aResult must not be NULL");
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
   nsAutoCString result;
   nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), true);
   if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(result, *aResult);
+    CopyUTF8toUTF16(result, aResult);
   }
   return rv;
 }
 
 // static
 nsresult
 Preferences::GetDefaultLocalizedCString(const char* aPref,
-                                        nsACString* aResult)
+                                        nsACString& aResult)
 {
   nsAutoString result;
-  nsresult rv = GetDefaultLocalizedString(aPref, &result);
+  nsresult rv = GetDefaultLocalizedString(aPref, result);
   if (NS_SUCCEEDED(rv)) {
-    CopyUTF16toUTF8(result, *aResult);
+    CopyUTF16toUTF8(result, aResult);
   }
   return rv;
 }
 
 // static
 nsresult
 Preferences::GetDefaultLocalizedString(const char* aPref,
-                                       nsAString* aResult)
+                                       nsAString& aResult)
 {
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
   nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
   nsresult rv =
     sDefaultRootBranch->GetComplexValue(aPref,
                                         NS_GET_IID(nsIPrefLocalizedString),
                                         getter_AddRefs(prefLocalString));
   if (NS_SUCCEEDED(rv)) {
     NS_ASSERTION(prefLocalString, "Succeeded but the result is NULL");
-    prefLocalString->GetData(getter_Copies(*aResult));
+    prefLocalString->GetData(getter_Copies(aResult));
   }
   return rv;
 }
 
 // static
-nsAdoptingString
-Preferences::GetDefaultString(const char* aPref)
-{
-  nsAdoptingString result;
-  GetDefaultString(aPref, &result);
-  return result;
-}
-
-// static
-nsAdoptingCString
-Preferences::GetDefaultCString(const char* aPref)
-{
-  nsAdoptingCString result;
-  PREF_CopyCharPref(aPref, getter_Copies(result), true);
-  return result;
-}
-
-// static
-nsAdoptingString
-Preferences::GetDefaultLocalizedString(const char* aPref)
-{
-  nsAdoptingString result;
-  GetDefaultLocalizedString(aPref, &result);
-  return result;
-}
-
-// static
-nsAdoptingCString
-Preferences::GetDefaultLocalizedCString(const char* aPref)
-{
-  nsAdoptingCString result;
-  GetDefaultLocalizedCString(aPref, &result);
-  return result;
-}
-
-// static
 nsresult
 Preferences::GetDefaultComplex(const char* aPref, const nsIID &aType,
                                void** aResult)
 {
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
   return sDefaultRootBranch->GetComplexValue(aPref, aType, aResult);
 }
 
--- a/modules/libpref/Preferences.h
+++ b/modules/libpref/Preferences.h
@@ -16,18 +16,16 @@
 #include "nsIObserver.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsWeakReference.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/MemoryReporting.h"
 
 class nsIFile;
-class nsAdoptingString;
-class nsAdoptingCString;
 
 #ifndef have_PrefChangedFunc_typedef
 typedef void (*PrefChangedFunc)(const char *, void *);
 #define have_PrefChangedFunc_typedef
 #endif
 
 #ifdef DEBUG
 enum pref_initPhase {
@@ -144,42 +142,16 @@ public:
   static float GetFloat(const char* aPref, float aDefault = 0)
   {
     float result = aDefault;
     GetFloat(aPref, &result);
     return result;
   }
 
   /**
-   * Gets char type pref value directly.  If failed, the get() of result
-   * returns nullptr.  Even if succeeded but the result was empty string, the
-   * get() does NOT return nullptr.  So, you can check whether the method
-   * succeeded or not by:
-   *
-   * nsAdoptingString value = Prefereces::GetString("foo.bar");
-   * if (!value) {
-   *   // failed
-   * }
-   *
-   * Be aware.  If you wrote as:
-   *
-   * nsAutoString value = Preferences::GetString("foo.bar");
-   * if (!value.get()) {
-   *   // the condition is always FALSE!!
-   * }
-   *
-   * The value.get() doesn't return nullptr. You must use nsAdoptingString
-   * when you need to check whether it was failure or not.
-   */
-  static nsAdoptingCString GetCString(const char* aPref);
-  static nsAdoptingString GetString(const char* aPref);
-  static nsAdoptingCString GetLocalizedCString(const char* aPref);
-  static nsAdoptingString GetLocalizedString(const char* aPref);
-
-  /**
    * Gets int, float, or bool type pref value with raw return value of
    * nsIPrefBranch.
    *
    * @param aPref       A pref name.
    * @param aResult     Must not be nullptr.  The value is never modified
    *                    when these methods fail.
    */
   static nsresult GetBool(const char* aPref, bool* aResult);
@@ -194,23 +166,22 @@ public:
     }
     return rv;
   }
 
   /**
    * Gets string type pref value with raw return value of nsIPrefBranch.
    *
    * @param aPref       A pref name.
-   * @param aResult     Must not be nullptr.  The value is never modified
-   *                    when these methods fail.
+   * @param aResult     The value is never modified when these methods fail.
    */
-  static nsresult GetCString(const char* aPref, nsACString* aResult);
-  static nsresult GetString(const char* aPref, nsAString* aResult);
-  static nsresult GetLocalizedCString(const char* aPref, nsACString* aResult);
-  static nsresult GetLocalizedString(const char* aPref, nsAString* aResult);
+  static nsresult GetCString(const char* aPref, nsACString& aResult);
+  static nsresult GetString(const char* aPref, nsAString& aResult);
+  static nsresult GetLocalizedCString(const char* aPref, nsACString& aResult);
+  static nsresult GetLocalizedString(const char* aPref, nsAString& aResult);
 
   static nsresult GetComplex(const char* aPref, const nsIID &aType,
                              void** aResult);
 
   /**
    * Sets various type pref values.
    */
   static nsresult SetBool(const char* aPref, bool aValue);
@@ -377,33 +348,23 @@ public:
   static uint32_t GetDefaultUint(const char* aPref, uint32_t aFailedResult)
   {
    return static_cast<uint32_t>(
      GetDefaultInt(aPref, static_cast<int32_t>(aFailedResult)));
   }
 
   /**
    * Gets the default value of the char type pref.
-   * If the get() of the result returned nullptr, that meant the value didn't
-   * have default value.
-   *
-   * See the comment at definition at GetString() and GetCString() for more
-   * details of the result.
    */
-  static nsAdoptingString GetDefaultString(const char* aPref);
-  static nsAdoptingCString GetDefaultCString(const char* aPref);
-  static nsAdoptingString GetDefaultLocalizedString(const char* aPref);
-  static nsAdoptingCString GetDefaultLocalizedCString(const char* aPref);
-
-  static nsresult GetDefaultCString(const char* aPref, nsACString* aResult);
-  static nsresult GetDefaultString(const char* aPref, nsAString* aResult);
+  static nsresult GetDefaultCString(const char* aPref, nsACString& aResult);
+  static nsresult GetDefaultString(const char* aPref, nsAString& aResult);
   static nsresult GetDefaultLocalizedCString(const char* aPref,
-                                             nsACString* aResult);
+                                             nsACString& aResult);
   static nsresult GetDefaultLocalizedString(const char* aPref,
-                                            nsAString* aResult);
+                                            nsAString& aResult);
 
   static nsresult GetDefaultComplex(const char* aPref, const nsIID &aType,
                                     void** aResult);
 
   /**
    * Gets the type of the pref.
    */
   static int32_t GetDefaultType(const char* aPref);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4763,17 +4763,17 @@ pref("network.tcp.keepalive.idle_time", 
 pref("network.tcp.keepalive.retry_interval", 1); // seconds
 #endif
 // Default maximum probe retransmissions.
 // Linux only; not configurable on Win and Mac; fixed at 10 and 8 respectively.
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
 pref("network.tcp.keepalive.probe_count", 4);
 #endif
 
-pref("network.tcp.tcp_fastopen_enable", true);
+pref("network.tcp.tcp_fastopen_enable", false);
 pref("network.tcp.tcp_fastopen_consecutive_failure_limit", 5);
 
 // Whether to disable acceleration for all widgets.
 pref("layers.acceleration.disabled", false);
 // Preference that when switched at runtime will run a series of benchmarks
 // and output the result to stderr.
 pref("layers.bench.enabled", false);
 
--- a/netwerk/base/TCPFastOpenLayer.cpp
+++ b/netwerk/base/TCPFastOpenLayer.cpp
@@ -373,17 +373,17 @@ TCPFastOpenFinish(PRFileDesc *fd, PRErro
   tfoStatus = TFO_NOT_TRIED;
   PRErrorCode result = 0;
 
   // If we do not have data to send with syn packet or nspr version does not
   // have sendto implemented we will call normal connect.
   // If sendto is not implemented it points to _PR_InvalidInt, therefore we
   // check if sendto != _PR_InvalidInt. _PR_InvalidInt is exposed so we use
   // reserved_fn_0 which also points to _PR_InvalidInt.
-  if ((secret->mFirstPacketBufLen < 10) ||
+  if (!secret->mFirstPacketBufLen ||
       (tfoFd->lower->methods->sendto == (PRSendtoFN)tfoFd->lower->methods->reserved_fn_0)) {
     // Because of the way our nsHttpTransaction dispatch work, it can happened
     // that data has not been written into the socket.
     // In this case we can just call connect.
     PRInt32 rv = (tfoFd->lower->methods->connect)(tfoFd->lower, &secret->mAddr,
                                                   PR_INTERVAL_NO_WAIT);
     if (rv == PR_SUCCESS) {
       result = PR_IS_CONNECTED_ERROR;
@@ -394,27 +394,25 @@ TCPFastOpenFinish(PRFileDesc *fd, PRErro
         // sendto is not implemented, it is equal to _PR_InvalidInt!
         // We will disable Fast Open.
         SOCKET_LOG(("TCPFastOpenFinish - sendto not implemented.\n"));
         fastOpenNotSupported = true;
     }
   } else {
     // We have some data ready in the buffer we will send it with the syn
     // packet.
-    MOZ_ASSERT(secret->mFirstPacketBufLen >= 10);
     PRInt32 rv = (tfoFd->lower->methods->sendto)(tfoFd->lower,
                                                  secret->mFirstPacketBuf,
-                                                 10,
+                                                 secret->mFirstPacketBufLen,
                                                  0, //flags
                                                  &secret->mAddr,
                                                  PR_INTERVAL_NO_WAIT);
 
     SOCKET_LOG(("TCPFastOpenFinish - sendto result=%d.\n", rv));
     if (rv > 0) {
-      MOZ_DIAGNOSTIC_ASSERT(rv <= 10);
       result = PR_IN_PROGRESS_ERROR;
       secret->mFirstPacketBufLen -= rv;
       if (secret->mFirstPacketBufLen) {
         memmove(secret->mFirstPacketBuf,
                 secret->mFirstPacketBuf + rv,
                 secret->mFirstPacketBufLen);
       }
       tfoStatus = TFO_DATA_SENT;
--- a/netwerk/base/nsChannelClassifier.cpp
+++ b/netwerk/base/nsChannelClassifier.cpp
@@ -115,24 +115,28 @@ StaticAutoPtr<CachedPrefs> CachedPrefs::
 
 // static
 void
 CachedPrefs::OnPrefsChange(const char* aPref, void* aClosure)
 {
   CachedPrefs* prefs = static_cast<CachedPrefs*> (aClosure);
 
   if (!strcmp(aPref, URLCLASSIFIER_SKIP_HOSTNAMES)) {
-    nsCString skipHostnames = Preferences::GetCString(URLCLASSIFIER_SKIP_HOSTNAMES);
+    nsCString skipHostnames;
+    Preferences::GetCString(URLCLASSIFIER_SKIP_HOSTNAMES, skipHostnames);
     ToLowerCase(skipHostnames);
     prefs->SetSkipHostnames(skipHostnames);
   } else if (!strcmp(aPref, URLCLASSIFIER_TRACKING_WHITELIST)) {
-    nsCString trackingWhitelist = Preferences::GetCString(URLCLASSIFIER_TRACKING_WHITELIST);
+    nsCString trackingWhitelist;
+    Preferences::GetCString(URLCLASSIFIER_TRACKING_WHITELIST,
+                            trackingWhitelist);
     prefs->SetTrackingWhiteList(trackingWhitelist);
   } else if (!strcmp(aPref, URLCLASSIFIER_TRACKING_TABLE)) {
-    nsCString trackingBlacklist = Preferences::GetCString(URLCLASSIFIER_TRACKING_TABLE);
+    nsCString trackingBlacklist;
+    Preferences::GetCString(URLCLASSIFIER_TRACKING_TABLE, trackingBlacklist);
     prefs->SetTrackingBlackList(trackingBlacklist);
   }
 }
 
 void
 CachedPrefs::Init()
 {
   Preferences::AddBoolVarCache(&sAnnotateChannelEnabled,
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -147,17 +147,17 @@ GetDeviceModelId() {
     nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
     MOZ_ASSERT(infoService, "Could not find a system info service");
     nsAutoString androidDevice;
     nsresult rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("device"), androidDevice);
     if (NS_SUCCEEDED(rv)) {
         deviceModelId = NS_LossyConvertUTF16toASCII(androidDevice);
     }
     nsAutoCString deviceString;
-    rv = Preferences::GetCString(UA_PREF("device_string"), &deviceString);
+    rv = Preferences::GetCString(UA_PREF("device_string"), deviceString);
     if (NS_SUCCEEDED(rv)) {
         deviceString.Trim(" ", true, true);
         deviceString.ReplaceSubstring(NS_LITERAL_CSTRING("%DEVICEID%"), deviceModelId);
         return deviceString;
     }
     return deviceModelId;
 }
 #endif
@@ -985,18 +985,18 @@ nsHttpHandler::InitUserAgentComponents()
         mDeviceModelId = mozilla::net::GetDeviceModelId();
     }
 #endif // ANDROID
 
 #ifdef MOZ_MULET
     {
         // Add the `Mobile` or `Tablet` or `TV` token when running in the b2g
         // desktop simulator via preference.
-        nsCString deviceType;
-        nsresult rv = Preferences::GetCString("devtools.useragent.device_type", &deviceType);
+        nsAutoCString deviceType;
+        nsresult rv = Preferences::GetCString("devtools.useragent.device_type", deviceType);
         if (NS_SUCCEEDED(rv)) {
             mCompatDevice.Assign(deviceType);
         } else {
             mCompatDevice.AssignLiteral("Mobile");
         }
     }
 #endif // MOZ_MULET
 
@@ -1998,18 +1998,18 @@ PrepareAcceptLanguages(const char *i_Acc
     return NS_OK;
 }
 
 nsresult
 nsHttpHandler::SetAcceptLanguages()
 {
     mAcceptLanguagesIsDirty = false;
 
-    const nsAdoptingCString& acceptLanguages =
-        Preferences::GetLocalizedCString(INTL_ACCEPT_LANGUAGES);
+    nsAutoCString acceptLanguages;
+    Preferences::GetLocalizedCString(INTL_ACCEPT_LANGUAGES, acceptLanguages);
 
     nsAutoCString buf;
     nsresult rv = PrepareAcceptLanguages(acceptLanguages.get(), buf);
     if (NS_SUCCEEDED(rv)) {
         mAcceptLanguages.Assign(buf);
     }
     return rv;
 }
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -199,18 +199,18 @@ nsHtml5StreamParser::nsHtml5StreamParser
     mTokenizer->EnableViewSource(highlighter); // takes ownership
     mTreeBuilder->EnableViewSource(highlighter); // doesn't own
   }
 
   // Chardet instantiation adapted from File.
   // Chardet is initialized here even if it turns out to be useless
   // to make the chardet refcount its observer (nsHtml5StreamParser)
   // on the main thread.
-  const nsAdoptingCString& detectorName =
-    Preferences::GetLocalizedCString("intl.charset.detector");
+  nsAutoCString detectorName;
+  Preferences::GetLocalizedCString("intl.charset.detector", detectorName);
   if (!detectorName.IsEmpty()) {
     nsAutoCString detectorContractID;
     detectorContractID.AssignLiteral(NS_CHARSET_DETECTOR_CONTRACTID_BASE);
     detectorContractID += detectorName;
     if ((mChardet = do_CreateInstance(detectorContractID.get()))) {
       (void) mChardet->Init(this);
       mFeedChardet = true;
     }
--- a/security/apps/AppTrustDomain.cpp
+++ b/security/apps/AppTrustDomain.cpp
@@ -80,18 +80,19 @@ AppTrustDomain::SetTrustedRoot(AppTruste
     case nsIX509CertDB::DeveloperImportedRoot: {
       StaticMutexAutoLock lock(sMutex);
       if (!sDevImportedDERData) {
         MOZ_ASSERT(!NS_IsMainThread());
         nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1"));
         if (!file) {
           return NS_ERROR_FAILURE;
         }
-        nsresult rv = file->InitWithNativePath(
-          Preferences::GetCString(kDevImportedDER));
+        nsAutoCString path;
+        Preferences::GetCString(kDevImportedDER, path);
+        nsresult rv = file->InitWithNativePath(path);
         if (NS_FAILED(rv)) {
           return rv;
         }
 
         nsCOMPtr<nsIInputStream> inputStream;
         rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), file, -1,
                                         -1, nsIFileInputStream::CLOSE_ON_EOF);
         if (NS_FAILED(rv)) {
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -1945,21 +1945,23 @@ nsNSSComponent::InitializeNSS()
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS Initialization done\n"));
 
   {
     MutexAutoLock lock(mMutex);
 
     // ensure we have initial values for various root hashes
 #ifdef DEBUG
-    mTestBuiltInRootHash =
-      Preferences::GetString("security.test.built_in_root_hash");
+    mTestBuiltInRootHash.Truncate();
+    Preferences::GetString("security.test.built_in_root_hash",
+                           mTestBuiltInRootHash);
 #endif
-    mContentSigningRootHash =
-      Preferences::GetString("security.content.signature.root_hash");
+    mContentSigningRootHash.Truncate();
+    Preferences::GetString("security.content.signature.root_hash",
+                           mContentSigningRootHash);
 
     mNSSInitialized = true;
   }
 
   return NS_OK;
 }
 
 void
@@ -2117,24 +2119,27 @@ nsNSSComponent::Observe(nsISupports* aSu
                prefName.EqualsLiteral("security.pki.name_matching_mode") ||
                prefName.EqualsLiteral("security.pki.netscape_step_up_policy") ||
                prefName.EqualsLiteral("security.OCSP.timeoutMilliseconds.soft") ||
                prefName.EqualsLiteral("security.OCSP.timeoutMilliseconds.hard")) {
       setValidationOptions(false);
 #ifdef DEBUG
     } else if (prefName.EqualsLiteral("security.test.built_in_root_hash")) {
       MutexAutoLock lock(mMutex);
-      mTestBuiltInRootHash = Preferences::GetString("security.test.built_in_root_hash");
+      mTestBuiltInRootHash.Truncate();
+      Preferences::GetString("security.test.built_in_root_hash",
+                             mTestBuiltInRootHash);
 #endif // DEBUG
     } else if (prefName.Equals(kFamilySafetyModePref)) {
       MaybeEnableFamilySafetyCompatibility();
     } else if (prefName.EqualsLiteral("security.content.signature.root_hash")) {
       MutexAutoLock lock(mMutex);
-      mContentSigningRootHash =
-        Preferences::GetString("security.content.signature.root_hash");
+      mContentSigningRootHash.Truncate();
+      Preferences::GetString("security.content.signature.root_hash",
+                             mContentSigningRootHash);
     } else if (prefName.Equals(kEnterpriseRootModePref)) {
       MaybeImportEnterpriseRoots();
     } else {
       clearSessionCache = false;
     }
     if (clearSessionCache)
       SSL_ClearSessionCache();
   }
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -1709,19 +1709,19 @@ nsSSLIOLayerHelpers::setInsecureFallback
     }
   }
 }
 
 void
 nsSSLIOLayerHelpers::initInsecureFallbackSites()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  nsCString insecureFallbackHosts;
+  nsAutoCString insecureFallbackHosts;
   Preferences::GetCString("security.tls.insecure_fallback_hosts",
-                          &insecureFallbackHosts);
+                          insecureFallbackHosts);
   setInsecureFallbackSites(insecureFallbackHosts);
 }
 
 bool
 nsSSLIOLayerHelpers::isPublic() const
 {
   return this == &PublicSSLState()->IOLayerHelpers();
 }
@@ -1737,18 +1737,18 @@ public:
 private:
   nsCString mHost;
 };
 
 NS_IMETHODIMP
 FallbackPrefRemover::Run()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  nsCString oldValue;
-  Preferences::GetCString("security.tls.insecure_fallback_hosts", &oldValue);
+  nsAutoCString oldValue;
+  Preferences::GetCString("security.tls.insecure_fallback_hosts", oldValue);
   nsCCharSeparatedTokenizer toker(oldValue, ',');
   nsCString newValue;
   while (toker.hasMoreTokens()) {
     const nsACString& host = toker.nextToken();
     if (host.Equals(mHost)) {
       continue;
     }
     if (!newValue.IsEmpty()) {
@@ -1939,17 +1939,18 @@ enum class UserCertChoice {
 };
 
 // Returns the most appropriate user cert choice based on the value of the
 // security.default_personal_cert preference.
 UserCertChoice
 nsGetUserCertChoice()
 {
   nsAutoCString value;
-  nsresult rv = Preferences::GetCString("security.default_personal_cert", &value);
+  nsresult rv =
+    Preferences::GetCString("security.default_personal_cert", value);
   if (NS_FAILED(rv)) {
     return UserCertChoice::Ask;
   }
 
   // There are three cases for what the preference could be set to:
   //   1. "Select Automatically" -> Auto.
   //   2. "Ask Every Time" -> Ask.
   //   3. Something else -> Ask. This might be a nickname from a migrated cert,
--- a/security/manager/ssl/nsNTLMAuthModule.cpp
+++ b/security/manager/ssl/nsNTLMAuthModule.cpp
@@ -617,17 +617,17 @@ GenerateType3Msg(const nsString &domain,
     userLen = oemUserBuf.Length();
   }
 
   //
   // get workstation name
   // (do not use local machine's hostname after bug 1046421)
   //
   rv = mozilla::Preferences::GetCString("network.generic-ntlm-auth.workstation",
-                                        &hostBuf);
+                                        hostBuf);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (unicode)
   {
     ucsHostBuf = NS_ConvertUTF8toUTF16(hostBuf);
     hostPtr = ucsHostBuf.get();
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
@@ -233,38 +233,41 @@ SandboxBrokerPolicyFactory::GetContentPo
   policy->AddPath(rdonly, nsPrintfCString("/proc/%d/maps", aPid).get());
 
   // Bug 1198552: memory reporting.
   policy->AddPath(rdonly, nsPrintfCString("/proc/%d/statm", aPid).get());
   policy->AddPath(rdonly, nsPrintfCString("/proc/%d/smaps", aPid).get());
   // Now read any extra paths, this requires accessing user preferences
   // so we can only do it now. Our constructor is initialized before
   // user preferences are read in.
-  nsAdoptingCString extraReadPathString =
-    Preferences::GetCString("security.sandbox.content.read_path_whitelist");
-  AddDynamicPathList(policy.get(), extraReadPathString, rdonly);
-  nsAdoptingCString extraWritePathString =
-    Preferences::GetCString("security.sandbox.content.write_path_whitelist");
-  AddDynamicPathList(policy.get(), extraWritePathString, rdwr);
+  AddDynamicPathList(policy.get(),
+                     "security.sandbox.content.read_path_whitelist",
+                     rdonly);
+  AddDynamicPathList(policy.get(),
+                     "security.sandbox.content.write_path_whitelist",
+                     rdwr);
 
   // file:// processes get global read permissions
   if (aFileProcess) {
     policy->AddDir(rdonly, "/");
   }
 
   // Return the common policy.
   return policy;
 
 }
 
 void
 SandboxBrokerPolicyFactory::AddDynamicPathList(SandboxBroker::Policy *policy,
-                                               nsAdoptingCString& pathList,
-                                               int perms) {
- if (pathList) {
+                                               const char* aPathListPref,
+                                               int perms)
+{
+  nsAutoCString pathList;
+  nsresult rv = Preferences::GetCString(aPathListPref, pathList);
+  if (NS_SUCCEEDED(rv)) {
     for (const nsACString& path : pathList.Split(',')) {
       nsCString trimPath(path);
       trimPath.Trim(" ", true, true);
       policy->AddDynamic(perms, trimPath.get());
     }
   }
 }
 
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.h
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.h
@@ -17,15 +17,15 @@ public:
 
 #ifdef MOZ_CONTENT_SANDBOX
   UniquePtr<SandboxBroker::Policy> GetContentPolicy(int aPid, bool aFileProcess);
 #endif
 
 private:
   UniquePtr<const SandboxBroker::Policy> mCommonContentPolicy;
   static void AddDynamicPathList(SandboxBroker::Policy *policy,
-                                 nsAdoptingCString& paths,
+                                 const char* aPathListPref,
                                  int perms);
 };
 
 } // namespace mozilla
 
 #endif // mozilla_SandboxBrokerPolicyFactory_h
--- a/taskcluster/taskgraph/create.py
+++ b/taskcluster/taskgraph/create.py
@@ -53,21 +53,25 @@ def create_tasks(taskgraph, label_to_tas
         # Using visit_postorder() here isn't the most efficient: we'll
         # block waiting for dependencies of task N to submit even though
         # dependencies for task N+1 may be finished. If we need to optimize
         # this further, we can build a graph of task dependencies and walk
         # that.
         for task_id in taskgraph.graph.visit_postorder():
             task_def = taskgraph.tasks[task_id].task
             attributes = taskgraph.tasks[task_id].attributes
-            # if this task has no dependencies, make it depend on this decision
-            # task so that it does not start immediately; and so that if this loop
-            # fails halfway through, none of the already-created tasks run.
-            if decision_task_id and not task_def.get('dependencies'):
-                task_def['dependencies'] = [decision_task_id]
+
+            # if this task has no dependencies *within* this taskgraph, make it
+            # depend on this decision task. If it has another dependency within
+            # the taskgraph, then it already implicitly depends on the decision
+            # task.  The result is that tasks do not start immediately. if this
+            # loop fails halfway through, none of the already-created tasks run.
+            if decision_task_id:
+                if not any(t in taskgraph.tasks for t in task_def.get('dependencies', [])):
+                    task_def.setdefault('dependencies', []).append(decision_task_id)
 
             task_def['taskGroupId'] = task_group_id
             task_def['schedulerId'] = scheduler_id
 
             # Wait for dependencies before submitting this.
             deps_fs = [fs[dep] for dep in task_def.get('dependencies', [])
                        if dep in fs]
             for f in futures.as_completed(deps_fs):
--- a/testing/marionette/.eslintrc.js
+++ b/testing/marionette/.eslintrc.js
@@ -1,18 +1,21 @@
 "use strict";
 
 module.exports = {
   "rules": {
     "comma-dangle": ["error", "always-multiline"],
     "indent": ["error", 2, {
-      "SwitchCase": 1,
+      "CallExpression": {"arguments": 2},
       "FunctionExpression": {"body": 1, "parameters": 2},
       "MemberExpression": 2,
+      "SwitchCase": 1,
     }],
     "max-len": ["error", 78, {
       "ignoreStrings": true,
       "ignoreUrls": true,
     }],
     "no-new-object": "error",
+    "no-undef-init": "error",
     "object-curly-spacing": ["error", "never"],
+    "semi": "error",
   }
 };
--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -9,17 +9,17 @@ const {Constructor: CC, interfaces: Ci, 
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(
     this, "env", "@mozilla.org/process/environment;1", "nsIEnvironment");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
-  "resource://gre/modules/Preferences.jsm");
+    "resource://gre/modules/Preferences.jsm");
 
 const MARIONETTE_CONTRACT_ID = "@mozilla.org/remote/marionette;1";
 const MARIONETTE_CID = Components.ID("{786a1369-dca5-4adc-8486-33d23c88010a}");
 
 const PREF_PORT = "marionette.port";
 const PREF_PORT_FALLBACK = "marionette.defaultPrefs.port";
 const PREF_LOG_LEVEL = "marionette.log.level";
 const PREF_LOG_LEVEL_FALLBACK = "marionette.logging";
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -175,17 +175,17 @@ this.GeckoDriver = function(appName, ser
   this.inactivityTimer = null;
 
   this.testName = null;
 
   this.capabilities = new session.Capabilities();
 
   this.mm = globalMessageManager;
   this.listener = proxy.toListener(() => this.mm, this.sendAsync.bind(this),
-                                   () => this.curBrowser);
+      () => this.curBrowser);
 
   // points to an alert instance if a modal dialog is present
   this.dialog = null;
   this.dialogHandler = this.globalModalDialogHandler.bind(this);
 };
 
 Object.defineProperty(GeckoDriver.prototype, "a11yChecks", {
   get() {
@@ -1195,17 +1195,17 @@ GeckoDriver.prototype.goForward = functi
  *     A modal dialog is open, blocking this operation.
  */
 GeckoDriver.prototype.refresh = function* (cmd, resp) {
   assert.content(this.context);
   assert.window(this.getCurrentWindow());
   assert.noUserPrompt(this.dialog);
 
   let refresh = this.listener.refresh(
-      {pageTimeout: this.timeouts.pageLoad})
+      {pageTimeout: this.timeouts.pageLoad});
 
   // If a reload of the frame script interrupts our page load, this will
   // never return. We need to re-issue this request to correctly poll for
   // readyState and send errors.
   this.curBrowser.pendingCommands.push(() => {
     let parameters = {
       // TODO(ato): Bug 1242595
       command_id: this.listener.activeMessageId,
@@ -1277,17 +1277,17 @@ GeckoDriver.prototype.getWindowHandle = 
  * Each window handle is assigned by the server and is guaranteed unique,
  * however the return array does not have a specified ordering.
  *
  * @return {Array.<string>}
  *     Unique window handles.
  */
 GeckoDriver.prototype.getWindowHandles = function(cmd, resp) {
   return this.windowHandles.map(String);
-}
+};
 
 /**
  * Get the current window's handle.  This corresponds to a window that
  * may itself contain tabs.
  *
  * Return an opaque server-assigned identifier to this window that
  * uniquely identifies it within this Marionette instance.  This can
  * be used to switch to this window at a later point.
@@ -1313,17 +1313,17 @@ GeckoDriver.prototype.getChromeWindowHan
  * Returns identifiers for each open chrome window for tests interested in
  * managing a set of chrome windows and tabs separately.
  *
  * @return {Array.<string>}
  *     Unique window handles.
  */
 GeckoDriver.prototype.getChromeWindowHandles = function(cmd, resp) {
   return this.chromeWindowHandles.map(String);
-}
+};
 
 /**
  * Get the current position and size of the browser window currently in focus.
  *
  * Will return the current browser window size in pixels. Refers to
  * window outerWidth and outerHeight values, which include scroll bars,
  * title bars, etc.
  *
@@ -1368,17 +1368,17 @@ GeckoDriver.prototype.getWindowRect = fu
  * @throws {UnsupportedOperationError}
  *     Not applicable to application.
  * @throws {NoSuchWindowError}
  *     Top-level browsing context has been discarded.
  * @throws {UnexpectedAlertOpenError}
  *     A modal dialog is open, blocking this operation.
  */
 GeckoDriver.prototype.setWindowRect = async function(cmd, resp) {
-  assert.firefox()
+  assert.firefox();
   const win = assert.window(this.getCurrentWindow());
   assert.noUserPrompt(this.dialog);
 
   let {x, y, width, height} = cmd.parameters;
   let origRect = this.curBrowser.rect;
 
   // Throttle resize event by forcing the event queue to flush and delay
   // until the main thread is idle.
@@ -3103,17 +3103,17 @@ GeckoDriver.prototype._checkIfAlertIsPre
  * marionette.quit() or marionette.restart(), like File -> Quit.
  *
  * @param {boolean} state
  *     True if the server should accept new socket connections.
  */
 GeckoDriver.prototype.acceptConnections = function(cmd, resp) {
   assert.boolean(cmd.parameters.value);
   this._server.acceptConnections = cmd.parameters.value;
-}
+};
 
 /**
  * Quits the application with the provided flags.
  *
  * Marionette will stop accepting new connections before ending the
  * current session, and finally attempting to quit the application.
  *
  * Optional {@link nsIAppStartup} flags may be provided as
@@ -3142,17 +3142,17 @@ GeckoDriver.prototype.quit = function* (
   const quits = ["eConsiderQuit", "eAttemptQuit", "eForceQuit"];
 
   let flags = [];
   if (typeof cmd.parameters.flags != "undefined") {
     flags = assert.array(cmd.parameters.flags);
   }
 
   // bug 1298921
-  assert.firefox()
+  assert.firefox();
 
   let quitSeen;
   let mode = 0;
   if (flags.length > 0) {
     for (let k of flags) {
       assert.in(k, Ci.nsIAppStartup);
 
       if (quits.includes(k)) {
@@ -3182,30 +3182,30 @@ GeckoDriver.prototype.quit = function* (
   Services.startup.quit(mode);
 
   yield quitApplication
       .then(cause => resp.body.cause = cause)
       .then(() => resp.send());
 };
 
 GeckoDriver.prototype.installAddon = function(cmd, resp) {
-  assert.firefox()
+  assert.firefox();
 
   let path = cmd.parameters.path;
   let temp = cmd.parameters.temporary || false;
   if (typeof path == "undefined" || typeof path != "string" ||
       typeof temp != "boolean") {
     throw InvalidArgumentError();
   }
 
   return addon.install(path, temp);
 };
 
 GeckoDriver.prototype.uninstallAddon = function(cmd, resp) {
-  assert.firefox()
+  assert.firefox();
 
   let id = cmd.parameters.id;
   if (typeof id == "undefined" || typeof id != "string") {
     throw new InvalidArgumentError();
   }
 
   return addon.uninstall(id);
 };
@@ -3300,17 +3300,17 @@ GeckoDriver.prototype.localizeEntity = f
   if (!Array.isArray(urls)) {
     throw new InvalidArgumentError("Value of `urls` should be of type 'Array'");
   }
   if (typeof id != "string") {
     throw new InvalidArgumentError("Value of `id` should be of type 'string'");
   }
 
   resp.body.value = l10n.localizeEntity(urls, id);
-}
+};
 
 /**
  * Retrieve the localized string for the specified property id.
  *
  * Example:
  *
  *     localizeProperty(
  *         ["chrome://global/locale/findbar.properties"], "FastFind");
@@ -3329,17 +3329,17 @@ GeckoDriver.prototype.localizeProperty =
   if (!Array.isArray(urls)) {
     throw new InvalidArgumentError("Value of `urls` should be of type 'Array'");
   }
   if (typeof id != "string") {
     throw new InvalidArgumentError("Value of `id` should be of type 'string'");
   }
 
   resp.body.value = l10n.localizeProperty(urls, id);
-}
+};
 
 /**
  * Initialize the reftest mode
  */
 GeckoDriver.prototype.setupReftest = function* (cmd, resp) {
   if (this._reftest) {
     throw new UnsupportedOperationError("Called reftest:setup with a reftest session already active");
   }
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -1022,10 +1022,10 @@ element.isBooleanAttribute = function(el
   const customElement = !el.localName.includes("-");
   if ((attr == "hidden" || attr == "itemscope") && customElement) {
     return true;
   }
 
   if (!boolEls.hasOwnProperty(el.localName)) {
     return false;
   }
-  return boolEls[el.localName].includes(attr)
+  return boolEls[el.localName].includes(attr);
 };
--- a/testing/marionette/error.js
+++ b/testing/marionette/error.js
@@ -238,17 +238,17 @@ class WebDriverError extends Error {
    * @return {Object.<string, string>}
    *     JSON serialisation of error prototype.
    */
   toJSON() {
     return {
       error: this.status,
       message: this.message || "",
       stacktrace: this.stack || "",
-    }
+    };
   }
 
   /**
    * Unmarshals a JSON error representation to the appropriate Marionette
    * error type.
    *
    * @param {Object.<string, string>} json
    *     Error object.
--- a/testing/marionette/event.js
+++ b/testing/marionette/event.js
@@ -626,43 +626,43 @@ function emulateToActivateModifiers_(TIP
     ],
     lockable: [
       {key: "CapsLock",   attr: "capsLockKey"},
       {key: "FnLock",     attr: "fnLockKey"},
       {key: "NumLock",    attr: "numLockKey"},
       {key: "ScrollLock", attr: "scrollLockKey"},
       {key: "SymbolLock", attr: "symbolLockKey"},
     ],
-  }
+  };
 
   for (let i = 0; i < modifiers.normal.length; i++) {
     if (!keyEvent[modifiers.normal[i].attr]) {
       continue;
     }
     if (TIP.getModifierState(modifiers.normal[i].key)) {
       continue; // already activated.
     }
     let event = new KeyboardEvent("", {key: modifiers.normal[i].key});
     TIP.keydown(event,
-      TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
+        TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
     modifiers.normal[i].activated = true;
   }
 
   for (let j = 0; j < modifiers.lockable.length; j++) {
     if (!keyEvent[modifiers.lockable[j].attr]) {
       continue;
     }
     if (TIP.getModifierState(modifiers.lockable[j].key)) {
       continue; // already activated.
     }
     let event = new KeyboardEvent("", {key: modifiers.lockable[j].key});
     TIP.keydown(event,
-      TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
+        TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
     TIP.keyup(event,
-      TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
+        TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
     modifiers.lockable[j].activated = true;
   }
 
   return modifiers;
 }
 
 function emulateToInactivateModifiers_(TIP, modifiers, win = window) {
   if (!modifiers) {
@@ -670,30 +670,30 @@ function emulateToInactivateModifiers_(T
   }
   let KeyboardEvent = getKeyboardEvent_(win);
   for (let i = 0; i < modifiers.normal.length; i++) {
     if (!modifiers.normal[i].activated) {
       continue;
     }
     let event = new KeyboardEvent("", {key: modifiers.normal[i].key});
     TIP.keyup(event,
-      TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
+        TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
   }
   for (let j = 0; j < modifiers.lockable.length; j++) {
     if (!modifiers.lockable[j].activated) {
       continue;
     }
     if (!TIP.getModifierState(modifiers.lockable[j].key)) {
       continue; // who already inactivated this?
     }
     let event = new KeyboardEvent("", {key: modifiers.lockable[j].key});
     TIP.keydown(event,
-      TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
+        TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
     TIP.keyup(event,
-      TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
+        TIP.KEY_NON_PRINTABLE_KEY | TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
   }
 }
 
 function isMac_(win = window) {
   if (win) {
     try {
       return win.navigator.platform.indexOf("Mac") > -1;
     } catch (ex) {}
--- a/testing/marionette/l10n.js
+++ b/testing/marionette/l10n.js
@@ -45,17 +45,17 @@ this.l10n = {};
  * @return {string}
  *     The localized string for the requested entity.
  */
 l10n.localizeEntity = function(urls, id) {
   // Build a string which contains all possible entity locations
   let locations = [];
   urls.forEach((url, index) => {
     locations.push(`<!ENTITY % dtd_${index} SYSTEM "${url}">%dtd_${index};`);
-  })
+  });
 
   // Use the DOM parser to resolve the entity and extract its real value
   let header = `<?xml version="1.0"?><!DOCTYPE elem [${locations.join("")}]>`;
   let elem = `<elem id="elementID">&${id};</elem>`;
   let doc = domParser.parseFromString(header + elem, "text/xml");
   let element = doc.querySelector("elem[id='elementID']");
 
   if (element === null) {
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -351,17 +351,17 @@ var loadListener = {
         //
         // Otherwise the timeout waiting for the document to start
         // navigating is increased by 5000 ms to ensure a possible load
         // event is not missed. In the common case such an event should
         // occur pretty soon after beforeunload, and we optimise for this.
         if (this.seenBeforeUnload) {
           this.seenBeforeUnload = null;
           this.timerPageUnload.initWithCallback(
-              this, 5000, Ci.nsITimer.TYPE_ONE_SHOT)
+              this, 5000, Ci.nsITimer.TYPE_ONE_SHOT);
 
         // If no page unload has been detected, ensure to properly stop
         // the load listener, and return from the currently active command.
         } else if (!this.seenUnload) {
           logger.debug("Canceled page load listener because no navigation " +
               "has been detected");
           this.stop();
           sendOk(this.command_id);
@@ -465,17 +465,17 @@ var loadListener = {
       if (loadEventExpected) {
         this.stop();
       }
 
       sendError(err, command_id);
 
     });
   },
-}
+};
 
 /**
  * Called when listener is first started up.  The listener sends its
  * unique window ID and its current URI to the actor.  If the actor returns
  * an ID, we start the listeners. Otherwise, nothing happens.
  */
 function registerSelf() {
   let msg = {value: winUtil.outerWindowID};
@@ -983,24 +983,24 @@ function emitMultiEvents(type, touch, to
     return ((t.target === target) &&
         ((type != "touchcancel") || (type != "touchend")));
   }));
   // Create changed touches
   let changedTouches = doc.createTouchList(touch);
   // Create the event object
   let event = doc.createEvent("TouchEvent");
   event.initTouchEvent(type,
-                       true,
-                       true,
-                       win,
-                       0,
-                       false, false, false, false,
-                       documentTouches,
-                       targetTouches,
-                       changedTouches);
+      true,
+      true,
+      win,
+      0,
+      false, false, false, false,
+      documentTouches,
+      targetTouches,
+      changedTouches);
   target.dispatchEvent(event);
 }
 
 function setDispatch(batches, touches, batchIndex = 0) {
   // check if all the sets have been fired
   if (batchIndex >= batches.length) {
     multiLast = {};
     return;
@@ -1361,19 +1361,19 @@ function clickElement(msg) {
     let target = getElementAttribute(id, "target");
 
     if (target === "_blank") {
       loadEventExpected = false;
     }
 
     loadListener.navigate(() => {
       return interaction.clickElement(
-        seenEls.get(id, curContainer),
-        capabilities.get("moz:accessibilityChecks"),
-        capabilities.get("specificationLevel") >= 1
+          seenEls.get(id, curContainer),
+          capabilities.get("moz:accessibilityChecks"),
+          capabilities.get("specificationLevel") >= 1
       );
     }, command_id, pageTimeout, loadEventExpected, true);
 
   } catch (e) {
     sendError(e, command_id);
   }
 }
 
--- a/testing/marionette/message.js
+++ b/testing/marionette/message.js
@@ -184,17 +184,17 @@ const validator = {
           throw new TypeError(`${t} set, cannot set ${prop}`);
         }
       }
     }
 
     obj[prop] = val;
     return true;
   },
-}
+};
 
 /**
  * The response body is exposed as an argument to commands.
  * Commands can set fields on the body through defining properties.
  *
  * Setting properties invokes a validator that performs tests for
  * mutually exclusionary fields on the input against the existing data
  * in the body.
--- a/testing/marionette/packets.js
+++ b/testing/marionette/packets.js
@@ -304,17 +304,17 @@ BulkPacket.prototype.write = function(st
     // Format the serialized packet header to a buffer
     this._outgoingHeader = "bulk " + this.actor + " " + this.type + " " +
                            this.length + ":";
   }
 
   // Write the header, or whatever's left of it to write.
   if (this._outgoingHeader.length) {
     let written = stream.write(this._outgoingHeader,
-                               this._outgoingHeader.length);
+        this._outgoingHeader.length);
     this._outgoingHeader = this._outgoingHeader.slice(written);
     return;
   }
 
   // Temporarily pause the monitoring of the output stream
   this._transport.pauseOutgoing();
 
   let deferred = defer();
--- a/testing/marionette/proxy.js
+++ b/testing/marionette/proxy.js
@@ -148,17 +148,17 @@ proxy.AsyncMessageChannel = class {
 
         switch (event.type) {
           case "TabClose":
           case "unload":
             this.removeHandlers();
             resolve();
             break;
         }
-      }
+      };
 
       // A modal or tab modal dialog has been opened. To be able to handle it,
       // the active command has to be aborted. Therefore remove all handlers,
       // and cancel any ongoing requests in the listener.
       this.dialogueObserver_ = (subject, topic) => {
         logger.debug(`Received observer notification "${topic}"`);
 
         this.removeAllListeners_();
--- a/testing/marionette/reftest.js
+++ b/testing/marionette/reftest.js
@@ -95,20 +95,21 @@ reftest.Runner = class {
       .getInterface(Ci.nsIDOMWindowUtils);
     this.reftestWin = reftestWin;
     return reftestWin;
   }
 
   *openWindow() {
     let reftestWin;
     yield new Promise(resolve => {
-      reftestWin = this.parentWindow.openDialog("chrome://marionette/content/reftest.xul",
-                                                "reftest",
-                                                "chrome,dialog,height=600,width=600,all",
-                                                () => resolve());
+      reftestWin = this.parentWindow.openDialog(
+          "chrome://marionette/content/reftest.xul",
+          "reftest",
+          "chrome,dialog,height=600,width=600,all",
+          () => resolve());
     });
 
     let browser = reftestWin.document.createElementNS(XUL_NS, "xul:browser");
     browser.permanentKey = {};
     browser.setAttribute("id", "browser");
     browser.setAttribute("anonid", "initialBrowser");
     browser.setAttribute("type", "content");
     browser.setAttribute("primary", "true");
--- a/testing/marionette/stream-utils.js
+++ b/testing/marionette/stream-utils.js
@@ -1,24 +1,28 @@
 /* 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";
 
-const {Constructor: CC, classes: Cc, interfaces: Ci, utils: Cu, results: Cr} =
-    Components;
+const {
+  Constructor: CC,
+  classes: Cc,
+  interfaces: Ci,
+  utils: Cu,
+  results: Cr,
+} = Components;
 
 Cu.import("resource://gre/modules/EventEmitter.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const IOUtil = Cc["@mozilla.org/io-util;1"].getService(Ci.nsIIOUtil);
-const ScriptableInputStream =
-  CC("@mozilla.org/scriptableinputstream;1",
-     "nsIScriptableInputStream", "init");
+const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
+    "nsIScriptableInputStream", "init");
 
 this.EXPORTED_SYMBOLS = ["StreamUtils"];
 
 const BUFFER_SIZE = 0x8000;
 
 /**
  * This helper function (and its companion object) are used by bulk
  * senders and receivers to read and write data in and out of other streams.
--- a/testing/marionette/transport.js
+++ b/testing/marionette/transport.js
@@ -35,17 +35,17 @@ const flags = {wantVerbose: false, wantL
 const dumpv =
   flags.wantVerbose ?
   function(msg) { dump(msg + "\n"); } :
   function() {};
 
 const Pipe = CC("@mozilla.org/pipe;1", "nsIPipe", "init");
 
 const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
-  "nsIScriptableInputStream", "init");
+    "nsIScriptableInputStream", "init");
 
 this.EXPORTED_SYMBOLS = ["DebuggerTransport"];
 
 const PACKET_HEADER_MAX = 200;
 
 /**
  * An adapter that handles data transfers between the debugger client
  * and server. It can work with both nsIPipe and nsIServerSocket
--- a/toolkit/components/downloads/ApplicationReputation.cpp
+++ b/toolkit/components/downloads/ApplicationReputation.cpp
@@ -330,48 +330,48 @@ PendingDBLookup::LookupSpecInternal(cons
   // blacklisted.
   LOG(("Checking DB service for principal %s [this = %p]", mSpec.get(), this));
   nsCOMPtr<nsIUrlClassifierDBService> dbService =
     do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString tables;
   nsAutoCString allowlist;
-  Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE, &allowlist);
+  Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE, allowlist);
   if (!allowlist.IsEmpty()) {
     tables.Append(allowlist);
   }
   nsAutoCString blocklist;
-  Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE, &blocklist);
+  Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE, blocklist);
   if (!mAllowlistOnly && !blocklist.IsEmpty()) {
     tables.Append(',');
     tables.Append(blocklist);
   }
   return dbService->Lookup(principal, tables, this);
 }
 
 NS_IMETHODIMP
 PendingDBLookup::HandleEvent(const nsACString& tables)
 {
   // HandleEvent is guaranteed to call either:
   // 1) PendingLookup::OnComplete if the URL matches the blocklist, or
   // 2) PendingLookup::LookupNext if the URL does not match the blocklist.
   // Blocklisting trumps allowlisting.
   nsAutoCString blockList;
-  Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE, &blockList);
+  Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE, blockList);
   if (!mAllowlistOnly && FindInReadable(blockList, tables)) {
     mPendingLookup->mBlocklistCount++;
     Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, BLOCK_LIST);
     LOG(("Found principal %s on blocklist [this = %p]", mSpec.get(), this));
     return mPendingLookup->OnComplete(true, NS_OK,
       nsIApplicationReputationService::VERDICT_DANGEROUS);
   }
 
   nsAutoCString allowList;
-  Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE, &allowList);
+  Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE, allowList);
   if (FindInReadable(allowList, tables)) {
     mPendingLookup->mAllowlistCount++;
     Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, ALLOW_LIST);
     LOG(("Found principal %s on allowlist [this = %p]", mSpec.get(), this));
     // Don't call onComplete, since blocklisting trumps allowlisting
   } else {
     LOG(("Didn't find principal %s on any list [this = %p]", mSpec.get(),
          this));
@@ -1250,40 +1250,40 @@ nsresult
 PendingLookup::SendRemoteQueryInternal()
 {
   // If we aren't supposed to do remote lookups, bail.
   if (!Preferences::GetBool(PREF_SB_DOWNLOADS_REMOTE_ENABLED, false)) {
     LOG(("Remote lookups are disabled [this = %p]", this));
     return NS_ERROR_NOT_AVAILABLE;
   }
   // If the remote lookup URL is empty or absent, bail.
-  nsCString serviceUrl;
-  NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, &serviceUrl),
+  nsAutoCString serviceUrl;
+  NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, serviceUrl),
                     NS_ERROR_NOT_AVAILABLE);
   if (serviceUrl.IsEmpty()) {
     LOG(("Remote lookup URL is empty [this = %p]", this));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // If the blocklist or allowlist is empty (so we couldn't do local lookups),
   // bail
   {
     nsAutoCString table;
     NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE,
-                                              &table),
+                                              table),
                       NS_ERROR_NOT_AVAILABLE);
     if (table.IsEmpty()) {
       LOG(("Blocklist is empty [this = %p]", this));
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
   {
     nsAutoCString table;
     NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE,
-                                              &table),
+                                              table),
                       NS_ERROR_NOT_AVAILABLE);
     if (table.IsEmpty()) {
       LOG(("Allowlist is empty [this = %p]", this));
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
 
   LOG(("Sending remote query for application reputation [this = %p]",
--- a/toolkit/components/extensions/ExtensionPolicyService.cpp
+++ b/toolkit/components/extensions/ExtensionPolicyService.cpp
@@ -143,28 +143,28 @@ ExtensionPolicyService::UnregisterExtens
 }
 
 
 void
 ExtensionPolicyService::BaseCSP(nsAString& aBaseCSP) const
 {
   nsresult rv;
 
-  rv = Preferences::GetString("extensions.webextensions.base-content-security-policy", &aBaseCSP);
+  rv = Preferences::GetString("extensions.webextensions.base-content-security-policy", aBaseCSP);
   if (NS_FAILED(rv)) {
     aBaseCSP.AssignLiteral(DEFAULT_BASE_CSP);
   }
 }
 
 void
 ExtensionPolicyService::DefaultCSP(nsAString& aDefaultCSP) const
 {
   nsresult rv;
 
-  rv = Preferences::GetString("extensions.webextensions.default-content-security-policy", &aDefaultCSP);
+  rv = Preferences::GetString("extensions.webextensions.default-content-security-policy", aDefaultCSP);
   if (NS_FAILED(rv)) {
     aDefaultCSP.AssignLiteral(DEFAULT_DEFAULT_CSP);
   }
 }
 
 
 /*****************************************************************************
  * Content script management
--- a/toolkit/components/telemetry/TelemetryController.jsm
+++ b/toolkit/components/telemetry/TelemetryController.jsm
@@ -11,36 +11,35 @@ const Cr = Components.results;
 const Cu = Components.utils;
 const myScope = this;
 
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/PromiseUtils.jsm", this);
 Cu.import("resource://gre/modules/DeferredTask.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
 Cu.import("resource://gre/modules/AppConstants.jsm");
 
 const Utils = TelemetryUtils;
 
 const LOGGER_NAME = "Toolkit.Telemetry";
 const LOGGER_PREFIX = "TelemetryController::";
 
 const PREF_BRANCH_LOG = "toolkit.telemetry.log.";
 
 // Whether the FHR/Telemetry unification features are enabled.
 // Changing this pref requires a restart.
-const IS_UNIFIED_TELEMETRY = Preferences.get(TelemetryUtils.Preferences.Unified, false);
+const IS_UNIFIED_TELEMETRY = Services.prefs.getBoolPref(TelemetryUtils.Preferences.Unified, false);
 
 const PING_FORMAT_VERSION = 4;
 
 // Delay before intializing telemetry (ms)
-const TELEMETRY_DELAY = Preferences.get("toolkit.telemetry.initDelay", 60) * 1000;
+const TELEMETRY_DELAY = Services.prefs.getIntPref("toolkit.telemetry.initDelay", 60) * 1000;
 // Delay before initializing telemetry if we're testing (ms)
 const TELEMETRY_TEST_DELAY = 1;
 
 // How long to wait (ms) before sending the new profile ping on the first
 // run of a new profile.
 const NEWPROFILE_PING_DEFAULT_DELAY = 30 * 60 * 1000;
 
 // Ping types.
@@ -90,24 +89,24 @@ var gLogAppenderDump = null;
 function configureLogging() {
   if (!gLogger) {
     gLogger = Log.repository.getLogger(LOGGER_NAME);
 
     // Log messages need to go to the browser console.
     let consoleAppender = new Log.ConsoleAppender(new Log.BasicFormatter());
     gLogger.addAppender(consoleAppender);
 
-    Preferences.observe(PREF_BRANCH_LOG, configureLogging);
+    Services.prefs.addObserver(PREF_BRANCH_LOG, configureLogging);
   }
 
   // Make sure the logger keeps up with the logging level preference.
-  gLogger.level = Log.Level[Preferences.get(TelemetryUtils.Preferences.LogLevel, "Warn")];
+  gLogger.level = Log.Level[Services.prefs.getStringPref(TelemetryUtils.Preferences.LogLevel, "Warn")];
 
   // If enabled in the preferences, add a dump appender.
-  let logDumping = Preferences.get(TelemetryUtils.Preferences.LogDump, false);
+  let logDumping = Services.prefs.getBoolPref(TelemetryUtils.Preferences.LogDump, false);
   if (logDumping != !!gLogAppenderDump) {
     if (logDumping) {
       gLogAppenderDump = new Log.DumpAppender(new Log.BasicFormatter());
       gLogger.addAppender(gLogAppenderDump);
     } else {
       gLogger.removeAppender(gLogAppenderDump);
       gLogAppenderDump = null;
     }
@@ -716,17 +715,17 @@ var Impl = {
         // Load the ClientID.
         this._clientID = await ClientID.getClientID();
 
         await TelemetrySend.setup(this._testMode);
 
         // Perform TelemetrySession delayed init.
         await TelemetrySession.delayedInit();
 
-        if (Preferences.get(TelemetryUtils.Preferences.NewProfilePingEnabled, false) &&
+        if (Services.prefs.getBoolPref(TelemetryUtils.Preferences.NewProfilePingEnabled, false) &&
             !TelemetrySession.newProfilePingSent) {
           // Kick off the scheduling of the new-profile ping.
           this.scheduleNewProfilePing();
         }
 
         // Purge the pings archive by removing outdated pings. We don't wait for
         // this task to complete, but TelemetryStorage blocks on it during
         // shutdown.
@@ -775,17 +774,17 @@ var Impl = {
   // Do proper shutdown waiting and cleanup.
   async _cleanupOnShutdown() {
     if (!this._initialized) {
       return;
     }
 
     this._shuttingDown = true;
 
-    Preferences.ignore(PREF_BRANCH_LOG, configureLogging);
+    Services.prefs.removeObserver(PREF_BRANCH_LOG, configureLogging);
     this._detachObservers();
 
     // Now do an orderly shutdown.
     try {
       if (this._delayedNewPingTask) {
         await this._delayedNewPingTask.finalize();
       }
 
@@ -861,16 +860,20 @@ var Impl = {
 
     switch (aTopic) {
     case "profile-after-change":
       // profile-after-change is only registered for chrome processes.
       return this.setupTelemetry();
     case "app-startup":
       // app-startup is only registered for content processes.
       return this.setupContentTelemetry();
+    case "nsPref:changed":
+      if (aData == TelemetryUtils.Preferences.FhrUploadEnabled) {
+        return this._onUploadPrefChange();
+      }
     }
     return undefined;
   },
 
   /**
    * Get an object describing the current state of this module for AsyncShutdown diagnostics.
    */
   _getState() {
@@ -885,17 +888,17 @@ var Impl = {
     };
   },
 
   /**
    * Called whenever the FHR Upload preference changes (e.g. when user disables FHR from
    * the preferences panel), this triggers sending the deletion ping.
    */
   _onUploadPrefChange() {
-    const uploadEnabled = Preferences.get(TelemetryUtils.Preferences.FhrUploadEnabled, false);
+    const uploadEnabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, false);
     if (uploadEnabled) {
       // There's nothing we should do if we are enabling upload.
       return;
     }
 
     let p = (async () => {
       try {
         // Clear the current pings.
@@ -911,29 +914,31 @@ var Impl = {
         this.submitExternalPing(PING_TYPE_DELETION, {}, { addClientId: true });
       }
     })();
 
     this._shutdownBarrier.client.addBlocker(
       "TelemetryController: removing pending pings after data upload was disabled", p);
   },
 
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference]),
+
   _attachObservers() {
     if (IS_UNIFIED_TELEMETRY) {
       // Watch the FHR upload setting to trigger deletion pings.
-      Preferences.observe(TelemetryUtils.Preferences.FhrUploadEnabled, this._onUploadPrefChange, this);
+      Services.prefs.addObserver(TelemetryUtils.Preferences.FhrUploadEnabled, this, true);
     }
   },
 
   /**
    * Remove the preference observer to avoid leaks.
    */
   _detachObservers() {
     if (IS_UNIFIED_TELEMETRY) {
-      Preferences.ignore(TelemetryUtils.Preferences.FhrUploadEnabled, this._onUploadPrefChange, this);
+      Services.prefs.removeObserver(TelemetryUtils.Preferences.FhrUploadEnabled, this);
     }
   },
 
   /**
    * Allows waiting for TelemetryControllers delayed initialization to complete.
    * This will complete before TelemetryController is shutting down.
    * @return {Promise} Resolved when delayed TelemetryController initialization completed.
    */
@@ -985,17 +990,17 @@ var Impl = {
 
   /**
    * Schedule sending the "new-profile" ping.
    */
   scheduleNewProfilePing() {
     this._log.trace("scheduleNewProfilePing");
 
     const sendDelay =
-      Preferences.get(TelemetryUtils.Preferences.NewProfilePingDelay, NEWPROFILE_PING_DEFAULT_DELAY);
+      Services.prefs.getIntPref(TelemetryUtils.Preferences.NewProfilePingDelay, NEWPROFILE_PING_DEFAULT_DELAY);
 
     this._delayedNewPingTask = new DeferredTask(async () => {
       try {
         await this.sendNewProfilePing();
       } finally {
         this._delayedNewPingTask = null;
       }
     }, sendDelay);
--- a/toolkit/components/telemetry/TelemetryEnvironment.jsm
+++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm
@@ -8,17 +8,16 @@ this.EXPORTED_SYMBOLS = [
   "TelemetryEnvironment",
 ];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 const myScope = this;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
 Cu.import("resource://gre/modules/ObjectUtils.jsm");
 Cu.import("resource://gre/modules/TelemetryController.jsm", this);
 Cu.import("resource://gre/modules/AppConstants.jsm");
 
 const Utils = TelemetryUtils;
 
@@ -253,16 +252,17 @@ const PREF_E10S_COHORT = "e10s.rollout.c
 const COMPOSITOR_CREATED_TOPIC = "compositor:created";
 const COMPOSITOR_PROCESS_ABORTED_TOPIC = "compositor:process-aborted";
 const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC = "distribution-customization-complete";
 const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed";
 const GFX_FEATURES_READY_TOPIC = "gfx-features-ready";
 const SEARCH_ENGINE_MODIFIED_TOPIC = "browser-search-engine-modified";
 const SEARCH_SERVICE_TOPIC = "browser-search-service";
 const SESSIONSTORE_WINDOWS_RESTORED_TOPIC = "sessionstore-windows-restored";
+const PREF_CHANGED_TOPIC = "nsPref:changed";
 
 /**
  * Enforces the parameter to a boolean value.
  * @param aValue The input value.
  * @return {Boolean|Object} If aValue is a boolean or a number, returns its truthfulness
  *         value. Otherwise, return null.
  */
 function enforceBoolean(aValue) {
@@ -994,48 +994,60 @@ EnvironmentCache.prototype = {
    * Get an object containing the values for the watched preferences. Depending on the
    * policy, the value for a preference or whether it was changed by user is reported.
    *
    * @return An object containing the preferences values.
    */
   _getPrefData() {
     let prefData = {};
     for (let [pref, policy] of this._watchedPrefs.entries()) {
+      let prefType = Services.prefs.getPrefType(pref);
+
       if (policy.what == TelemetryEnvironment.RECORD_DEFAULTPREF_VALUE) {
         // For default prefs, make sure they exist
-        if (!Preferences.has(pref)) {
+        if (prefType == Ci.nsIPrefBranch.PREF_INVALID) {
           continue;
         }
-      } else if (!Preferences.isSet(pref)) {
+      } else if (!Services.prefs.prefHasUserValue(pref)) {
         // For user prefs, make sure they are set
         continue;
       }
 
       // Check the policy for the preference and decide if we need to store its value
       // or whether it changed from the default value.
-      let prefValue = undefined;
+      let prefValue;
       if (policy.what == TelemetryEnvironment.RECORD_PREF_STATE) {
         prefValue = "<user-set>";
+      } else if (prefType == Ci.nsIPrefBranch.PREF_STRING) {
+        prefValue = Services.prefs.getStringPref(pref);
+      } else if (prefType == Ci.nsIPrefBranch.PREF_BOOL) {
+        prefValue = Services.prefs.getBoolPref(pref);
+      } else if (prefType == Ci.nsIPrefBranch.PREF_INT) {
+        prefValue = Services.prefs.getIntPref(pref);
+      } else if (prefType == Ci.nsIPrefBranch.PREF_INVALID) {
+        prefValue = null;
       } else {
-        prefValue = Preferences.get(pref, null);
+        throw new Error(`Unexpected preference type ("${prefType}") for "${pref}".`);
       }
       prefData[pref] = prefValue;
     }
     return prefData;
   },
 
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference]),
+
   /**
    * Start watching the preferences.
    */
   _startWatchingPrefs() {
     this._log.trace("_startWatchingPrefs - " + this._watchedPrefs);
 
     for (let [pref, options] of this._watchedPrefs) {
       if (!("requiresRestart" in options) || !options.requiresRestart) {
-        Preferences.observe(pref, this._onPrefChanged, this);
+        Services.prefs.addObserver(pref, this, true);
       }
     }
   },
 
   _onPrefChanged() {
     this._log.trace("_onPrefChanged");
     let oldEnvironment = Cu.cloneInto(this._currentEnvironment, myScope);
     this._updateSettings();
@@ -1045,17 +1057,17 @@ EnvironmentCache.prototype = {
   /**
    * Do not receive any more change notifications for the preferences.
    */
   _stopWatchingPrefs() {
     this._log.trace("_stopWatchingPrefs");
 
     for (let [pref, options] of this._watchedPrefs) {
       if (!("requiresRestart" in options) || !options.requiresRestart) {
-        Preferences.ignore(pref, this._onPrefChanged, this);
+        Services.prefs.removeObserver(pref, this);
       }
     }
   },
 
   _addObservers() {
     // Watch the search engine change and service topics.
     Services.obs.addObserver(this, SESSIONSTORE_WINDOWS_RESTORED_TOPIC);
     Services.obs.addObserver(this, COMPOSITOR_CREATED_TOPIC);
@@ -1118,16 +1130,21 @@ EnvironmentCache.prototype = {
         this._sessionWasRestored = true;
         // Make sure to initialize the search service once we've done restoring
         // the windows, so that we don't risk loosing search data.
         Services.search.init();
         // The default browser check could take some time, so just call it after
         // the session was restored.
         this._updateDefaultBrowser();
         break;
+      case PREF_CHANGED_TOPIC:
+        if (this._watchedPrefs.has(aData)) {
+          this._onPrefChanged();
+        }
+        break;
     }
   },
 
   /**
    * Get the default search engine.
    * @return {String} Returns the search engine identifier, "NONE" if no default search
    *         engine is defined or "UNDEFINED" if no engine identifier or name can be found.
    */
@@ -1240,17 +1257,17 @@ EnvironmentCache.prototype = {
       applicationId: Services.appinfo.ID || null,
       applicationName: Services.appinfo.name || null,
       architecture: Services.sysinfo.get("arch"),
       buildId: Services.appinfo.appBuildID || null,
       version: Services.appinfo.version || null,
       vendor: Services.appinfo.vendor || null,
       platformVersion: Services.appinfo.platformVersion || null,
       xpcomAbi: Services.appinfo.XPCOMABI,
-      hotfixVersion: Preferences.get(PREF_HOTFIX_LASTVERSION, null),
+      hotfixVersion: Services.prefs.getStringPref(PREF_HOTFIX_LASTVERSION, null),
     };
 
     // Add |architecturesInBinary| only for Mac Universal builds.
     if ("@mozilla.org/xpcom/mac-utils;1" in Cc) {
       let macUtils = Cc["@mozilla.org/xpcom/mac-utils;1"].getService(Ci.nsIMacUtils);
       if (macUtils && macUtils.isUniversalBinary) {
         buildData.architecturesInBinary = macUtils.architecturesInBinary;
       }
@@ -1312,26 +1329,26 @@ EnvironmentCache.prototype = {
    */
   _updateSettings() {
     let updateChannel = null;
     try {
       updateChannel = UpdateUtils.getUpdateChannel(false);
     } catch (e) {}
 
     this._currentEnvironment.settings = {
-      blocklistEnabled: Preferences.get(PREF_BLOCKLIST_ENABLED, true),
+      blocklistEnabled: Services.prefs.getBoolPref(PREF_BLOCKLIST_ENABLED, true),
       e10sEnabled: Services.appinfo.browserTabsRemoteAutostart,
       e10sMultiProcesses: Services.appinfo.maxWebProcessCount,
-      e10sCohort: Preferences.get(PREF_E10S_COHORT, "unknown"),
+      e10sCohort: Services.prefs.getStringPref(PREF_E10S_COHORT, "unknown"),
       telemetryEnabled: Utils.isTelemetryEnabled,
       locale: getBrowserLocale(),
       update: {
         channel: updateChannel,
-        enabled: Preferences.get(PREF_UPDATE_ENABLED, true),
-        autoDownload: Preferences.get(PREF_UPDATE_AUTODOWNLOAD, true),
+        enabled: Services.prefs.getBoolPref(PREF_UPDATE_ENABLED, true),
+        autoDownload: Services.prefs.getBoolPref(PREF_UPDATE_AUTODOWNLOAD, true),
       },
       userPrefs: this._getPrefData(),
       sandbox: this._getSandboxData(),
     };
 
     this._currentEnvironment.settings.addonCompatibilityCheckEnabled =
       AddonManager.checkCompatibility;
 
@@ -1387,21 +1404,21 @@ EnvironmentCache.prototype = {
   },
 
   /**
    * Get the partner data in object form.
    * @return Object containing the partner data.
    */
   _getPartner() {
     let partnerData = {
-      distributionId: Preferences.get(PREF_DISTRIBUTION_ID, null),
-      distributionVersion: Preferences.get(PREF_DISTRIBUTION_VERSION, null),
-      partnerId: Preferences.get(PREF_PARTNER_ID, null),
-      distributor: Preferences.get(PREF_DISTRIBUTOR, null),
-      distributorChannel: Preferences.get(PREF_DISTRIBUTOR_CHANNEL, null),
+      distributionId: Services.prefs.getStringPref(PREF_DISTRIBUTION_ID, null),
+      distributionVersion: Services.prefs.getStringPref(PREF_DISTRIBUTION_VERSION, null),
+      partnerId: Services.prefs.getStringPref(PREF_PARTNER_ID, null),
+      distributor: Services.prefs.getStringPref(PREF_DISTRIBUTOR, null),
+      distributorChannel: Services.prefs.getStringPref(PREF_DISTRIBUTOR_CHANNEL, null),
     };
 
     // Get the PREF_APP_PARTNER_BRANCH branch and append its children to partner data.
     let partnerBranch = Services.prefs.getBranch(PREF_APP_PARTNER_BRANCH);
     partnerData.partnerNames = partnerBranch.getChildList("");
 
     return partnerData;
   },
--- a/toolkit/components/telemetry/TelemetryReportingPolicy.jsm
+++ b/toolkit/components/telemetry/TelemetryReportingPolicy.jsm
@@ -6,17 +6,16 @@
 
 this.EXPORTED_SYMBOLS = [
   "TelemetryReportingPolicy"
 ];
 
 const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Log.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/Timer.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://services-common/observers.js", this);
 Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
 
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetrySend",
                                   "resource://gre/modules/TelemetrySend.jsm");
@@ -181,17 +180,17 @@ var TelemetryReportingPolicyImpl = {
     return this._logger;
   },
 
   /**
    * Get the date the policy was notified.
    * @return {Object} A date object or null on errors.
    */
   get dataSubmissionPolicyNotifiedDate() {
-    let prefString = Preferences.get(TelemetryUtils.Preferences.AcceptedPolicyDate, "0");
+    let prefString = Services.prefs.getStringPref(TelemetryUtils.Preferences.AcceptedPolicyDate, "0");
     let valueInteger = parseInt(prefString, 10);
 
     // Bail out if we didn't store any value yet.
     if (valueInteger == 0) {
       this._log.info("get dataSubmissionPolicyNotifiedDate - No date stored yet.");
       return null;
     }
 
@@ -218,61 +217,61 @@ var TelemetryReportingPolicyImpl = {
   set dataSubmissionPolicyNotifiedDate(aDate) {
     this._log.trace("set dataSubmissionPolicyNotifiedDate - aDate: " + aDate);
 
     if (!aDate || aDate.getFullYear() < OLDEST_ALLOWED_ACCEPTANCE_YEAR) {
       this._log.error("set dataSubmissionPolicyNotifiedDate - Invalid notification date.");
       return;
     }
 
-    Preferences.set(TelemetryUtils.Preferences.AcceptedPolicyDate, aDate.getTime().toString());
+    Services.prefs.setStringPref(TelemetryUtils.Preferences.AcceptedPolicyDate, aDate.getTime().toString());
   },
 
   /**
    * Whether submission of data is allowed.
    *
    * This is the master switch for remote server communication. If it is
    * false, we never request upload or deletion.
    */
   get dataSubmissionEnabled() {
     // Default is true because we are opt-out.
-    return Preferences.get(TelemetryUtils.Preferences.DataSubmissionEnabled, true);
+    return Services.prefs.getBoolPref(TelemetryUtils.Preferences.DataSubmissionEnabled, true);
   },
 
   get currentPolicyVersion() {
-    return Preferences.get(TelemetryUtils.Preferences.CurrentPolicyVersion,
-                           TelemetryReportingPolicy.DEFAULT_DATAREPORTING_POLICY_VERSION);
+    return Services.prefs.getIntPref(TelemetryUtils.Preferences.CurrentPolicyVersion,
+                                     TelemetryReportingPolicy.DEFAULT_DATAREPORTING_POLICY_VERSION);
   },
 
   /**
    * The minimum policy version which for dataSubmissionPolicyAccepted to
    * to be valid.
    */
   get minimumPolicyVersion() {
-    const minPolicyVersion = Preferences.get(TelemetryUtils.Preferences.MinimumPolicyVersion, 1);
+    const minPolicyVersion = Services.prefs.getIntPref(TelemetryUtils.Preferences.MinimumPolicyVersion, 1);
 
     // First check if the current channel has a specific minimum policy version. If not,
     // use the general minimum policy version.
     let channel = "";
     try {
       channel = UpdateUtils.getUpdateChannel(false);
     } catch (e) {
       this._log.error("minimumPolicyVersion - Unable to retrieve the current channel.");
       return minPolicyVersion;
     }
     const channelPref = TelemetryUtils.Preferences.MinimumPolicyVersion + ".channel-" + channel;
-    return Preferences.get(channelPref, minPolicyVersion);
+    return Services.prefs.getIntPref(channelPref, minPolicyVersion);
   },
 
   get dataSubmissionPolicyAcceptedVersion() {
-    return Preferences.get(TelemetryUtils.Preferences.AcceptedPolicyVersion, 0);
+    return Services.prefs.getIntPref(TelemetryUtils.Preferences.AcceptedPolicyVersion, 0);
   },
 
   set dataSubmissionPolicyAcceptedVersion(value) {
-    Preferences.set(TelemetryUtils.Preferences.AcceptedPolicyVersion, value);
+    Services.prefs.setIntPref(TelemetryUtils.Preferences.AcceptedPolicyVersion, value);
   },
 
   /**
    * Checks to see if the user has been notified about data submission
    * @return {Bool} True if user has been notified and the notification is still valid,
    *         false otherwise.
    */
   get isUserNotifiedOfCurrentPolicy() {
@@ -342,44 +341,44 @@ var TelemetryReportingPolicyImpl = {
     // If data submission is disabled, there's no point in showing the infobar. Just
     // forbid to upload.
     if (!this.dataSubmissionEnabled) {
       return false;
     }
 
     // Submission is enabled. We enable upload if user is notified or we need to bypass
     // the policy.
-    const bypassNotification = Preferences.get(TelemetryUtils.Preferences.BypassNotification, false);
+    const bypassNotification = Services.prefs.getBoolPref(TelemetryUtils.Preferences.BypassNotification, false);
     return this.isUserNotifiedOfCurrentPolicy || bypassNotification;
   },
 
   isFirstRun() {
     return this._isFirstRun;
   },
 
   /**
    * Migrate the data policy preferences, if needed.
    */
   _migratePreferences() {
     // Current prefs are mostly the same than the old ones, except for some deprecated ones.
     for (let pref of DEPRECATED_FHR_PREFS) {
-      Preferences.reset(pref);
+      Services.prefs.clearUserPref(pref);
     }
   },
 
   /**
    * Determine whether the user should be notified.
    */
   _shouldNotify() {
     if (!this.dataSubmissionEnabled) {
       this._log.trace("_shouldNotify - Data submission disabled by the policy.");
       return false;
     }
 
-    const bypassNotification = Preferences.get(TelemetryUtils.Preferences.BypassNotification, false);
+    const bypassNotification = Services.prefs.getBoolPref(TelemetryUtils.Preferences.BypassNotification, false);
     if (this.isUserNotifiedOfCurrentPolicy || bypassNotification) {
       this._log.trace("_shouldNotify - User already notified or bypassing the policy.");
       return false;
     }
 
     if (this._notificationInProgress) {
       this._log.trace("_shouldNotify - User not notified, notification already in progress.");
       return false;
@@ -426,17 +425,17 @@ var TelemetryReportingPolicyImpl = {
   /**
    * Try to open the privacy policy in a background tab instead of showing the infobar.
    */
   _openFirstRunPage() {
     if (!this._shouldNotify()) {
       return false;
     }
 
-    let firstRunPolicyURL = Preferences.get(TelemetryUtils.Preferences.FirsRunURL, "");
+    let firstRunPolicyURL = Services.prefs.getStringPref(TelemetryUtils.Preferences.FirsRunURL, "");
     if (!firstRunPolicyURL) {
       return false;
     }
     firstRunPolicyURL = Services.urlFormatter.formatURL(firstRunPolicyURL);
 
     let win;
     try {
       const { RecentWindow } = Cu.import("resource:///modules/RecentWindow.jsm", {});
@@ -485,20 +484,20 @@ var TelemetryReportingPolicyImpl = {
     return true;
   },
 
   observe(aSubject, aTopic, aData) {
     if (aTopic != "sessionstore-windows-restored") {
       return;
     }
 
-    this._isFirstRun = Preferences.get(TelemetryUtils.Preferences.FirstRun, true);
+    this._isFirstRun = Services.prefs.getBoolPref(TelemetryUtils.Preferences.FirstRun, true);
     if (this._isFirstRun) {
       // We're performing the first run, flip firstRun preference for subsequent runs.
-      Preferences.set(TelemetryUtils.Preferences.FirstRun, false);
+      Services.prefs.setBoolPref(TelemetryUtils.Preferences.FirstRun, false);
 
       try {
         if (this._openFirstRunPage()) {
           return;
         }
       } catch (e) {
         this._log.error("Failed to open privacy policy tab: " + e);
       }
--- a/toolkit/components/telemetry/TelemetrySend.jsm
+++ b/toolkit/components/telemetry/TelemetrySend.jsm
@@ -16,17 +16,16 @@ this.EXPORTED_SYMBOLS = [
 ];
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/AppConstants.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/ClientID.jsm");
 Cu.import("resource://gre/modules/Log.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/PromiseUtils.jsm");
 Cu.import("resource://gre/modules/ServiceRequest.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
 Cu.import("resource://gre/modules/Timer.jsm", this);
 
 XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
                                   "resource://gre/modules/AsyncShutdown.jsm");
@@ -48,20 +47,21 @@ const Utils = TelemetryUtils;
 const LOGGER_NAME = "Toolkit.Telemetry";
 const LOGGER_PREFIX = "TelemetrySend::";
 
 const TOPIC_IDLE_DAILY = "idle-daily";
 // The following topics are notified when Firefox is closing
 // because the OS is shutting down.
 const TOPIC_QUIT_APPLICATION_GRANTED = "quit-application-granted";
 const TOPIC_QUIT_APPLICATION_FORCED = "quit-application-forced";
+const PREF_CHANGED_TOPIC = "nsPref:changed";
 
 // Whether the FHR/Telemetry unification features are enabled.
 // Changing this pref requires a restart.
-const IS_UNIFIED_TELEMETRY = Preferences.get(TelemetryUtils.Preferences.Unified, false);
+const IS_UNIFIED_TELEMETRY = Services.prefs.getBoolPref(TelemetryUtils.Preferences.Unified, false);
 
 const PING_FORMAT_VERSION = 4;
 
 const MS_IN_A_MINUTE = 60 * 1000;
 
 const PING_TYPE_DELETION = "deletion";
 
 // We try to spread "midnight" pings out over this interval.
@@ -604,17 +604,17 @@ var TelemetrySendImpl = {
 
   OBSERVED_PREFERENCES: [
     TelemetryUtils.Preferences.TelemetryEnabled,
     TelemetryUtils.Preferences.FhrUploadEnabled,
   ],
 
   // Whether sending pings has been overridden.
   get _overrideOfficialCheck() {
-    return Preferences.get(TelemetryUtils.Preferences.OverrideOfficialCheck, false);
+    return Services.prefs.getBoolPref(TelemetryUtils.Preferences.OverrideOfficialCheck, false);
   },
 
   get _log() {
     if (!this._logger) {
       this._logger = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, LOGGER_PREFIX);
     }
 
     return this._logger;
@@ -640,30 +640,32 @@ var TelemetrySendImpl = {
     this._annotateCrashReport();
 
     // Install the observer to detect OS shutdown early enough, so
     // that we catch this before the delayed setup happens.
     Services.obs.addObserver(this, TOPIC_QUIT_APPLICATION_FORCED);
     Services.obs.addObserver(this, TOPIC_QUIT_APPLICATION_GRANTED);
   },
 
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference]),
+
   async setup(testing) {
     this._log.trace("setup");
 
     this._testMode = testing;
     this._sendingEnabled = true;
 
     Services.obs.addObserver(this, TOPIC_IDLE_DAILY);
 
-    this._server = Preferences.get(TelemetryUtils.Preferences.Server, undefined);
+    this._server = Services.prefs.getStringPref(TelemetryUtils.Preferences.Server, undefined);
 
     // Annotate crash reports so that crash pings are sent correctly and listen
     // to pref changes to adjust the annotations accordingly.
     for (let pref of this.OBSERVED_PREFERENCES) {
-      Preferences.observe(pref, this._annotateCrashReport, this);
+      Services.prefs.addObserver(pref, this, true);
     }
     this._annotateCrashReport();
 
     // Check the pending pings on disk now.
     try {
       await this._checkPendingPings();
     } catch (ex) {
       this._log.error("setup - _checkPendingPings rejected", ex);
@@ -685,17 +687,17 @@ var TelemetrySendImpl = {
    */
   _annotateCrashReport() {
     try {
       const cr = Cc["@mozilla.org/toolkit/crash-reporter;1"];
       if (cr) {
         const crs = cr.getService(Ci.nsICrashReporter);
 
         let clientId = ClientID.getCachedClientID();
-        let server = this._server || Preferences.get(TelemetryUtils.Preferences.Server, undefined);
+        let server = this._server || Services.prefs.getStringPref(TelemetryUtils.Preferences.Server, undefined);
 
         if (!this.sendingEnabled() || !TelemetryReportingPolicy.canUpload()) {
           // If we cannot send pings then clear the crash annotations
           crs.annotateCrashReport("TelemetryClientId", "");
           crs.annotateCrashReport("TelemetryServerURL", "");
         } else {
           crs.annotateCrashReport("TelemetryClientId", clientId);
           crs.annotateCrashReport("TelemetryServerURL", server);
@@ -736,17 +738,17 @@ var TelemetrySendImpl = {
 
   async shutdown() {
     this._shutdown = true;
 
     for (let pref of this.OBSERVED_PREFERENCES) {
       // FIXME: When running tests this causes errors to be printed out if
       // TelemetrySend.shutdown() is called twice in a row without calling
       // TelemetrySend.setup() in-between.
-      Preferences.ignore(pref, this._annotateCrashReport, this);
+      Services.prefs.removeObserver(pref, this);
     }
 
     for (let topic of this.OBSERVER_TOPICS) {
       try {
         Services.obs.removeObserver(this, topic);
       } catch (ex) {
         this._log.error("shutdown - failed to remove observer for " + topic, ex);
       }
@@ -813,16 +815,21 @@ var TelemetrySendImpl = {
     case TOPIC_QUIT_APPLICATION_FORCED:
       setOSShutdown();
       break;
     case TOPIC_QUIT_APPLICATION_GRANTED:
       if (data == "syncShutdown") {
         setOSShutdown();
       }
       break;
+    case PREF_CHANGED_TOPIC:
+      if (this.OBSERVED_PREFERENCES.includes(data)) {
+        this._annotateCrashReport();
+      }
+      break;
     }
   },
 
   /**
    * Spawn the PingSender process that sends a ping. This function does
    * not return an error or throw, it only logs an error.
    *
    * Even if the function doesn't fail, it doesn't mean that the ping was
@@ -1233,17 +1240,17 @@ var TelemetrySendImpl = {
 
     // With unified Telemetry, the FHR upload setting controls whether we can send pings.
     // The Telemetry pref enables sending extended data sets instead.
     if (IS_UNIFIED_TELEMETRY) {
       // Deletion pings are sent even if the upload is disabled.
       if (ping && isDeletionPing(ping)) {
         return true;
       }
-      return Preferences.get(TelemetryUtils.Preferences.FhrUploadEnabled, false);
+      return Services.prefs.getBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, false);
     }
 
     // Without unified Telemetry, the Telemetry enabled pref controls ping sending.
     return Utils.isTelemetryEnabled;
   },
 
   /**
    * Track any pending ping send and save tasks through the promise passed here.
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -9,17 +9,16 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/DeferredTask.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
 Cu.import("resource://gre/modules/AppConstants.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetrySend",
                                   "resource://gre/modules/TelemetrySend.jsm");
 
 const Utils = TelemetryUtils;
@@ -38,59 +37,59 @@ const REASON_GATHER_PAYLOAD = "gather-pa
 const REASON_GATHER_SUBSESSION_PAYLOAD = "gather-subsession-payload";
 const REASON_TEST_PING = "test-ping";
 const REASON_ENVIRONMENT_CHANGE = "environment-change";
 const REASON_SHUTDOWN = "shutdown";
 
 const ENVIRONMENT_CHANGE_LISTENER = "TelemetrySession::onEnvironmentChange";
 
 const MS_IN_ONE_HOUR  = 60 * 60 * 1000;
-const MIN_SUBSESSION_LENGTH_MS = Preferences.get("toolkit.telemetry.minSubsessionLength", 5 * 60) * 1000;
+const MIN_SUBSESSION_LENGTH_MS = Services.prefs.getIntPref("toolkit.telemetry.minSubsessionLength", 5 * 60) * 1000;
 
 const LOGGER_NAME = "Toolkit.Telemetry";
 const LOGGER_PREFIX = "TelemetrySession" + (Utils.isContentProcess ? "#content::" : "::");
 
 const MESSAGE_TELEMETRY_PAYLOAD = "Telemetry:Payload";
 const MESSAGE_TELEMETRY_THREAD_HANGS = "Telemetry:ChildThreadHangs";
 const MESSAGE_TELEMETRY_GET_CHILD_THREAD_HANGS = "Telemetry:GetChildThreadHangs";
 const MESSAGE_TELEMETRY_USS = "Telemetry:USS";
 const MESSAGE_TELEMETRY_GET_CHILD_USS = "Telemetry:GetChildUSS";
 
 const DATAREPORTING_DIRECTORY = "datareporting";
 const ABORTED_SESSION_FILE_NAME = "aborted-session-ping";
 
 // Whether the FHR/Telemetry unification features are enabled.
 // Changing this pref requires a restart.
-const IS_UNIFIED_TELEMETRY = Preferences.get(TelemetryUtils.Preferences.Unified, false);
+const IS_UNIFIED_TELEMETRY = Services.prefs.getBoolPref(TelemetryUtils.Preferences.Unified, false);
 
 // Maximum number of content payloads that we are willing to store.
 const MAX_NUM_CONTENT_PAYLOADS = 10;
 
 // Do not gather data more than once a minute (ms)
 const TELEMETRY_INTERVAL = 60 * 1000;
 // Delay before intializing telemetry (ms)
-const TELEMETRY_DELAY = Preferences.get("toolkit.telemetry.initDelay", 60) * 1000;
+const TELEMETRY_DELAY = Services.prefs.getIntPref("toolkit.telemetry.initDelay", 60) * 1000;
 // Delay before initializing telemetry if we're testing (ms)
 const TELEMETRY_TEST_DELAY = 1;
 // Execute a scheduler tick every 5 minutes.
-const SCHEDULER_TICK_INTERVAL_MS = Preferences.get("toolkit.telemetry.scheduler.tickInterval", 5 * 60) * 1000;
+const SCHEDULER_TICK_INTERVAL_MS = Services.prefs.getIntPref("toolkit.telemetry.scheduler.tickInterval", 5 * 60) * 1000;
 // When user is idle, execute a scheduler tick every 60 minutes.
-const SCHEDULER_TICK_IDLE_INTERVAL_MS = Preferences.get("toolkit.telemetry.scheduler.idleTickInterval", 60 * 60) * 1000;
+const SCHEDULER_TICK_IDLE_INTERVAL_MS = Services.prefs.getIntPref("toolkit.telemetry.scheduler.idleTickInterval", 60 * 60) * 1000;
 
 // The tolerance we have when checking if it's midnight (15 minutes).
 const SCHEDULER_MIDNIGHT_TOLERANCE_MS = 15 * 60 * 1000;
 
 // The maximum time (ms) until the tick should moved from the idle
 // queue to the regular queue if it hasn't been executed yet.
 const SCHEDULER_TICK_MAX_IDLE_DELAY_MS = 60 * 1000;
 
 // Seconds of idle time before pinging.
 // On idle-daily a gather-telemetry notification is fired, during it probes can
 // start asynchronous tasks to gather data.
-const IDLE_TIMEOUT_SECONDS = Preferences.get("toolkit.telemetry.idleTimeout", 5 * 60);
+const IDLE_TIMEOUT_SECONDS = Services.prefs.getIntPref("toolkit.telemetry.idleTimeout", 5 * 60);
 
 // The frequency at which we persist session data to the disk to prevent data loss
 // in case of aborted sessions (currently 5 minutes).
 const ABORTED_SESSION_UPDATE_INTERVAL_MS = 5 * 60 * 1000;
 
 const TOPIC_CYCLE_COLLECTOR_BEGIN = "cycle-collector-begin";
 
 // How long to wait in millis for all the child memory reports to come in
@@ -1502,22 +1501,22 @@ var Impl = {
     annotateCrashReport(this._sessionId);
 
     // Initialize some probes that are kept in their own modules
     this._thirdPartyCookies = new ThirdPartyCookieProbe();
     this._thirdPartyCookies.init();
 
     // Record old value and update build ID preference if this is the first
     // run with a new build ID.
-    let previousBuildId = Preferences.get(TelemetryUtils.Preferences.PreviousBuildID, null);
+    let previousBuildId = Services.prefs.getStringPref(TelemetryUtils.Preferences.PreviousBuildID, null);
     let thisBuildID = Services.appinfo.appBuildID;
     // If there is no previousBuildId preference, we send null to the server.
     if (previousBuildId != thisBuildID) {
       this._previousBuildId = previousBuildId;
-      Preferences.set(TelemetryUtils.Preferences.PreviousBuildID, thisBuildID);
+      Services.prefs.setStringPref(TelemetryUtils.Preferences.PreviousBuildID, thisBuildID);
     }
 
     this.attachEarlyObservers();
 
     ppml.addMessageListener(MESSAGE_TELEMETRY_PAYLOAD, this);
     ppml.addMessageListener(MESSAGE_TELEMETRY_THREAD_HANGS, this);
     ppml.addMessageListener(MESSAGE_TELEMETRY_USS, this);
   },
@@ -1796,19 +1795,19 @@ var Impl = {
     let p = [];
 
     if (IS_UNIFIED_TELEMETRY) {
       let shutdownPayload = this.getSessionPayload(REASON_SHUTDOWN, false);
 
       // Only send the shutdown ping using the pingsender from the second
       // browsing session on, to mitigate issues with "bot" profiles (see bug 1354482).
       const sendOnThisSession =
-        Preferences.get(Utils.Preferences.ShutdownPingSenderFirstSession, false) ||
+        Services.prefs.getBoolPref(Utils.Preferences.ShutdownPingSenderFirstSession, false) ||
         !TelemetryReportingPolicy.isFirstRun();
-      let sendWithPingsender = Preferences.get(TelemetryUtils.Preferences.ShutdownPingSender, false) &&
+      let sendWithPingsender = Services.prefs.getBoolPref(TelemetryUtils.Preferences.ShutdownPingSender, false) &&
                                sendOnThisSession;
 
       let options = {
         addClientId: true,
         addEnvironment: true,
         usePingSender: sendWithPingsender,
       };
       p.push(TelemetryController.submitExternalPing(getPingType(shutdownPayload), shutdownPayload, options)
--- a/toolkit/components/telemetry/TelemetryUtils.jsm
+++ b/toolkit/components/telemetry/TelemetryUtils.jsm
@@ -5,17 +5,16 @@
 "use strict";
 
 this.EXPORTED_SYMBOLS = [
   "TelemetryUtils"
 ];
 
 const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
 
-Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 
 const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
 
 const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
 
 const IS_CONTENT_PROCESS = (function() {
   // We cannot use Services.appinfo here because in telemetry xpcshell tests,
@@ -64,17 +63,17 @@ this.TelemetryUtils = {
     return IS_CONTENT_PROCESS;
   },
 
   /**
    * Returns the state of the Telemetry enabled preference, making sure
    * it correctly evaluates to a boolean type.
    */
   get isTelemetryEnabled() {
-    return Preferences.get(PREF_TELEMETRY_ENABLED, false) === true;
+    return Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED, false) === true;
   },
 
   /**
    * Turn a millisecond timestamp into a day timestamp.
    *
    * @param aMsec A number of milliseconds since Unix epoch.
    * @return The number of whole days since Unix epoch.
    */
--- a/toolkit/components/telemetry/UpdatePing.jsm
+++ b/toolkit/components/telemetry/UpdatePing.jsm
@@ -3,17 +3,16 @@
  * 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";
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Log.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryController",
                                   "resource://gre/modules/TelemetryController.jsm");
 
 const LOGGER_NAME = "Toolkit.Telemetry";
@@ -25,17 +24,17 @@ this.EXPORTED_SYMBOLS = ["UpdatePing"];
 /**
  * This module is responsible for listening to all the relevant update
  * signals, gathering the needed information and assembling the "update"
  * ping.
  */
 this.UpdatePing = {
   earlyInit() {
     this._log = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, "UpdatePing::");
-    this._enabled = Preferences.get(TelemetryUtils.Preferences.UpdatePing, false);
+    this._enabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.UpdatePing, false);
 
     this._log.trace("init - enabled: " + this._enabled);
 
     if (!this._enabled) {
       return;
     }
 
     Services.obs.addObserver(this, UPDATE_DOWNLOADED_TOPIC);
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js
@@ -3,22 +3,22 @@
 */
 
 // This tests the public Telemetry API for submitting pings.
 
 "use strict";
 
 Cu.import("resource://gre/modules/TelemetryController.jsm", this);
 Cu.import("resource://testing-common/ContentTaskUtils.jsm", this);
+Cu.import("resource://testing-common/MockRegistrar.jsm", this);
 Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
 Cu.import("resource://gre/modules/TelemetrySend.jsm", this);
 Cu.import("resource://gre/modules/TelemetryStorage.jsm", this);
 Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://gre/modules/osfile.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryHealthPing",
   "resource://gre/modules/TelemetryHealthPing.jsm");
 
 const MS_IN_A_MINUTE = 60 * 1000;
 
@@ -78,17 +78,17 @@ function histogramValueCount(h) {
 }
 
 add_task(async function test_setup() {
   // Trigger a proper telemetry init.
   do_get_profile(true);
   // Make sure we don't generate unexpected pings due to pref changes.
   await setEmptyPrefWatchlist();
   Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, true);
-  Preferences.set(TelemetryUtils.Preferences.HealthPingEnabled, true);
+  Services.prefs.setBoolPref(TelemetryUtils.Preferences.HealthPingEnabled, true);
 });
 
 // Test the ping sending logic.
 add_task(async function test_sendPendingPings() {
   const TYPE_PREFIX = "test-sendPendingPings-";
   const TEST_TYPE_A = TYPE_PREFIX + "A";
   const TEST_TYPE_B = TYPE_PREFIX + "B";
 
@@ -136,17 +136,17 @@ add_task(async function test_sendPending
   Assert.equal(histSendTimeSuccess.snapshot().sum, 0,
                "Should not have recorded any sending in histograms yet.");
   Assert.equal(histSendTimeFail.snapshot().sum, 0,
                "Should not have recorded any sending in histograms yet.");
 
   // Now enable sending to the ping server.
   now = fakeNow(futureDate(now, MS_IN_A_MINUTE));
   PingServer.start();
-  Preferences.set(TelemetryUtils.Preferences.Server, "http://localhost:" + PingServer.port);
+  Services.prefs.setStringPref(TelemetryUtils.Preferences.Server, "http://localhost:" + PingServer.port);
 
   let timerPromise = waitForTimer();
   await TelemetryController.testReset();
   let [pingSendTimerCallback, pingSendTimeout] = await timerPromise;
   Assert.ok(!!pingSendTimerCallback, "Should have a timer callback");
 
   // We should have received 10 pings from the first send batch:
   // 5 of type B and 5 of type A, as sending is newest-first.
@@ -438,45 +438,45 @@ add_task(async function test_sendCheckOv
   const TEST_PING_TYPE = "test-sendCheckOverride";
 
   // Clear any pending pings.
   await TelemetryController.testShutdown();
   await TelemetryStorage.testClearPendingPings();
 
   // Enable the ping server.
   PingServer.start();
-  Preferences.set(TelemetryUtils.Preferences.Server, "http://localhost:" + PingServer.port);
+  Services.prefs.setStringPref(TelemetryUtils.Preferences.Server, "http://localhost:" + PingServer.port);
 
   // Start Telemetry and disable the test-mode so pings don't get
   // sent unless we enable the override.
   await TelemetryController.testReset();
 
   // Submit a test ping and make sure it doesn't get sent. We only do
   // that if we're on unofficial builds: pings will always get sent otherwise.
   if (!Services.telemetry.isOfficialTelemetry) {
     TelemetrySend.setTestModeEnabled(false);
     PingServer.registerPingHandler(() => Assert.ok(false, "Should not have received any pings now"));
 
     await TelemetryController.submitExternalPing(TEST_PING_TYPE, { test: "test" });
     Assert.equal(TelemetrySend.pendingPingCount, 0, "Should have no pending pings");
   }
 
   // Enable the override and try to send again.
-  Preferences.set(TelemetryUtils.Preferences.OverrideOfficialCheck, true);
+  Services.prefs.setBoolPref(TelemetryUtils.Preferences.OverrideOfficialCheck, true);
   PingServer.resetPingHandler();
   await TelemetrySend.reset();
   await TelemetryController.submitExternalPing(TEST_PING_TYPE, { test: "test" });
 
   // Make sure we received the ping.
   const ping = await PingServer.promiseNextPing();
   Assert.equal(ping.type, TEST_PING_TYPE, "Must receive a ping of the expected type");
 
   // Restore the test mode and disable the override.
   TelemetrySend.setTestModeEnabled(true);
-  Preferences.reset(TelemetryUtils.Preferences.OverrideOfficialCheck);
+  Services.prefs.clearUserPref(TelemetryUtils.Preferences.OverrideOfficialCheck);
 });
 
 add_task(async function test_measurePingsSize() {
   const TEST_TYPE = "test-measure-ping-size";
 
   let histSuccessPingSize = Telemetry.getHistogramById("TELEMETRY_SUCCESSFUL_SEND_PINGS_SIZE_KB");
   let histFailedPingSize = Telemetry.getHistogramById("TELEMETRY_FAILED_SEND_PINGS_SIZE_KB");
 
@@ -517,12 +517,74 @@ add_task(async function test_measurePing
 
   // Check that we recorded the ping sizes correctly into histograms.
   Assert.equal(histogramValueCount(histSuccessPingSize.snapshot()), 2,
     "Should have recorded 2 successful ping into histogram.");
   Assert.equal(histogramValueCount(histFailedPingSize.snapshot()), 1,
     "Should have recorded 1 failed ping into histogram.");
 });
 
+add_task(async function test_pref_observer() {
+  await TelemetrySend.setup(true);
+
+  let origTelemetryEnabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.TelemetryEnabled);
+  let origFhrUploadEnabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled);
+
+  Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, true);
+  Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, true);
+
+  function waitAnnotateCrashReport(expectedValue, trigger) {
+    return new Promise(function(resolve, reject) {
+      let keys = new Set(["TelemetryClientId", "TelemetryServerURL"]);
+
+      let crs = {
+        QueryInterface: XPCOMUtils.generateQI([Ci.nsICrashReporter]),
+        annotateCrashReport(key, value) {
+          if (!keys.delete(key)) {
+            MockRegistrar.unregister(gMockCrs);
+            reject(Error(`Crash report annotation with unexpected key: "${key}".`));
+          }
+
+          if (expectedValue && value == "") {
+            MockRegistrar.unregister(gMockCrs);
+            reject(Error("Crash report annotation without expected value."));
+          }
+
+          if (!expectedValue && value != "") {
+            MockRegistrar.unregister(gMockCrs);
+            reject(Error(`Crash report annotation ("${key}") with unexpected value: "${value}".`));
+          }
+
+          if (keys.size == 0) {
+            MockRegistrar.unregister(gMockCrs);
+            resolve();
+          }
+        },
+        UpdateCrashEventsDir() {
+        },
+      };
+
+      let gMockCrs = MockRegistrar.register("@mozilla.org/toolkit/crash-reporter;1", crs);
+      do_register_cleanup(function() {
+        MockRegistrar.unregister(gMockCrs);
+      });
+
+      trigger();
+    });
+  }
+
+  const IS_UNIFIED_TELEMETRY = Services.prefs.getBoolPref(TelemetryUtils.Preferences.Unified, false);
+
+  await waitAnnotateCrashReport(IS_UNIFIED_TELEMETRY, () => Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, false));
+
+  await waitAnnotateCrashReport(true, () => Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, true));
+
+  await waitAnnotateCrashReport(!IS_UNIFIED_TELEMETRY, () => Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, false));
+
+  await waitAnnotateCrashReport(true, () => Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, true));
+
+  Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, origTelemetryEnabled);
+  Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, origFhrUploadEnabled);
+});
 
 add_task(async function cleanup() {
   await PingServer.stop();
 });
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
@@ -1527,56 +1527,56 @@ nsUrlClassifierDBService::ReadTablesFrom
 {
   mCheckMalware = Preferences::GetBool(CHECK_MALWARE_PREF,
     CHECK_MALWARE_DEFAULT);
   mCheckPhishing = Preferences::GetBool(CHECK_PHISHING_PREF,
     CHECK_PHISHING_DEFAULT);
   mCheckBlockedURIs = Preferences::GetBool(CHECK_BLOCKED_PREF,
     CHECK_BLOCKED_DEFAULT);
 
-  nsCString allTables;
-  nsCString tables;
+  nsAutoCString allTables;
+  nsAutoCString tables;
 
   mBaseTables.Truncate();
   mTrackingProtectionTables.Truncate();
 
-  Preferences::GetCString(PHISH_TABLE_PREF, &allTables);
+  Preferences::GetCString(PHISH_TABLE_PREF, allTables);
   if (mCheckPhishing) {
     AppendTables(allTables, mBaseTables);
   }
 
-  Preferences::GetCString(MALWARE_TABLE_PREF, &tables);
+  Preferences::GetCString(MALWARE_TABLE_PREF, tables);
   AppendTables(tables, allTables);
   if (mCheckMalware) {
     AppendTables(tables, mBaseTables);
   }
 
-  Preferences::GetCString(BLOCKED_TABLE_PREF, &tables);
+  Preferences::GetCString(BLOCKED_TABLE_PREF, tables);
   AppendTables(tables, allTables);
   if (mCheckBlockedURIs) {
     AppendTables(tables, mBaseTables);
   }
 
-  Preferences::GetCString(DOWNLOAD_BLOCK_TABLE_PREF, &tables);
+  Preferences::GetCString(DOWNLOAD_BLOCK_TABLE_PREF, tables);
   AppendTables(tables, allTables);
 
-  Preferences::GetCString(DOWNLOAD_ALLOW_TABLE_PREF, &tables);
+  Preferences::GetCString(DOWNLOAD_ALLOW_TABLE_PREF, tables);
   AppendTables(tables, allTables);
 
-  Preferences::GetCString(TRACKING_TABLE_PREF, &tables);
+  Preferences::GetCString(TRACKING_TABLE_PREF, tables);
   AppendTables(tables, allTables);
   AppendTables(tables, mTrackingProtectionTables);
 
-  Preferences::GetCString(TRACKING_WHITELIST_TABLE_PREF, &tables);
+  Preferences::GetCString(TRACKING_WHITELIST_TABLE_PREF, tables);
   AppendTables(tables, allTables);
   AppendTables(tables, mTrackingProtectionTables);
 
   Classifier::SplitTables(allTables, mGethashTables);
 
-  Preferences::GetCString(DISALLOW_COMPLETION_TABLE_PREF, &tables);
+  Preferences::GetCString(DISALLOW_COMPLETION_TABLE_PREF, tables);
   Classifier::SplitTables(tables, mDisallowCompletionsTables);
 
   return NS_OK;
 }
 
 nsresult
 nsUrlClassifierDBService::Init()
 {
--- a/toolkit/modules/tests/browser/browser_WebRequest_filtering.js
+++ b/toolkit/modules/tests/browser/browser_WebRequest_filtering.js
@@ -54,16 +54,21 @@ function removeDupes(list) {
 function compareLists(list1, list2, kind) {
   list1.sort();
   removeDupes(list1);
   list2.sort();
   removeDupes(list2);
   is(String(list1), String(list2), `${kind} URLs correct`);
 }
 
+add_task(async function setup() {
+  // Disable rcwn to make cache behavior deterministic.
+  await SpecialPowers.pushPrefEnv({set: [["network.http.rcwn.enabled", false]]});
+});
+
 add_task(async function filter_urls() {
   let filter = {urls: new MatchPattern("*://*/*_style_*")};
 
   WebRequest.onBeforeRequest.addListener(onBeforeRequest, filter, ["blocking"]);
   WebRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, filter, ["blocking"]);
   WebRequest.onResponseStarted.addListener(onResponseStarted, filter);
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, URL);
@@ -105,16 +110,8 @@ add_task(async function filter_types() {
 
 function waitForLoad(browser = gBrowser.selectedBrowser) {
   return new Promise(resolve => {
     browser.addEventListener("load", function() {
       resolve();
     }, {capture: true, once: true});
   });
 }
-
-// Disable rcwn to make cache behavior deterministic.
-let rcwnEnabled = Preferences.get("network.http.rcwn.enabled");
-Preferences.set("network.http.rcwn.enabled", false);
-
-registerCleanupFunction(() => {
-  Preferences.set("network.http.rcwn.enabled", rcwnEnabled);
-});
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
@@ -1,14 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests various aspects of the details view
-Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 var gManagerWindow;
 var gCategoryUtilities;
 var gProvider;
 
 const SETTINGS_ROWS = 9;
 
 var MockFilePicker = SpecialPowers.MockFilePicker;
@@ -247,17 +246,17 @@ add_test(function() {
     EventUtils.synthesizeKey("b", {}, gManagerWindow);
     EventUtils.synthesizeKey("a", {}, gManagerWindow);
     EventUtils.synthesizeKey("r", {}, gManagerWindow);
     is(input.value, "bar", "Text box should have updated value");
     input.value += "\u03DE"; // Cheat to add this non-ASCII character without typing it.
     EventUtils.synthesizeKey("/", {}, gManagerWindow);
     is(input.value, "bar\u03DE/", "Text box should have updated value");
     is(gManagerWindow.document.getBindingParent(gManagerWindow.document.activeElement), input, "Search box should not have focus");
-    is(Preferences.get("extensions.inlinesettings1.string", "wrong"), "bar\u03DE/", "String pref should have been updated");
+    is(Services.prefs.getStringPref("extensions.inlinesettings1.string", "wrong"), "bar\u03DE/", "String pref should have been updated");
 
     ok(!settings[4].hasAttribute("first-row"), "Not the first row");
     input = settings[4].firstElementChild;
     is(input.value, "1", "Menulist should have initial value");
     input.focus();
     EventUtils.synthesizeKey("b", {}, gManagerWindow);
     is(input.value, "2", "Menulist should have updated value");
     is(gManagerWindow._testValue, "2", "Menulist oncommand handler should've updated the test value");
@@ -292,30 +291,30 @@ add_test(function() {
       MockFilePicker.afterOpenCallback = resolve;
       EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
     });
 
     promise.then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, testFile.path, "Label value should match file chosen");
       is(input.tooltipText, testFile.path, "Label tooltip should match file chosen");
-      is(Preferences.get("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should match file chosen");
+      is(Services.prefs.getStringPref("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should match file chosen");
 
       MockFilePicker.setFiles([curProcD]);
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnCancel;
 
       return new Promise(resolve => {
         MockFilePicker.afterOpenCallback = resolve;
         EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       });
     }).then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, testFile.path, "Label value should not have changed");
       is(input.tooltipText, testFile.path, "Label tooltip should not have changed");
-      is(Preferences.get("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should not have changed");
+      is(Services.prefs.getStringPref("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should not have changed");
 
       ok(!settings[7].hasAttribute("first-row"), "Not the first row");
       button = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "button");
       input = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "input");
       is(input.value, "", "Label value should be empty");
       is(input.tooltipText, "", "Label tooltip should be empty");
 
       MockFilePicker.setFiles([testFile]);
@@ -324,30 +323,30 @@ add_test(function() {
       return new Promise(resolve => {
         MockFilePicker.afterOpenCallback = resolve;
         EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       });
     }).then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, testFile.path, "Label value should match file chosen");
       is(input.tooltipText, testFile.path, "Label tooltip should match file chosen");
-      is(Preferences.get("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should match file chosen");
+      is(Services.prefs.getStringPref("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should match file chosen");
 
       MockFilePicker.setFiles([curProcD]);
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnCancel;
 
       return new Promise(resolve => {
         MockFilePicker.afterOpenCallback = resolve;
         EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       });
     }).then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, testFile.path, "Label value should not have changed");
       is(input.tooltipText, testFile.path, "Label tooltip should not have changed");
-      is(Preferences.get("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should not have changed");
+      is(Services.prefs.getStringPref("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should not have changed");
 
       var unsizedInput = gManagerWindow.document.getAnonymousElementByAttribute(settings[2], "anonid", "input");
       var sizedInput = gManagerWindow.document.getAnonymousElementByAttribute(settings[8], "anonid", "input");
       is(unsizedInput.clientWidth > sizedInput.clientWidth, true, "Input with size attribute should be smaller than input without");
     }).then(() => {
       button = gManagerWindow.document.getElementById("detail-prefs-btn");
       is_element_hidden(button, "Preferences button should not be visible");
 
@@ -396,19 +395,19 @@ add_test(function() {
 
     ok(!settings[2].hasAttribute("first-row"), "Not the first row");
     Services.prefs.setCharPref("extensions.inlinesettings3.radioString", "juliet");
     radios = settings[2].getElementsByTagName("radio");
     isnot(radios[0].selected, true, "Correct radio button should be selected");
     is(radios[1].selected, true, "Correct radio button should be selected");
     isnot(radios[2].selected, true, "Correct radio button should be selected");
     EventUtils.synthesizeMouseAtCenter(radios[0], { clickCount: 1 }, gManagerWindow);
-    is(Preferences.get("extensions.inlinesettings3.radioString", "wrong"), "india", "Radio pref should have been updated");
+    is(Services.prefs.getStringPref("extensions.inlinesettings3.radioString", "wrong"), "india", "Radio pref should have been updated");
     EventUtils.synthesizeMouseAtCenter(radios[2], { clickCount: 1 }, gManagerWindow);
-    is(Preferences.get("extensions.inlinesettings3.radioString", "wrong"), "kilo \u338F", "Radio pref should have been updated");
+    is(Services.prefs.getStringPref("extensions.inlinesettings3.radioString", "wrong"), "kilo \u338F", "Radio pref should have been updated");
 
     ok(!settings[3].hasAttribute("first-row"), "Not the first row");
     Services.prefs.setIntPref("extensions.inlinesettings3.menulist", 8);
     var input = settings[3].firstElementChild;
     is(input.value, "8", "Menulist should have initial value");
     input.focus();
     EventUtils.synthesizeKey("n", {}, gManagerWindow);
     is(input.value, "9", "Menulist should have updated value");
@@ -604,17 +603,17 @@ add_test(function() {
   observer.checkHidden("inlinesettings2@tests.mozilla.org");
 
   // Ensure these prefs are set. They should be set above, but somebody might
   // change the tests above.
   var profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
   Services.prefs.setBoolPref("extensions.inlinesettings1.bool", false);
   Services.prefs.setIntPref("extensions.inlinesettings1.boolint", 1);
   Services.prefs.setIntPref("extensions.inlinesettings1.integer", 12);
-  Preferences.set("extensions.inlinesettings1.string", "bar\u03DE/");
+  Services.prefs.setStringPref("extensions.inlinesettings1.string", "bar\u03DE/");
   Services.prefs.setCharPref("extensions.inlinesettings1.color", "#FF9900");
   Services.prefs.setCharPref("extensions.inlinesettings1.file", profD.path);
   Services.prefs.setCharPref("extensions.inlinesettings1.directory", profD.path);
 
   var addon = get_addon_element(gManagerWindow, "inlinesettings1@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
@@ -656,17 +655,17 @@ add_test(function() {
 // Tests bindings with existing prefs.
 add_test(function() {
   observer.checkHidden("inlinesettings1@tests.mozilla.org");
 
   // Ensure these prefs are set. They should be set above, but somebody might
   // change the tests above.
   Services.prefs.setBoolPref("extensions.inlinesettings3.radioBool", false);
   Services.prefs.setIntPref("extensions.inlinesettings3.radioInt", 6);
-  Preferences.set("extensions.inlinesettings3.radioString", "kilo \u338F");
+  Services.prefs.setStringPref("extensions.inlinesettings3.radioString", "kilo \u338F");
   Services.prefs.setIntPref("extensions.inlinesettings3.menulist", 9);
 
   var addon = get_addon_element(gManagerWindow, "inlinesettings3@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
   EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
@@ -1,14 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests various aspects of the details view
-Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 var gManagerWindow;
 var gCategoryUtilities;
 var gProvider;
 
 const SETTINGS_ROWS = 8;
 
 var MockFilePicker = SpecialPowers.MockFilePicker;
@@ -389,17 +388,17 @@ add_test(function() {
     Services.prefs.setCharPref("extensions.inlinesettings3.radioString", "juliet");
     radios = settings[2].getElementsByTagName("radio");
     isnot(radios[0].selected, true, "Correct radio button should be selected");
     is(radios[1].selected, true, "Correct radio button should be selected");
     isnot(radios[2].selected, true, "Correct radio button should be selected");
     EventUtils.synthesizeMouseAtCenter(radios[0], { clickCount: 1 }, gManagerWindow);
     is(Services.prefs.getCharPref("extensions.inlinesettings3.radioString"), "india", "Radio pref should have been updated");
     EventUtils.synthesizeMouseAtCenter(radios[2], { clickCount: 1 }, gManagerWindow);
-    is(Preferences.get("extensions.inlinesettings3.radioString", "wrong"), "kilo \u338F", "Radio pref should have been updated");
+    is(Services.prefs.getStringPref("extensions.inlinesettings3.radioString", "wrong"), "kilo \u338F", "Radio pref should have been updated");
 
     ok(!settings[3].hasAttribute("first-row"), "Not the first row");
     Services.prefs.setIntPref("extensions.inlinesettings3.menulist", 8);
     var input = settings[3].firstElementChild;
     is(input.value, "8", "Menulist should have initial value");
     input.focus();
     EventUtils.synthesizeKey("n", {}, gManagerWindow);
     is(input.value, "9", "Menulist should have updated value");
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -746,17 +746,17 @@ GetContentProcessSandboxTempDir()
   nsresult rv = NS_GetSpecialDirectory(GetContentProcessTempBaseDirKey(),
                                        getter_AddRefs(localFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   nsAutoString tempDirSuffix;
   rv = Preferences::GetString("security.sandbox.content.tempDirSuffix",
-                              &tempDirSuffix);
+                              tempDirSuffix);
   if (NS_WARN_IF(NS_FAILED(rv)) || tempDirSuffix.IsEmpty()) {
     return nullptr;
   }
 
   rv = localFile->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
@@ -774,18 +774,19 @@ static already_AddRefed<nsIFile>
 CreateContentProcessSandboxTempDir()
 {
   if (IsContentSandboxDisabled()) {
     return nullptr;
   }
 
   // Get (and create if blank) temp directory suffix pref.
   nsresult rv;
-  nsAdoptingString tempDirSuffix =
-    Preferences::GetString("security.sandbox.content.tempDirSuffix");
+  nsAutoString tempDirSuffix;
+  Preferences::GetString("security.sandbox.content.tempDirSuffix",
+                         tempDirSuffix);
   if (tempDirSuffix.IsEmpty()) {
     nsCOMPtr<nsIUUIDGenerator> uuidgen =
       do_GetService("@mozilla.org/uuid-generator;1", &rv);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return nullptr;
     }
 
     nsID uuid;
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -2504,17 +2504,18 @@ void nsExternalAppHandler::ProcessAnyRef
      }
      mOriginalChannel = nullptr;
    }
 }
 
 bool nsExternalAppHandler::GetNeverAskFlagFromPref(const char * prefName, const char * aContentType)
 {
   // Search the obsolete pref strings.
-  nsAdoptingCString prefCString = Preferences::GetCString(prefName);
+  nsAutoCString prefCString;
+  Preferences::GetCString(prefName, prefCString);
   if (prefCString.IsEmpty()) {
     // Default is true, if not found in the pref string.
     return true;
   }
 
   NS_UnescapeURL(prefCString);
   nsACString::const_iterator start, end;
   prefCString.BeginReading(start);
--- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
@@ -182,17 +182,17 @@ nsOSHelperAppService::GetFileLocation(co
   */
   NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
 
   /*
     If we have an env var we should check whether the pref is a user
     pref.  If we do not, we don't care.
   */
   if (Preferences::HasUserValue(aPrefName) &&
-      NS_SUCCEEDED(Preferences::GetString(aPrefName, &aFileLocation))) {
+      NS_SUCCEEDED(Preferences::GetString(aPrefName, aFileLocation))) {
     return NS_OK;
   }
 
   if (aEnvVarName && *aEnvVarName) {
     char* prefValue = PR_GetEnv(aEnvVarName);
     if (prefValue && *prefValue) {
       // the pref is in the system charset and it's a filepath... The
       // natural way to do the charset conversion is by just initing
@@ -207,17 +207,17 @@ nsOSHelperAppService::GetFileLocation(co
 
       rv = file->GetPath(aFileLocation);
       NS_ENSURE_SUCCESS(rv, rv);
 
       return NS_OK;
     }
   }
 
-  return Preferences::GetString(aPrefName, &aFileLocation);
+  return Preferences::GetString(aPrefName, aFileLocation);
 }
 
 
 /* Get the mime.types file names from prefs and look up info in them
    based on extension */
 // static
 nsresult
 nsOSHelperAppService::LookUpTypeAndDescription(const nsAString& aFileExtension,
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -201,18 +201,19 @@ GetPrefValueForFeature(int32_t aFeature,
 
   aValue = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
   if (!NS_SUCCEEDED(Preferences::GetInt(prefname, &aValue))) {
     return false;
   }
 
   nsCString failureprefname(prefname);
   failureprefname += ".failureid";
-  nsAdoptingCString failureValue = Preferences::GetCString(failureprefname.get());
-  if (failureValue) {
+  nsAutoCString failureValue;
+  nsresult rv = Preferences::GetCString(failureprefname.get(), failureValue);
+  if (NS_SUCCEEDED(rv)) {
     aFailureId = failureValue.get();
   } else {
     aFailureId = "FEATURE_FAILURE_BLACKLIST_PREF";
   }
 
   return true;
 }
 
@@ -240,17 +241,17 @@ RemovePrefForFeature(int32_t aFeature)
 
   Preferences::ClearUser(prefname);
 }
 
 static bool
 GetPrefValueForDriverVersion(nsCString& aVersion)
 {
   return NS_SUCCEEDED(Preferences::GetCString(SUGGESTED_VERSION_PREF,
-                                              &aVersion));
+                                              aVersion));
 }
 
 static void
 SetPrefValueForDriverVersion(const nsAString& aVersion)
 {
   Preferences::SetString(SUGGESTED_VERSION_PREF, aVersion);
 }
 
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -3782,17 +3782,17 @@ public:
         static constexpr char signature[] =
                 "(IIII)V";
         static const bool isStatic = false;
         static const mozilla::jni::ExceptionMode exceptionMode =
                 mozilla::jni::ExceptionMode::ABORT;
         static const mozilla::jni::CallingThread callingThread =
                 mozilla::jni::CallingThread::ANY;
         static const mozilla::jni::DispatchTarget dispatchTarget =
-                mozilla::jni::DispatchTarget::GECKO_PRIORITY;
+                mozilla::jni::DispatchTarget::GECKO;
     };
 
     struct Reattach_t {
         typedef Compositor Owner;
         typedef void ReturnType;
         typedef void SetterType;
         typedef mozilla::jni::Args<> Args;
         static constexpr char name[] = "reattach";
--- a/widget/android/PrefsHelper.h
+++ b/widget/android/PrefsHelper.h
@@ -133,45 +133,47 @@ class PrefsHelper
 public:
     static void GetPrefs(const jni::Class::LocalRef& aCls,
                          jni::ObjectArray::Param aPrefNames,
                          jni::Object::Param aPrefHandler)
     {
         nsTArray<jni::Object::LocalRef> nameRefArray(aPrefNames->GetElements());
         nsCOMPtr<nsIObserverService> obsServ;
         nsCOMPtr<nsIWritableVariant> value;
-        nsAdoptingString strVal;
+        nsAutoString strVal;
 
         for (jni::Object::LocalRef& nameRef : nameRefArray) {
             jni::String::LocalRef nameStr(mozilla::Move(nameRef));
             const nsCString& name = nameStr->ToCString();
 
             int32_t type = java::PrefsHelper::PREF_INVALID;
             bool boolVal = false;
             int32_t intVal = 0;
+            strVal.Truncate();
 
             switch (Preferences::GetType(name.get())) {
                 case nsIPrefBranch::PREF_BOOL:
                     type = java::PrefsHelper::PREF_BOOL;
                     boolVal = Preferences::GetBool(name.get());
                     break;
 
                 case nsIPrefBranch::PREF_INT:
                     type = java::PrefsHelper::PREF_INT;
                     intVal = Preferences::GetInt(name.get());
                     break;
 
-                case nsIPrefBranch::PREF_STRING:
+                case nsIPrefBranch::PREF_STRING: {
                     type = java::PrefsHelper::PREF_STRING;
-                    strVal = Preferences::GetLocalizedString(name.get());
-                    if (!strVal) {
-                        strVal = Preferences::GetString(name.get());
+                    nsresult rv =
+                      Preferences::GetLocalizedString(name.get(), strVal);
+                    if (NS_FAILED(rv)) {
+                        Preferences::GetString(name.get(), strVal);
                     }
                     break;
-
+                }
                 default:
                     // Pref not found; try to find it.
                     if (!obsServ) {
                         obsServ = services::GetObserverService();
                         if (!obsServ) {
                             continue;
                         }
                     }
@@ -283,34 +285,36 @@ public:
 
     static void OnPrefChange(const char16_t* aData)
     {
         const nsCString& name = NS_LossyConvertUTF16toASCII(aData);
 
         int32_t type = -1;
         bool boolVal = false;
         int32_t intVal = false;
-        nsAdoptingString strVal;
+        nsAutoString strVal;
 
         switch (Preferences::GetType(name.get())) {
             case nsIPrefBranch::PREF_BOOL:
                 type = java::PrefsHelper::PREF_BOOL;
                 boolVal = Preferences::GetBool(name.get());
                 break;
             case nsIPrefBranch::PREF_INT:
                 type = java::PrefsHelper::PREF_INT;
                 intVal = Preferences::GetInt(name.get());
                 break;
-            case nsIPrefBranch::PREF_STRING:
+            case nsIPrefBranch::PREF_STRING: {
                 type = java::PrefsHelper::PREF_STRING;
-                strVal = Preferences::GetLocalizedString(name.get());
-                if (!strVal) {
-                    strVal = Preferences::GetString(name.get());
+                nsresult rv =
+                  Preferences::GetLocalizedString(name.get(), strVal);
+                if (NS_FAILED(rv)) {
+                    Preferences::GetString(name.get(), strVal);
                 }
                 break;
+            }
             default:
                 NS_WARNING(nsPrintfCString("Invalid pref %s",
                                            name.get()).get());
                 return;
         }
 
         java::PrefsHelper::OnPrefChange(
                 name, type, boolVal, intVal,
--- a/widget/android/jni/Natives.h
+++ b/widget/android/jni/Natives.h
@@ -13,16 +13,32 @@
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/Unused.h"
 #include "mozilla/jni/Accessors.h"
 #include "mozilla/jni/Refs.h"
 #include "mozilla/jni/Types.h"
 #include "mozilla/jni/Utils.h"
 
+struct NativeException {
+    const char* str;
+};
+
+template<class T> static
+NativeException NullHandle()
+{
+    return { __func__ };
+}
+
+template<class T> static
+NativeException NullWeakPtr()
+{
+    return { __func__ };
+}
+
 namespace mozilla {
 namespace jni {
 
 /**
  * C++ classes implementing instance (non-static) native methods can choose
  * from one of two ownership models, when associating a C++ object with a Java
  * instance.
  *
@@ -121,36 +137,38 @@ class NativePtrPicker
             static char (&Test(int))[NativePtrType::REFPTR];
 
     template<class> static char (&Test(...))[NativePtrType::OWNING];
 
 public:
     static const int value = sizeof(Test<Impl>('\0')) / sizeof(char);
 };
 
+template<class Impl>
 inline uintptr_t CheckNativeHandle(JNIEnv* env, uintptr_t handle)
 {
     if (!handle) {
         if (!env->ExceptionCheck()) {
-            ThrowException(env, "java/lang/NullPointerException",
-                           "Null native pointer");
+            ThrowException(env,
+                           "java/lang/NullPointerException",
+                           NullHandle<Impl>().str);
         }
         return 0;
     }
     return handle;
 }
 
 template<class Impl, int Type = NativePtrPicker<Impl>::value> struct NativePtr;
 
 template<class Impl>
 struct NativePtr<Impl, /* Type = */ NativePtrType::OWNING>
 {
     static Impl* Get(JNIEnv* env, jobject instance)
     {
-        return reinterpret_cast<Impl*>(CheckNativeHandle(
+        return reinterpret_cast<Impl*>(CheckNativeHandle<Impl>(
                 env, GetNativeHandle(env, instance)));
     }
 
     template<class LocalRef>
     static Impl* Get(const LocalRef& instance)
     {
         return Get(instance.Env(), instance.Get());
     }
@@ -179,25 +197,26 @@ struct NativePtr<Impl, /* Type = */ Nati
 };
 
 template<class Impl>
 struct NativePtr<Impl, /* Type = */ NativePtrType::WEAK>
 {
     static Impl* Get(JNIEnv* env, jobject instance)
     {
         const auto ptr = reinterpret_cast<WeakPtr<Impl>*>(
-                CheckNativeHandle(env, GetNativeHandle(env, instance)));
+                CheckNativeHandle<Impl>(env, GetNativeHandle(env, instance)));
         if (!ptr) {
             return nullptr;
         }
 
         Impl* const impl = *ptr;
         if (!impl) {
-            ThrowException(env, "java/lang/NullPointerException",
-                           "Native weak object already released");
+            ThrowException(env,
+                           "java/lang/NullPointerException",
+                           NullWeakPtr<Impl>().str);
         }
         return impl;
     }
 
     template<class LocalRef>
     static Impl* Get(const LocalRef& instance)
     {
         return Get(instance.Env(), instance.Get());
@@ -228,17 +247,17 @@ struct NativePtr<Impl, /* Type = */ Nati
 };
 
 template<class Impl>
 struct NativePtr<Impl, /* Type = */ NativePtrType::REFPTR>
 {
     static Impl* Get(JNIEnv* env, jobject instance)
     {
         const auto ptr = reinterpret_cast<RefPtr<Impl>*>(
-                CheckNativeHandle(env, GetNativeHandle(env, instance)));
+                CheckNativeHandle<Impl>(env, GetNativeHandle(env, instance)));
         if (!ptr) {
             return nullptr;
         }
 
         MOZ_ASSERT(*ptr);
         return *ptr;
     }
 
@@ -399,31 +418,29 @@ class ProxyNativeCall
         (*mNativeCall)(mozilla::Get<Indices>(mArgs)...);
     }
 
     template<bool Static, bool ThisArg, size_t... Indices>
     typename mozilla::EnableIf<!Static && ThisArg, void>::Type
     Call(const typename Owner::LocalRef& inst,
          mozilla::IndexSequence<Indices...>) const
     {
-        if (Impl* const impl = NativePtr<Impl>::Get(inst)) {
-            MOZ_CATCH_JNI_EXCEPTION(inst.Env());
-            (impl->*mNativeCall)(inst, mozilla::Get<Indices>(mArgs)...);
-        }
+        Impl* const impl = NativePtr<Impl>::Get(inst);
+        MOZ_CATCH_JNI_EXCEPTION(inst.Env());
+        (impl->*mNativeCall)(inst, mozilla::Get<Indices>(mArgs)...);
     }
 
     template<bool Static, bool ThisArg, size_t... Indices>
     typename mozilla::EnableIf<!Static && !ThisArg, void>::Type
     Call(const typename Owner::LocalRef& inst,
          mozilla::IndexSequence<Indices...>) const
     {
-        if (Impl* const impl = NativePtr<Impl>::Get(inst)) {
-            MOZ_CATCH_JNI_EXCEPTION(inst.Env());
-            (impl->*mNativeCall)(mozilla::Get<Indices>(mArgs)...);
-        }
+        Impl* const impl = NativePtr<Impl>::Get(inst);
+        MOZ_CATCH_JNI_EXCEPTION(inst.Env());
+        (impl->*mNativeCall)(mozilla::Get<Indices>(mArgs)...);
     }
 
     template<size_t... Indices>
     void Clear(JNIEnv* env, mozilla::IndexSequence<Indices...>)
     {
         int dummy[] = {
             (ProxyArg<Args>::Clear(env, Get<Indices>(mArgs)), 0)...
         };
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -972,24 +972,21 @@ public:
                 : mCompositor(mozilla::Move(aCompositor))
             {}
 
             void Run() override
             {
                 MOZ_ASSERT(NS_IsMainThread());
 
                 JNIEnv* const env = jni::GetGeckoThreadEnv();
-                // Make sure LayerViewSupport hasn't been detached from the
-                // Java object since this event was dispatched.
-                if (LayerViewSupport* const lvs = GetNative(
-                        LayerView::Compositor::LocalRef(env, mCompositor))) {
-                    MOZ_CATCH_JNI_EXCEPTION(env);
+                LayerViewSupport* const lvs = GetNative(
+                        LayerView::Compositor::LocalRef(env, mCompositor));
+                MOZ_CATCH_JNI_EXCEPTION(env);
 
-                    lvs->OnResumedCompositor();
-                }
+                lvs->OnResumedCompositor();
             }
         };
 
         // Use priority queue for timing-sensitive event.
         nsAppShell::PostEvent(MakeUnique<LayerViewEvent>(
                 MakeUnique<OnResumedEvent>(aObj)));
     }
 
@@ -1253,39 +1250,39 @@ nsWindow::GeckoViewSupport::Open(const j
 {
     MOZ_ASSERT(NS_IsMainThread());
 
     AUTO_PROFILER_LABEL("nsWindow::GeckoViewSupport::Open", OTHER);
 
     nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
     MOZ_RELEASE_ASSERT(ww);
 
-    nsAdoptingCString url;
+    nsAutoCString url;
     if (aChromeURI) {
         url = aChromeURI->ToCString();
     } else {
-        url = Preferences::GetCString("toolkit.defaultChromeURI");
-        if (!url) {
+        nsresult rv = Preferences::GetCString("toolkit.defaultChromeURI", url);
+        if (NS_FAILED(rv)) {
             url = NS_LITERAL_CSTRING("chrome://geckoview/content/geckoview.xul");
         }
     }
 
     RefPtr<AndroidView> androidView = new AndroidView();
     androidView->mEventDispatcher->Attach(
             java::EventDispatcher::Ref::From(aDispatcher), nullptr);
     if (aSettings) {
         androidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
     }
 
     nsAutoCString chromeFlags("chrome,dialog=0,resizable,scrollbars");
     if (aPrivateMode) {
         chromeFlags += ",private";
     }
     nsCOMPtr<mozIDOMWindowProxy> domWindow;
-    ww->OpenWindow(nullptr, url, nullptr, chromeFlags.get(),
+    ww->OpenWindow(nullptr, url.get(), nullptr, chromeFlags.get(),
                    androidView, getter_AddRefs(domWindow));
     MOZ_RELEASE_ASSERT(domWindow);
 
     nsCOMPtr<nsPIDOMWindowOuter> pdomWindow =
             nsPIDOMWindowOuter::From(domWindow);
     nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(pdomWindow);
     MOZ_ASSERT(widget);
 
--- a/widget/cocoa/nsDeviceContextSpecX.mm
+++ b/widget/cocoa/nsDeviceContextSpecX.mm
@@ -75,19 +75,19 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init
   }
 
   mPrintSession = settings->GetPMPrintSession();
   ::PMRetain(mPrintSession);
   mPageFormat = settings->GetPMPageFormat();
   mPrintSettings = settings->GetPMPrintSettings();
 
 #ifdef MOZ_ENABLE_SKIA_PDF
-  const nsAdoptingString& printViaPdf =
-    mozilla::Preferences::GetString("print.print_via_pdf_encoder");
-  if (printViaPdf == NS_LITERAL_STRING("skia-pdf")) {
+  nsAutoString printViaPdf;
+  mozilla::Preferences::GetString("print.print_via_pdf_encoder", printViaPdf);
+  if (printViaPdf.EqualsLiteral("skia-pdf")) {
     // Annoyingly, PMPrinterPrintWithFile does not pay attention to the
     // kPMDestination* value set in the PMPrintSession; it always sends the PDF
     // to the specified printer.  This means that if we create the PDF using
     // SkPDF then we need to manually handle user actions like "Open PDF in
     // Preview" and "Save as PDF...".
     // TODO: Currently we do not support using SkPDF for kPMDestinationFax or
     // kPMDestinationProcessPDF ("Add PDF to iBooks, etc.), and we only support
     // it for kPMDestinationFile if the destination file is a PDF.
--- a/widget/cocoa/nsPrintSettingsX.mm
+++ b/widget/cocoa/nsPrintSettingsX.mm
@@ -122,17 +122,17 @@ nsPrintSettingsX::SetCocoaPrintInfo(NSPr
 }
 
 NS_IMETHODIMP nsPrintSettingsX::ReadPageFormatFromPrefs()
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsAutoCString encodedData;
   nsresult rv =
-    Preferences::GetCString(MAC_OS_X_PAGE_SETUP_PREFNAME, &encodedData);
+    Preferences::GetCString(MAC_OS_X_PAGE_SETUP_PREFNAME, encodedData);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // decode the base64
   char* decodedData = PL_Base64Decode(encodedData.get(), encodedData.Length(), nullptr);
   NSData* data = [NSData dataWithBytes:decodedData length:strlen(decodedData)];
   if (!data)
--- a/widget/gtk/nsLookAndFeel.cpp
+++ b/widget/gtk/nsLookAndFeel.cpp
@@ -1169,18 +1169,19 @@ nsLookAndFeel::EnsureInit()
         if (!allowDarkTheme) {
             g_object_set(settings, dark_setting, FALSE, nullptr);
         }
     }
 
     // Allow content Gtk theme override by pref, it's useful when styled Gtk+
     // widgets break web content.
     if (XRE_IsContentProcess()) {
-        auto contentThemeName =
-            mozilla::Preferences::GetCString("widget.content.gtk-theme-override");
+        nsAutoCString contentThemeName;
+        mozilla::Preferences::GetCString("widget.content.gtk-theme-override",
+                                         contentThemeName);
         if (!contentThemeName.IsEmpty()) {
             g_object_set(settings, "gtk-theme-name", contentThemeName.get(), nullptr);
         }
     }
 
     // Scrollbar colors
     style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
--- a/widget/gtk/nsPSPrinters.cpp
+++ b/widget/gtk/nsPSPrinters.cpp
@@ -84,17 +84,17 @@ nsPSPrinterList::GetPrinterList(nsTArray
     // MOZILLA_POSTSCRIPT_PRINTER_LIST or a preference setting
     // print.printer_list, which contains a space-separated list of printer
     // names.
     aList.AppendElement(
             NS_LITERAL_CSTRING(NS_POSTSCRIPT_DRIVER_NAME "default"));
 
     nsAutoCString list(PR_GetEnv("MOZILLA_POSTSCRIPT_PRINTER_LIST"));
     if (list.IsEmpty()) {
-        list = Preferences::GetCString("print.printer_list");
+        Preferences::GetCString("print.printer_list", list);
     }
     if (!list.IsEmpty()) {
         // For each printer (except "default" which was already added),
         // construct a string "PostScript/<name>" and append it to the list.
         char *state;
 
         for (char *name = PL_strtok_r(list.BeginWriting(), " ", &state);
                 nullptr != name;
--- a/widget/nsPrintOptionsImpl.cpp
+++ b/widget/nsPrintOptionsImpl.cpp
@@ -487,17 +487,17 @@ nsPrintOptions::ReadPrefs(nsIPrintSettin
   // Paper size prefs are read as a group
   if (aFlags & nsIPrintSettings::kInitSavePaperSize) {
     int32_t sizeUnit;
     double width, height;
 
     bool success = GETINTPREF(kPrintPaperSizeUnit, &sizeUnit)
                   && GETDBLPREF(kPrintPaperWidth, width)
                   && GETDBLPREF(kPrintPaperHeight, height)
-                  && GETSTRPREF(kPrintPaperName, &str);
+                  && GETSTRPREF(kPrintPaperName, str);
 
     // Bug 315687: Sanity check paper size to avoid paper size values in
     // mm when the size unit flag is inches. The value 100 is arbitrary
     // and can be changed.
 #if defined(XP_WIN)
     bool saveSanitizedSizePrefs = false;
 #endif
     if (success) {
@@ -554,52 +554,52 @@ nsPrintOptions::ReadPrefs(nsIPrintSettin
   if (aFlags & nsIPrintSettings::kInitSaveOddEvenPages) {
     if (GETBOOLPREF(kPrintOddPages, &b)) {
       aPS->SetPrintOptions(nsIPrintSettings::kPrintOddPages, b);
       DUMP_BOOL(kReadStr, kPrintOddPages, b);
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSaveHeaderLeft) {
-    if (GETSTRPREF(kPrintHeaderStrLeft, &str)) {
+    if (GETSTRPREF(kPrintHeaderStrLeft, str)) {
       aPS->SetHeaderStrLeft(str.get());
       DUMP_STR(kReadStr, kPrintHeaderStrLeft, str.get());
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSaveHeaderCenter) {
-    if (GETSTRPREF(kPrintHeaderStrCenter, &str)) {
+    if (GETSTRPREF(kPrintHeaderStrCenter, str)) {
       aPS->SetHeaderStrCenter(str.get());
       DUMP_STR(kReadStr, kPrintHeaderStrCenter, str.get());
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSaveHeaderRight) {
-    if (GETSTRPREF(kPrintHeaderStrRight, &str)) {
+    if (GETSTRPREF(kPrintHeaderStrRight, str)) {
       aPS->SetHeaderStrRight(str.get());
       DUMP_STR(kReadStr, kPrintHeaderStrRight, str.get());
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSaveFooterLeft) {
-    if (GETSTRPREF(kPrintFooterStrLeft, &str)) {
+    if (GETSTRPREF(kPrintFooterStrLeft, str)) {
       aPS->SetFooterStrLeft(str.get());
       DUMP_STR(kReadStr, kPrintFooterStrLeft, str.get());
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSaveFooterCenter) {
-    if (GETSTRPREF(kPrintFooterStrCenter, &str)) {
+    if (GETSTRPREF(kPrintFooterStrCenter, str)) {
       aPS->SetFooterStrCenter(str.get());
       DUMP_STR(kReadStr, kPrintFooterStrCenter, str.get());
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSaveFooterRight) {
-    if (GETSTRPREF(kPrintFooterStrRight, &str)) {
+    if (GETSTRPREF(kPrintFooterStrRight, str)) {
       aPS->SetFooterStrRight(str.get());
       DUMP_STR(kReadStr, kPrintFooterStrRight, str.get());
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSaveBGColors) {
     if (GETBOOLPREF(kPrintBGColors, &b)) {
       aPS->SetPrintBGColors(b);
@@ -645,17 +645,17 @@ nsPrintOptions::ReadPrefs(nsIPrintSettin
   if (aFlags & nsIPrintSettings::kInitSavePrintToFile) {
     if (GETBOOLPREF(kPrintToFile, &b)) {
       aPS->SetPrintToFile(b);
       DUMP_BOOL(kReadStr, kPrintToFile, b);
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSaveToFileName) {
-    if (GETSTRPREF(kPrintToFileName, &str)) {
+    if (GETSTRPREF(kPrintToFileName, str)) {
       aPS->SetToFileName(str.get());
       DUMP_STR(kReadStr, kPrintToFileName, str.get());
     }
   }
 
   if (aFlags & nsIPrintSettings::kInitSavePageDelay) {
     if (GETINTPREF(kPrintPageDelay, &iVal)) {
       aPS->SetPrintPageDelay(iVal);
@@ -1019,17 +1019,17 @@ nsPrintOptions::GetDefaultPrinterName(ch
 {
   nsresult rv;
   nsCOMPtr<nsIPrinterEnumerator> prtEnum =
            do_GetService(NS_PRINTER_ENUMERATOR_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Look up the printer from the last print job
   nsAutoString lastPrinterName;
-  Preferences::GetString(kPrinterName, &lastPrinterName);
+  Preferences::GetString(kPrinterName, lastPrinterName);
   if (!lastPrinterName.IsEmpty()) {
     // Verify it's still a valid printer
     nsCOMPtr<nsIStringEnumerator> printers;
     rv = prtEnum->GetPrinterNameList(getter_AddRefs(printers));
     if (NS_SUCCEEDED(rv)) {
       bool isValid = false;
       bool hasMore;
       while (NS_SUCCEEDED(printers->HasMore(&hasMore)) && hasMore) {
@@ -1209,17 +1209,17 @@ nsPrintOptions::SavePrintSettingsToPrefs
 //-- Protected Methods --------------------------------
 //-----------------------------------------------------
 nsresult
 nsPrintOptions::ReadPrefDouble(const char * aPrefId, double& aVal)
 {
   NS_ENSURE_ARG_POINTER(aPrefId);
 
   nsAutoCString str;
-  nsresult rv = Preferences::GetCString(aPrefId, &str);
+  nsresult rv = Preferences::GetCString(aPrefId, str);
   if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
     aVal = atof(str.get());
   }
   return rv;
 }
 
 nsresult
 nsPrintOptions::WritePrefDouble(const char * aPrefId, double aVal)
@@ -1232,19 +1232,19 @@ nsPrintOptions::WritePrefDouble(const ch
   return Preferences::SetCString(aPrefId, str);
 }
 
 void
 nsPrintOptions::ReadInchesToTwipsPref(const char * aPrefId, int32_t& aTwips,
                                       const char * aMarginPref)
 {
   nsAutoString str;
-  nsresult rv = Preferences::GetString(aPrefId, &str);
+  nsresult rv = Preferences::GetString(aPrefId, str);
   if (NS_FAILED(rv) || str.IsEmpty()) {
-    rv = Preferences::GetString(aMarginPref, &str);
+    rv = Preferences::GetString(aMarginPref, str);
   }
   if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
     nsresult errCode;
     float inches = str.ToFloat(&errCode);
     if (NS_SUCCEEDED(errCode)) {
       aTwips = NS_INCHES_TO_INT_TWIPS(inches);
     } else {
       aTwips = 0;
@@ -1286,17 +1286,17 @@ nsPrintOptions::WriteInchesIntFromTwipsP
 }
 
 void
 nsPrintOptions::ReadJustification(const char * aPrefId, int16_t& aJust,
                                   int16_t aInitValue)
 {
   aJust = aInitValue;
   nsAutoString justStr;
-  if (NS_SUCCEEDED(Preferences::GetString(aPrefId, &justStr))) {
+  if (NS_SUCCEEDED(Preferences::GetString(aPrefId, justStr))) {
     if (justStr.EqualsASCII(kJustRight)) {
       aJust = nsIPrintSettings::kJustRight;
     } else if (justStr.EqualsASCII(kJustCenter)) {
       aJust = nsIPrintSettings::kJustCenter;
     } else {
       aJust = nsIPrintSettings::kJustLeft;
     }
   }
--- a/widget/nsXPLookAndFeel.cpp
+++ b/widget/nsXPLookAndFeel.cpp
@@ -329,17 +329,17 @@ nsXPLookAndFeel::FloatPrefChanged(nsLook
 #endif
 }
 
 // static
 void
 nsXPLookAndFeel::ColorPrefChanged (unsigned int index, const char *prefName)
 {
   nsAutoString colorStr;
-  nsresult rv = Preferences::GetString(prefName, &colorStr);
+  nsresult rv = Preferences::GetString(prefName, colorStr);
   if (NS_FAILED(rv)) {
     return;
   }
   if (!colorStr.IsEmpty()) {
     nscolor thecolor;
     if (colorStr[0] == char16_t('#')) {
       if (NS_HexToRGBA(nsDependentString(colorStr, 1),
                        nsHexColorType::NoAlpha, &thecolor)) {
@@ -383,17 +383,17 @@ nsXPLookAndFeel::InitFromPref(nsLookAndF
     aPref->floatVar = (float)intpref / 100.0f;
   }
 }
 
 void
 nsXPLookAndFeel::InitColorFromPref(int32_t i)
 {
   nsAutoString colorStr;
-  nsresult rv = Preferences::GetString(sColorPrefs[i], &colorStr);
+  nsresult rv = Preferences::GetString(sColorPrefs[i], colorStr);
   if (NS_FAILED(rv) || colorStr.IsEmpty()) {
     return;
   }
   nscolor thecolor;
   if (colorStr[0] == char16_t('#')) {
     nsAutoString hexString;
     colorStr.Right(hexString, colorStr.Length() - 1);
     if (NS_HexToRGBA(hexString, nsHexColorType::NoAlpha, &thecolor)) {
--- a/widget/windows/IMMHandler.cpp
+++ b/widget/windows/IMMHandler.cpp
@@ -358,18 +358,18 @@ IMMHandler::InitKeyboardLayout(nsWindow*
                    (PWSTR)&sCodePage, sizeof(sCodePage) / sizeof(WCHAR));
   sIMEProperty = ::ImmGetProperty(aKeyboardLayout, IGP_PROPERTY);
   sIMEUIProperty = ::ImmGetProperty(aKeyboardLayout, IGP_UI);
 
   // If active IME is a TIP of TSF, we cannot retrieve the name with IMM32 API.
   // For hacking some bugs of some TIP, we should set an IME name from the
   // pref.
   if (sCodePage == 932 && sIMEName.IsEmpty()) {
-    sIMEName =
-      Preferences::GetString("intl.imm.japanese.assume_active_tip_name_as");
+    Preferences::GetString("intl.imm.japanese.assume_active_tip_name_as",
+                           sIMEName);
   }
 
   // Whether the IME supports vertical writing mode might be changed or
   // some IMEs may need specific font for their UI.  Therefore, we should
   // update composition font forcibly here.
   if (aWindow) {
     MaybeAdjustCompositionFont(aWindow, sWritingModeOfCompositionFont, true);
   }
@@ -2533,18 +2533,22 @@ IMMHandler::AdjustCompositionFont(nsWind
                                   const IMEContext& aContext,
                                   const WritingMode& aWritingMode,
                                   bool aForceUpdate)
 {
   // An instance of IMMHandler is destroyed when active IME is changed.
   // Therefore, we need to store the information which are set to the IM
   // context to static variables since IM context is never recreated.
   static bool sCompositionFontsInitialized = false;
-  static nsString sCompositionFont =
-    Preferences::GetString("intl.imm.composition_font");
+  static nsString sCompositionFont;
+  static bool sCompositionFontPrefDone = false;
+  if (!sCompositionFontPrefDone) {
+    sCompositionFontPrefDone = true;
+    Preferences::GetString("intl.imm.composition_font", sCompositionFont);
+  }
 
   // If composition font is customized by pref, we need to modify the
   // composition font of the IME context at first time even if the writing mode
   // is horizontal.
   bool setCompositionFontForcibly = aForceUpdate ||
     (!sCompositionFontsInitialized && !sCompositionFont.IsEmpty());
 
   static WritingMode sCurrentWritingMode;
@@ -2583,18 +2587,18 @@ IMMHandler::AdjustCompositionFont(nsWind
       ("AdjustCompositionFont, sCompositionFont=\"%s\" is initialized",
        NS_ConvertUTF16toUTF8(sCompositionFont).get()));
   }
 
   static nsString sCompositionFontForJapanist2003;
   if (IsJapanist2003Active() && sCompositionFontForJapanist2003.IsEmpty()) {
     const char* kCompositionFontForJapanist2003 =
       "intl.imm.composition_font.japanist_2003";
-    sCompositionFontForJapanist2003 =
-      Preferences::GetString(kCompositionFontForJapanist2003);
+    Preferences::GetString(kCompositionFontForJapanist2003,
+                           sCompositionFontForJapanist2003);
     // If the font name is not specified properly, let's use
     // "MS PGothic" instead.
     if (sCompositionFontForJapanist2003.IsEmpty() ||
         sCompositionFontForJapanist2003.Length() > LF_FACESIZE - 2 ||
         sCompositionFontForJapanist2003[0] == '@') {
       sCompositionFontForJapanist2003.AssignLiteral("MS PGothic");
     }
   }
--- a/widget/windows/PDFiumEngineShim.cpp
+++ b/widget/windows/PDFiumEngineShim.cpp
@@ -60,18 +60,18 @@ PDFiumEngineShim::~PDFiumEngineShim()
 bool
 PDFiumEngineShim::Init()
 {
   if (mInitialized) {
     return true;
   }
 
 #ifdef USE_EXTERNAL_PDFIUM
-  const nsAdoptingString& PDFiumPath =
-    mozilla::Preferences::GetString("print.load_external_pdfium");
+  nsAutoString PDFiumPath;
+  mozilla::Preferences::GetString("print.load_external_pdfium", PDFiumPath);
   NS_ENSURE_FALSE(PDFiumPath.IsEmpty(), false);
 
   nsAutoCString filePath = NS_ConvertUTF16toUTF8(PDFiumPath);
   mPRLibrary = PR_LoadLibrary(filePath.get());
   NS_ENSURE_TRUE(mPRLibrary, false);
 
   mFPDF_InitLibrary = (FPDF_InitLibrary_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_InitLibrary");
@@ -164,9 +164,9 @@ PDFiumEngineShim::RenderPage(HDC aDC, FP
                              int aRotate, int aFlags)
 {
   MOZ_ASSERT(mInitialized);
   mFPDF_RenderPage(aDC, aPage, aStartX, aStartY,
                    aSizeX, aSizeY, aRotate, aFlags);
 }
 
 } // namespace widget
-} // namespace mozilla
\ No newline at end of file
+} // namespace mozilla
--- a/widget/windows/WinIMEHandler.cpp
+++ b/widget/windows/WinIMEHandler.cpp
@@ -933,17 +933,17 @@ IMEHandler::AutoInvokeOnScreenKeyboardIn
 }
 
 // Based on DisplayVirtualKeyboard() in Chromium's base/win/win_util.cc.
 // static
 void
 IMEHandler::ShowOnScreenKeyboard()
 {
   nsAutoString cachedPath;
-  nsresult result = Preferences::GetString(kOskPathPrefName, &cachedPath);
+  nsresult result = Preferences::GetString(kOskPathPrefName, cachedPath);
   if (NS_FAILED(result) || cachedPath.IsEmpty()) {
     wchar_t path[MAX_PATH];
     // The path to TabTip.exe is defined at the following registry key.
     // This is pulled out of the 64-bit registry hive directly.
     const wchar_t kRegKeyName[] =
       L"Software\\Classes\\CLSID\\"
       L"{054AAE20-4BEA-4347-8A35-64A533254A9D}\\LocalServer32";
     if (!WinUtils::GetRegistryKey(HKEY_LOCAL_MACHINE,
--- a/widget/windows/nsDeviceContextSpecWin.cpp
+++ b/widget/windows/nsDeviceContextSpecWin.cpp
@@ -148,20 +148,19 @@ NS_IMETHODIMP nsDeviceContextSpecWin::In
                                            nsIPrintSettings* aPrintSettings,
                                            bool aIsPrintPreview)
 {
   mPrintSettings = aPrintSettings;
 
   nsresult rv = NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
   if (aPrintSettings) {
 #ifdef MOZ_ENABLE_SKIA_PDF
-    const nsAdoptingString& printViaPdf =
-      mozilla::Preferences::GetString("print.print_via_pdf_encoder");
-
-    if (printViaPdf == NS_LITERAL_STRING("skia-pdf")) {
+    nsAutoString printViaPdf;
+    Preferences::GetString("print.print_via_pdf_encoder", printViaPdf);
+    if (printViaPdf.EqualsLiteral("skia-pdf")) {
       mPrintViaSkPDF = true;
     }
 #endif
 
     // If we're in the child and printing via the parent or we're printing to
     // PDF we only need information from the print settings.
     mPrintSettings->GetOutputFormat(&mOutputFormat);
     if ((XRE_IsContentProcess() &&
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -8127,18 +8127,18 @@ bool nsWindow::CanTakeFocus()
   return false;
 }
 
 /* static */ const wchar_t*
 nsWindow::GetMainWindowClass()
 {
   static const wchar_t* sMainWindowClass = nullptr;
   if (!sMainWindowClass) {
-    nsAdoptingString className =
-      Preferences::GetString("ui.window_class_override");
+    nsAutoString className;
+    Preferences::GetString("ui.window_class_override", className);
     if (!className.IsEmpty()) {
       sMainWindowClass = wcsdup(className.get());
     } else {
       sMainWindowClass = kClassNameGeneral;
     }
   }
   return sMainWindowClass;
 }
--- a/xpcom/base/LogModulePrefWatcher.cpp
+++ b/xpcom/base/LogModulePrefWatcher.cpp
@@ -59,17 +59,17 @@ LoadPrefValue(const char* aName)
   nsresult rv;
   int32_t prefLevel = 0;
   nsAutoCString prefValue;
 
   if (strncmp(aName, kLoggingConfigPrefPrefix, kLoggingConfigPrefixLen) == 0) {
     nsAutoCString prefName(aName);
 
     if (prefName.EqualsLiteral(kLoggingPrefLogFile)) {
-      rv = Preferences::GetCString(aName, &prefValue);
+      rv = Preferences::GetCString(aName, prefValue);
       // The pref was reset. Clear the user file.
       if (NS_FAILED(rv) || prefValue.IsEmpty()) {
         LogModule::SetLogFile(nullptr);
         return;
       }
 
       // If the pref value doesn't have a PID placeholder, append it to the end.
       if (!strstr(prefValue.get(), "%PID")) {
@@ -84,17 +84,17 @@ LoadPrefValue(const char* aName)
       bool sync = Preferences::GetBool(aName, false);
       LogModule::SetIsSync(sync);
     }
     return;
   }
 
   if (Preferences::GetInt(aName, &prefLevel) == NS_OK) {
     logLevel = ToLogLevel(prefLevel);
-  } else if (Preferences::GetCString(aName, &prefValue) == NS_OK) {
+  } else if (Preferences::GetCString(aName, prefValue) == NS_OK) {
     if (prefValue.LowerCaseEqualsLiteral("error")) {
       logLevel = LogLevel::Error;
     } else if (prefValue.LowerCaseEqualsLiteral("warning")) {
       logLevel = LogLevel::Warning;
     } else if (prefValue.LowerCaseEqualsLiteral("info")) {
       logLevel = LogLevel::Info;
     } else if (prefValue.LowerCaseEqualsLiteral("debug")) {
       logLevel = LogLevel::Debug;
--- a/xpcom/base/nsDumpUtils.cpp
+++ b/xpcom/base/nsDumpUtils.cpp
@@ -242,18 +242,17 @@ SignalPipeWatcher::OnFileCanReadWithoutB
 
 StaticRefPtr<FifoWatcher> FifoWatcher::sSingleton;
 
 /* static */ FifoWatcher*
 FifoWatcher::GetSingleton()
 {
   if (!sSingleton) {
     nsAutoCString dirPath;
-    Preferences::GetCString(
-      "memory_info_dumper.watch_fifo.directory", &dirPath);
+    Preferences::GetCString("memory_info_dumper.watch_fifo.directory", dirPath);
     sSingleton = new FifoWatcher(dirPath);
     sSingleton->Init();
     ClearOnShutdown(&sSingleton);
   }
   return sSingleton;
 }
 
 /* static */ bool
--- a/xpcom/threads/BackgroundHangMonitor.cpp
+++ b/xpcom/threads/BackgroundHangMonitor.cpp
@@ -740,20 +740,23 @@ BackgroundHangMonitor::IsDisabled() {
   return BackgroundHangManager::sDisabled;
 #else
   return true;
 #endif
 }
 
 bool
 BackgroundHangMonitor::DisableOnBeta() {
-  nsAdoptingCString clientID = Preferences::GetCString("toolkit.telemetry.cachedClientID");
+  nsAutoCString clientID;
+  nsresult rv =
+    Preferences::GetCString("toolkit.telemetry.cachedClientID", clientID);
   bool telemetryEnabled = Preferences::GetBool("toolkit.telemetry.enabled");
 
-  if (!telemetryEnabled || !clientID || BackgroundHangMonitor::ShouldDisableOnBeta(clientID)) {
+  if (!telemetryEnabled || NS_FAILED(rv) ||
+      BackgroundHangMonitor::ShouldDisableOnBeta(clientID)) {
     if (XRE_IsParentProcess()) {
       BackgroundHangMonitor::Shutdown();
     } else {
       BackgroundHangManager::sDisabled = true;
     }
     return true;
   }
 
--- a/xpfe/appshell/nsAppShellService.cpp
+++ b/xpfe/appshell/nsAppShellService.cpp
@@ -109,19 +109,20 @@ nsAppShellService::EnsurePrivateHiddenWi
 nsresult
 nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
 {
   nsresult rv;
   int32_t initialHeight = 100, initialWidth = 100;
 
 #ifdef XP_MACOSX
   uint32_t    chromeMask = 0;
-  nsAdoptingCString prefVal =
-      Preferences::GetCString("browser.hiddenWindowChromeURL");
-  const char* hiddenWindowURL = prefVal.get() ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL;
+  nsAutoCString prefVal;
+  rv = Preferences::GetCString("browser.hiddenWindowChromeURL", prefVal);
+  const char* hiddenWindowURL =
+    NS_SUCCEEDED(rv) ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL;
   if (aIsPrivate) {
     hiddenWindowURL = DEFAULT_HIDDENWINDOW_URL;
   } else {
     mApplicationProvidedHiddenWindow = prefVal.get() ? true : false;
   }
 #else
   static const char hiddenWindowURL[] = DEFAULT_HIDDENWINDOW_URL;
   uint32_t    chromeMask =  nsIWebBrowserChrome::CHROME_ALL;
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -1953,17 +1953,18 @@ NS_IMETHODIMP nsXULWindow::CreateNewCont
 
   // We need to create a new top level window and then enter a nested
   // loop. Eventually the new window will be told that it has loaded,
   // at which time we know it is safe to spin out of the nested loop
   // and allow the opening code to proceed.
 
   nsCOMPtr<nsIURI> uri;
 
-  nsAdoptingCString urlStr = Preferences::GetCString("browser.chromeURL");
+  nsAutoCString urlStr;
+  Preferences::GetCString("browser.chromeURL", urlStr);
   if (urlStr.IsEmpty()) {
     urlStr.AssignLiteral("chrome://navigator/content/navigator.xul");
   }
 
   nsCOMPtr<nsIIOService> service(do_GetService(NS_IOSERVICE_CONTRACTID));
   if (service) {
     service->NewURI(urlStr, nullptr, nullptr, getter_AddRefs(uri));
   }