Merge mozilla-central to mozilla-inbound. CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Wed, 17 Oct 2018 19:56:29 +0300
changeset 497533 d6ab96f62188cfb6b5121be03048e09f27ad8405
parent 497532 01368a04b48aeca172e2153cd0f8401e5162226a (current diff)
parent 497458 4c944453210c428f505bc2d81b3b7f1c99a262a6 (diff)
child 497534 373da42b11e7be5a5a85973cf41833033d744446
push id9996
push userarchaeopteryx@coole-files.de
push dateThu, 18 Oct 2018 18:37:15 +0000
treeherdermozilla-beta@8efe26839243 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to mozilla-inbound. CLOSED TREE
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -989,16 +989,20 @@ window._gBrowser = {
           previousTab: oldTab,
         },
       });
       newTab.dispatchEvent(event);
 
       this._tabAttrModified(oldTab, ["selected"]);
       this._tabAttrModified(newTab, ["selected"]);
 
+      this._startMultiSelectChange();
+      this._multiSelectChangeSelected = true;
+      this.clearMultiSelectedTabs(true);
+
       if (oldBrowser != newBrowser &&
           oldBrowser.getInPermitUnload) {
         oldBrowser.getInPermitUnload(inPermitUnload => {
           if (!inPermitUnload) {
             return;
           }
           // Since the user is switching away from a tab that has
           // a beforeunload prompt active, we remove the prompt.
@@ -2109,22 +2113,22 @@ window._gBrowser = {
   discardBrowser(aBrowser, aForceDiscard) {
     "use strict";
 
     let tab = this.getTabForBrowser(aBrowser);
 
     let permitUnloadFlags = aForceDiscard ? aBrowser.dontPromptAndUnload : aBrowser.dontPromptAndDontUnload;
 
     if (!tab ||
-      tab.selected ||
-      tab.closing ||
-      this._windowIsClosing ||
-      !aBrowser.isConnected ||
-      !aBrowser.isRemoteBrowser ||
-      !aBrowser.permitUnload(permitUnloadFlags).permitUnload) {
+        tab.selected ||
+        tab.closing ||
+        this._windowIsClosing ||
+        !aBrowser.isConnected ||
+        !aBrowser.isRemoteBrowser ||
+        !aBrowser.permitUnload(permitUnloadFlags).permitUnload) {
       return;
     }
 
     // Reset webrtc sharing state.
     if (tab._sharingState) {
       this.setBrowserSharing(aBrowser, {});
     }
     webrtcUI.forgetStreamsFromBrowser(aBrowser);
@@ -4676,21 +4680,16 @@ window._gBrowser = {
       let browser = event.originalTarget;
       let tab = this.getTabForBrowser(browser);
       if (!tab) {
         return;
       }
 
       Services.obs.notifyObservers(tab, "AudibleAutoplayMediaOccurred");
     });
-
-    this.ownerGlobal.addEventListener("TabSelect", (event) => {
-      this._startMultiSelectChange();
-      this._multiSelectChangeSelected = true;
-    }, {passive: true});
   },
 };
 
 /**
  * A web progress listener object definition for a given tab.
  */
 class TabProgressListener {
   constructor(aTab, aBrowser, aStartsBlank, aWasPreloadedBrowser, aOrigStateFlags) {
@@ -5477,9 +5476,8 @@ var TabContextMenu = {
     }
     if (this.contextTab.muted) {
       if (!newTab.muted) {
         newTab.toggleMuteAudio(this.contextTab.muteReason);
       }
     }
   },
 };
-
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1184,17 +1184,16 @@
           }
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="TabSelect"><![CDATA[
         this._handleTabSelect();
-        gBrowser.clearMultiSelectedTabs(true);
       ]]></handler>
 
       <handler event="TabClose"><![CDATA[
         this._hiddenSoundPlayingStatusChanged(event.target, {closed: true});
       ]]></handler>
 
       <handler event="TabAttrModified"><![CDATA[
         if (event.detail.changed.includes("soundplaying") && event.target.hidden) {
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -522,17 +522,17 @@ class CopyCutController {
       let start = urlbar.selectionStart;
       let end = urlbar.selectionEnd;
       urlbar.inputField.value = urlbar.inputField.value.substring(0, start) +
                                 urlbar.inputField.value.substring(end);
       urlbar.selectionStart = urlbar.selectionEnd = start;
 
       let event = urlbar.document.createEvent("UIEvents");
       event.initUIEvent("input", true, false, this.window, 0);
-      urlbar.dispatchEvent(event);
+      urlbar.textbox.dispatchEvent(event);
 
       urlbar.window.SetPageProxyState("invalid");
     }
 
     ClipboardHelper.copyString(val);
   }
 
   /**
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -28,17 +28,16 @@ loader.lazyGetter(this, "AccessibilityPa
 loader.lazyGetter(this, "ApplicationPanel", () => require("devtools/client/application/panel").ApplicationPanel);
 loader.lazyGetter(this, "reloadAndRecordTab", () => require("devtools/client/webreplay/menu.js").reloadAndRecordTab);
 loader.lazyGetter(this, "reloadAndStopRecordingTab", () => require("devtools/client/webreplay/menu.js").reloadAndStopRecordingTab);
 
 // Other dependencies
 loader.lazyRequireGetter(this, "AccessibilityStartup", "devtools/client/accessibility/accessibility-startup", true);
 loader.lazyRequireGetter(this, "ResponsiveUIManager", "devtools/client/responsive.html/manager", true);
 loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
-loader.lazyRequireGetter(this, "getScreenshotFront", "resource://devtools/shared/fronts/screenshot", true);
 
 const {MultiLocalizationHelper} = require("devtools/shared/l10n");
 const L10N = new MultiLocalizationHelper(
   "devtools/client/locales/startup.properties",
   "devtools/startup/locales/key-shortcuts.properties"
 );
 
 var Tools = {};
@@ -586,17 +585,17 @@ exports.ToolboxButtons = [
     async onClick(event, toolbox) {
       // Special case for screenshot button to check for clipboard preference
       const clipboardEnabled = Services.prefs
         .getBoolPref("devtools.screenshot.clipboard.enabled");
       const args = { fullpage: true, file: true };
       if (clipboardEnabled) {
         args.clipboard = true;
       }
-      const screenshotFront = getScreenshotFront(toolbox.target);
+      const screenshotFront = toolbox.target.getFront("screenshot");
       await screenshotFront.captureAndSave(toolbox.win, args);
     }
   },
   createHighlightButton("RulersHighlighter", "rulers"),
   createHighlightButton("MeasuringToolHighlighter", "measure"),
 ];
 
 function createHighlightButton(highlighterName, id) {
--- a/devtools/client/framework/test/browser_toolbox_options_disable_js.js
+++ b/devtools/client/framework/test/browser_toolbox_options_disable_js.js
@@ -2,29 +2,22 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that disabling JavaScript for a tab works as it should.
 
 const TEST_URI = URL_ROOT + "browser_toolbox_options_disable_js.html";
 
-function test() {
-  addTab(TEST_URI).then(async (tab) => {
-    const target = await TargetFactory.forTab(tab);
-    gDevTools.showToolbox(target).then(testSelectTool);
-  });
-}
+add_task(async function() {
+  const tab = await addTab(TEST_URI);
+  const target = await TargetFactory.forTab(tab);
+  const toolbox = await gDevTools.showToolbox(target);
 
-function testSelectTool(toolbox) {
-  toolbox.once("options-selected", () => testToggleJS(toolbox));
-  toolbox.selectTool("options");
-}
-
-const testToggleJS = async function(toolbox) {
+  await toolbox.selectTool("options");
   ok(true, "Toolbox selected via selectTool method");
 
   await testJSEnabled();
   await testJSEnabledIframe();
 
   // Disable JS.
   await toggleJS(toolbox);
 
@@ -32,18 +25,19 @@ const testToggleJS = async function(tool
   await testJSDisabledIframe();
 
   // Re-enable JS.
   await toggleJS(toolbox);
 
   await testJSEnabled();
   await testJSEnabledIframe();
 
-  finishUp(toolbox);
-};
+  await toolbox.destroy();
+  gBrowser.removeCurrentTab();
+});
 
 async function testJSEnabled() {
   info("Testing that JS is enabled");
 
   // We use waitForTick here because switching docShell.allowJavascript to true
   // takes a while to become live.
   await waitForTick();
 
@@ -74,19 +68,27 @@ async function toggleJS(toolbox) {
   const cbx = panel.panelDoc.getElementById("devtools-disable-javascript");
 
   if (cbx.checked) {
     info("Clearing checkbox to re-enable JS");
   } else {
     info("Checking checkbox to disable JS");
   }
 
+  let { javascriptEnabled } = toolbox.target.activeTab.configureOptions;
+  is(javascriptEnabled, !cbx.checked,
+    "BrowsingContextFront's configureOptions is correct before the toggle");
+
   const browserLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   cbx.click();
   await browserLoaded;
+
+  ({ javascriptEnabled } = toolbox.target.activeTab.configureOptions);
+  is(javascriptEnabled, !cbx.checked,
+    "BrowsingContextFront's configureOptions is correctly updated");
 }
 
 async function testJSDisabled() {
   info("Testing that JS is disabled");
 
   await ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
     const doc = content.document;
     const output = doc.getElementById("output");
@@ -105,15 +107,8 @@ async function testJSDisabledIframe() {
     const iframe = doc.querySelector("iframe");
     const iframeDoc = iframe.contentDocument;
     const output = iframeDoc.getElementById("output");
     iframeDoc.querySelector("#logJSDisabled").click();
     ok(output.textContent !== "JavaScript Disabled",
        'output is not "JavaScript Disabled" in iframe');
   });
 }
-
-function finishUp(toolbox) {
-  toolbox.destroy().then(function() {
-    gBrowser.removeCurrentTab();
-    finish();
-  });
-}
--- a/devtools/client/framework/toolbox-options.js
+++ b/devtools/client/framework/toolbox-options.js
@@ -455,19 +455,18 @@ OptionsPanel.prototype = {
       prefSelect.addEventListener("change", function(e) {
         const select = e.target;
         SetPref(select.getAttribute("data-pref"),
           select.options[select.selectedIndex].value);
       });
     }
 
     if (this.target.activeTab && !this.target.chrome) {
-      const response = await this.target.activeTab.attach();
-      this._origJavascriptEnabled = !response.javascriptEnabled;
-      this.disableJSNode.checked = this._origJavascriptEnabled;
+      this.disableJSNode.checked =
+        !this.target.activeTab.configureOptions.javascriptEnabled;
       this.disableJSNode.addEventListener("click", this._disableJSClicked);
     } else {
       // Hide the checkbox and label
       this.disableJSNode.parentNode.style.display = "none";
 
       const triggersPageRefreshLabel =
         this.panelDoc.getElementById("triggers-page-refresh-label");
       triggersPageRefreshLabel.style.display = "none";
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -29,17 +29,16 @@ loader.lazyRequireGetter(this, "ToolSide
 loader.lazyRequireGetter(this, "MarkupView", "devtools/client/inspector/markup/markup");
 loader.lazyRequireGetter(this, "HighlightersOverlay", "devtools/client/inspector/shared/highlighters-overlay");
 loader.lazyRequireGetter(this, "nodeConstants", "devtools/shared/dom-node-constants");
 loader.lazyRequireGetter(this, "Menu", "devtools/client/framework/menu");
 loader.lazyRequireGetter(this, "MenuItem", "devtools/client/framework/menu-item");
 loader.lazyRequireGetter(this, "ExtensionSidebar", "devtools/client/inspector/extensions/extension-sidebar");
 loader.lazyRequireGetter(this, "clipboardHelper", "devtools/shared/platform/clipboard");
 loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
-loader.lazyRequireGetter(this, "getScreenshotFront", "devtools/shared/fronts/screenshot", true);
 loader.lazyRequireGetter(this, "saveScreenshot", "devtools/shared/screenshot/save");
 loader.lazyRequireGetter(this, "ChangesManager",
 "devtools/client/inspector/changes/ChangesManager");
 
 loader.lazyImporter(this, "DeferredTask", "resource://gre/modules/DeferredTask.jsm");
 
 const {LocalizationHelper, localizeMarkup} = require("devtools/shared/l10n");
 const INSPECTOR_L10N =
@@ -2329,17 +2328,17 @@ Inspector.prototype = {
 
     const clipboardEnabled = Services.prefs
       .getBoolPref("devtools.screenshot.clipboard.enabled");
     const args = {
       file: true,
       selector: this.selectionCssSelector,
       clipboard: clipboardEnabled
     };
-    const screenshotFront = getScreenshotFront(this.target);
+    const screenshotFront = this.target.getFront("screenshot");
     const screenshot = await screenshotFront.capture(args);
     await saveScreenshot(this.panelWin, args, screenshot);
   },
 
   /**
    * Scroll the node into view.
    */
   scrollNodeIntoView: function() {
--- a/devtools/shared/fronts/screenshot.js
+++ b/devtools/shared/fronts/screenshot.js
@@ -15,24 +15,9 @@ const ScreenshotFront = protocol.FrontCl
   },
 
   async captureAndSave(window, args) {
     const screenshot = await this.capture(args);
     return saveScreenshot(window, args, screenshot);
   }
 });
 
-// A cache of created fronts: WeakMap<Client, Front>
-const knownFronts = new WeakMap();
-
-/**
- * Create a screenshot front only when needed
- */
-function getScreenshotFront(target) {
-  let front = knownFronts.get(target.client);
-  if (front == null && target.form.screenshotActor != null) {
-    front = new ScreenshotFront(target.client, target.form);
-    knownFronts.set(target.client, front);
-  }
-  return front;
-}
-
-exports.getScreenshotFront = getScreenshotFront;
+exports.ScreenshotFront = ScreenshotFront;
--- a/devtools/shared/fronts/targets/browsing-context.js
+++ b/devtools/shared/fronts/targets/browsing-context.js
@@ -10,16 +10,22 @@ const {custom} = protocol;
 loader.lazyRequireGetter(this, "ThreadClient", "devtools/shared/client/thread-client");
 
 const BrowsingContextFront = protocol.FrontClassWithSpec(browsingContextTargetSpec, {
   initialize: function(client, form) {
     protocol.Front.prototype.initialize.call(this, client, form);
 
     this.thread = null;
 
+    // Cache the value of some target properties that are being returned by `attach`
+    // request and then keep them up-to-date in `reconfigure` request.
+    this.configureOptions = {
+      javascriptEnabled: null,
+    };
+
     // TODO: remove once ThreadClient becomes a front
     this.client = client;
   },
 
   /**
    * Attach to a thread actor.
    *
    * @param object options
@@ -42,25 +48,36 @@ const BrowsingContextFront = protocol.Fr
       return [response, this.thread];
     });
   },
 
   attach: custom(async function() {
     const response = await this._attach();
 
     this._threadActor = response.threadActor;
-    this.javascriptEnabled = response.javascriptEnabled;
-    this.cacheDisabled = response.cacheDisabled;
+    this.configureOptions.javascriptEnabled = response.javascriptEnabled;
     this.traits = response.traits || {};
 
     return response;
   }, {
     impl: "_attach"
   }),
 
+  reconfigure: custom(async function({ options }) {
+    const response = await this._reconfigure({ options });
+
+    if (typeof options.javascriptEnabled != "undefined") {
+      this.configureOptions.javascriptEnabled = options.javascriptEnabled;
+    }
+
+    return response;
+  }, {
+    impl: "_reconfigure"
+  }),
+
   detach: custom(async function() {
     let response;
     try {
       response = await this._detach();
     } catch (e) {
       console.warn(
         `Error while detaching the browsing context target front: ${e.message}`);
     }
--- a/devtools/shared/specs/index.js
+++ b/devtools/shared/specs/index.js
@@ -177,16 +177,21 @@ const Types = exports.__TypesForTests = 
     spec: "devtools/shared/specs/property-iterator",
     front: null,
   },
   {
     types: ["reflow"],
     spec: "devtools/shared/specs/reflow",
     front: "devtools/shared/fronts/reflow",
   },
+  {
+    types: ["screenshot"],
+    spec: "devtools/shared/specs/screenshot",
+    front: "devtools/shared/fronts/screenshot",
+  },
   /* Script and source have old fashion client and no front */
   {
     types: ["context"],
     spec: "devtools/shared/specs/script",
     front: null,
   },
   {
     types: ["source"],
--- a/dom/cache/TypeUtils.cpp
+++ b/dom/cache/TypeUtils.cpp
@@ -514,33 +514,13 @@ TypeUtils::SerializeCacheStream(nsIInput
 
   cacheStream.controlChild() = nullptr;
   cacheStream.controlParent() = nullptr;
 
   UniquePtr<AutoIPCStream> autoStream(new AutoIPCStream(cacheStream.stream()));
   autoStream->Serialize(aStream, GetIPCManager());
 
   aStreamCleanupList.AppendElement(std::move(autoStream));
-
-  // This nested condition guards against silent failures in IPC code
-  // that would cause a crash when the message is sent. Specifically,
-  // if IPCStreamSource::Initialize fails to get a StrongWorkerRef
-  // (e.g. when the worker terminates), a nullptr is silently stored
-  // in IPCRemoteStreamType.
-  // This is a workaround, requested in bug 1484524, and a more
-  // reasonable solution should replace it.
-  if (cacheStream.stream().type() == OptionalIPCStream::TIPCStream) {
-    const auto& ipcStream = cacheStream.stream().get_IPCStream();
-    if (ipcStream.type() == IPCStream::TIPCRemoteStream) {
-      const auto& ipcRemoteStream = ipcStream.get_IPCRemoteStream();
-      using mozilla::ipc::IPCRemoteStreamType;
-      if (ipcRemoteStream.stream().type() == IPCRemoteStreamType::TPChildToParentStreamChild) {
-        if (!ipcRemoteStream.stream().get_PChildToParentStreamChild()) {
-          aRv.Throw(NS_ERROR_FAILURE);
-        }
-      }
-    }
-  }
 }
 
 } // namespace cache
 } // namespace dom
 } // namespace mozilla
--- a/netwerk/dns/TRR.cpp
+++ b/netwerk/dns/TRR.cpp
@@ -994,17 +994,18 @@ TRR::OnStopRequest(nsIRequest *aRequest,
 {
   // The dtor will be run after the function returns
   LOG(("TRR:OnStopRequest %p %s %d failed=%d code=%X\n",
        this, mHost.get(), mType, mFailed, (unsigned int)aStatusCode));
   nsCOMPtr<nsIChannel> channel;
   channel.swap(mChannel);
 
   // Bad content is still considered "okay" if the HTTP response is okay
-  gTRRService->TRRIsOkay(NS_SUCCEEDED(aStatusCode));
+  gTRRService->TRRIsOkay(NS_SUCCEEDED(aStatusCode) ? TRRService::OKAY_NORMAL :
+                         TRRService::OKAY_BAD);
 
   // if status was "fine", parse the response and pass on the answer
   if (!mFailed && NS_SUCCEEDED(aStatusCode)) {
     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
     if (!httpChannel) {
       return NS_ERROR_UNEXPECTED;
     }
     nsresult rv = NS_OK;
@@ -1132,17 +1133,17 @@ TRR::Cancel()
   if (!NS_IsMainThread()) {
     NS_DispatchToMainThread(new ProxyCancel(this));
     return;
   }
   if (mChannel) {
     LOG(("TRR: %p canceling Channel %p %s %d\n", this,
          mChannel.get(), mHost.get(), mType));
     mChannel->Cancel(NS_ERROR_ABORT);
-    gTRRService->TRRIsOkay(false);
+    gTRRService->TRRIsOkay(TRRService::OKAY_TIMEOUT);
   }
 }
 
 #undef LOG
 
 // namespace
 }
 }
--- a/netwerk/dns/TRRService.cpp
+++ b/netwerk/dns/TRRService.cpp
@@ -593,19 +593,24 @@ TRRService::Notify(nsITimer *aTimer)
     MOZ_CRASH("Unknown timer");
   }
 
   return NS_OK;
 }
 
 
 void
-TRRService::TRRIsOkay(bool aWorks)
+TRRService::TRRIsOkay(enum TrrOkay aReason)
 {
-  if (aWorks) {
+  Telemetry::AccumulateCategorical(aReason == OKAY_NORMAL ?
+                                   Telemetry::LABELS_DNS_TRR_SUCCESS::Fine :
+                                   (aReason == OKAY_TIMEOUT ?
+                                    Telemetry::LABELS_DNS_TRR_SUCCESS::Timeout :
+                                    Telemetry::LABELS_DNS_TRR_SUCCESS::Bad));
+  if (aReason == OKAY_NORMAL) {
     mTRRFailures = 0;
   } else if ((mMode == MODE_TRRFIRST) && (mConfirmationState == CONFIRM_OK)) {
     // only count failures while in OK state
     uint32_t fails = ++mTRRFailures;
     if (fails >= mDisableAfterFails) {
       LOG(("TRRService goes FAILED after %u failures in a row\n", fails));
       mConfirmationState = CONFIRM_FAILED;
       // Fire off a timer and start re-trying the NS domain again
--- a/netwerk/dns/TRRService.h
+++ b/netwerk/dns/TRRService.h
@@ -44,17 +44,22 @@ public:
   uint32_t GetRequestTimeout() { return mTRRTimeout; }
 
   LookupStatus CompleteLookup(nsHostRecord *, nsresult, mozilla::net::AddrInfo *, bool pb) override;
   LookupStatus CompleteLookupByType(nsHostRecord *, nsresult, const nsTArray<nsCString> *, uint32_t, bool pb) override;
   void TRRBlacklist(const nsACString &host, bool privateBrowsing, bool aParentsToo);
   bool IsTRRBlacklisted(const nsACString &host, bool privateBrowsing, bool fullhost);
 
   bool MaybeBootstrap(const nsACString &possible, nsACString &result);
-  void TRRIsOkay(bool aWorks);
+  enum TrrOkay {
+    OKAY_NORMAL = 0,
+    OKAY_TIMEOUT = 1,
+    OKAY_BAD = 2
+  };
+  void TRRIsOkay(enum TrrOkay aReason);
 
 private:
   virtual  ~TRRService();
   nsresult ReadPrefs(const char *name);
   void GetPrefBranch(nsIPrefBranch **result);
   void MaybeConfirm();
 
   bool                      mInitialized;
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -510,20 +510,27 @@ AddrHostRecord::ResolveComplete()
                               ((mNativeSuccess ? Telemetry::LABELS_DNS_TRR_COMPARE::NativeWorked :
                                 (mTRRSuccess ? Telemetry::LABELS_DNS_TRR_COMPARE::TRRWorked:
                                  Telemetry::LABELS_DNS_TRR_COMPARE::BothFailed))));
     } else if (mResolverMode == MODE_TRRFIRST) {
         if(flags & nsIDNSService::RESOLVE_DISABLE_TRR) {
             // TRR is disabled on request, which is a next-level back-off method.
             Telemetry::Accumulate(Telemetry::DNS_TRR_DISABLED, mNativeSuccess);
         } else {
-            AccumulateCategorical(mTRRSuccess?
-                                  Telemetry::LABELS_DNS_TRR_FIRST::TRRWorked :
-                                  ((mNativeSuccess ? Telemetry::LABELS_DNS_TRR_FIRST::NativeFallback :
-                                    Telemetry::LABELS_DNS_TRR_FIRST::BothFailed)));
+            if (mTRRSuccess) {
+                AccumulateCategorical(Telemetry::LABELS_DNS_TRR_FIRST2::TRR);
+            } else if(mNativeSuccess) {
+                if (mTRRUsed) {
+                    AccumulateCategorical(Telemetry::LABELS_DNS_TRR_FIRST2::NativeAfterTRR);
+                } else {
+                    AccumulateCategorical(Telemetry::LABELS_DNS_TRR_FIRST2::Native);
+                }
+            } else {
+                AccumulateCategorical(Telemetry::LABELS_DNS_TRR_FIRST2::BothFailed);
+            }
         }
     }
 
     switch(mResolverMode) {
     case MODE_NATIVEONLY:
     case MODE_TRROFF:
         AccumulateCategorical(Telemetry::LABELS_DNS_LOOKUP_ALGORITHM::nativeOnly);
         break;
--- a/testing/jsshell/benchmark.py
+++ b/testing/jsshell/benchmark.py
@@ -105,22 +105,29 @@ class Benchmark(object):
         if fetches_dir and os.path.isdir(fetches_dir):
             fetchdir = os.path.join(fetches_dir, self.name)
             if os.path.isdir(fetchdir):
                 shutil.copytree(fetchdir, self.path)
 
     def run(self):
         self.reset()
 
+        # Update the environment variables
+        env = os.environ.copy()
+
+        # disable "GC poisoning" Bug# 1499043
+        env['JSGC_DISABLE_POISONING'] = '1'
+
         process_args = {
             'cmd': self.command,
             'cwd': self.path,
             'onFinish': self.collect_results,
             'processOutputLine': self.process_line,
             'stream': sys.stdout,
+            'env': env,
         }
         proc = ProcessHandler(**process_args)
         proc.run()
         return proc.wait()
 
 
 class RunOnceBenchmark(Benchmark):
     def collect_results(self):
--- a/testing/mozharness/mozharness/mozilla/testing/raptor.py
+++ b/testing/mozharness/mozharness/mozilla/testing/raptor.py
@@ -435,16 +435,19 @@ class Raptor(TestingMixin, MercurialScri
             self.info("webrender is enabled so setting MOZ_WEBRENDER=1 and MOZ_ACCELERATED=1")
             env['MOZ_WEBRENDER'] = '1'
             env['MOZ_ACCELERATED'] = '1'
 
         # mitmproxy needs path to mozharness when installing the cert, and tooltool
         env['SCRIPTSPATH'] = scripts_path
         env['EXTERNALTOOLSPATH'] = external_tools_path
 
+        # disable "GC poisoning" Bug# 1499043
+        env['JSGC_DISABLE_POISONING'] = '1'
+
         if self.repo_path is not None:
             env['MOZ_DEVELOPER_REPO_DIR'] = self.repo_path
         if self.obj_path is not None:
             env['MOZ_DEVELOPER_OBJ_DIR'] = self.obj_path
 
         # sets a timeout for how long raptor should run without output
         output_timeout = self.config.get('raptor_output_timeout', 3600)
         # run raptor tests
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -3385,24 +3385,24 @@
     "record_in_processes": ["main"],
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
     "labels": ["BothWorked", "NativeWorked", "TRRWorked", "BothFailed"],
     "bug_numbers": [1460589],
     "description": "DNS: success distribution when both native and TRR were used"
   },
-  "DNS_TRR_FIRST": {
+  "DNS_TRR_FIRST2": {
     "record_in_processes": ["main"],
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
-    "labels": ["TRRWorked", "NativeFallback", "BothFailed"],
-    "bug_numbers": [1472659],
-    "description": "TRR-first mode distribution. 0=Worked, 1=fell back to native, 2=both failed"
+    "labels": ["TRR", "NativeAfterTRR", "Native", "BothFailed"],
+    "bug_numbers": [1497252],
+    "description": "TRR-first mode distribution. 0=Worked, 1=fell back fine after TRR fail, 2=native worked, 3=both failed"
   },
   "DNS_TRR_DISABLED": {
     "record_in_processes": ["main"],
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "Resolve success rate when in TRR-first and called TRR-disabled (fall-back mode)",
     "bug_numbers": [1472659],
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"]
@@ -3428,16 +3428,25 @@
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"],
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 5000,
     "n_buckets": 100,
     "bug_numbers": [1470853],
     "description": "Number of DOH requests per connection"
   },
+  "DNS_TRR_SUCCESS": {
+    "record_in_processes": ["main"],
+    "expires_in_version": "never",
+    "kind": "categorical",
+    "labels": ["Fine", "Timeout", "Bad"],
+    "description": "How often TRR (Trusted Recursive Resolver) requests are fine, time-out or error.",
+    "bug_numbers": [1497438],
+    "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"]
+  },
   "DNS_LOOKUP_ALGORITHM": {
     "record_in_processes": ["main"],
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
     "labels": ["nativeOnly", "trrRace", "trrFirst", "trrOnly", "trrShadow"],
     "bug_numbers": [1434852],
     "description": "DNS: lookup algorithm"