Merge autoland to mozilla-central. a=merge
authorshindli <shindli@mozilla.com>
Thu, 17 Oct 2019 00:28:26 +0300
changeset 559292 cdcbac30666276f484747875e430ab0a74f123fb
parent 559291 f2644bf19c9ff6acb2182f2ac44b0df46c967cda (current diff)
parent 559215 945fcfda3d1fefef54b791d60c9ec41f1b0e15c4 (diff)
child 559293 9e3ef2b6a8898c813666bd2e6c5f302dfde87653
push id12175
push userccoroiu@mozilla.com
push dateThu, 17 Oct 2019 19:29:09 +0000
treeherdermozilla-beta@d333b6ef1fd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone71.0a1
first release with
nightly linux32
cdcbac306662 / 71.0a1 / 20191016212918 / files
nightly linux64
cdcbac306662 / 71.0a1 / 20191016212918 / files
nightly mac
cdcbac306662 / 71.0a1 / 20191016212918 / files
nightly win32
cdcbac306662 / 71.0a1 / 20191016212918 / files
nightly win64
cdcbac306662 / 71.0a1 / 20191016212918 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla-central. a=merge
taskcluster/ci/test/browsertime-fenix.yml
taskcluster/ci/test/browsertime-gve.yml
taskcluster/ci/test/browsertime-refbrow.yml
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-1.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-10.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-11.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-12.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-13.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-14.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-15.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-16.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-17.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-18.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-19.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-2.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-20.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-21.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-22.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-23.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-24.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-25.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-26.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-27.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-28.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-29.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-3.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-30.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-4.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-5.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-6.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-7.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-8.ini
testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-9.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-1-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-1.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-10-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-10.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-11-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-11.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-12-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-12.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-13-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-13.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-14-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-14.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-15.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-16.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-17.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-18.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-19.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-2-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-2.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-20.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-21.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-22.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-23.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-24.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-25.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-26.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-27.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-28.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-3-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-3.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-4-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-4.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-5-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-5.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-6-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-6.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-7-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-7.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-8-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-8.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-9-fennec68.ini
testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-9.ini
testing/web-platform/meta/mathml/presentation-markup/scripts/subsup-legacy-scriptshift-attributes-001.tentative.html.ini
--- a/.eslintignore
+++ b/.eslintignore
@@ -58,22 +58,16 @@ browser/extensions/mortar/
 browser/extensions/formautofill/phonenumberutils/PhoneNumberMetaData.jsm
 
 # devtools/ exclusions
 devtools/client/inspector/markup/test/doc_markup_events_*.html
 devtools/client/performance/components/test/test_jit_optimizations_01.html
 devtools/client/shared/test/*.html
 devtools/client/shared/components/test/mochitest/*.html
 !devtools/client/shared/components/test/mochitest/test_stack-trace.html
-devtools/client/storage/test/*.html
-!devtools/client/storage/test/storage-cookies.html
-!devtools/client/storage/test/storage-overflow.html
-!devtools/client/storage/test/storage-search.html
-!devtools/client/storage/test/storage-unsecured-iframe.html
-!devtools/client/storage/test/storage-unsecured-iframe-usercontextid.html
 devtools/server/tests/browser/storage-*.html
 !devtools/server/tests/browser/storage-unsecured-iframe.html
 devtools/server/tests/browser/stylesheets-nested-iframes.html
 devtools/shared/qrcode/tests/mochitest/test_decode.html
 devtools/shared/tests/mochitest/*.html
 devtools/shared/webconsole/test/test_*.html
 devtools/client/webreplay/mochitest/examples/*.html
 
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -34,16 +34,17 @@
 #include "nsTextFragment.h"
 #include "mozilla/BinarySearch.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/TextEditor.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLBRElement.h"
+#include "mozilla/dom/HTMLHeadingElement.h"
 #include "mozilla/dom/Selection.h"
 #include "gfxSkipChars.h"
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -902,23 +903,19 @@ HyperTextAccessible::DefaultTextAttribut
   RefPtr<nsPersistentProperties> attributes = new nsPersistentProperties();
 
   TextAttrsMgr textAttrsMgr(this);
   textAttrsMgr.GetAttributes(attributes);
   return attributes.forget();
 }
 
 int32_t HyperTextAccessible::GetLevelInternal() {
-  if (mContent->IsHTMLElement(nsGkAtoms::h1)) return 1;
-  if (mContent->IsHTMLElement(nsGkAtoms::h2)) return 2;
-  if (mContent->IsHTMLElement(nsGkAtoms::h3)) return 3;
-  if (mContent->IsHTMLElement(nsGkAtoms::h4)) return 4;
-  if (mContent->IsHTMLElement(nsGkAtoms::h5)) return 5;
-  if (mContent->IsHTMLElement(nsGkAtoms::h6)) return 6;
-
+  if (auto* heading = dom::HTMLHeadingElement::FromNode(mContent)) {
+    return heading->AccessibilityLevel();
+  }
   return AccessibleWrap::GetLevelInternal();
 }
 
 void HyperTextAccessible::SetMathMLXMLRoles(
     nsIPersistentProperties* aAttributes) {
   // Add MathML xmlroles based on the position inside the parent.
   Accessible* parent = Parent();
   if (parent) {
--- a/accessible/tests/mochitest/elm/test_HTMLSpec.html
+++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html
@@ -568,57 +568,33 @@
           } ],
         } ],
       };
       testElm("frameset_container", obj);
 
       // ////////////////////////////////////////////////////////////////////////
       // HTML:h1, HTML:h2, HTML:h3, HTML:h4, HTML:h5, HTML:h6
 
-      obj = {
-        role: ROLE_HEADING,
-        attributes: { "level": "1" },
-        interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
-      };
-      testElm("h1", obj);
-
-      obj = {
-        role: ROLE_HEADING,
-        attributes: { "level": "2" },
-        interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
-      };
-      testElm("h2", obj);
-
-      obj = {
-        role: ROLE_HEADING,
-        attributes: { "level": "3" },
-        interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
-      };
-      testElm("h3", obj);
+      function headingWithLevel(i) {
+        return {
+          role: ROLE_HEADING,
+          attributes: { "level": i.toString() },
+          interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
+        };
+      }
 
-      obj = {
-        role: ROLE_HEADING,
-        attributes: { "level": "4" },
-        interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
-      };
-      testElm("h4", obj);
-
-      obj = {
-        role: ROLE_HEADING,
-        attributes: { "level": "5" },
-        interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
-      };
-      testElm("h5", obj);
-
-      obj = {
-        role: ROLE_HEADING,
-        attributes: { "level": "6" },
-        interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
-      };
-      testElm("h6", obj);
+      const headingChangesEnabled = SpecialPowers.getBoolPref("accessibility.heading-element-level-changes.enabled");
+      for (let level = 1; level <= 6; ++level) {
+        testElm("h" + level, headingWithLevel(level));
+        let expectedLevelWithAncestors = headingChangesEnabled ? level + 1 : level;
+        for (const ancestor of ["section", "article", "aside", "nav"]) {
+          testElm("h" + level + "_in_" + ancestor, headingWithLevel(level == 1 ? expectedLevelWithAncestors : level));
+          testElm("h" + level + "_in_" + ancestor + "_in_hgroup", headingWithLevel(expectedLevelWithAncestors));
+        }
+      }
 
       // ////////////////////////////////////////////////////////////////////////
       // HTML:header
 
       obj = {
         role: ROLE_LANDMARK,
         attributes: { "xml-roles": "banner" },
         interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
@@ -1599,28 +1575,84 @@
   <h3 id="h3">heading3</h3>
   <h4 id="h4">heading4</h4>
   <h5 id="h5">heading5</h5>
   <h6 id="h6">heading6</h6>
 
   <header id="header">A logo</header>
   <article>
     <header id="header_in_article">Not logo</header>
+    <h1 id="h1_in_article">heading1</h1>
+    <h2 id="h2_in_article">heading2</h2>
+    <h3 id="h3_in_article">heading3</h3>
+    <h4 id="h4_in_article">heading4</h4>
+    <h5 id="h5_in_article">heading5</h5>
+    <h6 id="h6_in_article">heading6</h6>
+    <hgroup>
+      <h1 id="h1_in_article_in_hgroup">heading1</h1>
+      <h2 id="h2_in_article_in_hgroup">heading2</h2>
+      <h3 id="h3_in_article_in_hgroup">heading3</h3>
+      <h4 id="h4_in_article_in_hgroup">heading4</h4>
+      <h5 id="h5_in_article_in_hgroup">heading5</h5>
+      <h6 id="h6_in_article_in_hgroup">heading6</h6>
+    </hgroup>
   </article>
   <aside>
     <header id="header_in_aside">Not logo</header>
+    <h1 id="h1_in_aside">heading1</h1>
+    <h2 id="h2_in_aside">heading2</h2>
+    <h3 id="h3_in_aside">heading3</h3>
+    <h4 id="h4_in_aside">heading4</h4>
+    <h5 id="h5_in_aside">heading5</h5>
+    <h6 id="h6_in_aside">heading6</h6>
+    <hgroup>
+      <h1 id="h1_in_aside_in_hgroup">heading1</h1>
+      <h2 id="h2_in_aside_in_hgroup">heading2</h2>
+      <h3 id="h3_in_aside_in_hgroup">heading3</h3>
+      <h4 id="h4_in_aside_in_hgroup">heading4</h4>
+      <h5 id="h5_in_aside_in_hgroup">heading5</h5>
+      <h6 id="h6_in_aside_in_hgroup">heading6</h6>
+    </hgroup>
   </aside>
   <main>
     <header id="header_in_main">Not logo</header>
   </main>
   <nav>
     <header id="header_in_nav">Not logo</header>
+    <h1 id="h1_in_nav">heading1</h1>
+    <h2 id="h2_in_nav">heading2</h2>
+    <h3 id="h3_in_nav">heading3</h3>
+    <h4 id="h4_in_nav">heading4</h4>
+    <h5 id="h5_in_nav">heading5</h5>
+    <h6 id="h6_in_nav">heading6</h6>
+    <hgroup>
+      <h1 id="h1_in_nav_in_hgroup">heading1</h1>
+      <h2 id="h2_in_nav_in_hgroup">heading2</h2>
+      <h3 id="h3_in_nav_in_hgroup">heading3</h3>
+      <h4 id="h4_in_nav_in_hgroup">heading4</h4>
+      <h5 id="h5_in_nav_in_hgroup">heading5</h5>
+      <h6 id="h6_in_nav_in_hgroup">heading6</h6>
+    </hgroup>
   </nav>
   <section>
     <header id="header_in_section">Not logo</header>
+    <h1 id="h1_in_section">heading1</h1>
+    <h2 id="h2_in_section">heading2</h2>
+    <h3 id="h3_in_section">heading3</h3>
+    <h4 id="h4_in_section">heading4</h4>
+    <h5 id="h5_in_section">heading5</h5>
+    <h6 id="h6_in_section">heading6</h6>
+    <hgroup>
+      <h1 id="h1_in_section_in_hgroup">heading1</h1>
+      <h2 id="h2_in_section_in_hgroup">heading2</h2>
+      <h3 id="h3_in_section_in_hgroup">heading3</h3>
+      <h4 id="h4_in_section_in_hgroup">heading4</h4>
+      <h5 id="h5_in_section_in_hgroup">heading5</h5>
+      <h6 id="h6_in_section_in_hgroup">heading6</h6>
+    </hgroup>
   </section>
   <blockquote>
     <header id="header_in_blockquote">Not logo</header>
   </blockquote>
   <details open="true">
     <header id="header_in_details">Not logo</header>
   </details>
   <dialog open="true">
--- a/browser/base/content/browser-fullScreenAndPointerLock.js
+++ b/browser/base/content/browser-fullScreenAndPointerLock.js
@@ -1,18 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This file is loaded into the browser window scope.
 /* eslint-env mozilla/browser-window */
 
-ChromeUtils.import("resource:///modules/PermissionUI.jsm", this);
-
 var PointerlockFsWarning = {
   _element: null,
   _origin: null,
 
   /**
    * Timeout object for managing timeout request. If it is started when
    * the previous call hasn't finished, it would automatically cancelled
    * the previous one.
@@ -236,22 +234,16 @@ var PointerLock = {
   },
 
   exited() {
     PointerlockFsWarning.close();
   },
 };
 
 var FullScreen = {
-  _permissionNotificationIDs: Object.values(PermissionUI)
-    .filter(value => value.prototype && value.prototype.notificationID)
-    .map(value => value.prototype.notificationID)
-    // Additionally include webRTC permission prompt which does not use PermissionUI
-    .concat(["webRTC-shareDevices"]),
-
   init() {
     XPCOMUtils.defineLazyPreferenceGetter(
       this,
       "permissionsFullScreenAllowed",
       "permissions.fullscreen.allowed"
     );
 
     // Called when the Firefox window go into fullscreen.
@@ -784,17 +776,32 @@ var FullScreen = {
       document.getElementById("TabsToolbar").appendChild(fullscreenctls);
     } else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
       fullscreenctls.setAttribute("flex", "1");
       navbar.appendChild(fullscreenctls);
     }
     fullscreenctls.hidden = !aEnterFS;
   },
 };
-XPCOMUtils.defineLazyGetter(FullScreen, "useLionFullScreen", function() {
+
+XPCOMUtils.defineLazyGetter(FullScreen, "_permissionNotificationIDs", () => {
+  let { PermissionUI } = ChromeUtils.import(
+    "resource:///modules/PermissionUI.jsm",
+    {}
+  );
+  return (
+    Object.values(PermissionUI)
+      .filter(value => value.prototype && value.prototype.notificationID)
+      .map(value => value.prototype.notificationID)
+      // Additionally include webRTC permission prompt which does not use PermissionUI
+      .concat(["webRTC-shareDevices"])
+  );
+});
+
+XPCOMUtils.defineLazyGetter(FullScreen, "useLionFullScreen", () => {
   // We'll only use OS X Lion full screen if we're
   // * on OS X
   // * on Lion or higher (Darwin 11+)
   // * have fullscreenbutton="true"
   return (
     AppConstants.isPlatformAndVersionAtLeast("macosx", 11) &&
     document.documentElement.getAttribute("fullscreenbutton") == "true"
   );
--- a/browser/base/content/browser-siteProtections.js
+++ b/browser/base/content/browser-siteProtections.js
@@ -1259,16 +1259,23 @@ var gProtectionsHandler = {
 
   get noTrackersDetectedDescription() {
     delete this.noTrackersDetectedDescription;
     return (this.noTrackersDetectedDescription = document.getElementById(
       "protections-popup-no-trackers-found-description"
     ));
   },
 
+  get _protectionsPopupMilestonesText() {
+    delete this._protectionsPopupMilestonesText;
+    return (this._protectionsPopupMilestonesText = document.getElementById(
+      "protections-popup-milestones-text"
+    ));
+  },
+
   get _notBlockingWhyLink() {
     delete this._notBlockingWhyLink;
     return (this._notBlockingWhyLink = document.getElementById(
       "protections-popup-not-blocking-section-why"
     ));
   },
 
   get hasException() {
@@ -1332,16 +1339,52 @@ var gProtectionsHandler = {
 
     XPCOMUtils.defineLazyPreferenceGetter(
       this,
       "_protectionsPopupToastTimeout",
       "browser.protections_panel.toast.timeout",
       3000
     );
 
+    XPCOMUtils.defineLazyPreferenceGetter(
+      this,
+      "milestoneListPref",
+      "browser.contentblocking.cfr-milestone.milestones",
+      [],
+      () => this.maybeSetMilestoneCounterText(),
+      val => JSON.parse(val)
+    );
+
+    XPCOMUtils.defineLazyPreferenceGetter(
+      this,
+      "milestonePref",
+      "browser.contentblocking.cfr-milestone.milestone-achieved",
+      0,
+      () => this.maybeSetMilestoneCounterText()
+    );
+
+    XPCOMUtils.defineLazyPreferenceGetter(
+      this,
+      "milestoneTimestampPref",
+      "browser.contentblocking.cfr-milestone.milestone-shown-time",
+      0,
+      null,
+      val => parseInt(val)
+    );
+
+    XPCOMUtils.defineLazyPreferenceGetter(
+      this,
+      "milestonesEnabledPref",
+      "browser.contentblocking.cfr-milestone.enabled",
+      false,
+      () => this.maybeSetMilestoneCounterText()
+    );
+
+    this.maybeSetMilestoneCounterText();
+
     for (let blocker of this.blockers) {
       if (blocker.init) {
         blocker.init();
       }
     }
 
     this.updateAnimationsEnabled();
 
@@ -1378,16 +1421,21 @@ var gProtectionsHandler = {
   },
 
   openProtections(relatedToCurrent = false) {
     switchToTabHavingURI("about:protections", true, {
       replaceQueryString: true,
       relatedToCurrent,
       triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
     });
+
+    // Don't show the milestones section anymore.
+    Services.prefs.clearUserPref(
+      "browser.contentblocking.cfr-milestone.milestone-shown-time"
+    );
   },
 
   async showTrackersSubview(event) {
     await TrackingProtection.updateSubView();
     this._protectionsPopupMultiView.showSubView(
       "protections-popup-trackersView"
     );
   },
@@ -1783,16 +1831,26 @@ var gProtectionsHandler = {
         gNavigatorBundle.getFormattedString("protections.enableAriaLabel", [
           host,
         ])
       );
     }
 
     // Update the tooltip of the blocked tracker counter.
     this.maybeUpdateEarliestRecordedDateTooltip();
+
+    let today = Date.now();
+    let threeDaysMillis = 72 * 60 * 60 * 1000;
+    let expired = today - this.milestoneTimestampPref > threeDaysMillis;
+
+    if (this._milestoneTextSet && !expired) {
+      this._protectionsPopup.setAttribute("milestone", this.milestonePref);
+    } else {
+      this._protectionsPopup.removeAttribute("milestone");
+    }
   },
 
   /*
    * This function sorts the category items into the Blocked/Allowed/None Detected
    * sections. It's called immediately in onContentBlockingEvent if the popup
    * is presently open. Otherwise, the next time the popup is shown.
    */
   reorderCategoryItems() {
@@ -1947,16 +2005,56 @@ var gProtectionsHandler = {
 
     // Show the counter if the number of tracker is not zero.
     this._protectionsPopupTrackersCounterBox.toggleAttribute(
       "showing",
       trackerCount != 0
     );
   },
 
+  // Whenever one of the milestone prefs are changed, we attempt to update
+  // the milestone section string. This requires us to fetch the earliest
+  // recorded date from the Tracking DB, hence this process is async.
+  // When completed, we set _milestoneSetText to signal that the section
+  // is populated and ready to be shown - which happens next time we call
+  // refreshProtectionsPopup.
+  _milestoneTextSet: false,
+  async maybeSetMilestoneCounterText() {
+    let trackerCount = this.milestonePref;
+    if (
+      !this.milestonesEnabledPref ||
+      !trackerCount ||
+      !this.milestoneListPref.includes(trackerCount)
+    ) {
+      this._milestoneTextSet = false;
+      return;
+    }
+
+    let date = await TrackingDBService.getEarliestRecordedDate();
+    let dateLocaleStr = new Date(date).toLocaleDateString("default", {
+      month: "short",
+      year: "numeric",
+    });
+
+    let desc = PluralForm.get(
+      trackerCount,
+      gNavigatorBundle.getString("protections.milestone.description")
+    );
+
+    this._protectionsPopupMilestonesText.textContent = desc
+      .replace("#1", gBrandBundle.GetStringFromName("brandShortName"))
+      .replace(
+        "#2",
+        trackerCount.toLocaleString(Services.locale.appLocalesAsBCP47)
+      )
+      .replace("#3", dateLocaleStr);
+
+    this._milestoneTextSet = true;
+  },
+
   showDisabledTooltipForTPIcon() {
     this._trackingProtectionIconTooltipLabel.textContent = this.strings.disabledTooltipText;
     gIdentityHandler._trackingProtectionIconContainer.setAttribute(
       "aria-label",
       this.strings.disabledTooltipText
     );
   },
 
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -161,17 +161,17 @@ skip-if = fission
 [browser_bug575830.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 skip-if = (os == "mac") #Bug 1526628
 [browser_bug577121.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug578534.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug579872.js]
-skip-if = (verify && debug && (os == 'linux'))
+skip-if = (verify && debug && (os == 'linux')) || (os == 'mac') || (os == 'linux' && !debug) #Bug 1448915
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug581242.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug581253.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug585785.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug585830.js]
--- a/browser/base/content/test/siteProtections/browser.ini
+++ b/browser/base/content/test/siteProtections/browser.ini
@@ -1,5 +1,6 @@
 [DEFAULT]
 support-files =
   head.js
 
 [browser_protections_UI.js]
+[browser_protections_UI_milestones.js]
--- a/browser/base/content/test/siteProtections/browser_protections_UI.js
+++ b/browser/base/content/test/siteProtections/browser_protections_UI.js
@@ -4,60 +4,16 @@
 /* Basic UI tests for the protections panel */
 
 ChromeUtils.defineModuleGetter(
   this,
   "ContentBlockingAllowList",
   "resource://gre/modules/ContentBlockingAllowList.jsm"
 );
 
-function checkClickTelemetry(objectName, value) {
-  let events = Services.telemetry.snapshotEvents(
-    Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS
-  ).parent;
-  let buttonEvents = events.filter(
-    e =>
-      e[1] == "security.ui.protectionspopup" &&
-      e[2] == "click" &&
-      e[3] == objectName &&
-      (!value || e[4] == value)
-  );
-  is(buttonEvents.length, 1, `recorded ${objectName} telemetry event`);
-}
-
-XPCOMUtils.defineLazyServiceGetter(
-  this,
-  "TrackingDBService",
-  "@mozilla.org/tracking-db-service;1",
-  "nsITrackingDBService"
-);
-
-XPCOMUtils.defineLazyGetter(this, "TRACK_DB_PATH", function() {
-  return OS.Path.join(OS.Constants.Path.profileDir, "protections.sqlite");
-});
-
-const { Sqlite } = ChromeUtils.import("resource://gre/modules/Sqlite.jsm");
-
-async function addTrackerDataIntoDB(count) {
-  const insertSQL =
-    "INSERT INTO events (type, count, timestamp)" +
-    "VALUES (:type, :count, date(:timestamp));";
-
-  let db = await Sqlite.openConnection({ path: TRACK_DB_PATH });
-  let date = new Date().toISOString();
-
-  await db.execute(insertSQL, {
-    type: TrackingDBService.TRACKERS_ID,
-    count,
-    timestamp: date,
-  });
-
-  await db.close();
-}
-
 add_task(async function setup() {
   await SpecialPowers.pushPrefEnv({
     set: [
       // Set the auto hide timing to 100ms for blocking the test less.
       ["browser.protections_panel.toast.timeout", 100],
       // Hide protections cards so as not to trigger more async messaging
       // when landing on the page.
       ["browser.contentblocking.report.monitor.enabled", false],
@@ -217,42 +173,30 @@ add_task(async function testShowFullRepo
     "https://example.com"
   );
   await openProtectionsPanel();
 
   let popuphiddenPromise = BrowserTestUtils.waitForEvent(
     protectionsPopup,
     "popuphidden"
   );
-  let newTabPromise = BrowserTestUtils.waitForNewTab(
-    gBrowser,
-    "about:protections"
-  );
+  let newTabPromise = waitForAboutProtectionsTab();
   let showFullReportButton = document.getElementById(
     "protections-popup-show-report-button"
   );
 
   showFullReportButton.click();
 
   // The protection popup should be hidden after clicking the link.
   await popuphiddenPromise;
   // Wait until the 'about:protections' has been opened correctly.
   let newTab = await newTabPromise;
 
   ok(true, "about:protections has been opened successfully");
 
-  // When the graph is built it means the messaging has finished,
-  // we can close the tab.
-  await ContentTask.spawn(newTab.linkedBrowser, {}, async function() {
-    await ContentTaskUtils.waitForCondition(() => {
-      let bars = content.document.querySelectorAll(".graph-bar");
-      return bars.length;
-    }, "The graph has been built");
-  });
-
   checkClickTelemetry("full_report");
 
   BrowserTestUtils.removeTab(newTab);
   BrowserTestUtils.removeTab(tab);
 });
 
 /**
  * A test for ensuring the mini panel is working correctly
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/siteProtections/browser_protections_UI_milestones.js
@@ -0,0 +1,96 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function setup() {
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      // Hide protections cards so as not to trigger more async messaging
+      // when landing on the page.
+      ["browser.contentblocking.report.monitor.enabled", false],
+      ["browser.contentblocking.report.lockwise.enabled", false],
+      ["browser.contentblocking.report.proxy.enabled", false],
+    ],
+  });
+});
+
+add_task(async function doTest() {
+  // This also ensures that the DB tables have been initialized.
+  await TrackingDBService.clearAll();
+
+  let milestones = JSON.parse(
+    Services.prefs.getStringPref(
+      "browser.contentblocking.cfr-milestone.milestones"
+    )
+  );
+  let totalTrackerCount = 0;
+
+  let tab = await BrowserTestUtils.openNewForegroundTab(
+    gBrowser,
+    "https://example.com"
+  );
+
+  for (let milestone of milestones) {
+    let trackerCount = milestone - totalTrackerCount;
+    await addTrackerDataIntoDB(trackerCount);
+    totalTrackerCount += trackerCount;
+
+    // Trigger the milestone feature.
+    await TrackingDBService.saveEvents("{}");
+
+    await TestUtils.waitForCondition(
+      () => gProtectionsHandler._milestoneTextSet
+    );
+
+    // We set the shown-time pref to pretend that the CFR has been
+    // shown, so that we can test the panel.
+    // TODO: Full integration test for robustness.
+    Services.prefs.setStringPref(
+      "browser.contentblocking.cfr-milestone.milestone-shown-time",
+      Date.now().toString()
+    );
+
+    await openProtectionsPanel();
+
+    ok(
+      BrowserTestUtils.is_visible(
+        gProtectionsHandler._protectionsPopupMilestonesText
+      ),
+      "Milestones section should be visible in the panel."
+    );
+
+    await closeProtectionsPanel();
+    await openProtectionsPanel();
+
+    ok(
+      BrowserTestUtils.is_visible(
+        gProtectionsHandler._protectionsPopupMilestonesText
+      ),
+      "Milestones section should still be visible in the panel."
+    );
+
+    let newTabPromise = waitForAboutProtectionsTab();
+    await EventUtils.synthesizeMouseAtCenter(
+      document.getElementById("protections-popup-milestones-content"),
+      {}
+    );
+    let protectionsTab = await newTabPromise;
+
+    ok(true, "about:protections has been opened as expected.");
+
+    BrowserTestUtils.removeTab(protectionsTab);
+
+    await openProtectionsPanel();
+
+    ok(
+      !BrowserTestUtils.is_visible(
+        gProtectionsHandler._protectionsPopupMilestonesText
+      ),
+      "Milestones section should no longer be visible in the panel."
+    );
+
+    await closeProtectionsPanel();
+  }
+
+  BrowserTestUtils.removeTab(tab);
+  await TrackingDBService.clearAll();
+});
--- a/browser/base/content/test/siteProtections/head.js
+++ b/browser/base/content/test/siteProtections/head.js
@@ -1,11 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
+const { Sqlite } = ChromeUtils.import("resource://gre/modules/Sqlite.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(
+  this,
+  "TrackingDBService",
+  "@mozilla.org/tracking-db-service;1",
+  "nsITrackingDBService"
+);
+
+XPCOMUtils.defineLazyGetter(this, "TRACK_DB_PATH", function() {
+  return OS.Path.join(OS.Constants.Path.profileDir, "protections.sqlite");
+});
+
 var protectionsPopup = document.getElementById("protections-popup");
 var protectionsPopupMainView = document.getElementById(
   "protections-popup-mainView"
 );
 var protectionsPopupHeader = document.getElementById(
   "protections-popup-mainView-panel-header"
 );
 
@@ -56,8 +69,54 @@ async function closeProtectionsPanel() {
   let popuphiddenPromise = BrowserTestUtils.waitForEvent(
     protectionsPopup,
     "popuphidden"
   );
 
   PanelMultiView.hidePopup(protectionsPopup);
   await popuphiddenPromise;
 }
+
+function checkClickTelemetry(objectName, value) {
+  let events = Services.telemetry.snapshotEvents(
+    Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS
+  ).parent;
+  let buttonEvents = events.filter(
+    e =>
+      e[1] == "security.ui.protectionspopup" &&
+      e[2] == "click" &&
+      e[3] == objectName &&
+      (!value || e[4] == value)
+  );
+  is(buttonEvents.length, 1, `recorded ${objectName} telemetry event`);
+}
+
+async function addTrackerDataIntoDB(count) {
+  const insertSQL =
+    "INSERT INTO events (type, count, timestamp)" +
+    "VALUES (:type, :count, date(:timestamp));";
+
+  let db = await Sqlite.openConnection({ path: TRACK_DB_PATH });
+  let date = new Date().toISOString();
+
+  await db.execute(insertSQL, {
+    type: TrackingDBService.TRACKERS_ID,
+    count,
+    timestamp: date,
+  });
+
+  await db.close();
+}
+
+async function waitForAboutProtectionsTab() {
+  let tab = await BrowserTestUtils.waitForNewTab(gBrowser, "about:protections");
+
+  // When the graph is built it means the messaging has finished,
+  // we can close the tab.
+  await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
+    await ContentTaskUtils.waitForCondition(() => {
+      let bars = content.document.querySelectorAll(".graph-bar");
+      return bars.length;
+    }, "The graph has been built");
+  });
+
+  return tab;
+}
--- a/browser/components/aboutlogins/content/components/login-list.js
+++ b/browser/components/aboutlogins/content/components/login-list.js
@@ -372,16 +372,23 @@ export default class LoginList extends H
   loginAdded(login) {
     this._logins[login.guid] = { login };
     this._loginGuidsSortedOrder.push(login.guid);
     this._applySort();
 
     // Add the list item and update any other related state that may pertain
     // to the list item such as breach alerts.
     this.render();
+
+    if (
+      this.classList.contains("no-logins") &&
+      !this.classList.contains("create-login-selected")
+    ) {
+      this._selectFirstVisibleLogin();
+    }
   }
 
   /**
    * @param {login} login A login that was modified in storage. The related
    *                      login-list-item will get updated.
    */
   loginModified(login) {
     this._logins[login.guid] = Object.assign(this._logins[login.guid], {
--- a/browser/components/aboutlogins/tests/browser/browser_noLoginsView.js
+++ b/browser/components/aboutlogins/tests/browser/browser_noLoginsView.js
@@ -8,20 +8,16 @@ add_task(async function setup() {
   });
   registerCleanupFunction(() => {
     BrowserTestUtils.removeTab(gBrowser.selectedTab);
   });
 });
 
 add_task(async function test_no_logins_class() {
   await ContentTask.spawn(gBrowser.selectedBrowser, null, async () => {
-    function isElementHidden(element) {
-      return content.getComputedStyle(element).display === "none";
-    }
-
     let loginList = content.document.querySelector("login-list");
 
     ok(
       content.document.documentElement.classList.contains("no-logins"),
       "root should be in no logins view"
     );
     ok(
       loginList.classList.contains("no-logins"),
@@ -31,30 +27,30 @@ add_task(async function test_no_logins_c
     let loginIntro = Cu.waiveXrays(
       content.document.querySelector("login-intro")
     );
     let loginItem = content.document.querySelector("login-item");
     let loginListIntro = loginList.shadowRoot.querySelector(".intro");
     let loginListList = loginList.shadowRoot.querySelector("ol");
 
     ok(
-      !isElementHidden(loginIntro),
+      !ContentTaskUtils.is_hidden(loginIntro),
       "login-intro should be shown in no logins view"
     );
     ok(
-      !isElementHidden(loginListIntro),
+      !ContentTaskUtils.is_hidden(loginListIntro),
       "login-list intro should be shown in no logins view"
     );
 
     ok(
-      isElementHidden(loginItem),
+      ContentTaskUtils.is_hidden(loginItem),
       "login-item should be hidden in no logins view"
     );
     ok(
-      isElementHidden(loginListList),
+      ContentTaskUtils.is_hidden(loginListList),
       "login-list logins list should be hidden in no logins view"
     );
     is(
       content.document.l10n.getAttributes(
         loginIntro.shadowRoot.querySelector(".heading")
       ).id,
       "login-intro-heading",
       "The default message should be the non-logged-in message"
@@ -66,8 +62,87 @@ add_task(async function test_no_logins_c
       content.document.l10n.getAttributes(
         loginIntro.shadowRoot.querySelector(".heading")
       ).id,
       "about-logins-login-intro-heading-logged-in",
       "When logged in the message should update"
     );
   });
 });
+
+add_task(
+  async function login_selected_when_login_added_and_in_no_logins_view() {
+    await ContentTask.spawn(gBrowser.selectedBrowser, null, async () => {
+      let loginList = content.document.querySelector("login-list");
+      let loginItem = content.document.querySelector("login-item");
+      let loginIntro = content.document.querySelector("login-intro");
+      ok(
+        loginList.classList.contains("empty-search"),
+        "login-list should be showing no logins view from a search with no results"
+      );
+      ok(
+        loginList.classList.contains("no-logins"),
+        "login-list should be showing no logins view since there are no saved logins"
+      );
+      ok(
+        !loginList.classList.contains("create-login-selected"),
+        "login-list should not be in create-login-selected mode"
+      );
+      ok(
+        loginItem.classList.contains("no-logins"),
+        "login-item should be marked as having no-logins"
+      );
+      ok(ContentTaskUtils.is_hidden(loginItem), "login-item should be hidden");
+      ok(
+        !ContentTaskUtils.is_hidden(loginIntro),
+        "login-intro should be visible"
+      );
+    });
+
+    TEST_LOGIN1 = await addLogin(TEST_LOGIN1);
+
+    await ContentTask.spawn(
+      gBrowser.selectedBrowser,
+      TEST_LOGIN1.guid,
+      async testLogin1Guid => {
+        let loginList = content.document.querySelector("login-list");
+        let loginItem = content.document.querySelector("login-item");
+        let loginIntro = content.document.querySelector("login-intro");
+        ok(
+          !loginList.classList.contains("empty-search"),
+          "login-list should not be showing no logins view since one login exists"
+        );
+        ok(
+          !loginList.classList.contains("no-logins"),
+          "login-list should not be showing no logins view since one login exists"
+        );
+        ok(
+          !loginList.classList.contains("create-login-selected"),
+          "login-list should not be in create-login-selected mode"
+        );
+        is(
+          loginList.shadowRoot.querySelector(
+            ".login-list-item.selected[data-guid]"
+          ).dataset.guid,
+          testLogin1Guid,
+          "the login that was just added should be selected"
+        );
+        ok(
+          !loginItem.classList.contains("no-logins"),
+          "login-item should not be marked as having no-logins"
+        );
+        is(
+          Cu.waiveXrays(loginItem)._login.guid,
+          testLogin1Guid,
+          "the login-item should have the newly added login selected"
+        );
+        ok(
+          !ContentTaskUtils.is_hidden(loginItem),
+          "login-item should be visible"
+        );
+        ok(
+          ContentTaskUtils.is_hidden(loginIntro),
+          "login-intro should be hidden"
+        );
+      }
+    );
+  }
+);
--- a/browser/components/controlcenter/content/protectionsPanel.inc.xul
+++ b/browser/components/controlcenter/content/protectionsPanel.inc.xul
@@ -150,16 +150,28 @@
           <hbox id="protections-popup-trackers-blocked-counter-box"
                 align="center"
                 end="0">
             <description id="protections-popup-trackers-blocked-counter-description"
                          onclick="gProtectionsHandler.openProtections(true);"/>
           </hbox>
         </stack>
       </vbox>
+
+      <hbox id="protections-popup-milestones" class="protections-popup-section">
+        <!-- wrap=true is needed for descriptionheightworkaround, see bug 1564077 -->
+        <toolbarbutton id="protections-popup-milestones-content"
+                       flex="1"
+                       wrap="true"
+                       oncommand="gProtectionsHandler.openProtections(true);">
+          <description id="protections-popup-milestones-text" flex="1"
+                       role="heading" aria-level="2"/>
+          <image id="protections-popup-milestones-illustration"/>
+        </toolbarbutton>
+      </hbox>
     </panelview>
 
     <!-- Site Not Working? SubView -->
     <panelview id="protections-popup-siteNotWorkingView"
                role="document"
                title="&protections.siteNotWorkingView.title;"
                descriptionheightworkaround="true"
                flex="1">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -570,16 +570,26 @@ protections.notBlocking.socialMediaTrack
 #   Semicolon-separated list of plural forms.
 #   See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
 #   Replacement for #1 is a locale-string converted positive integer.
 protections.footer.blockedTrackerCounter.description=1 Blocked;#1 Blocked
 # LOCALIZATION NOTE (protections.footer.blockedTrackerCounter.tooltip):
 #   %S is the date on which we started counting (e.g., July 17, 2019).
 protections.footer.blockedTrackerCounter.tooltip=Since %S
 
+# Milestones section in the Protections Panel
+# LOCALIZATION NOTE (protections.milestone.description):
+#   Semicolon-separated list of plural forms.
+#   See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+#   #1 is replaced with brandShortName.
+#   #2 is replaced with the (locale-formatted) number of trackers blocked
+#   #3 is replaced by a locale-formatted date with short month and numeric year.
+#   In English this looks like "Firefox blocked over 10,000 trackers since Oct 2019"
+protections.milestone.description=#1 blocked #2 tracker since #3;#1 blocked over #2 trackers since #3
+
 # Edit Bookmark UI
 editBookmarkPanel.newBookmarkTitle=New Bookmark
 editBookmarkPanel.editBookmarkTitle=Edit This Bookmark
 editBookmarkPanel.cancel.label=Cancel
 editBookmarkPanel.cancel.accesskey=C
 
 # LOCALIZATION NOTE (editBookmark.removeBookmarks.label): Semicolon-separated list of plural forms.
 # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/controlcenter/etp-milestone.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg width="32" height="40" xmlns="http://www.w3.org/2000/svg"><path d="M31.617 10.435V5.009a1.74 1.74 0 00-1.443-1.74L16.296.87a1.687 1.687 0 00-.592 0L1.87 3.288a1.74 1.74 0 00-1.444 1.74v5.425c-.043 2.87-.07 4.948.052 6.244.748 8.295 2.496 12.078 5.47 16.147a16.165 16.165 0 009.704 6.287c.113.013.227.013.34 0 .112.014.226.014.338 0a16.409 16.409 0 009.757-6.313c2.974-4.07 4.722-7.826 5.47-16.156.13-1.287.104-3.365.06-6.226z" fill="context-fill"/><path d="M15.704.87L1.87 3.287a1.74 1.74 0 00-1.444 1.74v5.425c-.043 2.87-.07 4.948.052 6.244.748 8.295 2.496 12.078 5.47 16.147a16.165 16.165 0 009.704 6.287c.113.013.227.013.34 0V.87a1.74 1.74 0 00-.288 0z" opacity=".5" fill="context-stroke"/><path d="M12.878 11.635c-1.4.174-2.295 2.191-2.052 4.122.122.982.713 1.452.87 3.217 0 .174 0 .322.043.47a16.66 16.66 0 003.044-.166 5.009 5.009 0 01-.053-.87c.219-1.13.347-2.275.383-3.425-.226-1.757-.983-3.505-2.235-3.348zm2.052 8.487c-.84.135-1.688.202-2.539.2h-.548c.025.398.083.794.174 1.182.14.566.618 1.557 1.687 1.418a1.452 1.452 0 001.374-1.809c-.035-.348-.095-.67-.148-.991zm4.2-5.879c-1.252-.156-2.008 1.592-2.234 3.34.036 1.15.164 2.296.382 3.426.008.29-.01.581-.052.87 1.002.146 2.015.202 3.026.164v-.47c.174-1.738.765-2.234.87-3.216.295-1.922-.6-3.94-1.992-4.114zm-2.208 9.47a1.452 1.452 0 001.339 1.809c1.07.139 1.548-.87 1.687-1.418a7.07 7.07 0 00.174-1.174H19.6c-.845 0-1.688-.066-2.522-.2-.06.322-.121.644-.156.983z" fill="#FBFBFE"/></svg>
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -1102,8 +1102,79 @@ description#identity-popup-content-verif
 
 .protections-popup-description {
   border-bottom: 1px solid var(--panel-separator-color);
 }
 
 .protections-popup-description > description {
   margin: 10px 24px;
 }
+
+#protections-popup:not([milestone]) #protections-popup-milestones {
+  display: none;
+}
+
+#protections-popup-milestones {
+  margin: 0 calc(var(--horizontal-padding) * 0.5) var(--vertical-section-padding);
+  /* Override .protections-popup-section */
+  border-top: none;
+  background-color: var(--arrowpanel-dimmed);
+}
+
+#protections-popup-milestones-content {
+  padding: var(--vertical-section-padding) calc(var(--horizontal-padding) * 0.5);
+  margin: 0;
+}
+
+#protections-popup-milestones-content:hover {
+  background-color: var(--arrowpanel-dimmed);
+}
+
+#protections-popup-milestones-content:hover:active {
+  background-color: var(--arrowpanel-dimmed-further);
+}
+
+#protections-popup-milestones-text {
+  font-size: 1.23em;
+  margin: 0;
+}
+
+#protections-popup-milestones-illustration {
+  list-style-image: url(chrome://browser/skin/controlcenter/etp-milestone.svg);
+  -moz-context-properties: fill, stroke;
+  margin-inline-start: var(--horizontal-padding);
+  margin-inline-end: 4px;
+}
+
+#protections-popup[milestone] #protections-popup-milestones-illustration {
+  fill: #45278d;
+  stroke: #321c64;
+}
+
+#protections-popup[milestone="5000"] #protections-popup-milestones-illustration {
+  fill: #5a29cb;
+  stroke: #45278d;
+}
+
+#protections-popup[milestone="10000"] #protections-popup-milestones-illustration {
+  fill: #7641e5;
+  stroke: #5a29cb;
+}
+
+#protections-popup[milestone="25000"] #protections-popup-milestones-illustration {
+  fill: #e31587;
+  stroke: #c60084;
+}
+
+#protections-popup[milestone="50000"] #protections-popup-milestones-illustration {
+  fill: #ff298a;
+  stroke: #e31587;
+}
+
+#protections-popup[milestone="100000"] #protections-popup-milestones-illustration {
+  fill: #ffa436;
+  stroke: #e27f2e;
+}
+
+#protections-popup[milestone="500000"] #protections-popup-milestones-illustration {
+  fill: #ffd567;
+  stroke: #ffbd4f;
+}
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -26,16 +26,17 @@
   skin/classic/browser/addons/addon-private-browsing.svg       (../shared/addons/addon-private-browsing.svg)
   skin/classic/browser/controlcenter/3rdpartycookies.svg       (../shared/controlcenter/3rdpartycookies.svg)
   skin/classic/browser/controlcenter/3rdpartycookies-disabled.svg (../shared/controlcenter/3rdpartycookies-disabled.svg)
   skin/classic/browser/controlcenter/cryptominers.svg          (../shared/controlcenter/cryptominers.svg)
   skin/classic/browser/controlcenter/dashboard.svg             (../shared/controlcenter/dashboard.svg)
   skin/classic/browser/controlcenter/cryptominers-disabled.svg (../shared/controlcenter/cryptominers-disabled.svg)
   skin/classic/browser/controlcenter/mcb-disabled.svg          (../shared/controlcenter/mcb-disabled.svg)
   skin/classic/browser/controlcenter/extension.svg             (../shared/controlcenter/extension.svg)
+  skin/classic/browser/controlcenter/etp-milestone.svg         (../shared/controlcenter/etp-milestone.svg)
   skin/classic/browser/controlcenter/fingerprinters.svg        (../shared/controlcenter/fingerprinters.svg)
   skin/classic/browser/controlcenter/fingerprinters-disabled.svg (../shared/controlcenter/fingerprinters-disabled.svg)
   skin/classic/browser/controlcenter/info.svg                  (../shared/controlcenter/info.svg)
   skin/classic/browser/controlcenter/socialblock.svg           (../shared/controlcenter/socialblock.svg)
   skin/classic/browser/controlcenter/socialblock-disabled.svg  (../shared/controlcenter/socialblock-disabled.svg)
   skin/classic/browser/controlcenter/tracker-image.svg         (../shared/controlcenter/tracker-image.svg)
   skin/classic/browser/controlcenter/tracker-image-disabled.svg  (../shared/controlcenter/tracker-image-disabled.svg)
   skin/classic/browser/controlcenter/trackers.svg              (../shared/controlcenter/trackers.svg)
--- a/devtools/client/storage/test/storage-cache-error.html
+++ b/devtools/client/storage/test/storage-cache-error.html
@@ -5,16 +5,16 @@
   <title>Storage inspector test for handling errors in CacheStorage</title>
 </head>
 <body>
 <script type="application/javascript">
 "use strict";
 
 // Create an iframe with a javascript: source URL. Such iframes are
 // considered untrusted by the CacheStorage.
-let frameEl = document.createElement("iframe");
+const frameEl = document.createElement("iframe");
 document.body.appendChild(frameEl);
 
 window.frameContent = 'Hello World';
 frameEl.contentWindow.location.href = "javascript:parent.frameContent";
 </script>
 </body>
 </html>
--- a/devtools/client/storage/test/storage-complex-values.html
+++ b/devtools/client/storage/test/storage-complex-values.html
@@ -5,18 +5,18 @@ Bug 970517 - Storage inspector front end
 -->
 <head>
   <meta charset="utf-8">
   <title>Storage inspector test for correct values in the sidebar</title>
 </head>
 <body>
 <script type="application/javascript">
 "use strict";
-let partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
-let cookieExpiresTime = 2000000000000;
+const partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
+const cookieExpiresTime = 2000000000000;
 // Setting up some cookies to eat.
 document.cookie = "c1=" + JSON.stringify([
   "foo", "Bar", {
     foo: "Bar"
   }]) + "; expires=" + new Date(cookieExpiresTime).toGMTString() +
   "; path=/browser";
 document.cookie = "cs2=sessionCookie; path=/; domain=" + partialHostname;
 // URLEncoded cookie
@@ -33,66 +33,66 @@ localStorage.setItem("ls2", "foobar-2");
 localStorage.setItem("ls3", "http://foobar.com/baz.php");
 // ... and finally some session storage items too
 sessionStorage.setItem("ss1", "This#is#an#array");
 sessionStorage.setItem("ss2", "This~is~another~array");
 sessionStorage.setItem("ss3", "this#is~an#object~foo#bar");
 sessionStorage.setItem("ss4", "#array##with#empty#items");
 // long string that is almost an object and might trigger exponential
 // regexp backtracking
-let s = "a".repeat(1000);
+const s = "a".repeat(1000);
 sessionStorage.setItem("ss5", `${s}=${s}=${s}=${s}&${s}=${s}&${s}`);
 console.log("added cookies and stuff from main page");
 
-let idbGenerator = async function () {
+const idbGenerator = async function () {
   let request = indexedDB.open("idb1", 1);
   request.onerror = function() {
     throw new Error("error opening db connection");
   };
-  let db = await new Promise(done => {
+  const db = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db = event.target.result;
-      let store1 = db.createObjectStore("obj1", { keyPath: "id" });
+      const _db = event.target.result;
+      const store1 = _db.createObjectStore("obj1", { keyPath: "id" });
       store1.createIndex("name", "name", { unique: false });
       store1.createIndex("email", "email", { unique: true });
-      db.createObjectStore("obj2", { keyPath: "id2" });
+      _db.createObjectStore("obj2", { keyPath: "id2" });
       store1.transaction.oncomplete = () => {
-        done(db);
+        done(_db);
       };
     };
   });
 
   // Prevents AbortError
   await new Promise(done => {
     request.onsuccess = done;
   });
 
-  let transaction = db.transaction(["obj1", "obj2"], "readwrite");
-  let store1 = transaction.objectStore("obj1");
-  let store2 = transaction.objectStore("obj2");
+  const transaction = db.transaction(["obj1", "obj2"], "readwrite");
+  const store1 = transaction.objectStore("obj1");
+  const store2 = transaction.objectStore("obj2");
 
   store1.add({id: 1, name: "foo", email: "foo@bar.com"});
   store1.add({id: 2, name: "foo2", email: "foo2@bar.com"});
   store1.add({id: 3, name: "foo2", email: "foo3@bar.com"});
   store2.add({
     id2: 1,
     name: "foo",
     email: "foo@bar.com",
     extra: "baz"});
 
   db.close();
 
   request = indexedDB.open("idb2", 1);
-  let db2 = await new Promise(done => {
+  const db2 = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db2 = event.target.result;
-      let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
+      const _db2 = event.target.result;
+      const store3 = _db2.createObjectStore("obj3", { keyPath: "id3" });
       store3.createIndex("name2", "name2", { unique: true });
       store3.transaction.oncomplete = () => {
-        done(db2);
+        done(_db2);
       };
     };
   });
 
   // Prevents AbortError during close()
   await new Promise(done => {
     request.onsuccess = done;
   });
--- a/devtools/client/storage/test/storage-cookies-samesite.html
+++ b/devtools/client/storage/test/storage-cookies-samesite.html
@@ -2,16 +2,16 @@
 <html>
   <head>
     <meta charset="utf-8">
     <title>Storage inspector cookie samesite test</title>
   </head>
   <body>
     <script type="application/javascript">
     "use strict";
-    let expiresIn24Hours = new Date(Date.now() + 60 * 60 * 24 * 1000).toUTCString();
+    const expiresIn24Hours = new Date(Date.now() + 60 * 60 * 24 * 1000).toUTCString();
 
     document.cookie = "test1=value1;expires=" + expiresIn24Hours + ";";
     document.cookie = "test2=value2;expires=" + expiresIn24Hours + ";SameSite=lax";
     document.cookie = "test3=value3;expires=" + expiresIn24Hours + ";SameSite=strict";
     </script>
   </body>
 </html>
--- a/devtools/client/storage/test/storage-empty-objectstores.html
+++ b/devtools/client/storage/test/storage-empty-objectstores.html
@@ -1,60 +1,60 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test for proper listing indexedDB databases with no object stores</title>
 </head>
 <body>
 <script type="application/javascript">
-
+"use strict";
 window.setup = async function () {
   let request = indexedDB.open("idb1", 1);
-  let db = await new Promise((resolve, reject) => {
+  const db = await new Promise((resolve, reject) => {
     request.onerror = e => reject(Error("error opening db connection"));
     request.onupgradeneeded = event => {
-      let db = event.target.result;
-      let store1 = db.createObjectStore("obj1", { keyPath: "id" });
+      const _db = event.target.result;
+      const store1 = _db.createObjectStore("obj1", { keyPath: "id" });
       store1.createIndex("name", "name", { unique: false });
       store1.createIndex("email", "email", { unique: true });
-      let store2 = db.createObjectStore("obj2", { keyPath: "id2" });
-      store1.transaction.oncomplete = () => resolve(db);
+      _db.createObjectStore("obj2", { keyPath: "id2" });
+      store1.transaction.oncomplete = () => resolve(_db);
     };
   });
 
-  await new Promise(resolve => request.onsuccess = resolve);
+  await new Promise(resolve => (request.onsuccess = resolve));
 
-  let transaction = db.transaction(["obj1", "obj2"], "readwrite");
-  let store1 = transaction.objectStore("obj1");
-  let store2 = transaction.objectStore("obj2");
+  const transaction = db.transaction(["obj1", "obj2"], "readwrite");
+  const store1 = transaction.objectStore("obj1");
+  const store2 = transaction.objectStore("obj2");
 
   store1.add({id: 1, name: "foo", email: "foo@bar.com"});
   store1.add({id: 2, name: "foo2", email: "foo2@bar.com"});
   store1.add({id: 3, name: "foo2", email: "foo3@bar.com"});
   store2.add({id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"});
 
-  await new Promise(resolve => transaction.oncomplete = resolve);
+  await new Promise(resolve => (transaction.oncomplete = resolve));
 
   db.close();
 
   request = indexedDB.open("idb2", 1);
-  let db2 = await new Promise((resolve, reject) => {
+  const db2 = await new Promise((resolve, reject) => {
     request.onerror = e => reject(Error("error opening db2 connection"));
     request.onupgradeneeded = event => resolve(event.target.result);
   });
 
-  await new Promise(resolve => request.onsuccess = resolve);
+  await new Promise(resolve => (request.onsuccess = resolve));
 
   db2.close();
   dump("added indexedDB items from main page\n");
 };
 
 window.clear = async function () {
-  for (let dbName of ["idb1", "idb2"]) {
+  for (const dbName of ["idb1", "idb2"]) {
     await new Promise(resolve => {
       indexedDB.deleteDatabase(dbName).onsuccess = resolve;
     });
   }
   dump("removed indexedDB items from main page\n");
 };
 
 </script>
--- a/devtools/client/storage/test/storage-file-url.html
+++ b/devtools/client/storage/test/storage-file-url.html
@@ -1,35 +1,35 @@
 <!DOCTYPE html>
 <html>
 <head>
   <meta charset="utf-8" />
   <title>Storage Test</title>
   <script>
+    "use strict";
+    /* exported init */
     function init() {
       createIndexedDB();
       createCookies();
       createLocalStorage();
       createSessionStorage();
     }
 
     function createIndexedDB() {
-      var open = indexedDB.open("MyDatabase", 1);
+      const open = indexedDB.open("MyDatabase", 1);
 
       open.onupgradeneeded = function () {
-        var db = open.result;
-        var store = db.createObjectStore("MyObjectStore", {keyPath: "id"});
-        var index = store.createIndex("NameIndex", ["name.last", "name.first"]);
+        const db = open.result;
+        db.createObjectStore("MyObjectStore", {keyPath: "id"});
       };
 
       open.onsuccess = function () {
-        var db = open.result;
-        var tx = db.transaction("MyObjectStore", "readwrite");
-        var store = tx.objectStore("MyObjectStore");
-        var index = store.index("NameIndex");
+        const db = open.result;
+        const tx = db.transaction("MyObjectStore", "readwrite");
+        const store = tx.objectStore("MyObjectStore");
 
         store.put({id: 12345, name: {first: "John", last: "Doe"}, age: 42});
         store.put({id: 54321, name: {first: "Ralph", last: "Wood"}, age: 38});
         store.put({id: 67890, name: {first: "Bob", last: "Smith"}, age: 35});
         store.put({id: 98765, name: {first: "Freddie", last: "Krueger"}, age: 40});
 
         tx.oncomplete = function () {
           db.close();
--- a/devtools/client/storage/test/storage-idb-delete-blocked.html
+++ b/devtools/client/storage/test/storage-idb-delete-blocked.html
@@ -1,50 +1,45 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test for proper listing indexedDB databases with no object stores</title>
 </head>
 <body>
 <script type="application/javascript">
-
+"use strict";
 let db;
 
 window.setup = async function () {
   db = await new Promise((resolve, reject) => {
-    let request = indexedDB.open("idb", 1);
+    const request = indexedDB.open("idb", 1);
 
     request.onsuccess = e => resolve(e.target.result);
     request.onerror = e => reject(new Error("error opening db connection"));
-
-    request.onupgradeneeded = e => {
-      let db = e.target.result;
-      let store = db.createObjectStore("obj", { keyPath: "id" });
-    };
   });
 
   dump("opened indexedDB\n");
 };
 
 window.closeDb = function() {
   db.close();
 };
 
 window.deleteDb = async function () {
   await new Promise((resolve, reject) => {
-    let request = indexedDB.deleteDatabase("idb");
+    const request = indexedDB.deleteDatabase("idb");
 
     request.onsuccess = resolve;
     request.onerror = e => reject(new Error("error deleting db"));
   });
 };
 
 window.clear = async function () {
-  for (let dbName of ["idb1", "idb2"]) {
+  for (const dbName of ["idb1", "idb2"]) {
     await new Promise(resolve => {
       indexedDB.deleteDatabase(dbName).onsuccess = resolve;
     });
   }
   dump("removed indexedDB items from main page\n");
 };
 
 </script>
--- a/devtools/client/storage/test/storage-indexeddb-duplicate-names.html
+++ b/devtools/client/storage/test/storage-indexeddb-duplicate-names.html
@@ -2,30 +2,31 @@
 <html><head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
   <meta charset="utf-8">
   <title>Storage inspector IndexedDBs with duplicate names</title>
 
   <script type="application/javascript">
     "use strict";
 
+    /* exported createIndexedDBs */
     function createIndexedDBs() {
       createIndexedDB("idb1", "temporary");
       createIndexedDB("idb1", "default");
       createIndexedDB("idb1", "persistent");
       createIndexedDB("idb2", "temporary");
       createIndexedDB("idb2", "default");
       createIndexedDB("idb2", "persistent");
     }
 
     function createIndexedDB(name, storage) {
-      let open = indexedDB.open(name, {storage: storage});
+      const open = indexedDB.open(name, {storage: storage});
 
       open.onsuccess = function () {
-        let db = open.result;
+        const db = open.result;
         db.close();
       };
     }
 
     function deleteDB(dbName, storage) {
       return new Promise(resolve => {
         dump(`removing database ${dbName} (${storage}) from ${document.location}\n`);
         indexedDB.deleteDatabase(dbName, { storage: storage }).onsuccess = resolve;
--- a/devtools/client/storage/test/storage-listings-usercontextid.html
+++ b/devtools/client/storage/test/storage-listings-usercontextid.html
@@ -7,58 +7,58 @@ Storage inspector front end for userCont
   <meta charset="utf-8">
   <title>Storage inspector test for listing hosts and storages</title>
 </head>
 <body>
 <iframe src="http://sectest1.example.org/browser/devtools/client/storage/test/storage-unsecured-iframe-usercontextid.html"></iframe>
 <iframe src="https://sectest1.example.org:443/browser/devtools/client/storage/test/storage-secured-iframe-usercontextid.html"></iframe>
 <script type="application/javascript">
 "use strict";
-let partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
-let cookieExpiresTime1 = 2000000000000;
-let cookieExpiresTime2 = 2000000001000;
+const partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
+const cookieExpiresTime1 = 2000000000000;
+const cookieExpiresTime2 = 2000000001000;
 // Setting up some cookies to eat.
 document.cookie = "c1uc1=foobar; expires=" +
   new Date(cookieExpiresTime1).toGMTString() + "; path=/browser";
 document.cookie = "cs2uc1=sessionCookie; path=/; domain=" + partialHostname;
 document.cookie = "c3uc1=foobar-2; expires=" +
   new Date(cookieExpiresTime2).toGMTString() + "; path=/";
 // ... and some local storage items ..
 localStorage.setItem("ls1uc1", "foobar");
 localStorage.setItem("ls2uc1", "foobar-2");
 // ... and finally some session storage items too
 sessionStorage.setItem("ss1uc1", "foobar-3");
 dump("added cookies and storage from main page\n");
 
-let idbGenerator = async function () {
+const idbGenerator = async function () {
   let request = indexedDB.open("idb1uc1", 1);
   request.onerror = function() {
     throw new Error("error opening db connection");
   };
-  let db = await new Promise(done => {
+  const db = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db = event.target.result;
-      let store1 = db.createObjectStore("obj1uc1", { keyPath: "id" });
+      const _db = event.target.result;
+      const store1 = _db.createObjectStore("obj1uc1", { keyPath: "id" });
       store1.createIndex("name", "name", { unique: false });
       store1.createIndex("email", "email", { unique: true });
-      let store2 = db.createObjectStore("obj2uc1", { keyPath: "id2" });
+      _db.createObjectStore("obj2uc1", { keyPath: "id2" });
       store1.transaction.oncomplete = () => {
-        done(db);
+        done(_db);
       };
     };
   });
 
   // Prevents AbortError
   await new Promise(done => {
     request.onsuccess = done;
   });
 
-  let transaction = db.transaction(["obj1uc1", "obj2uc1"], "readwrite");
-  let store1 = transaction.objectStore("obj1uc1");
-  let store2 = transaction.objectStore("obj2uc1");
+  const transaction = db.transaction(["obj1uc1", "obj2uc1"], "readwrite");
+  const store1 = transaction.objectStore("obj1uc1");
+  const store2 = transaction.objectStore("obj2uc1");
   store1.add({id: 1, name: "foo", email: "foo@bar.com"});
   store1.add({id: 2, name: "foo2", email: "foo2@bar.com"});
   store1.add({id: 3, name: "foo2", email: "foo3@bar.com"});
   store2.add({
     id2: 1,
     name: "foo",
     email: "foo@bar.com",
     extra: "baz"
@@ -66,23 +66,23 @@ let idbGenerator = async function () {
   // Prevents AbortError during close()
   await new Promise(success => {
     transaction.oncomplete = success;
   });
 
   db.close();
 
   request = indexedDB.open("idb2uc1", 1);
-  let db2 = await new Promise(done => {
+  const db2 = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db2 = event.target.result;
-      let store3 = db2.createObjectStore("obj3uc1", { keyPath: "id3" });
+      const _db2 = event.target.result;
+      const store3 = _db2.createObjectStore("obj3uc1", { keyPath: "id3" });
       store3.createIndex("name2", "name2", { unique: true });
       store3.transaction.oncomplete = () => {
-        done(db2);
+        done(_db2);
       }
     };
   });
   // Prevents AbortError during close()
   await new Promise(done => {
     request.onsuccess = done;
   });
   db2.close();
@@ -93,22 +93,22 @@ let idbGenerator = async function () {
 function deleteDB(dbName) {
   return new Promise(resolve => {
     dump("removing database " + dbName + " from " + document.location + "\n");
     indexedDB.deleteDatabase(dbName).onsuccess = resolve;
   });
 }
 
 async function fetchPut(cache, url) {
-  let response = await fetch(url);
+  const response = await fetch(url);
   await cache.put(url, response);
 }
 
-let cacheGenerator = async function () {
-  let cache = await caches.open("plopuc1");
+const cacheGenerator = async function () {
+  const cache = await caches.open("plopuc1");
   await fetchPut(cache, "404_cached_file.js");
   await fetchPut(cache, "browser_storage_basic.js");
 };
 
 window.setup = async function () {
   await idbGenerator();
 
   if (window.caches) {
--- a/devtools/client/storage/test/storage-listings-with-fragment.html
+++ b/devtools/client/storage/test/storage-listings-with-fragment.html
@@ -10,58 +10,58 @@ include fragments e.g. http://example.co
   <meta charset="utf-8">
   <title>Storage inspector test for listing hosts and storages with URL fragments</title>
 </head>
 <body>
 <iframe src="http://sectest1.example.org/browser/devtools/client/storage/test/storage-unsecured-iframe.html#def"></iframe>
 <iframe src="https://sectest1.example.org:443/browser/devtools/client/storage/test/storage-secured-iframe.html#ghi"></iframe>
 <script type="application/javascript">
 "use strict";
-let partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
-let cookieExpiresTime1 = 2000000000000;
-let cookieExpiresTime2 = 2000000001000;
+const partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
+const cookieExpiresTime1 = 2000000000000;
+const cookieExpiresTime2 = 2000000001000;
 // Setting up some cookies to eat.
 document.cookie = "c1=foobar; expires=" +
   new Date(cookieExpiresTime1).toGMTString() + "; path=/browser";
 document.cookie = "cs2=sessionCookie; path=/; domain=" + partialHostname;
 document.cookie = "c3=foobar-2; expires=" +
   new Date(cookieExpiresTime2).toGMTString() + "; path=/";
 // ... and some local storage items ..
 localStorage.setItem("ls1", "foobar");
 localStorage.setItem("ls2", "foobar-2");
 // ... and finally some session storage items too
 sessionStorage.setItem("ss1", "foobar-3");
 dump("added cookies and storage from main page\n");
 
-let idbGenerator = async function () {
+const idbGenerator = async function () {
   let request = indexedDB.open("idb1", 1);
   request.onerror = function() {
     throw new Error("error opening db connection");
   };
-  let db = await new Promise(done => {
+  const db = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db = event.target.result;
-      let store1 = db.createObjectStore("obj1", { keyPath: "id" });
+      const _db = event.target.result;
+      const store1 = _db.createObjectStore("obj1", { keyPath: "id" });
       store1.createIndex("name", "name", { unique: false });
       store1.createIndex("email", "email", { unique: true });
-      let store2 = db.createObjectStore("obj2", { keyPath: "id2" });
+      _db.createObjectStore("obj2", { keyPath: "id2" }); // eslint-disable-line no-unused-vars
       store1.transaction.oncomplete = () => {
-        done(db);
+        done(_db);
       };
     };
   });
 
   // Prevents AbortError
   await new Promise(done => {
     request.onsuccess = done;
   });
 
-  let transaction = db.transaction(["obj1", "obj2"], "readwrite");
-  let store1 = transaction.objectStore("obj1");
-  let store2 = transaction.objectStore("obj2");
+  const transaction = db.transaction(["obj1", "obj2"], "readwrite");
+  const store1 = transaction.objectStore("obj1");
+  const store2 = transaction.objectStore("obj2");
   store1.add({id: 1, name: "foo", email: "foo@bar.com"});
   store1.add({id: 2, name: "foo2", email: "foo2@bar.com"});
   store1.add({id: 3, name: "foo2", email: "foo3@bar.com"});
   store2.add({
     id2: 1,
     name: "foo",
     email: "foo@bar.com",
     extra: "baz"
@@ -69,23 +69,23 @@ let idbGenerator = async function () {
   // Prevents AbortError during close()
   await new Promise(success => {
     transaction.oncomplete = success;
   });
 
   db.close();
 
   request = indexedDB.open("idb2", 1);
-  let db2 = await new Promise(done => {
+  const db2 = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db2 = event.target.result;
-      let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
+      const _db2 = event.target.result;
+      const store3 = _db2.createObjectStore("obj3", { keyPath: "id3" });
       store3.createIndex("name2", "name2", { unique: true });
       store3.transaction.oncomplete = () => {
-        done(db2);
+        done(_db2);
       }
     };
   });
   // Prevents AbortError during close()
   await new Promise(done => {
     request.onsuccess = done;
   });
   db2.close();
@@ -96,22 +96,22 @@ let idbGenerator = async function () {
 function deleteDB(dbName) {
   return new Promise(resolve => {
     dump("removing database " + dbName + " from " + document.location + "\n");
     indexedDB.deleteDatabase(dbName).onsuccess = resolve;
   });
 }
 
 async function fetchPut(cache, url) {
-  let response = await fetch(url);
+  const response = await fetch(url);
   await cache.put(url, response);
 }
 
-let cacheGenerator = async function () {
-  let cache = await caches.open("plop");
+const cacheGenerator = async function () {
+  const cache = await caches.open("plop");
   await fetchPut(cache, "404_cached_file.js");
   await fetchPut(cache, "browser_storage_basic.js");
 };
 
 window.setup = async function () {
   await idbGenerator();
 
   if (window.caches) {
--- a/devtools/client/storage/test/storage-listings.html
+++ b/devtools/client/storage/test/storage-listings.html
@@ -7,19 +7,19 @@ Storage inspector front end - tests
   <meta charset="utf-8">
   <title>Storage inspector test for listing hosts and storages</title>
 </head>
 <body>
 <iframe src="http://sectest1.example.org/browser/devtools/client/storage/test/storage-unsecured-iframe.html"></iframe>
 <iframe src="https://sectest1.example.org:443/browser/devtools/client/storage/test/storage-secured-iframe.html"></iframe>
 <script type="application/javascript">
 "use strict";
-let partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
-let cookieExpiresTime1 = 2000000000000;
-let cookieExpiresTime2 = 2000000001000;
+const partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
+const cookieExpiresTime1 = 2000000000000;
+const cookieExpiresTime2 = 2000000001000;
 // Setting up some cookies to eat.
 document.cookie = "c1=foobar; expires=" +
   new Date(cookieExpiresTime1).toGMTString() + "; path=/browser";
 document.cookie = "cs2=sessionCookie; path=/; domain=" + partialHostname;
 document.cookie = "c3=foobar-2; expires=" +
   new Date(cookieExpiresTime1).toGMTString() + "; path=/";
 document.cookie = "c4=foobar-3; expires=" +
   new Date(cookieExpiresTime2).toGMTString() + "; path=/; domain=" +
@@ -38,42 +38,42 @@ sessionStorage.setItem("ss1", "foobar-3"
 
 // Because sessionStorage contains key() on the prototype and it can't be
 // iterated using object.keys() we check the the value "key" exists.
 // See bug 1451991 for details.
 sessionStorage.setItem("key", "value2");
 
 dump("added cookies and storage from main page\n");
 
-let idbGenerator = async function () {
+const idbGenerator = async function () {
   let request = indexedDB.open("idb1", 1);
   request.onerror = function() {
     throw new Error("error opening db connection");
   };
-  let db = await new Promise(done => {
+  const db = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db = event.target.result;
-      let store1 = db.createObjectStore("obj1", { keyPath: "id" });
+      const _db = event.target.result;
+      const store1 = _db.createObjectStore("obj1", { keyPath: "id" });
       store1.createIndex("name", "name", { unique: false });
       store1.createIndex("email", "email", { unique: true });
-      let store2 = db.createObjectStore("obj2", { keyPath: "id2" });
+      _db.createObjectStore("obj2", { keyPath: "id2" }); // eslint-disable-line no-unused-vars
       store1.transaction.oncomplete = () => {
-        done(db);
+        done(_db);
       };
     };
   });
 
   // Prevents AbortError
   await new Promise(done => {
     request.onsuccess = done;
   });
 
-  let transaction = db.transaction(["obj1", "obj2"], "readwrite");
-  let store1 = transaction.objectStore("obj1");
-  let store2 = transaction.objectStore("obj2");
+  const transaction = db.transaction(["obj1", "obj2"], "readwrite");
+  const store1 = transaction.objectStore("obj1");
+  const store2 = transaction.objectStore("obj2");
   store1.add({id: 1, name: "foo", email: "foo@bar.com"});
   store1.add({id: 2, name: "foo2", email: "foo2@bar.com"});
   store1.add({id: 3, name: "foo2", email: "foo3@bar.com"});
   store2.add({
     id2: 1,
     name: "foo",
     email: "foo@bar.com",
     extra: "baz"
@@ -81,23 +81,23 @@ let idbGenerator = async function () {
   // Prevents AbortError during close()
   await new Promise(success => {
     transaction.oncomplete = success;
   });
 
   db.close();
 
   request = indexedDB.open("idb2", 1);
-  let db2 = await new Promise(done => {
+  const db2 = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db2 = event.target.result;
-      let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
+      const _db2 = event.target.result;
+      const store3 = _db2.createObjectStore("obj3", { keyPath: "id3" });
       store3.createIndex("name2", "name2", { unique: true });
       store3.transaction.oncomplete = () => {
-        done(db2);
+        done(_db2);
       }
     };
   });
   // Prevents AbortError during close()
   await new Promise(done => {
     request.onsuccess = done;
   });
   db2.close();
@@ -108,22 +108,22 @@ let idbGenerator = async function () {
 function deleteDB(dbName) {
   return new Promise(resolve => {
     dump("removing database " + dbName + " from " + document.location + "\n");
     indexedDB.deleteDatabase(dbName).onsuccess = resolve;
   });
 }
 
 async function fetchPut(cache, url) {
-  let response = await fetch(url);
+  const response = await fetch(url);
   await cache.put(url, response);
 }
 
-let cacheGenerator = async function () {
-  let cache = await caches.open("plop");
+const cacheGenerator = async function () {
+  const cache = await caches.open("plop");
   await fetchPut(cache, "404_cached_file.js");
   await fetchPut(cache, "browser_storage_basic.js");
 };
 
 window.setup = async function () {
   await idbGenerator();
 
   if (window.caches) {
--- a/devtools/client/storage/test/storage-localstorage.html
+++ b/devtools/client/storage/test/storage-localstorage.html
@@ -3,17 +3,17 @@
   <!--
   Bug 1231155 - Storage inspector front end - tests
   -->
   <head>
     <meta charset="utf-8" />
     <title>Storage inspector localStorage test</title>
     <script type="application/javascript">
       "use strict";
-
+      /* exported setup */
       function setup() {
         localStorage.setItem("TestLS1", "ValueLS1");
         localStorage.setItem("TestLS2", "ValueLS2");
         localStorage.setItem("TestLS3", "ValueLS3");
         localStorage.setItem("TestLS4", "ValueLS4");
         localStorage.setItem("TestLS5", "ValueLS5");
       }
     </script>
--- a/devtools/client/storage/test/storage-secured-iframe-usercontextid.html
+++ b/devtools/client/storage/test/storage-secured-iframe-usercontextid.html
@@ -9,62 +9,62 @@ Iframe for testing multiple host detetio
 <body>
 <script type="application/javascript">
 "use strict";
 document.cookie = "sc1uc1=foobar;";
 localStorage.setItem("iframe-s-ls1uc1", "foobar");
 sessionStorage.setItem("iframe-s-ss1uc1", "foobar-2");
 dump("added cookies and storage from secured iframe\n");
 
-let idbGenerator = async function () {
+const idbGenerator = async function () {
   let request = indexedDB.open("idb-s1uc1", 1);
   request.onerror = function() {
     throw new Error("error opening db connection");
   };
-  let db = await new Promise(done => {
+  const db = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db = event.target.result;
-      let store1 = db.createObjectStore("obj-s1uc1", { keyPath: "id" });
+      const _db = event.target.result;
+      const store1 = _db.createObjectStore("obj-s1uc1", { keyPath: "id" });
       store1.transaction.oncomplete = () => {
-        done(db);
+        done(_db);
       };
     };
   });
   await new Promise(done => {
     request.onsuccess = done;
   });
 
   let transaction = db.transaction(["obj-s1uc1"], "readwrite");
-  let store1 = transaction.objectStore("obj-s1uc1");
+  const store1 = transaction.objectStore("obj-s1uc1");
   store1.add({id: 6, name: "foo", email: "foo@bar.com"});
   store1.add({id: 7, name: "foo2", email: "foo2@bar.com"});
   await new Promise(success => {
     transaction.oncomplete = success;
   });
 
   db.close();
 
   request = indexedDB.open("idb-s2uc1", 1);
-  let db2 = await new Promise(done => {
+  const db2 = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db2 = event.target.result;
-      let store3 =
-        db2.createObjectStore("obj-s2uc1", { keyPath: "id3", autoIncrement: true });
+      const _db2 = event.target.result;
+      const store3 =
+        _db2.createObjectStore("obj-s2uc1", { keyPath: "id3", autoIncrement: true });
       store3.createIndex("name2", "name2", { unique: true });
       store3.transaction.oncomplete = () => {
-        done(db2);
+        done(_db2);
       };
     };
   });
   await new Promise(done => {
     request.onsuccess = done;
   });
 
   transaction = db2.transaction(["obj-s2uc1"], "readwrite");
-  let store3 = transaction.objectStore("obj-s2uc1");
+  const store3 = transaction.objectStore("obj-s2uc1");
   store3.add({id3: 16, name2: "foo", email: "foo@bar.com"});
   await new Promise(success => {
     transaction.oncomplete = success;
   });
 
   db2.close();
   dump("added indexedDB from secured iframe\n");
 };
--- a/devtools/client/storage/test/storage-secured-iframe.html
+++ b/devtools/client/storage/test/storage-secured-iframe.html
@@ -4,70 +4,70 @@
 Iframe for testing multiple host detetion in storage actor
 -->
 <head>
   <meta charset="utf-8">
 </head>
 <body>
 <script type="application/javascript">
 "use strict";
-let cookieExpiresTime = 2000000000000;
+const cookieExpiresTime = 2000000000000;
 document.cookie = "sc1=foobar;";
 document.cookie = "sc2=foobar-2; expires=" +
   new Date(cookieExpiresTime).toGMTString() + ";";
 localStorage.setItem("iframe-s-ls1", "foobar");
 sessionStorage.setItem("iframe-s-ss1", "foobar-2");
 dump("added cookies and storage from secured iframe\n");
 
-let idbGenerator = async function () {
+const idbGenerator = async function () {
   let request = indexedDB.open("idb-s1", 1);
   request.onerror = function() {
     throw new Error("error opening db connection");
   };
-  let db = await new Promise(done => {
+  const db = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db = event.target.result;
-      let store1 = db.createObjectStore("obj-s1", { keyPath: "id" });
+      const _db = event.target.result;
+      const store1 = _db.createObjectStore("obj-s1", { keyPath: "id" });
       store1.transaction.oncomplete = () => {
-        done(db);
+        done(_db);
       };
     };
   });
   await new Promise(done => {
     request.onsuccess = done;
   });
 
   let transaction = db.transaction(["obj-s1"], "readwrite");
-  let store1 = transaction.objectStore("obj-s1");
+  const store1 = transaction.objectStore("obj-s1");
   store1.add({id: 6, name: "foo", email: "foo@bar.com"});
   store1.add({id: 7, name: "foo2", email: "foo2@bar.com"});
   await new Promise(success => {
     transaction.oncomplete = success;
   });
 
   db.close();
 
   request = indexedDB.open("idb-s2", 1);
-  let db2 = await new Promise(done => {
+  const db2 = await new Promise(done => {
     request.onupgradeneeded = event => {
-      let db2 = event.target.result;
-      let store3 =
-        db2.createObjectStore("obj-s2", { keyPath: "id3", autoIncrement: true });
+      const _db2 = event.target.result;
+      const store3 =
+        _db2.createObjectStore("obj-s2", { keyPath: "id3", autoIncrement: true });
       store3.createIndex("name2", "name2", { unique: true });
       store3.transaction.oncomplete = () => {
-        done(db2);
+        done(_db2);
       };
     };
   });
   await new Promise(done => {
     request.onsuccess = done;
   });
 
   transaction = db2.transaction(["obj-s2"], "readwrite");
-  let store3 = transaction.objectStore("obj-s2");
+  const store3 = transaction.objectStore("obj-s2");
   store3.add({id3: 16, name2: "foo", email: "foo@bar.com"});
   await new Promise(success => {
     transaction.oncomplete = success;
   });
 
   db2.close();
   dump("added indexedDB from secured iframe\n");
 };
--- a/devtools/client/storage/test/storage-sessionstorage.html
+++ b/devtools/client/storage/test/storage-sessionstorage.html
@@ -3,17 +3,17 @@
   <!--
   Bug 1231179 - Storage inspector front end - tests
   -->
   <head>
     <meta charset="utf-8" />
     <title>Storage inspector sessionStorage test</title>
     <script type="application/javascript">
       "use strict";
-
+      /* exported setup */
       function setup() {
         sessionStorage.setItem("TestSS1", "ValueSS1");
         sessionStorage.setItem("TestSS2", "ValueSS2");
         sessionStorage.setItem("TestSS3", "ValueSS3");
         sessionStorage.setItem("TestSS4", "ValueSS4");
         sessionStorage.setItem("TestSS5", "ValueSS5");
       }
     </script>
--- a/devtools/client/storage/test/storage-sidebar-parsetree.html
+++ b/devtools/client/storage/test/storage-sidebar-parsetree.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8" />
     <title>Storage inspector sidebar parsetree test</title>
     <script type="application/javascript">
       "use strict";
-
+      /* exported setup */
       function setup() {
         // These values should not be parsed into a tree.
         localStorage.setItem("base64", "aGVsbG93b3JsZA==");
         localStorage.setItem("boolean", "true");
         localStorage.setItem("color", "#ff0034");
         localStorage.setItem("dataURI", "data:,Hello World!");
         localStorage.setItem("date", "2009-05-19 14:39:22-01");
         localStorage.setItem("email", "foo@bar.co.uk");
--- a/devtools/client/storage/test/storage-updates.html
+++ b/devtools/client/storage/test/storage-updates.html
@@ -41,18 +41,18 @@ window.clear = function() {
   localStorage.clear();
   dump("removed localStorage from " + document.location + "\n");
 
   sessionStorage.clear();
   dump("removed sessionStorage from " + document.location + "\n");
 };
 
 window.onload = function() {
-  addCookie("c1", "1.2.3.4.5.6.7", "/browser");
-  addCookie("c2", "foobar", "/browser");
+  window.addCookie("c1", "1.2.3.4.5.6.7", "/browser");
+  window.addCookie("c2", "foobar", "/browser");
 
   // Some keys have to be set to strings that JSON.parse can parse successfully
   // instead of throwings (to verify the issue fixed by Bug 1578447 doesn't regress).
   localStorage.setItem("1", "testing");
   localStorage.setItem("2", "testing");
   localStorage.setItem("3", "testing");
   localStorage.setItem("4", "testing");
   localStorage.setItem("5", "testing");
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -828,16 +828,17 @@ uint32_t Navigator::MaxTouchPoints(Calle
 
 void Navigator::RegisterContentHandler(const nsAString& aMIMEType,
                                        const nsAString& aURI,
                                        const nsAString& aTitle,
                                        ErrorResult& aRv) {}
 
 // This list should be kept up-to-date with the spec:
 // https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers
+// If you change this list, please also update the copy in E10SUtils.jsm.
 static const char* const kSafeSchemes[] = {
     "bitcoin", "geo",  "im",   "irc",         "ircs", "magnet", "mailto",
     "mms",     "news", "nntp", "openpgp4fpr", "sip",  "sms",    "smsto",
     "ssh",     "tel",  "urn",  "webcal",      "wtai", "xmpp"};
 
 void Navigator::CheckProtocolHandlerAllowed(const nsAString& aScheme,
                                             nsIURI* aHandlerURI,
                                             nsIURI* aDocumentURI,
--- a/dom/base/nsDeprecatedOperationList.h
+++ b/dom/base/nsDeprecatedOperationList.h
@@ -46,10 +46,11 @@ DEPRECATED_OPERATION(Mozfullscreenchange
 DEPRECATED_OPERATION(MozfullscreenerrorDeprecatedPrefix)
 DEPRECATED_OPERATION(External_AddSearchProvider)
 DEPRECATED_OPERATION(MouseEvent_MozPressure)
 DEPRECATED_OPERATION(MathML_DeprecatedAlignmentAttributes)
 DEPRECATED_OPERATION(MathML_DeprecatedLineThicknessValue)
 DEPRECATED_OPERATION(MathML_DeprecatedMathSizeValue)
 DEPRECATED_OPERATION(MathML_DeprecatedMathSpaceValue)
 DEPRECATED_OPERATION(MathML_DeprecatedMencloseNotationRadical)
+DEPRECATED_OPERATION(MathML_DeprecatedScriptShiftAttributes)
 DEPRECATED_OPERATION(MathML_DeprecatedStyleAttribute)
 DEPRECATED_OPERATION(MathML_DeprecatedXLinkAttribute)
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -741,16 +741,21 @@ class nsINode : public mozilla::dom::Eve
   }
 
   bool IsShadowRoot() const {
     const bool isShadowRoot = IsInShadowTree() && !GetParentNode();
     MOZ_ASSERT_IF(isShadowRoot, IsDocumentFragment());
     return isShadowRoot;
   }
 
+  bool IsHTMLHeadingElement() const {
+    return IsAnyOfHTMLElements(nsGkAtoms::h1, nsGkAtoms::h2, nsGkAtoms::h3,
+                               nsGkAtoms::h4, nsGkAtoms::h5, nsGkAtoms::h6);
+  }
+
   /**
    * Insert a content node before another or at the end.
    * This method handles calling BindToTree on the child appropriately.
    *
    * @param aKid the content to insert
    * @param aBeforeThis an existing node. Use nullptr if you want to
    *        add aKid at the end.
    * @param aNotify whether to notify the document (current document for
--- a/dom/html/HTMLHeadingElement.cpp
+++ b/dom/html/HTMLHeadingElement.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLHeadingElement.h"
 #include "mozilla/dom/HTMLHeadingElementBinding.h"
 
 #include "mozilla/MappedDeclarations.h"
+#include "mozilla/StaticPrefs_accessibility.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsMappedAttributes.h"
 #include "mozAutoDocUpdate.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Heading)
 
 namespace mozilla {
@@ -22,16 +23,45 @@ HTMLHeadingElement::~HTMLHeadingElement(
 
 NS_IMPL_ELEMENT_CLONE(HTMLHeadingElement)
 
 JSObject* HTMLHeadingElement::WrapNode(JSContext* aCx,
                                        JS::Handle<JSObject*> aGivenProto) {
   return HTMLHeadingElement_Binding::Wrap(aCx, this, aGivenProto);
 }
 
+int32_t HTMLHeadingElement::AccessibilityLevel() const {
+  int32_t level = BaseAccessibilityLevel();
+  if (!StaticPrefs::accessibility_heading_element_level_changes_enabled()) {
+    return level;
+  }
+
+  // What follows is an implementation of
+  // the proposal in https://github.com/whatwg/html/issues/5002.
+  //
+  // FIXME(emilio): Should this really use the light tree rather than the flat
+  // tree?
+  nsAtom* name = NodeInfo()->NameAtom();
+  nsINode* parent = GetParentNode();
+  const bool considerAncestors =
+      name == nsGkAtoms::h1 ||
+      (parent && parent->IsHTMLElement(nsGkAtoms::hgroup));
+  if (!considerAncestors) {
+    return level;
+  }
+
+  for (; parent; parent = parent->GetParentNode()) {
+    if (parent->IsAnyOfHTMLElements(nsGkAtoms::section, nsGkAtoms::article,
+                                    nsGkAtoms::aside, nsGkAtoms::nav)) {
+      level++;
+    }
+  }
+  return level;
+}
+
 bool HTMLHeadingElement::ParseAttribute(int32_t aNamespaceID,
                                         nsAtom* aAttribute,
                                         const nsAString& aValue,
                                         nsIPrincipal* aMaybeScriptedPrincipal,
                                         nsAttrValue& aResult) {
   if (aAttribute == nsGkAtoms::align && aNamespaceID == kNameSpaceID_None) {
     return ParseDivAlignValue(aValue, aResult);
   }
--- a/dom/html/HTMLHeadingElement.h
+++ b/dom/html/HTMLHeadingElement.h
@@ -12,38 +12,64 @@
 
 namespace mozilla {
 namespace dom {
 
 class HTMLHeadingElement final : public nsGenericHTMLElement {
  public:
   explicit HTMLHeadingElement(
       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
-      : nsGenericHTMLElement(std::move(aNodeInfo)) {}
+      : nsGenericHTMLElement(std::move(aNodeInfo)) {
+    MOZ_ASSERT(IsHTMLHeadingElement());
+  }
 
-  virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
-                              const nsAString& aValue,
-                              nsIPrincipal* aMaybeScriptedPrincipal,
-                              nsAttrValue& aResult) override;
+  bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
+                      const nsAString& aValue,
+                      nsIPrincipal* aMaybeScriptedPrincipal,
+                      nsAttrValue& aResult) override;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
   nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
-  virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
+  nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
 
   void SetAlign(const nsAString& aAlign, ErrorResult& aError) {
     return SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
   }
   void GetAlign(DOMString& aAlign) const {
     return GetHTMLAttr(nsGkAtoms::align, aAlign);
   }
 
+  int32_t AccessibilityLevel() const;
+
+  int32_t BaseAccessibilityLevel() const {
+    nsAtom* name = NodeInfo()->NameAtom();
+    if (name == nsGkAtoms::h1) {
+      return 1;
+    }
+    if (name == nsGkAtoms::h2) {
+      return 2;
+    }
+    if (name == nsGkAtoms::h3) {
+      return 3;
+    }
+    if (name == nsGkAtoms::h4) {
+      return 4;
+    }
+    if (name == nsGkAtoms::h5) {
+      return 5;
+    }
+    MOZ_ASSERT(name == nsGkAtoms::h6);
+    return 6;
+  }
+
+  NS_IMPL_FROMNODE_HELPER(HTMLHeadingElement, IsHTMLHeadingElement())
+
  protected:
   virtual ~HTMLHeadingElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx,
-                             JS::Handle<JSObject*> aGivenProto) override;
+  JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
 
  private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     MappedDeclarations&);
 };
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -370,14 +370,16 @@ MathML_DeprecatedAlignmentAttributesWarning=MathML attributes “align”, “numalign” and “denomalign” are deprecated values and will be removed at a future date.
 MathML_DeprecatedLineThicknessValueWarning=“thin”, “medium” and “thick” are deprecated values for the linethickness attribute and will be removed at a future date.
 # LOCALIZATION NOTE: Do not translate small, normal, big and mathsize.
 MathML_DeprecatedMathSizeValueWarning=“small”, “normal” and “big” are deprecated values for the mathsize attribute and will be removed at a future date.
 # LOCALIZATION NOTE: Do not translate veryverythinmathspace, verythinmathspace,
 # thinmathspace, mediummathspace, thickmathspace, verythickmathspace, veryverythickmathspace and MathML.
 MathML_DeprecatedMathSpaceValueWarning=“veryverythinmathspace”, “verythinmathspace”, “thinmathspace”, “mediummathspace”, “thickmathspace”, “verythickmathspace” and “veryverythickmathspace” are deprecated values for MathML lengths and will be removed at a future date.
 # LOCALIZATION NOTE: Do not translate radical, notation and menclose.
 MathML_DeprecatedMencloseNotationRadical=The “radical” value is deprecated for the “notation” attribute of the <menclose> element and will be removed at a future date.
+# LOCALIZATION NOTE: Do not translate MathML, subscriptshift and superscriptshift.
+MathML_DeprecatedScriptShiftAttributes=MathML attributes “subscriptshift” and “superscriptshift” are deprecated and may be removed at a future date.
 # LOCALIZATION NOTE: Do not translate MathML, background, color, fontfamily, fontsize, fontstyle and fontweight.
 MathML_DeprecatedStyleAttributeWarning=MathML attributes “background”, “color”, “fontfamily”, “fontsize”, “fontstyle” and “fontweight” are deprecated and will be removed at a future date.
 # LOCALIZATION NOTE: Do not translate MathML and XLink.
 MathML_DeprecatedXLinkAttributeWarning=XLink attributes “href”, “type”, “show” and “actuate” are deprecated on MathML elements and will be removed at a future date.
 # LOCALIZATION NOTE: Do not translate title, text, url as they are the names of JS properties.
 WebShareAPI_NeedOneMember=title or text or url member of the ShareData dictionary. At least one of the members is required.
--- a/dom/media/systemservices/video_engine/platform_uithread.cc
+++ b/dom/media/systemservices/video_engine/platform_uithread.cc
@@ -85,22 +85,22 @@ void PlatformUIThread::Stop() {
 
   hwnd_ = NULL;
 
   PlatformThread::Stop();
 }
 
 void PlatformUIThread::Run() {
   RTC_CHECK(InternalInit());  // always evaluates
+  // The interface contract of Start/Stop is that for a successful call to
+  // Start, there should be at least one call to the run function.  So we
+  // call the function before checking |stop_|.
+  run_function_deprecated_(obj_);
+
   do {
-    // The interface contract of Start/Stop is that for a successful call to
-    // Start, there should be at least one call to the run function.  So we
-    // call the function before checking |stop_|.
-    run_function_deprecated_(obj_);
-
     // Alertable sleep to permit RaiseFlag to run and update |stop_|.
     if (MsgWaitForMultipleObjectsEx(0, nullptr, INFINITE, QS_ALLINPUT,
                                     MWMO_ALERTABLE | MWMO_INPUTAVAILABLE) ==
         WAIT_OBJECT_0) {
       MSG msg;
       if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
         if (msg.message == WM_QUIT) {
           stop_ = true;
--- a/dom/webgpu/thread/WebGPUThreading.cpp
+++ b/dom/webgpu/thread/WebGPUThreading.cpp
@@ -7,22 +7,19 @@
 #include "WebGPUThreading.h"
 #include "mtransport/runnable_utils.h"
 
 namespace mozilla {
 namespace webgpu {
 
 static StaticRefPtr<WebGPUThreading> sWebGPUThread;
 
-WebGPUThreading::WebGPUThreading(base::Thread* aThread)
-: mThread(aThread) {}
+WebGPUThreading::WebGPUThreading(base::Thread* aThread) : mThread(aThread) {}
 
-WebGPUThreading::~WebGPUThreading() {
-  delete mThread;
-}
+WebGPUThreading::~WebGPUThreading() { delete mThread; }
 
 // static
 void WebGPUThreading::Start() {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!sWebGPUThread);
 
   base::Thread* thread = new base::Thread("WebGPU");
 
@@ -30,35 +27,35 @@ void WebGPUThreading::Start() {
   if (!thread->StartWithOptions(options)) {
     delete thread;
     return;
   }
 
   sWebGPUThread = new WebGPUThreading(thread);
   const auto fnInit = []() {};
 
-  RefPtr<Runnable> runnable = NS_NewRunnableFunction(
-    "WebGPUThreading fnInit", fnInit);
+  RefPtr<Runnable> runnable =
+      NS_NewRunnableFunction("WebGPUThreading fnInit", fnInit);
   sWebGPUThread->GetLoop()->PostTask(runnable.forget());
 }
 
 // static
 void WebGPUThreading::ShutDown() {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(sWebGPUThread);
 
-  const auto fnExit = []() {
-  };
+  const auto fnExit = []() {};
 
-  RefPtr<Runnable> runnable = NS_NewRunnableFunction(
-    "WebGPUThreading fnExit", fnExit);
+  RefPtr<Runnable> runnable =
+      NS_NewRunnableFunction("WebGPUThreading fnExit", fnExit);
   sWebGPUThread->GetLoop()->PostTask(runnable.forget());
 
   sWebGPUThread = nullptr;
 }
 
 // static
 MessageLoop* WebGPUThreading::GetLoop() {
+  MOZ_ASSERT(NS_IsMainThread());
   return sWebGPUThread ? sWebGPUThread->mThread->message_loop() : nullptr;
 }
 
 }  // namespace webgpu
 }  // namespace mozilla
--- a/dom/webgpu/thread/WebGPUThreading.h
+++ b/dom/webgpu/thread/WebGPUThreading.h
@@ -3,39 +3,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_WEBGPU_THREADING_H
 #define MOZILLA_WEBGPU_THREADING_H
 
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
-#include "base/thread.h"           // for Thread
+#include "base/thread.h"  // for Thread
 #include "mozilla/layers/SynchronousTask.h"
 
 namespace mozilla {
 namespace webgpu {
 
 class WebGPUThreading final {
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(WebGPUThreading)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(
+      WebGPUThreading)
 
-public:
+ public:
   /// Can only be called from the main thread.
   static void Start();
 
   /// Can only be called from the main thread.
   static void ShutDown();
 
   /// Can be called from any thread. Returns `nullptr` if
   /// the threading is not initialized.
   static MessageLoop* GetLoop();
 
-private:
+ private:
   explicit WebGPUThreading(base::Thread* aThread);
   ~WebGPUThreading();
 
   base::Thread* const mThread;
 };
 
-}
-}
+}  // namespace webgpu
+}  // namespace mozilla
 
-#endif // MOZILLA_WEBGPU_THREADING_H
+#endif  // MOZILLA_WEBGPU_THREADING_H
--- a/js/public/Class.h
+++ b/js/public/Class.h
@@ -577,17 +577,17 @@ typedef JSObject* (*ClassObjectCreationO
 
 /**
  * Callback for custom post-processing after class initialization via
  * ClassSpec.
  */
 typedef bool (*FinishClassInitOp)(JSContext* cx, JS::HandleObject ctor,
                                   JS::HandleObject proto);
 
-const size_t JSCLASS_CACHED_PROTO_WIDTH = 6;
+const size_t JSCLASS_CACHED_PROTO_WIDTH = 7;
 
 struct MOZ_STATIC_CLASS ClassSpec {
   ClassObjectCreationOp createConstructor;
   ClassObjectCreationOp createPrototype;
   const JSFunctionSpec* constructorFunctions;
   const JSPropertySpec* constructorProperties;
   const JSFunctionSpec* prototypeFunctions;
   const JSPropertySpec* prototypeProperties;
@@ -637,34 +637,34 @@ struct MOZ_STATIC_CLASS ClassExtension {
    * tenured bytes used, which may be nonzero e.g. if some nursery-allocated
    * data beyond the actual GC thing is moved into malloced memory.
    *
    * This is used to compute the nursery promotion rate.
    */
   JSObjectMovedOp objectMovedOp;
 };
 
-#define JS_NULL_CLASS_SPEC nullptr
-#define JS_NULL_CLASS_EXT nullptr
-
 struct MOZ_STATIC_CLASS ObjectOps {
   LookupPropertyOp lookupProperty;
   DefinePropertyOp defineProperty;
   HasPropertyOp hasProperty;
   GetPropertyOp getProperty;
   SetPropertyOp setProperty;
   GetOwnPropertyOp getOwnPropertyDescriptor;
   DeletePropertyOp deleteProperty;
   GetElementsOp getElements;
   JSFunToStringOp funToString;
 };
 
-#define JS_NULL_OBJECT_OPS nullptr
+}  // namespace js
 
-}  // namespace js
+static constexpr const js::ClassSpec* JS_NULL_CLASS_SPEC = nullptr;
+static constexpr const js::ClassExtension* JS_NULL_CLASS_EXT = nullptr;
+
+static constexpr const js::ObjectOps* JS_NULL_OBJECT_OPS = nullptr;
 
 // Classes, objects, and properties.
 
 // Objects have private slot.
 static const uint32_t JSCLASS_HAS_PRIVATE = 1 << 0;
 
 // Class's initialization code will call `SetNewObjectMetadata` itself.
 static const uint32_t JSCLASS_DELAY_METADATA_BUILDER = 1 << 1;
@@ -698,46 +698,42 @@ static const uint32_t JSCLASS_USERBIT1 =
 // Room for 8 flags below ...
 static const uintptr_t JSCLASS_RESERVED_SLOTS_SHIFT = 8;
 // ... and 16 above this field.
 static const uint32_t JSCLASS_RESERVED_SLOTS_WIDTH = 8;
 
 static const uint32_t JSCLASS_RESERVED_SLOTS_MASK =
     JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH);
 
-#define JSCLASS_HAS_RESERVED_SLOTS(n) \
-  (((n)&JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT)
-#define JSCLASS_RESERVED_SLOTS(clasp)                 \
-  (((clasp)->flags >> JSCLASS_RESERVED_SLOTS_SHIFT) & \
-   JSCLASS_RESERVED_SLOTS_MASK)
+static constexpr uint32_t JSCLASS_HAS_RESERVED_SLOTS(uint32_t n) {
+  return (n & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT;
+}
 
-#define JSCLASS_HIGH_FLAGS_SHIFT \
-  (JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH)
+static constexpr uint32_t JSCLASS_HIGH_FLAGS_SHIFT =
+    JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH;
 
 static const uint32_t JSCLASS_INTERNAL_FLAG1 =
     1 << (JSCLASS_HIGH_FLAGS_SHIFT + 0);
 static const uint32_t JSCLASS_IS_GLOBAL = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 1);
 static const uint32_t JSCLASS_INTERNAL_FLAG2 =
     1 << (JSCLASS_HIGH_FLAGS_SHIFT + 2);
-static const uint32_t JSCLASS_INTERNAL_FLAG3 =
-    1 << (JSCLASS_HIGH_FLAGS_SHIFT + 3);
-static const uint32_t JSCLASS_IS_PROXY = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 4);
+static const uint32_t JSCLASS_IS_PROXY = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 3);
 static const uint32_t JSCLASS_SKIP_NURSERY_FINALIZE =
-    1 << (JSCLASS_HIGH_FLAGS_SHIFT + 5);
+    1 << (JSCLASS_HIGH_FLAGS_SHIFT + 4);
 
 // Reserved for embeddings.
-static const uint32_t JSCLASS_USERBIT2 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 6);
-static const uint32_t JSCLASS_USERBIT3 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 7);
+static const uint32_t JSCLASS_USERBIT2 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 5);
+static const uint32_t JSCLASS_USERBIT3 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 6);
 
 static const uint32_t JSCLASS_BACKGROUND_FINALIZE =
-    1 << (JSCLASS_HIGH_FLAGS_SHIFT + 8);
+    1 << (JSCLASS_HIGH_FLAGS_SHIFT + 7);
 static const uint32_t JSCLASS_FOREGROUND_FINALIZE =
-    1 << (JSCLASS_HIGH_FLAGS_SHIFT + 9);
+    1 << (JSCLASS_HIGH_FLAGS_SHIFT + 8);
 
-// Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see
+// Bits 25 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see
 // below.
 
 // ECMA-262 requires that most constructors used internally create objects
 // with "the original Foo.prototype value" as their [[Prototype]] (__proto__)
 // member initial value.  The "original ... value" verbiage is there because
 // in ECMA-262, global properties naming class objects are read/write and
 // deleteable, for the most part.
 //
@@ -745,54 +741,54 @@ static const uint32_t JSCLASS_FOREGROUND
 // with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was
 // previously allowed, but is now an ES5 violation and thus unsupported.
 //
 // JSCLASS_GLOBAL_APPLICATION_SLOTS is the number of slots reserved at
 // the beginning of every global object's slots for use by the
 // application.
 static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5;
 static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT =
-    JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 40;
+    JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 26;
 
-#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
-  (JSCLASS_IS_GLOBAL |                     \
-   JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
-#define JSCLASS_GLOBAL_FLAGS JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0)
-#define JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(clasp) \
-  (((clasp)->flags & JSCLASS_IS_GLOBAL) &&       \
-   JSCLASS_RESERVED_SLOTS(clasp) >= JSCLASS_GLOBAL_SLOT_COUNT)
+static constexpr uint32_t JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(uint32_t n) {
+  return JSCLASS_IS_GLOBAL |
+         JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + n);
+}
+
+static constexpr uint32_t JSCLASS_GLOBAL_FLAGS =
+    JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0);
 
 // Fast access to the original value of each standard class's prototype.
-static const uint32_t JSCLASS_CACHED_PROTO_SHIFT =
-    JSCLASS_HIGH_FLAGS_SHIFT + 10;
+static const uint32_t JSCLASS_CACHED_PROTO_SHIFT = JSCLASS_HIGH_FLAGS_SHIFT + 9;
 static const uint32_t JSCLASS_CACHED_PROTO_MASK =
     JS_BITMASK(js::JSCLASS_CACHED_PROTO_WIDTH);
 
-#define JSCLASS_HAS_CACHED_PROTO(key) \
-  (uint32_t(key) << JSCLASS_CACHED_PROTO_SHIFT)
-#define JSCLASS_CACHED_PROTO_KEY(clasp)                          \
-  ((JSProtoKey)(((clasp)->flags >> JSCLASS_CACHED_PROTO_SHIFT) & \
-                JSCLASS_CACHED_PROTO_MASK))
+static_assert(JSProto_LIMIT <= (JSCLASS_CACHED_PROTO_MASK + 1),
+              "JSProtoKey must not exceed the maximum cacheable proto-mask");
+
+static constexpr uint32_t JSCLASS_HAS_CACHED_PROTO(JSProtoKey key) {
+  return uint32_t(key) << JSCLASS_CACHED_PROTO_SHIFT;
+}
 
 struct MOZ_STATIC_CLASS JSClassOps {
   /* Function pointer members (may be null). */
   JSAddPropertyOp addProperty;
   JSDeletePropertyOp delProperty;
   JSEnumerateOp enumerate;
   JSNewEnumerateOp newEnumerate;
   JSResolveOp resolve;
   JSMayResolveOp mayResolve;
   JSFinalizeOp finalize;
   JSNative call;
   JSHasInstanceOp hasInstance;
   JSNative construct;
   JSTraceOp trace;
 };
 
-#define JS_NULL_CLASS_OPS nullptr
+static constexpr const JSClassOps* JS_NULL_CLASS_OPS = nullptr;
 
 struct JSClass {
   const char* name;
   uint32_t flags;
   const JSClassOps* cOps;
 
   const js::ClassSpec* spec;
   const js::ClassExtension* ext;
@@ -934,16 +930,31 @@ struct JSClass {
   js::GetElementsOp getOpsGetElements() const {
     return oOps ? oOps->getElements : nullptr;
   }
   JSFunToStringOp getOpsFunToString() const {
     return oOps ? oOps->funToString : nullptr;
   }
 };
 
+static constexpr uint32_t JSCLASS_RESERVED_SLOTS(const JSClass* clasp) {
+  return (clasp->flags >> JSCLASS_RESERVED_SLOTS_SHIFT) &
+         JSCLASS_RESERVED_SLOTS_MASK;
+}
+
+static constexpr bool JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(const JSClass* clasp) {
+  return (clasp->flags & JSCLASS_IS_GLOBAL) &&
+         JSCLASS_RESERVED_SLOTS(clasp) >= JSCLASS_GLOBAL_SLOT_COUNT;
+}
+
+static constexpr JSProtoKey JSCLASS_CACHED_PROTO_KEY(const JSClass* clasp) {
+  return JSProtoKey((clasp->flags >> JSCLASS_CACHED_PROTO_SHIFT) &
+                    JSCLASS_CACHED_PROTO_MASK);
+}
+
 namespace js {
 
 /**
  * Enumeration describing possible values of the [[Class]] internal property
  * value of objects.
  */
 enum class ESClass {
   Object,
--- a/js/public/ProtoKey.h
+++ b/js/public/ProtoKey.h
@@ -96,25 +96,35 @@
   REAL(Proxy, InitProxyClass, &js::ProxyClass)                               \
   REAL(WeakMap, InitViaClassSpec, OCLASP(WeakMap))                           \
   REAL(Map, InitViaClassSpec, OCLASP(Map))                                   \
   REAL(Set, InitViaClassSpec, OCLASP(Set))                                   \
   REAL(DataView, InitViaClassSpec, OCLASP(DataView))                         \
   REAL(Symbol, InitSymbolClass, OCLASP(Symbol))                              \
   REAL(SharedArrayBuffer, InitViaClassSpec, OCLASP(SharedArrayBuffer))       \
   REAL_IF_INTL(Intl, InitIntlClass, CLASP(Intl))                             \
+  REAL_IF_INTL(Collator, InitViaClassSpec, OCLASP(Collator))                 \
+  REAL_IF_INTL(DateTimeFormat, InitViaClassSpec, OCLASP(DateTimeFormat))     \
+  REAL_IF_INTL(Locale, InitViaClassSpec, OCLASP(Locale))                     \
+  REAL_IF_INTL(NumberFormat, InitViaClassSpec, OCLASP(NumberFormat))         \
+  REAL_IF_INTL(PluralRules, InitViaClassSpec, OCLASP(PluralRules))           \
+  REAL_IF_INTL(RelativeTimeFormat, InitViaClassSpec,                         \
+               OCLASP(RelativeTimeFormat))                                   \
   REAL_IF_BDATA(TypedObject, InitTypedObjectModuleObject,                    \
                 OCLASP(TypedObjectModule))                                   \
   REAL(Reflect, InitReflect, nullptr)                                        \
   REAL(WeakSet, InitViaClassSpec, OCLASP(WeakSet))                           \
   REAL(TypedArray, InitViaClassSpec,                                         \
        &js::TypedArrayObject::sharedTypedArrayPrototypeClass)                \
   REAL(Atomics, InitAtomicsClass, OCLASP(Atomics))                           \
   REAL(SavedFrame, InitViaClassSpec, &js::SavedFrame::class_)                \
   REAL(Promise, InitViaClassSpec, OCLASP(Promise))                           \
+  REAL(AsyncFunction, InitAsyncFunction, nullptr)                            \
+  REAL(GeneratorFunction, InitGeneratorFunction, nullptr)                    \
+  REAL(AsyncGeneratorFunction, InitAsyncGeneratorFunction, nullptr)          \
   REAL(ReadableStream, InitViaClassSpec, &js::ReadableStream::class_)        \
   REAL(ReadableStreamDefaultReader, InitViaClassSpec,                        \
        &js::ReadableStreamDefaultReader::class_)                             \
   REAL(ReadableStreamDefaultController, InitViaClassSpec,                    \
        &js::ReadableStreamDefaultController::class_)                         \
   REAL(ReadableByteStreamController, InitViaClassSpec,                       \
        &js::ReadableByteStreamController::class_)                            \
   REAL(WritableStream, InitViaClassSpec, &js::WritableStream::class_)        \
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -2114,17 +2114,17 @@ static bool PromiseConstructor(JSContext
     JSObject* unwrappedNewTarget = CheckedUnwrapStatic(newTarget);
     MOZ_ASSERT(unwrappedNewTarget);
     MOZ_ASSERT(unwrappedNewTarget != newTarget);
 
     newTarget = unwrappedNewTarget;
     {
       AutoRealm ar(cx, newTarget);
       Handle<GlobalObject*> global = cx->global();
-      JSFunction* promiseCtor =
+      JSObject* promiseCtor =
           GlobalObject::getOrCreatePromiseConstructor(cx, global);
       if (!promiseCtor) {
         return false;
       }
 
       // Promise subclasses don't get the special Xray treatment, so
       // we only need to do the complex wrapping and unwrapping scheme
       // described above for instances of Promise itself.
--- a/js/src/builtin/intl/Collator.cpp
+++ b/js/src/builtin/intl/Collator.cpp
@@ -47,18 +47,21 @@ const JSClassOps CollatorObject::classOp
                                               nullptr, /* newEnumerate */
                                               nullptr, /* resolve */
                                               nullptr, /* mayResolve */
                                               CollatorObject::finalize};
 
 const JSClass CollatorObject::class_ = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(CollatorObject::SLOT_COUNT) |
+        JSCLASS_HAS_CACHED_PROTO(JSProto_Collator) |
         JSCLASS_FOREGROUND_FINALIZE,
-    &CollatorObject::classOps_};
+    &CollatorObject::classOps_, &CollatorObject::classSpec_};
+
+const JSClass& CollatorObject::protoClass_ = PlainObject::class_;
 
 static bool collator_toSource(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   args.rval().setString(cx->names().Collator);
   return true;
 }
 
 static const JSFunctionSpec collator_static_methods[] = {
@@ -69,39 +72,44 @@ static const JSFunctionSpec collator_sta
 static const JSFunctionSpec collator_methods[] = {
     JS_SELF_HOSTED_FN("resolvedOptions", "Intl_Collator_resolvedOptions", 0, 0),
     JS_FN(js_toSource_str, collator_toSource, 0, 0), JS_FS_END};
 
 static const JSPropertySpec collator_properties[] = {
     JS_SELF_HOSTED_GET("compare", "$Intl_Collator_compare_get", 0),
     JS_STRING_SYM_PS(toStringTag, "Object", JSPROP_READONLY), JS_PS_END};
 
+static bool Collator(JSContext* cx, unsigned argc, Value* vp);
+
+const ClassSpec CollatorObject::classSpec_ = {
+    GenericCreateConstructor<Collator, 0, gc::AllocKind::FUNCTION>,
+    GenericCreatePrototype<CollatorObject>,
+    collator_static_methods,
+    nullptr,
+    collator_methods,
+    collator_properties,
+    nullptr,
+    ClassSpec::DontDefineConstructor};
+
 /**
  * 10.1.2 Intl.Collator([ locales [, options]])
  *
  * ES2017 Intl draft rev 94045d234762ad107a3d09bb6f7381a65f1a2f9b
  */
 static bool Collator(JSContext* cx, const CallArgs& args) {
   // Step 1 (Handled by OrdinaryCreateFromConstructor fallback code).
 
   // Steps 2-5 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
   RootedObject proto(cx);
-  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_Null, &proto)) {
+  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_Collator, &proto)) {
     return false;
   }
 
-  if (!proto) {
-    proto = GlobalObject::getOrCreateCollatorPrototype(cx, cx->global());
-    if (!proto) {
-      return false;
-    }
-  }
-
   Rooted<CollatorObject*> collator(
-      cx, NewObjectWithGivenProto<CollatorObject>(cx, proto));
+      cx, NewObjectWithClassProto<CollatorObject>(cx, proto));
   if (!collator) {
     return false;
   }
 
   HandleValue locales = args.get(0);
   HandleValue options = args.get(1);
 
   // Step 6.
@@ -130,58 +138,16 @@ bool js::intl_Collator(JSContext* cx, un
 void js::CollatorObject::finalize(JSFreeOp* fop, JSObject* obj) {
   MOZ_ASSERT(fop->onMainThread());
 
   if (UCollator* coll = obj->as<CollatorObject>().getCollator()) {
     ucol_close(coll);
   }
 }
 
-JSObject* js::CreateCollatorPrototype(JSContext* cx, HandleObject Intl,
-                                      Handle<GlobalObject*> global) {
-  RootedFunction ctor(cx, GlobalObject::createConstructor(
-                              cx, &Collator, cx->names().Collator, 0));
-  if (!ctor) {
-    return nullptr;
-  }
-
-  RootedObject proto(
-      cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
-  if (!proto) {
-    return nullptr;
-  }
-
-  if (!LinkConstructorAndPrototype(cx, ctor, proto)) {
-    return nullptr;
-  }
-
-  // 10.2.2
-  if (!JS_DefineFunctions(cx, ctor, collator_static_methods)) {
-    return nullptr;
-  }
-
-  // 10.3.5
-  if (!JS_DefineFunctions(cx, proto, collator_methods)) {
-    return nullptr;
-  }
-
-  // 10.3.2 and 10.3.3
-  if (!JS_DefineProperties(cx, proto, collator_properties)) {
-    return nullptr;
-  }
-
-  // 8.1
-  RootedValue ctorValue(cx, ObjectValue(*ctor));
-  if (!DefineDataProperty(cx, Intl, cx->names().Collator, ctorValue, 0)) {
-    return nullptr;
-  }
-
-  return proto;
-}
-
 bool js::intl_availableCollations(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   MOZ_ASSERT(args.length() == 1);
   MOZ_ASSERT(args[0].isString());
 
   UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
   if (!locale) {
     return false;
--- a/js/src/builtin/intl/Collator.h
+++ b/js/src/builtin/intl/Collator.h
@@ -14,23 +14,22 @@
 #include "builtin/SelfHostingDefines.h"
 #include "js/Class.h"
 #include "vm/NativeObject.h"
 
 struct UCollator;
 
 namespace js {
 
-class GlobalObject;
-
 /******************** Collator ********************/
 
 class CollatorObject : public NativeObject {
  public:
   static const JSClass class_;
+  static const JSClass& protoClass_;
 
   static constexpr uint32_t INTERNALS_SLOT = 0;
   static constexpr uint32_t UCOLLATOR_SLOT = 1;
   static constexpr uint32_t SLOT_COUNT = 2;
 
   static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT,
                 "INTERNALS_SLOT must match self-hosting define for internals "
                 "object slot");
@@ -44,24 +43,21 @@ class CollatorObject : public NativeObje
   }
 
   void setCollator(UCollator* collator) {
     setFixedSlot(UCOLLATOR_SLOT, PrivateValue(collator));
   }
 
  private:
   static const JSClassOps classOps_;
+  static const ClassSpec classSpec_;
 
   static void finalize(JSFreeOp* fop, JSObject* obj);
 };
 
-extern JSObject* CreateCollatorPrototype(JSContext* cx,
-                                         JS::Handle<JSObject*> Intl,
-                                         JS::Handle<GlobalObject*> global);
-
 /**
  * Returns a new instance of the standard built-in Collator constructor.
  * Self-hosted code cannot cache this constructor (as it does for others in
  * Utilities.js) because it is initialized after self-hosted code is compiled.
  *
  * Usage: collator = intl_Collator(locales, options)
  */
 extern MOZ_MUST_USE bool intl_Collator(JSContext* cx, unsigned argc,
--- a/js/src/builtin/intl/DateTimeFormat.cpp
+++ b/js/src/builtin/intl/DateTimeFormat.cpp
@@ -58,18 +58,21 @@ const JSClassOps DateTimeFormatObject::c
     nullptr, /* newEnumerate */
     nullptr, /* resolve */
     nullptr, /* mayResolve */
     DateTimeFormatObject::finalize};
 
 const JSClass DateTimeFormatObject::class_ = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(DateTimeFormatObject::SLOT_COUNT) |
+        JSCLASS_HAS_CACHED_PROTO(JSProto_DateTimeFormat) |
         JSCLASS_FOREGROUND_FINALIZE,
-    &DateTimeFormatObject::classOps_};
+    &DateTimeFormatObject::classOps_, &DateTimeFormatObject::classSpec_};
+
+const JSClass& DateTimeFormatObject::protoClass_ = PlainObject::class_;
 
 static bool dateTimeFormat_toSource(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   args.rval().setString(cx->names().DateTimeFormat);
   return true;
 }
 
 static const JSFunctionSpec dateTimeFormat_static_methods[] = {
@@ -83,40 +86,48 @@ static const JSFunctionSpec dateTimeForm
     JS_SELF_HOSTED_FN("formatToParts", "Intl_DateTimeFormat_formatToParts", 1,
                       0),
     JS_FN(js_toSource_str, dateTimeFormat_toSource, 0, 0), JS_FS_END};
 
 static const JSPropertySpec dateTimeFormat_properties[] = {
     JS_SELF_HOSTED_GET("format", "$Intl_DateTimeFormat_format_get", 0),
     JS_STRING_SYM_PS(toStringTag, "Object", JSPROP_READONLY), JS_PS_END};
 
+static bool DateTimeFormat(JSContext* cx, unsigned argc, Value* vp);
+
+const ClassSpec DateTimeFormatObject::classSpec_ = {
+    GenericCreateConstructor<DateTimeFormat, 0, gc::AllocKind::FUNCTION>,
+    GenericCreatePrototype<DateTimeFormatObject>,
+    dateTimeFormat_static_methods,
+    nullptr,
+    dateTimeFormat_methods,
+    dateTimeFormat_properties,
+    nullptr,
+    ClassSpec::DontDefineConstructor};
+
 /**
  * 12.2.1 Intl.DateTimeFormat([ locales [, options]])
  *
  * ES2017 Intl draft rev 94045d234762ad107a3d09bb6f7381a65f1a2f9b
  */
 static bool DateTimeFormat(JSContext* cx, const CallArgs& args, bool construct,
                            DateTimeFormatOptions dtfOptions) {
   // Step 1 (Handled by OrdinaryCreateFromConstructor fallback code).
 
   // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
+  JSProtoKey protoKey = dtfOptions == DateTimeFormatOptions::Standard
+                            ? JSProto_DateTimeFormat
+                            : JSProto_Null;
   RootedObject proto(cx);
-  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_Null, &proto)) {
+  if (!GetPrototypeFromBuiltinConstructor(cx, args, protoKey, &proto)) {
     return false;
   }
 
-  if (!proto) {
-    proto = GlobalObject::getOrCreateDateTimeFormatPrototype(cx, cx->global());
-    if (!proto) {
-      return false;
-    }
-  }
-
   Rooted<DateTimeFormatObject*> dateTimeFormat(cx);
-  dateTimeFormat = NewObjectWithGivenProto<DateTimeFormatObject>(cx, proto);
+  dateTimeFormat = NewObjectWithClassProto<DateTimeFormatObject>(cx, proto);
   if (!dateTimeFormat) {
     return false;
   }
 
   RootedValue thisValue(
       cx, construct ? ObjectValue(*dateTimeFormat) : args.thisv());
   HandleValue locales = args.get(0);
   HandleValue options = args.get(1);
@@ -160,74 +171,52 @@ bool js::intl_DateTimeFormat(JSContext* 
 void js::DateTimeFormatObject::finalize(JSFreeOp* fop, JSObject* obj) {
   MOZ_ASSERT(fop->onMainThread());
 
   if (UDateFormat* df = obj->as<DateTimeFormatObject>().getDateFormat()) {
     udat_close(df);
   }
 }
 
-JSObject* js::CreateDateTimeFormatPrototype(
-    JSContext* cx, JS::Handle<JSObject*> Intl, JS::Handle<GlobalObject*> global,
-    JS::MutableHandle<JSObject*> constructor,
-    DateTimeFormatOptions dtfOptions) {
-  RootedFunction ctor(cx);
-  ctor = dtfOptions == DateTimeFormatOptions::EnableMozExtensions
-             ? GlobalObject::createConstructor(cx, MozDateTimeFormat,
-                                               cx->names().DateTimeFormat, 0)
-             : GlobalObject::createConstructor(cx, DateTimeFormat,
-                                               cx->names().DateTimeFormat, 0);
+bool js::AddMozDateTimeFormatConstructor(JSContext* cx,
+                                         JS::Handle<JSObject*> intl) {
+  RootedObject ctor(
+      cx, GlobalObject::createConstructor(cx, MozDateTimeFormat,
+                                          cx->names().DateTimeFormat, 0));
   if (!ctor) {
-    return nullptr;
+    return false;
   }
 
   RootedObject proto(
-      cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
+      cx, GlobalObject::createBlankPrototype<PlainObject>(cx, cx->global()));
   if (!proto) {
-    return nullptr;
+    return false;
   }
 
   if (!LinkConstructorAndPrototype(cx, ctor, proto)) {
-    return nullptr;
+    return false;
   }
 
   // 12.3.2
   if (!JS_DefineFunctions(cx, ctor, dateTimeFormat_static_methods)) {
-    return nullptr;
+    return false;
   }
 
   // 12.4.4 and 12.4.5
   if (!JS_DefineFunctions(cx, proto, dateTimeFormat_methods)) {
-    return nullptr;
+    return false;
   }
 
   // 12.4.2 and 12.4.3
   if (!JS_DefineProperties(cx, proto, dateTimeFormat_properties)) {
-    return nullptr;
-  }
-
-  // 8.1
-  RootedValue ctorValue(cx, ObjectValue(*ctor));
-  if (!DefineDataProperty(cx, Intl, cx->names().DateTimeFormat, ctorValue, 0)) {
-    return nullptr;
+    return false;
   }
 
-  constructor.set(ctor);
-  return proto;
-}
-
-bool js::AddMozDateTimeFormatConstructor(JSContext* cx,
-                                         JS::Handle<JSObject*> intl) {
-  Handle<GlobalObject*> global = cx->global();
-
-  RootedObject mozDateTimeFormat(cx);
-  JSObject* mozDateTimeFormatProto =
-      CreateDateTimeFormatPrototype(cx, intl, global, &mozDateTimeFormat,
-                                    DateTimeFormatOptions::EnableMozExtensions);
-  return mozDateTimeFormatProto != nullptr;
+  RootedValue ctorValue(cx, ObjectValue(*ctor));
+  return DefineDataProperty(cx, intl, cx->names().DateTimeFormat, ctorValue, 0);
 }
 
 static bool DefaultCalendar(JSContext* cx, const UniqueChars& locale,
                             MutableHandleValue rval) {
   UErrorCode status = U_ZERO_ERROR;
   UCalendar* cal = ucal_open(nullptr, 0, locale.get(), UCAL_DEFAULT, &status);
 
   // This correctly handles nullptr |cal| when opening failed.
--- a/js/src/builtin/intl/DateTimeFormat.h
+++ b/js/src/builtin/intl/DateTimeFormat.h
@@ -14,21 +14,20 @@
 #include "js/Class.h"
 #include "js/RootingAPI.h"
 #include "vm/NativeObject.h"
 
 using UDateFormat = void*;
 
 namespace js {
 
-class GlobalObject;
-
 class DateTimeFormatObject : public NativeObject {
  public:
   static const JSClass class_;
+  static const JSClass& protoClass_;
 
   static constexpr uint32_t INTERNALS_SLOT = 0;
   static constexpr uint32_t UDATE_FORMAT_SLOT = 1;
   static constexpr uint32_t SLOT_COUNT = 2;
 
   static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT,
                 "INTERNALS_SLOT must match self-hosting define for internals "
                 "object slot");
@@ -42,25 +41,21 @@ class DateTimeFormatObject : public Nati
   }
 
   void setDateFormat(UDateFormat* dateFormat) {
     setFixedSlot(UDATE_FORMAT_SLOT, PrivateValue(dateFormat));
   }
 
  private:
   static const JSClassOps classOps_;
+  static const ClassSpec classSpec_;
 
   static void finalize(JSFreeOp* fop, JSObject* obj);
 };
 
-extern JSObject* CreateDateTimeFormatPrototype(
-    JSContext* cx, JS::Handle<JSObject*> Intl, JS::Handle<GlobalObject*> global,
-    JS::MutableHandle<JSObject*> constructor,
-    intl::DateTimeFormatOptions dtfOptions);
-
 /**
  * Returns a new instance of the standard built-in DateTimeFormat constructor.
  * Self-hosted code cannot cache this constructor (as it does for others in
  * Utilities.js) because it is initialized after self-hosted code is compiled.
  *
  * Usage: dateTimeFormat = intl_DateTimeFormat(locales, options)
  */
 extern MOZ_MUST_USE bool intl_DateTimeFormat(JSContext* cx, unsigned argc,
--- a/js/src/builtin/intl/DateTimeFormat.js
+++ b/js/src/builtin/intl/DateTimeFormat.js
@@ -193,17 +193,17 @@ function getDateTimeFormatInternals(obj)
 /**
  * 12.1.10 UnwrapDateTimeFormat( dtf )
  */
 function UnwrapDateTimeFormat(dtf) {
     // Steps 2 and 4 (error handling moved to caller).
     if (IsObject(dtf) &&
         GuardToDateTimeFormat(dtf) === null &&
         !IsWrappedDateTimeFormat(dtf) &&
-        dtf instanceof GetDateTimeFormatConstructor())
+        dtf instanceof GetBuiltinConstructor("DateTimeFormat"))
     {
         dtf = dtf[intlFallbackSymbol()];
     }
     return dtf;
 }
 
 /**
  * 6.4.2 CanonicalizeTimeZoneName ( timeZone )
@@ -443,17 +443,17 @@ function InitializeDateTimeFormat(dateTi
     // We've done everything that must be done now: mark the lazy data as fully
     // computed and install it.
     initializeIntlObject(dateTimeFormat, "DateTimeFormat", lazyDateTimeFormatData);
 
     // 12.2.1, steps 4-5.
     // TODO: spec issue - The current spec doesn't have the IsObject check,
     // which means |Intl.DateTimeFormat.call(null)| is supposed to throw here.
     if (dateTimeFormat !== thisValue && IsObject(thisValue) &&
-        thisValue instanceof GetDateTimeFormatConstructor())
+        thisValue instanceof GetBuiltinConstructor("DateTimeFormat"))
     {
         _DefineDataProperty(thisValue, intlFallbackSymbol(), dateTimeFormat,
                             ATTR_NONENUMERABLE | ATTR_NONCONFIGURABLE | ATTR_NONWRITABLE);
 
         return thisValue;
     }
 
     // 12.2.1, step 6.
--- a/js/src/builtin/intl/IntlObject.cpp
+++ b/js/src/builtin/intl/IntlObject.cpp
@@ -33,16 +33,17 @@
 #include "js/Result.h"
 #include "js/StableStringChars.h"
 #include "unicode/ucal.h"
 #include "unicode/udat.h"
 #include "unicode/udatpg.h"
 #include "unicode/uloc.h"
 #include "unicode/utypes.h"
 #include "vm/GlobalObject.h"
+#include "vm/JSAtom.h"
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 #include "vm/StringType.h"
 
 #include "vm/JSObject-inl.h"
 #include "vm/NativeObject-inl.h"
 
 using namespace js;
@@ -797,99 +798,59 @@ static const JSFunctionSpec intl_static_
     JS_FN(js_toSource_str, intl_toSource, 0, 0),
     JS_SELF_HOSTED_FN("getCanonicalLocales", "Intl_getCanonicalLocales", 1, 0),
     JS_FS_END};
 
 /**
  * Initializes the Intl Object and its standard built-in properties.
  * Spec: ECMAScript Internationalization API Specification, 8.0, 8.1
  */
-/* static */
-bool GlobalObject::initIntlObject(JSContext* cx, Handle<GlobalObject*> global) {
+JSObject* js::InitIntlClass(JSContext* cx, Handle<GlobalObject*> global) {
   RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
   if (!proto) {
-    return false;
+    return nullptr;
   }
 
   // The |Intl| object is just a plain object with some "static" function
   // properties and some constructor properties.
   RootedObject intl(
       cx, NewObjectWithGivenProto(cx, &IntlClass, proto, SingletonObject));
   if (!intl) {
-    return false;
+    return nullptr;
   }
 
   // Add the static functions.
   if (!JS_DefineFunctions(cx, intl, intl_static_methods)) {
-    return false;
+    return nullptr;
   }
 
-  // Add the constructor properties, computing and returning the relevant
-  // prototype objects needed below.
-  RootedObject collatorProto(cx, CreateCollatorPrototype(cx, intl, global));
-  if (!collatorProto) {
-    return false;
-  }
-  RootedObject dateTimeFormatProto(cx), dateTimeFormat(cx);
-  dateTimeFormatProto = CreateDateTimeFormatPrototype(
-      cx, intl, global, &dateTimeFormat, DateTimeFormatOptions::Standard);
-  if (!dateTimeFormatProto) {
-    return false;
-  }
-  RootedObject numberFormatProto(cx), numberFormat(cx);
-  numberFormatProto =
-      CreateNumberFormatPrototype(cx, intl, global, &numberFormat);
-  if (!numberFormatProto) {
-    return false;
-  }
-  RootedObject pluralRulesProto(cx,
-                                CreatePluralRulesPrototype(cx, intl, global));
-  if (!pluralRulesProto) {
-    return false;
-  }
-  RootedObject relativeTimeFmtProto(
-      cx, CreateRelativeTimeFormatPrototype(cx, intl, global));
-  if (!relativeTimeFmtProto) {
-    return false;
+  // Add the constructor properties.
+  RootedId ctorId(cx);
+  RootedValue ctorValue(cx);
+  for (const auto& protoKey :
+       {JSProto_Collator, JSProto_DateTimeFormat, JSProto_NumberFormat,
+        JSProto_PluralRules, JSProto_RelativeTimeFormat}) {
+    JSObject* ctor = GlobalObject::getOrCreateConstructor(cx, protoKey);
+    if (!ctor) {
+      return nullptr;
+    }
+
+    ctorId = NameToId(ClassName(protoKey, cx));
+    ctorValue.setObject(*ctor);
+    if (!DefineDataProperty(cx, intl, ctorId, ctorValue, 0)) {
+      return nullptr;
+    }
   }
 
   // The |Intl| object is fully set up now, so define the global property.
   RootedValue intlValue(cx, ObjectValue(*intl));
   if (!DefineDataProperty(cx, global, cx->names().Intl, intlValue,
                           JSPROP_RESOLVING)) {
-    return false;
+    return nullptr;
   }
 
-  // Now that the |Intl| object is successfully added, we can OOM-safely fill
-  // in all relevant reserved global slots.
-
-  // Cache the various prototypes, for use in creating instances of these
-  // objects with the proper [[Prototype]] as "the original value of
-  // |Intl.Collator.prototype|" and similar.  For builtin classes like
-  // |String.prototype| we have |JSProto_*| that enables
-  // |getPrototype(JSProto_*)|, but that has global-object-property-related
-  // baggage we don't need or want, so we use one-off reserved slots.
-  global->setReservedSlot(COLLATOR_PROTO, ObjectValue(*collatorProto));
-  global->setReservedSlot(DATE_TIME_FORMAT, ObjectValue(*dateTimeFormat));
-  global->setReservedSlot(DATE_TIME_FORMAT_PROTO,
-                          ObjectValue(*dateTimeFormatProto));
-  global->setReservedSlot(NUMBER_FORMAT, ObjectValue(*numberFormat));
-  global->setReservedSlot(NUMBER_FORMAT_PROTO, ObjectValue(*numberFormatProto));
-  global->setReservedSlot(PLURAL_RULES_PROTO, ObjectValue(*pluralRulesProto));
-  global->setReservedSlot(RELATIVE_TIME_FORMAT_PROTO,
-                          ObjectValue(*relativeTimeFmtProto));
-
   // Also cache |Intl| to implement spec language that conditions behavior
   // based on values being equal to "the standard built-in |Intl| object".
   // Use |setConstructor| to correspond with |JSProto_Intl|.
-  //
-  // XXX We should possibly do a one-off reserved slot like above.
   global->setConstructor(JSProto_Intl, ObjectValue(*intl));
-  return true;
-}
 
-JSObject* js::InitIntlClass(JSContext* cx, Handle<GlobalObject*> global) {
-  if (!GlobalObject::initIntlObject(cx, global)) {
-    return nullptr;
-  }
-
-  return &global->getConstructor(JSProto_Intl).toObject();
+  return intl;
 }
--- a/js/src/builtin/intl/Locale.cpp
+++ b/js/src/builtin/intl/Locale.cpp
@@ -42,18 +42,21 @@
 using namespace js;
 using namespace js::intl::LanguageTagLimits;
 
 using intl::LanguageTag;
 using intl::LanguageTagParser;
 
 const JSClass LocaleObject::class_ = {
     js_Object_str,
-    JSCLASS_HAS_RESERVED_SLOTS(LocaleObject::SLOT_COUNT),
-};
+    JSCLASS_HAS_RESERVED_SLOTS(LocaleObject::SLOT_COUNT) |
+        JSCLASS_HAS_CACHED_PROTO(JSProto_Locale),
+    JS_NULL_CLASS_OPS, &LocaleObject::classSpec_};
+
+const JSClass& LocaleObject::protoClass_ = PlainObject::class_;
 
 static inline bool IsLocale(HandleValue v) {
   return v.isObject() && v.toObject().is<LocaleObject>();
 }
 
 // Return the length of the base-name subtags.
 static size_t BaseNameLength(const LanguageTag& tag) {
   size_t baseNameLength = tag.language().length();
@@ -94,24 +97,16 @@ static mozilla::Maybe<IndexAndLength> Un
     // Add +1 to skip over the preceding separator.
     index += 1 + extensionLength;
   }
   return mozilla::Nothing();
 }
 
 static LocaleObject* CreateLocaleObject(JSContext* cx, HandleObject prototype,
                                         const LanguageTag& tag) {
-  RootedObject proto(cx, prototype);
-  if (!proto) {
-    proto = GlobalObject::getOrCreateLocalePrototype(cx, cx->global());
-    if (!proto) {
-      return nullptr;
-    }
-  }
-
   RootedString tagStr(cx, tag.toString(cx));
   if (!tagStr) {
     return nullptr;
   }
 
   size_t baseNameLength = BaseNameLength(tag);
 
   RootedString baseName(cx, NewDependentString(cx, tagStr, 0, baseNameLength));
@@ -125,17 +120,17 @@ static LocaleObject* CreateLocaleObject(
         cx, tagStr, baseNameLength + 1 + result->index, result->length);
     if (!str) {
       return nullptr;
     }
 
     unicodeExtension.setString(str);
   }
 
-  auto* locale = NewObjectWithGivenProto<LocaleObject>(cx, proto);
+  auto* locale = NewObjectWithClassProto<LocaleObject>(cx, prototype);
   if (!locale) {
     return nullptr;
   }
 
   locale->setFixedSlot(LocaleObject::LANGUAGE_TAG_SLOT, StringValue(tagStr));
   locale->setFixedSlot(LocaleObject::BASENAME_SLOT, StringValue(baseName));
   locale->setFixedSlot(LocaleObject::UNICODE_EXTENSION_SLOT, unicodeExtension);
 
@@ -516,17 +511,17 @@ static bool Locale(JSContext* cx, unsign
 
   // Step 1.
   if (!ThrowIfNotConstructing(cx, args, "Intl.Locale")) {
     return false;
   }
 
   // Steps 2-6 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
   RootedObject proto(cx);
-  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_Null, &proto)) {
+  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_Locale, &proto)) {
     return false;
   }
 
   // Steps 7-9.
   HandleValue tagValue = args.get(0);
   JSString* tagStr;
   if (tagValue.isObject()) {
     JS_TRY_VAR_OR_RETURN_FALSE(
@@ -1227,74 +1222,34 @@ static const JSPropertySpec locale_prope
     JS_PSG("numeric", Locale_numeric, 0),
     JS_PSG("numberingSystem", Locale_numberingSystem, 0),
     JS_PSG("language", Locale_language, 0),
     JS_PSG("script", Locale_script, 0),
     JS_PSG("region", Locale_region, 0),
     JS_STRING_SYM_PS(toStringTag, "Intl.Locale", JSPROP_READONLY),
     JS_PS_END};
 
-JSObject* js::CreateLocalePrototype(JSContext* cx, HandleObject Intl,
-                                    Handle<GlobalObject*> global) {
-  RootedFunction ctor(
-      cx, GlobalObject::createConstructor(cx, &Locale, cx->names().Locale, 1));
-  if (!ctor) {
-    return nullptr;
-  }
+const ClassSpec LocaleObject::classSpec_ = {
+    GenericCreateConstructor<Locale, 1, gc::AllocKind::FUNCTION>,
+    GenericCreatePrototype<LocaleObject>,
+    nullptr,
+    nullptr,
+    locale_methods,
+    locale_properties,
+    nullptr,
+    ClassSpec::DontDefineConstructor};
 
-  RootedObject proto(
-      cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
-  if (!proto) {
-    return nullptr;
-  }
-
-  if (!LinkConstructorAndPrototype(cx, ctor, proto)) {
-    return nullptr;
-  }
-
-  if (!DefinePropertiesAndFunctions(cx, proto, locale_properties,
-                                    locale_methods)) {
-    return nullptr;
+bool js::AddLocaleConstructor(JSContext* cx, JS::Handle<JSObject*> intl) {
+  JSObject* ctor = GlobalObject::getOrCreateConstructor(cx, JSProto_Locale);
+  if (!ctor) {
+    return false;
   }
 
   RootedValue ctorValue(cx, ObjectValue(*ctor));
-  if (!DefineDataProperty(cx, Intl, cx->names().Locale, ctorValue, 0)) {
-    return nullptr;
-  }
-
-  return proto;
-}
-
-/* static */ bool js::GlobalObject::addLocaleConstructor(JSContext* cx,
-                                                         HandleObject intl) {
-  Handle<GlobalObject*> global = cx->global();
-
-  {
-    const Value& proto = global->getReservedSlot(LOCALE_PROTO);
-    if (!proto.isUndefined()) {
-      MOZ_ASSERT(proto.isObject());
-      JS_ReportErrorASCII(
-          cx,
-          "the Locale constructor can't be added multiple times in the"
-          "same global");
-      return false;
-    }
-  }
-
-  JSObject* localeProto = CreateLocalePrototype(cx, intl, global);
-  if (!localeProto) {
-    return false;
-  }
-
-  global->setReservedSlot(LOCALE_PROTO, ObjectValue(*localeProto));
-  return true;
-}
-
-bool js::AddLocaleConstructor(JSContext* cx, JS::Handle<JSObject*> intl) {
-  return GlobalObject::addLocaleConstructor(cx, intl);
+  return DefineDataProperty(cx, intl, cx->names().Locale, ctorValue, 0);
 }
 
 bool js::intl_ValidateAndCanonicalizeLanguageTag(JSContext* cx, unsigned argc,
                                                  Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   MOZ_ASSERT(args.length() == 2);
 
   HandleValue tagValue = args[0];
--- a/js/src/builtin/intl/Locale.h
+++ b/js/src/builtin/intl/Locale.h
@@ -10,21 +10,20 @@
 #include <stdint.h>
 
 #include "builtin/SelfHostingDefines.h"
 #include "js/Class.h"
 #include "vm/NativeObject.h"
 
 namespace js {
 
-class GlobalObject;
-
 class LocaleObject : public NativeObject {
  public:
   static const JSClass class_;
+  static const JSClass& protoClass_;
 
   static constexpr uint32_t LANGUAGE_TAG_SLOT = 0;
   static constexpr uint32_t BASENAME_SLOT = 1;
   static constexpr uint32_t UNICODE_EXTENSION_SLOT = 2;
   static constexpr uint32_t SLOT_COUNT = 3;
 
   /**
    * Returns the complete language tag, including any extensions and privateuse
@@ -38,22 +37,21 @@ class LocaleObject : public NativeObject
    * Returns the basename subtags, i.e. excluding any extensions and privateuse
    * subtags.
    */
   JSString* baseName() const { return getFixedSlot(BASENAME_SLOT).toString(); }
 
   const Value& unicodeExtension() const {
     return getFixedSlot(UNICODE_EXTENSION_SLOT);
   }
+
+ private:
+  static const ClassSpec classSpec_;
 };
 
-extern JSObject* CreateLocalePrototype(JSContext* cx,
-                                       JS::Handle<JSObject*> Intl,
-                                       JS::Handle<GlobalObject*> global);
-
 extern MOZ_MUST_USE bool intl_ValidateAndCanonicalizeLanguageTag(JSContext* cx,
                                                                  unsigned argc,
                                                                  Value* vp);
 
 extern MOZ_MUST_USE bool intl_TryValidateAndCanonicalizeLanguageTag(
     JSContext* cx, unsigned argc, Value* vp);
 
 }  // namespace js
--- a/js/src/builtin/intl/NumberFormat.cpp
+++ b/js/src/builtin/intl/NumberFormat.cpp
@@ -37,16 +37,17 @@
 #include "unicode/ufieldpositer.h"
 #include "unicode/uformattedvalue.h"
 #include "unicode/unum.h"
 #include "unicode/unumberformatter.h"
 #include "unicode/unumsys.h"
 #include "unicode/ures.h"
 #include "unicode/utypes.h"
 #include "vm/BigIntType.h"
+#include "vm/GlobalObject.h"
 #include "vm/JSContext.h"
 #include "vm/SelfHosting.h"
 #include "vm/Stack.h"
 #include "vm/StringType.h"
 
 #include "vm/JSObject-inl.h"
 
 using namespace js;
@@ -70,18 +71,21 @@ const JSClassOps NumberFormatObject::cla
                                                   nullptr, /* newEnumerate */
                                                   nullptr, /* resolve */
                                                   nullptr, /* mayResolve */
                                                   NumberFormatObject::finalize};
 
 const JSClass NumberFormatObject::class_ = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(NumberFormatObject::SLOT_COUNT) |
+        JSCLASS_HAS_CACHED_PROTO(JSProto_NumberFormat) |
         JSCLASS_FOREGROUND_FINALIZE,
-    &NumberFormatObject::classOps_};
+    &NumberFormatObject::classOps_, &NumberFormatObject::classSpec_};
+
+const JSClass& NumberFormatObject::protoClass_ = PlainObject::class_;
 
 static bool numberFormat_toSource(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   args.rval().setString(cx->names().NumberFormat);
   return true;
 }
 
 static const JSFunctionSpec numberFormat_static_methods[] = {
@@ -94,39 +98,45 @@ static const JSFunctionSpec numberFormat
                       0),
     JS_SELF_HOSTED_FN("formatToParts", "Intl_NumberFormat_formatToParts", 1, 0),
     JS_FN(js_toSource_str, numberFormat_toSource, 0, 0), JS_FS_END};
 
 static const JSPropertySpec numberFormat_properties[] = {
     JS_SELF_HOSTED_GET("format", "$Intl_NumberFormat_format_get", 0),
     JS_STRING_SYM_PS(toStringTag, "Object", JSPROP_READONLY), JS_PS_END};
 
+static bool NumberFormat(JSContext* cx, unsigned argc, Value* vp);
+
+const ClassSpec NumberFormatObject::classSpec_ = {
+    GenericCreateConstructor<NumberFormat, 0, gc::AllocKind::FUNCTION>,
+    GenericCreatePrototype<NumberFormatObject>,
+    numberFormat_static_methods,
+    nullptr,
+    numberFormat_methods,
+    numberFormat_properties,
+    nullptr,
+    ClassSpec::DontDefineConstructor};
+
 /**
  * 11.2.1 Intl.NumberFormat([ locales [, options]])
  *
  * ES2017 Intl draft rev 94045d234762ad107a3d09bb6f7381a65f1a2f9b
  */
 static bool NumberFormat(JSContext* cx, const CallArgs& args, bool construct) {
   // Step 1 (Handled by OrdinaryCreateFromConstructor fallback code).
 
   // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
   RootedObject proto(cx);
-  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_Null, &proto)) {
+  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_NumberFormat,
+                                          &proto)) {
     return false;
   }
 
-  if (!proto) {
-    proto = GlobalObject::getOrCreateNumberFormatPrototype(cx, cx->global());
-    if (!proto) {
-      return false;
-    }
-  }
-
   Rooted<NumberFormatObject*> numberFormat(cx);
-  numberFormat = NewObjectWithGivenProto<NumberFormatObject>(cx, proto);
+  numberFormat = NewObjectWithClassProto<NumberFormatObject>(cx, proto);
   if (!numberFormat) {
     return false;
   }
 
   RootedValue thisValue(cx,
                         construct ? ObjectValue(*numberFormat) : args.thisv());
   HandleValue locales = args.get(0);
   HandleValue options = args.get(1);
@@ -162,61 +172,16 @@ void js::NumberFormatObject::finalize(JS
   if (nf) {
     unumf_close(nf);
   }
   if (formatted) {
     unumf_closeResult(formatted);
   }
 }
 
-JSObject* js::CreateNumberFormatPrototype(JSContext* cx, HandleObject Intl,
-                                          Handle<GlobalObject*> global,
-                                          MutableHandleObject constructor) {
-  RootedFunction ctor(cx);
-  ctor = GlobalObject::createConstructor(cx, &NumberFormat,
-                                         cx->names().NumberFormat, 0);
-  if (!ctor) {
-    return nullptr;
-  }
-
-  RootedObject proto(
-      cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
-  if (!proto) {
-    return nullptr;
-  }
-
-  if (!LinkConstructorAndPrototype(cx, ctor, proto)) {
-    return nullptr;
-  }
-
-  // 11.3.2
-  if (!JS_DefineFunctions(cx, ctor, numberFormat_static_methods)) {
-    return nullptr;
-  }
-
-  // 11.4.4
-  if (!JS_DefineFunctions(cx, proto, numberFormat_methods)) {
-    return nullptr;
-  }
-
-  // 11.4.2 and 11.4.3
-  if (!JS_DefineProperties(cx, proto, numberFormat_properties)) {
-    return nullptr;
-  }
-
-  // 8.1
-  RootedValue ctorValue(cx, ObjectValue(*ctor));
-  if (!DefineDataProperty(cx, Intl, cx->names().NumberFormat, ctorValue, 0)) {
-    return nullptr;
-  }
-
-  constructor.set(ctor);
-  return proto;
-}
-
 bool js::intl_numberingSystem(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   MOZ_ASSERT(args.length() == 1);
   MOZ_ASSERT(args[0].isString());
 
   UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
   if (!locale) {
     return false;
--- a/js/src/builtin/intl/NumberFormat.h
+++ b/js/src/builtin/intl/NumberFormat.h
@@ -18,21 +18,20 @@
 #include "vm/Runtime.h"
 
 struct UFormattedNumber;
 struct UFormattedValue;
 struct UNumberFormatter;
 
 namespace js {
 
-class ArrayObject;
-
 class NumberFormatObject : public NativeObject {
  public:
   static const JSClass class_;
+  static const JSClass& protoClass_;
 
   static constexpr uint32_t INTERNALS_SLOT = 0;
   static constexpr uint32_t UNUMBER_FORMATTER_SLOT = 1;
   static constexpr uint32_t UFORMATTED_NUMBER_SLOT = 2;
   static constexpr uint32_t SLOT_COUNT = 3;
 
   static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT,
                 "INTERNALS_SLOT must match self-hosting define for internals "
@@ -59,24 +58,21 @@ class NumberFormatObject : public Native
   }
 
   void setFormattedNumber(UFormattedNumber* formatted) {
     setFixedSlot(UFORMATTED_NUMBER_SLOT, PrivateValue(formatted));
   }
 
  private:
   static const JSClassOps classOps_;
+  static const ClassSpec classSpec_;
 
   static void finalize(JSFreeOp* fop, JSObject* obj);
 };
 
-extern JSObject* CreateNumberFormatPrototype(JSContext* cx, HandleObject Intl,
-                                             Handle<GlobalObject*> global,
-                                             MutableHandleObject constructor);
-
 /**
  * Returns a new instance of the standard built-in NumberFormat constructor.
  * Self-hosted code cannot cache this constructor (as it does for others in
  * Utilities.js) because it is initialized after self-hosted code is compiled.
  *
  * Usage: numberFormat = intl_NumberFormat(locales, options)
  */
 extern MOZ_MUST_USE bool intl_NumberFormat(JSContext* cx, unsigned argc,
--- a/js/src/builtin/intl/NumberFormat.js
+++ b/js/src/builtin/intl/NumberFormat.js
@@ -120,17 +120,17 @@ function getNumberFormatInternals(obj) {
 /**
  * 11.1.11 UnwrapNumberFormat( nf )
  */
 function UnwrapNumberFormat(nf) {
     // Steps 2 and 4 (error handling moved to caller).
     if (IsObject(nf) &&
         GuardToNumberFormat(nf) === null &&
         !IsWrappedNumberFormat(nf) &&
-        nf instanceof GetNumberFormatConstructor())
+        nf instanceof GetBuiltinConstructor("NumberFormat"))
     {
         nf = nf[intlFallbackSymbol()];
     }
     return nf;
 }
 
 /**
  * Applies digit options used for number formatting onto the intl object.
@@ -578,17 +578,17 @@ function InitializeNumberFormat(numberFo
     // We've done everything that must be done now: mark the lazy data as fully
     // computed and install it.
     initializeIntlObject(numberFormat, "NumberFormat", lazyNumberFormatData);
 
     // 11.2.1, steps 4-5.
     // TODO: spec issue - The current spec doesn't have the IsObject check,
     // which means |Intl.NumberFormat.call(null)| is supposed to throw here.
     if (numberFormat !== thisValue && IsObject(thisValue) &&
-        thisValue instanceof GetNumberFormatConstructor())
+        thisValue instanceof GetBuiltinConstructor("NumberFormat"))
     {
         _DefineDataProperty(thisValue, intlFallbackSymbol(), numberFormat,
                             ATTR_NONENUMERABLE | ATTR_NONCONFIGURABLE | ATTR_NONWRITABLE);
 
         return thisValue;
     }
 
     // 11.2.1, step 6.
--- a/js/src/builtin/intl/PluralRules.cpp
+++ b/js/src/builtin/intl/PluralRules.cpp
@@ -43,18 +43,21 @@ const JSClassOps PluralRulesObject::clas
                                                  nullptr, /* newEnumerate */
                                                  nullptr, /* resolve */
                                                  nullptr, /* mayResolve */
                                                  PluralRulesObject::finalize};
 
 const JSClass PluralRulesObject::class_ = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(PluralRulesObject::SLOT_COUNT) |
+        JSCLASS_HAS_CACHED_PROTO(JSProto_PluralRules) |
         JSCLASS_FOREGROUND_FINALIZE,
-    &PluralRulesObject::classOps_};
+    &PluralRulesObject::classOps_, &PluralRulesObject::classSpec_};
+
+const JSClass& PluralRulesObject::protoClass_ = PlainObject::class_;
 
 static bool pluralRules_toSource(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   args.rval().setString(cx->names().PluralRules);
   return true;
 }
 
 static const JSFunctionSpec pluralRules_static_methods[] = {
@@ -63,43 +66,49 @@ static const JSFunctionSpec pluralRules_
     JS_FS_END};
 
 static const JSFunctionSpec pluralRules_methods[] = {
     JS_SELF_HOSTED_FN("resolvedOptions", "Intl_PluralRules_resolvedOptions", 0,
                       0),
     JS_SELF_HOSTED_FN("select", "Intl_PluralRules_select", 1, 0),
     JS_FN(js_toSource_str, pluralRules_toSource, 0, 0), JS_FS_END};
 
+static bool PluralRules(JSContext* cx, unsigned argc, Value* vp);
+
+const ClassSpec PluralRulesObject::classSpec_ = {
+    GenericCreateConstructor<PluralRules, 0, gc::AllocKind::FUNCTION>,
+    GenericCreatePrototype<PluralRulesObject>,
+    pluralRules_static_methods,
+    nullptr,
+    pluralRules_methods,
+    nullptr,
+    nullptr,
+    ClassSpec::DontDefineConstructor};
+
 /**
  * PluralRules constructor.
  * Spec: ECMAScript 402 API, PluralRules, 13.2.1
  */
 static bool PluralRules(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
 
   // Step 1.
   if (!ThrowIfNotConstructing(cx, args, "Intl.PluralRules")) {
     return false;
   }
 
   // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
   RootedObject proto(cx);
-  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_Null, &proto)) {
+  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_PluralRules,
+                                          &proto)) {
     return false;
   }
 
-  if (!proto) {
-    proto = GlobalObject::getOrCreatePluralRulesPrototype(cx, cx->global());
-    if (!proto) {
-      return false;
-    }
-  }
-
   Rooted<PluralRulesObject*> pluralRules(cx);
-  pluralRules = NewObjectWithGivenProto<PluralRulesObject>(cx, proto);
+  pluralRules = NewObjectWithClassProto<PluralRulesObject>(cx, proto);
   if (!pluralRules) {
     return false;
   }
 
   HandleValue locales = args.get(0);
   HandleValue options = args.get(1);
 
   // Step 3.
@@ -127,51 +136,16 @@ void js::PluralRulesObject::finalize(JSF
   if (nf) {
     unumf_close(nf);
   }
   if (formatted) {
     unumf_closeResult(formatted);
   }
 }
 
-JSObject* js::CreatePluralRulesPrototype(JSContext* cx, HandleObject Intl,
-                                         Handle<GlobalObject*> global) {
-  RootedFunction ctor(cx);
-  ctor =
-      global->createConstructor(cx, &PluralRules, cx->names().PluralRules, 0);
-  if (!ctor) {
-    return nullptr;
-  }
-
-  RootedObject proto(
-      cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
-  if (!proto) {
-    return nullptr;
-  }
-
-  if (!LinkConstructorAndPrototype(cx, ctor, proto)) {
-    return nullptr;
-  }
-
-  if (!JS_DefineFunctions(cx, ctor, pluralRules_static_methods)) {
-    return nullptr;
-  }
-
-  if (!JS_DefineFunctions(cx, proto, pluralRules_methods)) {
-    return nullptr;
-  }
-
-  RootedValue ctorValue(cx, ObjectValue(*ctor));
-  if (!DefineDataProperty(cx, Intl, cx->names().PluralRules, ctorValue, 0)) {
-    return nullptr;
-  }
-
-  return proto;
-}
-
 /**
  * This creates a new UNumberFormatter with calculated digit formatting
  * properties for PluralRules.
  *
  * This is similar to NewUNumberFormatter but doesn't allow for currency or
  * percent types.
  */
 static UNumberFormatter* NewUNumberFormatterForPluralRules(
--- a/js/src/builtin/intl/PluralRules.h
+++ b/js/src/builtin/intl/PluralRules.h
@@ -18,16 +18,17 @@ struct UFormattedNumber;
 struct UNumberFormatter;
 struct UPluralRules;
 
 namespace js {
 
 class PluralRulesObject : public NativeObject {
  public:
   static const JSClass class_;
+  static const JSClass& protoClass_;
 
   static constexpr uint32_t INTERNALS_SLOT = 0;
   static constexpr uint32_t UPLURAL_RULES_SLOT = 1;
   static constexpr uint32_t UNUMBER_FORMATTER_SLOT = 2;
   static constexpr uint32_t UFORMATTED_NUMBER_SLOT = 3;
   static constexpr uint32_t SLOT_COUNT = 4;
 
   static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT,
@@ -67,24 +68,21 @@ class PluralRulesObject : public NativeO
   }
 
   void setFormattedNumber(UFormattedNumber* formatted) {
     setFixedSlot(UFORMATTED_NUMBER_SLOT, PrivateValue(formatted));
   }
 
  private:
   static const JSClassOps classOps_;
+  static const ClassSpec classSpec_;
 
   static void finalize(JSFreeOp* fop, JSObject* obj);
 };
 
-extern JSObject* CreatePluralRulesPrototype(JSContext* cx,
-                                            JS::Handle<JSObject*> Intl,
-                                            JS::Handle<GlobalObject*> global);
-
 /**
  * Returns a plural rule for the number x according to the effective
  * locale and the formatting options of the given PluralRules.
  *
  * A plural rule is a grammatical category that expresses count distinctions
  * (such as "one", "two", "few" etc.).
  *
  * Usage: rule = intl_SelectPluralRule(pluralRules, x)
--- a/js/src/builtin/intl/RelativeTimeFormat.cpp
+++ b/js/src/builtin/intl/RelativeTimeFormat.cpp
@@ -42,18 +42,22 @@ const JSClassOps RelativeTimeFormatObjec
     nullptr, /* newEnumerate */
     nullptr, /* resolve */
     nullptr, /* mayResolve */
     RelativeTimeFormatObject::finalize};
 
 const JSClass RelativeTimeFormatObject::class_ = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(RelativeTimeFormatObject::SLOT_COUNT) |
+        JSCLASS_HAS_CACHED_PROTO(JSProto_RelativeTimeFormat) |
         JSCLASS_FOREGROUND_FINALIZE,
-    &RelativeTimeFormatObject::classOps_};
+    &RelativeTimeFormatObject::classOps_,
+    &RelativeTimeFormatObject::classSpec_};
+
+const JSClass& RelativeTimeFormatObject::protoClass_ = PlainObject::class_;
 
 static bool relativeTimeFormat_toSource(JSContext* cx, unsigned argc,
                                         Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   args.rval().setString(cx->names().RelativeTimeFormat);
   return true;
 }
 
@@ -71,45 +75,50 @@ static const JSFunctionSpec relativeTime
                       2, 0),
 #endif
     JS_FN(js_toSource_str, relativeTimeFormat_toSource, 0, 0), JS_FS_END};
 
 static const JSPropertySpec relativeTimeFormat_properties[] = {
     JS_STRING_SYM_PS(toStringTag, "Intl.RelativeTimeFormat", JSPROP_READONLY),
     JS_PS_END};
 
+static bool RelativeTimeFormat(JSContext* cx, unsigned argc, Value* vp);
+
+const ClassSpec RelativeTimeFormatObject::classSpec_ = {
+    GenericCreateConstructor<RelativeTimeFormat, 0, gc::AllocKind::FUNCTION>,
+    GenericCreatePrototype<RelativeTimeFormatObject>,
+    relativeTimeFormat_static_methods,
+    nullptr,
+    relativeTimeFormat_methods,
+    relativeTimeFormat_properties,
+    nullptr,
+    ClassSpec::DontDefineConstructor};
+
 /**
  * RelativeTimeFormat constructor.
  * Spec: ECMAScript 402 API, RelativeTimeFormat, 1.1
  */
 static bool RelativeTimeFormat(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
 
   // Step 1.
   if (!ThrowIfNotConstructing(cx, args, "Intl.RelativeTimeFormat")) {
     return false;
   }
 
   // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
   RootedObject proto(cx);
-  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_Null, &proto)) {
+  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_RelativeTimeFormat,
+                                          &proto)) {
     return false;
   }
 
-  if (!proto) {
-    proto =
-        GlobalObject::getOrCreateRelativeTimeFormatPrototype(cx, cx->global());
-    if (!proto) {
-      return false;
-    }
-  }
-
   Rooted<RelativeTimeFormatObject*> relativeTimeFormat(cx);
   relativeTimeFormat =
-      NewObjectWithGivenProto<RelativeTimeFormatObject>(cx, proto);
+      NewObjectWithClassProto<RelativeTimeFormatObject>(cx, proto);
   if (!relativeTimeFormat) {
     return false;
   }
 
   HandleValue locales = args.get(0);
   HandleValue options = args.get(1);
 
   // Step 3.
@@ -127,57 +136,16 @@ void js::RelativeTimeFormatObject::final
   MOZ_ASSERT(fop->onMainThread());
 
   if (URelativeDateTimeFormatter* rtf =
           obj->as<RelativeTimeFormatObject>().getRelativeDateTimeFormatter()) {
     ureldatefmt_close(rtf);
   }
 }
 
-JSObject* js::CreateRelativeTimeFormatPrototype(JSContext* cx,
-                                                HandleObject Intl,
-                                                Handle<GlobalObject*> global) {
-  RootedFunction ctor(cx);
-  ctor = global->createConstructor(cx, &RelativeTimeFormat,
-                                   cx->names().RelativeTimeFormat, 0);
-  if (!ctor) {
-    return nullptr;
-  }
-
-  RootedObject proto(
-      cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
-  if (!proto) {
-    return nullptr;
-  }
-
-  if (!LinkConstructorAndPrototype(cx, ctor, proto)) {
-    return nullptr;
-  }
-
-  if (!JS_DefineFunctions(cx, ctor, relativeTimeFormat_static_methods)) {
-    return nullptr;
-  }
-
-  if (!JS_DefineFunctions(cx, proto, relativeTimeFormat_methods)) {
-    return nullptr;
-  }
-
-  if (!JS_DefineProperties(cx, proto, relativeTimeFormat_properties)) {
-    return nullptr;
-  }
-
-  RootedValue ctorValue(cx, ObjectValue(*ctor));
-  if (!DefineDataProperty(cx, Intl, cx->names().RelativeTimeFormat, ctorValue,
-                          0)) {
-    return nullptr;
-  }
-
-  return proto;
-}
-
 /**
  * Returns a new URelativeDateTimeFormatter with the locale and options of the
  * given RelativeTimeFormatObject.
  */
 static URelativeDateTimeFormatter* NewURelativeDateTimeFormatter(
     JSContext* cx, Handle<RelativeTimeFormatObject*> relativeTimeFormat) {
   RootedObject internals(cx, intl::GetInternalsObject(cx, relativeTimeFormat));
   if (!internals) {
--- a/js/src/builtin/intl/RelativeTimeFormat.h
+++ b/js/src/builtin/intl/RelativeTimeFormat.h
@@ -17,16 +17,17 @@
 
 struct URelativeDateTimeFormatter;
 
 namespace js {
 
 class RelativeTimeFormatObject : public NativeObject {
  public:
   static const JSClass class_;
+  static const JSClass& protoClass_;
 
   static constexpr uint32_t INTERNALS_SLOT = 0;
   static constexpr uint32_t URELATIVE_TIME_FORMAT_SLOT = 1;
   static constexpr uint32_t SLOT_COUNT = 2;
 
   static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT,
                 "INTERNALS_SLOT must match self-hosting define for internals "
                 "object slot");
@@ -40,24 +41,21 @@ class RelativeTimeFormatObject : public 
   }
 
   void setRelativeDateTimeFormatter(URelativeDateTimeFormatter* rtf) {
     setFixedSlot(URELATIVE_TIME_FORMAT_SLOT, PrivateValue(rtf));
   }
 
  private:
   static const JSClassOps classOps_;
+  static const ClassSpec classSpec_;
 
   static void finalize(JSFreeOp* fop, JSObject* obj);
 };
 
-extern JSObject* CreateRelativeTimeFormatPrototype(
-    JSContext* cx, JS::Handle<JSObject*> Intl,
-    JS::Handle<GlobalObject*> global);
-
 /**
  * Returns a relative time as a string formatted according to the effective
  * locale and the formatting options of the given RelativeTimeFormat.
  *
  * |t| should be a number representing a number to be formatted.
  * |unit| should be "second", "minute", "hour", "day", "week", "month",
  *                  "quarter", or "year".
  * |numeric| should be "always" or "auto".
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -256,18 +256,22 @@ DefaultJitOptions::DefaultJitOptions() {
   // compiling a new wasm module, independently of other heuristics, and
   // should be delayed to test both baseline and ion paths in compiled code,
   // as well as the transition from one tier to the other.
   SET_DEFAULT(wasmDelayTier2, false);
 
   // Until which wasm bytecode size should we accumulate functions, in order
   // to compile efficiently on helper threads. Baseline code compiles much
   // faster than Ion code so use scaled thresholds (see also bug 1320374).
+  // Cranelift compiles at about half the speed of Ion, but is much more
+  // affected by malloc/free costs, so set its threshold relatively high, in
+  // order to reduce overall allocation costs.  See bug 1586791.
   SET_DEFAULT(wasmBatchBaselineThreshold, 10000);
   SET_DEFAULT(wasmBatchIonThreshold, 1100);
+  SET_DEFAULT(wasmBatchCraneliftThreshold, 5000);
 
 #ifdef JS_TRACE_LOGGING
   // Toggles whether the traceLogger should be on or off.  In either case,
   // some data structures will always be created and initialized such as
   // the traceLoggerState.  However, unless this option is set to true
   // the traceLogger will not be recording any events.
   SET_DEFAULT(enableTraceLogger, false);
 #endif
--- a/js/src/jit/JitOptions.h
+++ b/js/src/jit/JitOptions.h
@@ -93,18 +93,19 @@ struct DefaultJitOptions {
   uint32_t branchPruningInstFactor;
   uint32_t branchPruningBlockSpanFactor;
   uint32_t branchPruningEffectfulInstFactor;
   uint32_t branchPruningThreshold;
   uint32_t ionMaxScriptSize;
   uint32_t ionMaxScriptSizeMainThread;
   uint32_t ionMaxLocalsAndArgs;
   uint32_t ionMaxLocalsAndArgsMainThread;
+  uint32_t wasmBatchBaselineThreshold;
   uint32_t wasmBatchIonThreshold;
-  uint32_t wasmBatchBaselineThreshold;
+  uint32_t wasmBatchCraneliftThreshold;
   mozilla::Maybe<IonRegisterAllocator> forcedRegisterAllocator;
 
   // Spectre mitigation flags. Each mitigation has its own flag in order to
   // measure the effectiveness of each mitigation with various proof of
   // concept.
   bool spectreIndexMasking;
   bool spectreObjectMitigationsBarriers;
   bool spectreObjectMitigationsMisc;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -906,17 +906,19 @@ JS_PUBLIC_API bool JS_ResolveStandardCla
 
   if (stdnm && GlobalObject::skipDeselectedConstructor(cx, stdnm->key)) {
     stdnm = nullptr;
   }
 
   // If this class is anonymous, then it doesn't exist as a global
   // property, so we won't resolve anything.
   JSProtoKey key = stdnm ? stdnm->key : JSProto_Null;
-  if (key != JSProto_Null) {
+  if (key != JSProto_Null && key != JSProto_AsyncFunction &&
+      key != JSProto_GeneratorFunction &&
+      key != JSProto_AsyncGeneratorFunction) {
     const JSClass* clasp = ProtoKeyToClass(key);
     if (!clasp || clasp->specShouldDefineConstructor()) {
       if (!GlobalObject::ensureConstructor(cx, global, key)) {
         return false;
       }
 
       *resolved = true;
       return true;
@@ -982,16 +984,22 @@ static bool EnumerateStandardClassesInTa
     if (!includeResolved && global->isStandardClassResolved(key)) {
       continue;
     }
 
     if (GlobalObject::skipDeselectedConstructor(cx, key)) {
       continue;
     }
 
+    // Async(Function|Generator) and Generator don't yet use ClassSpec.
+    if (key == JSProto_AsyncFunction || key == JSProto_GeneratorFunction ||
+        key == JSProto_AsyncGeneratorFunction) {
+      continue;
+    }
+
     if (const JSClass* clasp = ProtoKeyToClass(key)) {
       if (!clasp->specShouldDefineConstructor()) {
         continue;
       }
     }
 
     jsid id = NameToId(AtomStateOffsetToName(cx->names(), table[i].atomOffset));
     if (!properties.append(id)) {
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -2602,17 +2602,16 @@ extern JS_FRIEND_API JSObject* ToWindowI
 // and emphatically not shippable on the web, and it *must* be fixed before
 // this functionality can be exposed in the real world. (There are also some
 // questions about whether the format exposed here is the *right* one to
 // standardize, that will also need to be resolved to ship this.)
 extern bool AddMozDateTimeFormatConstructor(JSContext* cx,
                                             JS::Handle<JSObject*> intl);
 
 // Create and add the Intl.Locale constructor function to the provided object.
-// This function throws if called more than once per realm/global object.
 extern bool AddLocaleConstructor(JSContext* cx, JS::Handle<JSObject*> intl);
 #endif  // ENABLE_INTL_API
 
 class MOZ_STACK_CLASS JS_FRIEND_API AutoAssertNoContentJS {
  public:
   explicit AutoAssertNoContentJS(JSContext* cx);
   ~AutoAssertNoContentJS();
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/Proxy/revoked-get-function-realm-typeerror.js
@@ -0,0 +1,119 @@
+var constructors = [
+    // 19.1 Object Objects
+    {constructor: Object},
+
+    // 19.2 Function Objects
+    {constructor: Function},
+
+    // 19.3 Boolean Objects
+    {constructor: Boolean},
+
+    // 19.5 Error Objects
+    {constructor: Error},
+
+    // 19.5.5 Native Error Types Used in This Standard
+    {constructor: EvalError},
+    {constructor: RangeError},
+    {constructor: ReferenceError},
+    {constructor: SyntaxError},
+    {constructor: TypeError},
+    {constructor: URIError},
+
+    // 20.1 Number Objects
+    {constructor: Number},
+
+    // 20.3 Date Objects
+    {constructor: Date},
+
+    // 21.1 String Objects
+    {constructor: String},
+
+    // 21.2 RegExp (Regular Expression) Objects
+    {constructor: RegExp},
+
+    // 22.1 Array Objects
+    {constructor: Array},
+
+    // 22.2 TypedArray Objects
+    {constructor: Int8Array},
+
+    // 23.1 Map Objects
+    {constructor: Map},
+
+    // 23.2 Set Objects
+    {constructor: Set},
+
+    // 23.3 WeakMap Objects
+    {constructor: WeakMap},
+
+    // 23.4 WeakSet Objects
+    {constructor: WeakSet},
+
+    // 24.1 ArrayBuffer Objects
+    {constructor: ArrayBuffer},
+
+    // 24.2 SharedArrayBuffer Objects
+    ...(typeof SharedArrayBuffer === "function" ? [{constructor: SharedArrayBuffer}] : []),
+
+    // 24.3 DataView Objects
+    {constructor: DataView, args: [new ArrayBuffer(0)]},
+
+    // 25.2 GeneratorFunction Objects
+    {constructor: function*(){}.constructor},
+
+    // 25.3 AsyncGeneratorFunction Objects
+    {constructor: async function*(){}.constructor},
+
+    // 25.6 Promise Objects
+    {constructor: Promise, args: [function(){}]},
+
+    // 25.7 AsyncFunction Objects
+    {constructor: async function(){}.constructor},
+
+    // 9.2 ECMAScript Function Objects
+    {constructor: function(){}},
+
+    // Intl can be disabled at compile-time.
+    ...(typeof Intl !== "undefined" ? [
+        // 10 Collator Objects
+        {constructor: Intl.Collator},
+
+        // 11 NumberFormat Objects
+        {constructor: Intl.NumberFormat},
+
+        // 12 DateTimeFormat Objects
+        {constructor: Intl.DateTimeFormat},
+
+        // 13 PluralRules Objects
+        {constructor: Intl.PluralRules},
+
+        // Intl.RelativeTimeFormat proposal
+        {constructor: Intl.RelativeTimeFormat},
+
+        // Intl.Locale is not yet enabled by default.
+        ...(Intl.Locale ? [Intl.Locale] : []),
+    ] : []),
+];
+
+for (let {constructor, args = []} of constructors) {
+    let revoked = 0;
+    let {proxy, revoke} = Proxy.revocable(function(){}, {
+        get(t, pk, r) {
+            if (pk === "prototype") {
+                revoked++;
+                revoke();
+                return undefined;
+            }
+            return Reflect.get(t, pk, r);
+        }
+    });
+
+    assertThrowsInstanceOf(() => {
+        Reflect.construct(constructor, args, proxy);
+    }, TypeError);
+
+    assertEq(revoked, 1);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
--- a/js/src/vm/AsyncFunction.cpp
+++ b/js/src/vm/AsyncFunction.cpp
@@ -16,56 +16,49 @@
 #include "vm/SelfHosting.h"
 
 #include "vm/JSObject-inl.h"
 
 using namespace js;
 
 using mozilla::Maybe;
 
-/* static */
-bool GlobalObject::initAsyncFunction(JSContext* cx,
-                                     Handle<GlobalObject*> global) {
-  if (global->getReservedSlot(ASYNC_FUNCTION_PROTO).isObject()) {
-    return true;
-  }
-
+JSObject* js::InitAsyncFunction(JSContext* cx, Handle<GlobalObject*> global) {
   RootedObject asyncFunctionProto(
       cx, NewSingletonObjectWithFunctionPrototype(cx, global));
   if (!asyncFunctionProto) {
-    return false;
+    return nullptr;
   }
 
   if (!DefineToStringTag(cx, asyncFunctionProto, cx->names().AsyncFunction)) {
-    return false;
+    return nullptr;
   }
 
   RootedObject proto(
       cx, GlobalObject::getOrCreateFunctionConstructor(cx, cx->global()));
   if (!proto) {
-    return false;
+    return nullptr;
   }
   HandlePropertyName name = cx->names().AsyncFunction;
   RootedObject asyncFunction(
       cx,
       NewFunctionWithProto(cx, AsyncFunctionConstructor, 1,
                            FunctionFlags::NATIVE_CTOR, nullptr, name, proto));
   if (!asyncFunction) {
-    return false;
+    return nullptr;
   }
   if (!LinkConstructorAndPrototype(cx, asyncFunction, asyncFunctionProto,
                                    JSPROP_PERMANENT | JSPROP_READONLY,
                                    JSPROP_READONLY)) {
-    return false;
+    return nullptr;
   }
 
-  global->setReservedSlot(ASYNC_FUNCTION, ObjectValue(*asyncFunction));
-  global->setReservedSlot(ASYNC_FUNCTION_PROTO,
-                          ObjectValue(*asyncFunctionProto));
-  return true;
+  global->setConstructor(JSProto_AsyncFunction, ObjectValue(*asyncFunction));
+  global->setPrototype(JSProto_AsyncFunction, ObjectValue(*asyncFunctionProto));
+  return asyncFunction;
 }
 
 enum class ResumeKind { Normal, Throw };
 
 // ES2020 draft rev a09fc232c137800dbf51b6204f37fdede4ba1646
 // 6.2.3.1.1 Await Fulfilled Functions
 // 6.2.3.1.2 Await Rejected Functions
 static bool AsyncFunctionResume(JSContext* cx,
--- a/js/src/vm/AsyncFunction.h
+++ b/js/src/vm/AsyncFunction.h
@@ -11,16 +11,17 @@
 #include "js/Class.h"
 #include "vm/GeneratorObject.h"
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 
 namespace js {
 
 class AsyncFunctionGeneratorObject;
+class GlobalObject;
 
 // Resume the async function when the `await` operand resolves.
 // Split into two functions depending on whether the awaited value was
 // fulfilled or rejected.
 MOZ_MUST_USE bool AsyncFunctionAwaitedFulfilled(
     JSContext* cx, Handle<AsyncFunctionGeneratorObject*> generator,
     HandleValue value);
 
@@ -50,11 +51,14 @@ class AsyncFunctionGeneratorObject : pub
   static AsyncFunctionGeneratorObject* create(JSContext* cx,
                                               HandleFunction asyncGen);
 
   PromiseObject* promise() {
     return &getFixedSlot(PROMISE_SLOT).toObject().as<PromiseObject>();
   }
 };
 
+extern JSObject* InitAsyncFunction(JSContext* cx,
+                                   js::Handle<GlobalObject*> global);
+
 }  // namespace js
 
 #endif /* vm_AsyncFunction_h */
--- a/js/src/vm/AsyncIteration.cpp
+++ b/js/src/vm/AsyncIteration.cpp
@@ -401,94 +401,121 @@ static const JSFunctionSpec async_from_s
     JS_FN("throw", AsyncFromSyncIteratorThrow, 1, 0),
     JS_FN("return", AsyncFromSyncIteratorReturn, 1, 0), JS_FS_END};
 
 static const JSFunctionSpec async_generator_methods[] = {
     JS_FN("next", AsyncGeneratorNext, 1, 0),
     JS_FN("throw", AsyncGeneratorThrow, 1, 0),
     JS_FN("return", AsyncGeneratorReturn, 1, 0), JS_FS_END};
 
-/* static */ MOZ_MUST_USE bool GlobalObject::initAsyncGenerators(
-    JSContext* cx, Handle<GlobalObject*> global) {
+bool GlobalObject::initAsyncIteratorProto(JSContext* cx,
+                                          Handle<GlobalObject*> global) {
   if (global->getReservedSlot(ASYNC_ITERATOR_PROTO).isObject()) {
     return true;
   }
 
   // 25.1.3 The %AsyncIteratorPrototype% Object
   RootedObject asyncIterProto(
       cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
   if (!asyncIterProto) {
     return false;
   }
   if (!DefinePropertiesAndFunctions(cx, asyncIterProto, nullptr,
                                     async_iterator_proto_methods)) {
     return false;
   }
 
+  global->setReservedSlot(ASYNC_ITERATOR_PROTO, ObjectValue(*asyncIterProto));
+  return true;
+}
+
+bool GlobalObject::initAsyncFromSyncIteratorProto(
+    JSContext* cx, Handle<GlobalObject*> global) {
+  if (global->getReservedSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO).isObject()) {
+    return true;
+  }
+
+  RootedObject asyncIterProto(
+      cx, GlobalObject::getOrCreateAsyncIteratorPrototype(cx, global));
+  if (!asyncIterProto) {
+    return false;
+  }
+
   // 25.1.4.2 The %AsyncFromSyncIteratorPrototype% Object
   RootedObject asyncFromSyncIterProto(
       cx, GlobalObject::createBlankPrototypeInheriting(cx, &PlainObject::class_,
                                                        asyncIterProto));
   if (!asyncFromSyncIterProto) {
     return false;
   }
   if (!DefinePropertiesAndFunctions(cx, asyncFromSyncIterProto, nullptr,
                                     async_from_sync_iter_methods) ||
       !DefineToStringTag(cx, asyncFromSyncIterProto,
                          cx->names().AsyncFromSyncIterator)) {
     return false;
   }
 
+  global->setReservedSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO,
+                          ObjectValue(*asyncFromSyncIterProto));
+  return true;
+}
+
+JSObject* js::InitAsyncGeneratorFunction(JSContext* cx,
+                                         Handle<GlobalObject*> global) {
+  RootedObject asyncIterProto(
+      cx, GlobalObject::getOrCreateAsyncIteratorPrototype(cx, global));
+  if (!asyncIterProto) {
+    return nullptr;
+  }
+
   // 25.5 AsyncGenerator Objects
   RootedObject asyncGenProto(cx, GlobalObject::createBlankPrototypeInheriting(
                                      cx, &PlainObject::class_, asyncIterProto));
   if (!asyncGenProto) {
-    return false;
+    return nullptr;
   }
   if (!DefinePropertiesAndFunctions(cx, asyncGenProto, nullptr,
                                     async_generator_methods) ||
       !DefineToStringTag(cx, asyncGenProto, cx->names().AsyncGenerator)) {
-    return false;
+    return nullptr;
   }
 
   // 25.3.3 Properties of the AsyncGeneratorFunction Prototype Object
   RootedObject asyncGenerator(
       cx, NewSingletonObjectWithFunctionPrototype(cx, global));
   if (!asyncGenerator) {
-    return false;
+    return nullptr;
   }
   if (!LinkConstructorAndPrototype(cx, asyncGenerator, asyncGenProto,
                                    JSPROP_READONLY, JSPROP_READONLY) ||
       !DefineToStringTag(cx, asyncGenerator,
                          cx->names().AsyncGeneratorFunction)) {
-    return false;
+    return nullptr;
   }
 
   RootedObject proto(
       cx, GlobalObject::getOrCreateFunctionConstructor(cx, cx->global()));
   if (!proto) {
-    return false;
+    return nullptr;
   }
   HandlePropertyName name = cx->names().AsyncGeneratorFunction;
 
   // 25.3.1 The AsyncGeneratorFunction Constructor
   RootedObject asyncGenFunction(
       cx, NewFunctionWithProto(cx, AsyncGeneratorConstructor, 1,
                                FunctionFlags::NATIVE_CTOR, nullptr, name, proto,
                                gc::AllocKind::FUNCTION, SingletonObject));
   if (!asyncGenFunction) {
-    return false;
+    return nullptr;
   }
   if (!LinkConstructorAndPrototype(cx, asyncGenFunction, asyncGenerator,
                                    JSPROP_PERMANENT | JSPROP_READONLY,
                                    JSPROP_READONLY)) {
-    return false;
+    return nullptr;
   }
 
-  global->setReservedSlot(ASYNC_ITERATOR_PROTO, ObjectValue(*asyncIterProto));
-  global->setReservedSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO,
-                          ObjectValue(*asyncFromSyncIterProto));
-  global->setReservedSlot(ASYNC_GENERATOR, ObjectValue(*asyncGenerator));
-  global->setReservedSlot(ASYNC_GENERATOR_FUNCTION,
-                          ObjectValue(*asyncGenFunction));
-  global->setReservedSlot(ASYNC_GENERATOR_PROTO, ObjectValue(*asyncGenProto));
-  return true;
+  global->setAsyncGeneratorPrototype(asyncGenProto);
+  global->setConstructor(JSProto_AsyncGeneratorFunction,
+                         ObjectValue(*asyncGenFunction));
+  global->setPrototype(JSProto_AsyncGeneratorFunction,
+                       ObjectValue(*asyncGenerator));
+  return asyncGenFunction;
 }
--- a/js/src/vm/AsyncIteration.h
+++ b/js/src/vm/AsyncIteration.h
@@ -12,16 +12,17 @@
 #include "vm/GeneratorObject.h"
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 #include "vm/List.h"
 
 namespace js {
 
 class AsyncGeneratorObject;
+class GlobalObject;
 
 // Resume the async generator when the `await` operand fulfills to `value`.
 MOZ_MUST_USE bool AsyncGeneratorAwaitedFulfilled(
     JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
     HandleValue value);
 
 // Resume the async generator when the `await` operand rejects with `reason`.
 MOZ_MUST_USE bool AsyncGeneratorAwaitedRejected(
@@ -289,11 +290,14 @@ class AsyncFromSyncIteratorObject : publ
 
   const Value& nextMethod() const { return getFixedSlot(Slot_NextMethod); }
 };
 
 MOZ_MUST_USE bool AsyncGeneratorResume(
     JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
     CompletionKind completionKind, HandleValue argument);
 
+extern JSObject* InitAsyncGeneratorFunction(JSContext* cx,
+                                            js::Handle<GlobalObject*> global);
+
 }  // namespace js
 
 #endif /* vm_AsyncIteration_h */
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -28,22 +28,19 @@
   MACRO(ArraySpeciesCreate, ArraySpeciesCreate, "ArraySpeciesCreate")          \
   MACRO(ArrayToLocaleString, ArrayToLocaleString, "ArrayToLocaleString")       \
   MACRO(ArrayType, ArrayType, "ArrayType")                                     \
   MACRO(ArrayValues, ArrayValues, "$ArrayValues")                              \
   MACRO(as, as, "as")                                                          \
   MACRO(Async, Async, "Async")                                                 \
   MACRO(AsyncFromSyncIterator, AsyncFromSyncIterator,                          \
         "Async-from-Sync Iterator")                                            \
-  MACRO(AsyncFunction, AsyncFunction, "AsyncFunction")                         \
   MACRO(AsyncFunctionNext, AsyncFunctionNext, "AsyncFunctionNext")             \
   MACRO(AsyncFunctionThrow, AsyncFunctionThrow, "AsyncFunctionThrow")          \
   MACRO(AsyncGenerator, AsyncGenerator, "AsyncGenerator")                      \
-  MACRO(AsyncGeneratorFunction, AsyncGeneratorFunction,                        \
-        "AsyncGeneratorFunction")                                              \
   MACRO(AsyncGeneratorNext, AsyncGeneratorNext, "AsyncGeneratorNext")          \
   MACRO(AsyncGeneratorReturn, AsyncGeneratorReturn, "AsyncGeneratorReturn")    \
   MACRO(AsyncGeneratorThrow, AsyncGeneratorThrow, "AsyncGeneratorThrow")       \
   MACRO(AsyncWrapped, AsyncWrapped, "AsyncWrapped")                            \
   MACRO(async, async, "async")                                                 \
   MACRO(autoAllocateChunkSize, autoAllocateChunkSize, "autoAllocateChunkSize") \
   MACRO(await, await, "await")                                                 \
   MACRO(bigint64, bigint64, "bigint64")                                        \
@@ -74,17 +71,16 @@
         "CallRegExpMethodIfWrapped")                                           \
   MACRO(cancel, cancel, "cancel")                                              \
   MACRO(case, case_, "case")                                                   \
   MACRO(caseFirst, caseFirst, "caseFirst")                                     \
   MACRO(catch, catch_, "catch")                                                \
   MACRO(class, class_, "class")                                                \
   MACRO(close, close, "close")                                                 \
   MACRO(collation, collation, "collation")                                     \
-  MACRO(Collator, Collator, "Collator")                                        \
   MACRO(collections, collections, "collections")                               \
   MACRO(columnNumber, columnNumber, "columnNumber")                            \
   MACRO(comma, comma, ",")                                                     \
   MACRO(compare, compare, "compare")                                           \
   MACRO(configurable, configurable, "configurable")                            \
   MACRO(const, const_, "const")                                                \
   MACRO(construct, construct, "construct")                                     \
   MACRO(constructContentFunction, constructContentFunction,                    \
@@ -99,17 +95,16 @@
   MACRO(compact, compact, "compact")                                           \
   MACRO(compactDisplay, compactDisplay, "compactDisplay")                      \
   MACRO(count, count, "count")                                                 \
   MACRO(CreateResolvingFunctions, CreateResolvingFunctions,                    \
         "CreateResolvingFunctions")                                            \
   MACRO(currency, currency, "currency")                                        \
   MACRO(currencyDisplay, currencyDisplay, "currencyDisplay")                   \
   MACRO(currencySign, currencySign, "currencySign")                            \
-  MACRO(DateTimeFormat, DateTimeFormat, "DateTimeFormat")                      \
   MACRO(day, day, "day")                                                       \
   MACRO(dayPeriod, dayPeriod, "dayPeriod")                                     \
   MACRO(debugger, debugger, "debugger")                                        \
   MACRO(decimal, decimal, "decimal")                                           \
   MACRO(decodeURI, decodeURI, "decodeURI")                                     \
   MACRO(decodeURIComponent, decodeURIComponent, "decodeURIComponent")          \
   MACRO(DefaultBaseClassConstructor, DefaultBaseClassConstructor,              \
         "DefaultBaseClassConstructor")                                         \
@@ -179,17 +174,16 @@
   MACRO(frame, frame, "frame")                                                 \
   MACRO(from, from, "from")                                                    \
   MACRO(fulfilled, fulfilled, "fulfilled")                                     \
   MACRO(futexNotEqual, futexNotEqual, "not-equal")                             \
   MACRO(futexOK, futexOK, "ok")                                                \
   MACRO(futexTimedOut, futexTimedOut, "timed-out")                             \
   MACRO(gcCycleNumber, gcCycleNumber, "gcCycleNumber")                         \
   MACRO(Generator, Generator, "Generator")                                     \
-  MACRO(GeneratorFunction, GeneratorFunction, "GeneratorFunction")             \
   MACRO(GeneratorNext, GeneratorNext, "GeneratorNext")                         \
   MACRO(GeneratorReturn, GeneratorReturn, "GeneratorReturn")                   \
   MACRO(GeneratorThrow, GeneratorThrow, "GeneratorThrow")                      \
   MACRO(get, get, "get")                                                       \
   MACRO(GetInternalError, GetInternalError, "GetInternalError")                \
   MACRO(getBigInt64, getBigInt64, "getBigInt64")                               \
   MACRO(getBigUint64, getBigUint64, "getBigUint64")                            \
   MACRO(getInternals, getInternals, "getInternals")                            \
@@ -263,17 +257,16 @@
   MACRO(language, language, "language")                                        \
   MACRO(lastIndex, lastIndex, "lastIndex")                                     \
   MACRO(length, length, "length")                                              \
   MACRO(let, let, "let")                                                       \
   MACRO(line, line, "line")                                                    \
   MACRO(lineNumber, lineNumber, "lineNumber")                                  \
   MACRO(literal, literal, "literal")                                           \
   MACRO(loc, loc, "loc")                                                       \
-  MACRO(Locale, Locale, "Locale")                                              \
   MACRO(locale, locale, "locale")                                              \
   MACRO(lookupGetter, lookupGetter, "__lookupGetter__")                        \
   MACRO(lookupSetter, lookupSetter, "__lookupSetter__")                        \
   MACRO(ltr, ltr, "ltr")                                                       \
   MACRO(MapConstructorInit, MapConstructorInit, "MapConstructorInit")          \
   MACRO(MapIterator, MapIterator, "Map Iterator")                              \
   MACRO(maxColumn, maxColumn, "maxColumn")                                     \
   MACRO(maximumFractionDigits, maximumFractionDigits, "maximumFractionDigits") \
@@ -311,17 +304,16 @@
   MACRO(NFD, NFD, "NFD")                                                       \
   MACRO(NFKC, NFKC, "NFKC")                                                    \
   MACRO(NFKD, NFKD, "NFKD")                                                    \
   MACRO(noFilename, noFilename, "noFilename")                                  \
   MACRO(nonincrementalReason, nonincrementalReason, "nonincrementalReason")    \
   MACRO(noStack, noStack, "noStack")                                           \
   MACRO(notation, notation, "notation")                                        \
   MACRO(notes, notes, "notes")                                                 \
-  MACRO(NumberFormat, NumberFormat, "NumberFormat")                            \
   MACRO(numberingSystem, numberingSystem, "numberingSystem")                   \
   MACRO(numeric, numeric, "numeric")                                           \
   MACRO(objectArguments, objectArguments, "[object Arguments]")                \
   MACRO(objectArray, objectArray, "[object Array]")                            \
   MACRO(objectBigInt, objectBigInt, "[object BigInt]")                         \
   MACRO(objectBoolean, objectBoolean, "[object Boolean]")                      \
   MACRO(objectDate, objectDate, "[object Date]")                               \
   MACRO(objectError, objectError, "[object Error]")                            \
@@ -340,17 +332,16 @@
   MACRO(outOfMemory, outOfMemory, "out of memory")                             \
   MACRO(ownKeys, ownKeys, "ownKeys")                                           \
   MACRO(Object_valueOf, Object_valueOf, "Object_valueOf")                      \
   MACRO(package, package, "package")                                           \
   MACRO(parseFloat, parseFloat, "parseFloat")                                  \
   MACRO(parseInt, parseInt, "parseInt")                                        \
   MACRO(pattern, pattern, "pattern")                                           \
   MACRO(pending, pending, "pending")                                           \
-  MACRO(PluralRules, PluralRules, "PluralRules")                               \
   MACRO(percentSign, percentSign, "percentSign")                               \
   MACRO(plusSign, plusSign, "plusSign")                                        \
   MACRO(public, public_, "public")                                             \
   MACRO(pull, pull, "pull")                                                    \
   MACRO(preventExtensions, preventExtensions, "preventExtensions")             \
   MACRO(private, private_, "private")                                          \
   MACRO(promise, promise, "promise")                                           \
   MACRO(propertyIsEnumerable, propertyIsEnumerable, "propertyIsEnumerable")    \
@@ -368,17 +359,16 @@
   MACRO(RegExpStringIterator, RegExpStringIterator, "RegExp String Iterator")  \
   MACRO(RegExpTester, RegExpTester, "RegExpTester")                            \
   MACRO(RegExp_prototype_Exec, RegExp_prototype_Exec, "RegExp_prototype_Exec") \
   MACRO(region, region, "region")                                              \
   MACRO(Reify, Reify, "Reify")                                                 \
   MACRO(reject, reject, "reject")                                              \
   MACRO(rejected, rejected, "rejected")                                        \
   MACRO(relatedYear, relatedYear, "relatedYear")                               \
-  MACRO(RelativeTimeFormat, RelativeTimeFormat, "RelativeTimeFormat")          \
   MACRO(RelativeTimeFormatFormat, RelativeTimeFormatFormat,                    \
         "Intl_RelativeTimeFormat_Format")                                      \
   MACRO(RequireObjectCoercible, RequireObjectCoercible,                        \
         "RequireObjectCoercible")                                              \
   MACRO(resolve, resolve, "resolve")                                           \
   MACRO(resumeGenerator, resumeGenerator, "resumeGenerator")                   \
   MACRO(return, return_, "return")                                             \
   MACRO(revoke, revoke, "revoke")                                              \
--- a/js/src/vm/GeneratorObject.cpp
+++ b/js/src/vm/GeneratorObject.cpp
@@ -235,74 +235,70 @@ JSObject* js::NewSingletonObjectWithFunc
     return nullptr;
   }
   if (!JSObject::setDelegate(cx, obj)) {
     return nullptr;
   }
   return obj;
 }
 
-/* static */
-bool GlobalObject::initGenerators(JSContext* cx, Handle<GlobalObject*> global) {
-  if (global->getReservedSlot(GENERATOR_OBJECT_PROTO).isObject()) {
-    return true;
-  }
-
+JSObject* js::InitGeneratorFunction(JSContext* cx,
+                                    Handle<GlobalObject*> global) {
   RootedObject iteratorProto(
       cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
   if (!iteratorProto) {
-    return false;
+    return nullptr;
   }
 
   RootedObject genObjectProto(cx, GlobalObject::createBlankPrototypeInheriting(
                                       cx, &PlainObject::class_, iteratorProto));
   if (!genObjectProto) {
-    return false;
+    return nullptr;
   }
   if (!DefinePropertiesAndFunctions(cx, genObjectProto, nullptr,
                                     generator_methods) ||
       !DefineToStringTag(cx, genObjectProto, cx->names().Generator)) {
-    return false;
+    return nullptr;
   }
 
   RootedObject genFunctionProto(
       cx, NewSingletonObjectWithFunctionPrototype(cx, global));
   if (!genFunctionProto) {
-    return false;
+    return nullptr;
   }
   if (!LinkConstructorAndPrototype(cx, genFunctionProto, genObjectProto,
                                    JSPROP_READONLY, JSPROP_READONLY) ||
       !DefineToStringTag(cx, genFunctionProto, cx->names().GeneratorFunction)) {
-    return false;
+    return nullptr;
   }
 
   RootedObject proto(
       cx, GlobalObject::getOrCreateFunctionConstructor(cx, cx->global()));
   if (!proto) {
-    return false;
+    return nullptr;
   }
   HandlePropertyName name = cx->names().GeneratorFunction;
   RootedObject genFunction(
       cx, NewFunctionWithProto(cx, Generator, 1, FunctionFlags::NATIVE_CTOR,
                                nullptr, name, proto, gc::AllocKind::FUNCTION,
                                SingletonObject));
   if (!genFunction) {
-    return false;
+    return nullptr;
   }
   if (!LinkConstructorAndPrototype(cx, genFunction, genFunctionProto,
                                    JSPROP_PERMANENT | JSPROP_READONLY,
                                    JSPROP_READONLY)) {
-    return false;
+    return nullptr;
   }
 
-  global->setReservedSlot(GENERATOR_OBJECT_PROTO, ObjectValue(*genObjectProto));
-  global->setReservedSlot(GENERATOR_FUNCTION, ObjectValue(*genFunction));
-  global->setReservedSlot(GENERATOR_FUNCTION_PROTO,
-                          ObjectValue(*genFunctionProto));
-  return true;
+  global->setGeneratorObjectPrototype(genObjectProto);
+  global->setConstructor(JSProto_GeneratorFunction, ObjectValue(*genFunction));
+  global->setPrototype(JSProto_GeneratorFunction,
+                       ObjectValue(*genFunctionProto));
+  return genFunction;
 }
 
 bool AbstractGeneratorObject::isAfterYield() {
   return isAfterYieldOrAwait(JSOP_YIELD);
 }
 
 bool AbstractGeneratorObject::isAfterAwait() {
   return isAfterYieldOrAwait(JSOP_AWAIT);
--- a/js/src/vm/GeneratorObject.h
+++ b/js/src/vm/GeneratorObject.h
@@ -11,16 +11,18 @@
 #include "vm/ArgumentsObject.h"
 #include "vm/ArrayObject.h"
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 #include "vm/Stack.h"
 
 namespace js {
 
+class GlobalObject;
+
 enum class GeneratorResumeKind { Next, Throw, Return };
 
 class AbstractGeneratorObject : public NativeObject {
  public:
   // Magic value stored in the resumeIndex slot when the generator is
   // running or closing. See the resumeIndex comment below.
   static const int32_t RESUME_INDEX_RUNNING = INT32_MAX;
 
@@ -218,14 +220,17 @@ bool GeneratorThrowOrReturn(JSContext* c
  *   only on the stack, and not the `.generator` pseudo-variable this function
  *   consults.
  */
 AbstractGeneratorObject* GetGeneratorObjectForFrame(JSContext* cx,
                                                     AbstractFramePtr frame);
 
 void SetGeneratorClosed(JSContext* cx, AbstractFramePtr frame);
 
+extern JSObject* InitGeneratorFunction(JSContext* cx,
+                                       js::Handle<GlobalObject*> global);
+
 }  // namespace js
 
 template <>
 bool JSObject::is<js::AbstractGeneratorObject>() const;
 
 #endif /* vm_GeneratorObject_h */
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -9,16 +9,24 @@
 #include "jsdate.h"
 #include "jsexn.h"
 #include "jsfriendapi.h"
 
 #include "builtin/AtomicsObject.h"
 #include "builtin/BigInt.h"
 #include "builtin/DataViewObject.h"
 #include "builtin/Eval.h"
+#ifdef ENABLE_INTL_API
+#  include "builtin/intl/Collator.h"
+#  include "builtin/intl/DateTimeFormat.h"
+#  include "builtin/intl/Locale.h"
+#  include "builtin/intl/NumberFormat.h"
+#  include "builtin/intl/PluralRules.h"
+#  include "builtin/intl/RelativeTimeFormat.h"
+#endif
 #include "builtin/MapObject.h"
 #include "builtin/ModuleObject.h"
 #include "builtin/Object.h"
 #include "builtin/Promise.h"
 #include "builtin/RegExp.h"
 #include "builtin/SelfHostingDefines.h"
 #include "builtin/Stream.h"
 #include "builtin/streams/QueueingStrategies.h"  // js::{ByteLength,Count}QueueingStrategy
@@ -28,18 +36,21 @@
 #include "builtin/streams/WritableStream.h"        // js::WritableStream
 #include "builtin/Symbol.h"
 #include "builtin/TypedObject.h"
 #include "builtin/WeakMapObject.h"
 #include "builtin/WeakSetObject.h"
 #include "debugger/DebugAPI.h"
 #include "gc/FreeOp.h"
 #include "js/ProtoKey.h"
+#include "vm/AsyncFunction.h"
+#include "vm/AsyncIteration.h"
 #include "vm/DateObject.h"
 #include "vm/EnvironmentObject.h"
+#include "vm/GeneratorObject.h"
 #include "vm/HelperThreads.h"
 #include "vm/JSContext.h"
 #include "vm/PIC.h"
 #include "vm/RegExpStatics.h"
 #include "vm/RegExpStaticsObject.h"
 
 #include "gc/FreeOp-inl.h"
 #include "vm/JSObject-inl.h"
@@ -386,17 +397,19 @@ bool GlobalObject::resolveOffThreadConst
                                                JSProtoKey key) {
   // Don't resolve constructors for off-thread parse globals. Instead create a
   // placeholder object for the prototype which we can use to find the real
   // prototype when the off-thread compartment is merged back into the target
   // compartment.
 
   MOZ_ASSERT(global->zone()->createdForHelperThread());
   MOZ_ASSERT(key == JSProto_Object || key == JSProto_Function ||
-             key == JSProto_Array || key == JSProto_RegExp);
+             key == JSProto_Array || key == JSProto_RegExp ||
+             key == JSProto_AsyncFunction || key == JSProto_GeneratorFunction ||
+             key == JSProto_AsyncGeneratorFunction);
 
   Rooted<OffThreadPlaceholderObject*> placeholder(cx);
   placeholder = OffThreadPlaceholderObject::New(cx, prototypeSlot(key));
   if (!placeholder) {
     return false;
   }
 
   if (key == JSProto_Object &&
@@ -423,20 +436,18 @@ JSObject* GlobalObject::createOffThreadO
                                               Handle<GlobalObject*> global,
                                               unsigned slot) {
   // Don't create prototype objects for off-thread parse globals. Instead
   // create a placeholder object which we can use to find the real prototype
   // when the off-thread compartment is merged back into the target
   // compartment.
 
   MOZ_ASSERT(global->zone()->createdForHelperThread());
-  MOZ_ASSERT(slot == GENERATOR_FUNCTION_PROTO || slot == ASYNC_FUNCTION_PROTO ||
-             slot == ASYNC_GENERATOR || slot == MODULE_PROTO ||
-             slot == IMPORT_ENTRY_PROTO || slot == EXPORT_ENTRY_PROTO ||
-             slot == REQUESTED_MODULE_PROTO);
+  MOZ_ASSERT(slot == MODULE_PROTO || slot == IMPORT_ENTRY_PROTO ||
+             slot == EXPORT_ENTRY_PROTO || slot == REQUESTED_MODULE_PROTO);
 
   auto placeholder = OffThreadPlaceholderObject::New(cx, slot);
   if (!placeholder) {
     return nullptr;
   }
 
   global->setSlot(slot, ObjectValue(*placeholder));
   return placeholder;
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -72,35 +72,21 @@ class GlobalObject : public NativeObject
 
     /* One-off properties stored after slots for built-ins. */
     EMPTY_GLOBAL_SCOPE,
     ITERATOR_PROTO,
     ARRAY_ITERATOR_PROTO,
     STRING_ITERATOR_PROTO,
     REGEXP_STRING_ITERATOR_PROTO,
     GENERATOR_OBJECT_PROTO,
-    GENERATOR_FUNCTION_PROTO,
-    GENERATOR_FUNCTION,
-    ASYNC_FUNCTION_PROTO,
-    ASYNC_FUNCTION,
     ASYNC_ITERATOR_PROTO,
     ASYNC_FROM_SYNC_ITERATOR_PROTO,
-    ASYNC_GENERATOR,
-    ASYNC_GENERATOR_FUNCTION,
     ASYNC_GENERATOR_PROTO,
     MAP_ITERATOR_PROTO,
     SET_ITERATOR_PROTO,
-    COLLATOR_PROTO,
-    NUMBER_FORMAT,
-    NUMBER_FORMAT_PROTO,
-    DATE_TIME_FORMAT,
-    DATE_TIME_FORMAT_PROTO,
-    PLURAL_RULES_PROTO,
-    RELATIVE_TIME_FORMAT_PROTO,
-    LOCALE_PROTO,
     MODULE_PROTO,
     IMPORT_ENTRY_PROTO,
     EXPORT_ENTRY_PROTO,
     REQUESTED_MODULE_PROTO,
     REGEXP_STATICS,
     RUNTIME_CODEGEN_ENABLED,
     DEBUGGERS,
     INTRINSICS,
@@ -284,48 +270,44 @@ class GlobalObject : public NativeObject
                                                       HandleObject proto);
 
   template <typename T>
   static T* createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global) {
     NativeObject* res = createBlankPrototype(cx, global, &T::class_);
     return res ? &res->template as<T>() : nullptr;
   }
 
-  static NativeObject* getOrCreateObjectPrototype(
+  static JSObject* getOrCreateObjectPrototype(JSContext* cx,
+                                              Handle<GlobalObject*> global) {
+    if (!global->functionObjectClassesInitialized()) {
+      if (!ensureConstructor(cx, global, JSProto_Object)) {
+        return nullptr;
+      }
+    }
+    return &global->getPrototype(JSProto_Object).toObject();
+  }
+
+  static JSObject* getOrCreateFunctionConstructor(
       JSContext* cx, Handle<GlobalObject*> global) {
     if (!global->functionObjectClassesInitialized()) {
       if (!ensureConstructor(cx, global, JSProto_Object)) {
         return nullptr;
       }
     }
-    return &global->getPrototype(JSProto_Object).toObject().as<NativeObject>();
+    return &global->getConstructor(JSProto_Function).toObject();
   }
 
-  static NativeObject* getOrCreateFunctionConstructor(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreateFunctionPrototype(JSContext* cx,
+                                                Handle<GlobalObject*> global) {
     if (!global->functionObjectClassesInitialized()) {
       if (!ensureConstructor(cx, global, JSProto_Object)) {
         return nullptr;
       }
     }
-    return &global->getConstructor(JSProto_Function)
-                .toObject()
-                .as<NativeObject>();
-  }
-
-  static NativeObject* getOrCreateFunctionPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    if (!global->functionObjectClassesInitialized()) {
-      if (!ensureConstructor(cx, global, JSProto_Object)) {
-        return nullptr;
-      }
-    }
-    return &global->getPrototype(JSProto_Function)
-                .toObject()
-                .as<NativeObject>();
+    return &global->getPrototype(JSProto_Function).toObject();
   }
 
   static NativeObject* getOrCreateArrayPrototype(JSContext* cx,
                                                  Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_Array)) {
       return nullptr;
     }
     return &global->getPrototype(JSProto_Array).toObject().as<NativeObject>();
@@ -333,97 +315,93 @@ class GlobalObject : public NativeObject
 
   NativeObject* maybeGetArrayPrototype() {
     if (classIsInitialized(JSProto_Array)) {
       return &getPrototype(JSProto_Array).toObject().as<NativeObject>();
     }
     return nullptr;
   }
 
-  static NativeObject* getOrCreateBooleanPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreateBooleanPrototype(JSContext* cx,
+                                               Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_Boolean)) {
       return nullptr;
     }
-    return &global->getPrototype(JSProto_Boolean).toObject().as<NativeObject>();
+    return &global->getPrototype(JSProto_Boolean).toObject();
   }
 
-  static NativeObject* getOrCreateNumberPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreateNumberPrototype(JSContext* cx,
+                                              Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_Number)) {
       return nullptr;
     }
-    return &global->getPrototype(JSProto_Number).toObject().as<NativeObject>();
+    return &global->getPrototype(JSProto_Number).toObject();
   }
 
-  static NativeObject* getOrCreateStringPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreateStringPrototype(JSContext* cx,
+                                              Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_String)) {
       return nullptr;
     }
-    return &global->getPrototype(JSProto_String).toObject().as<NativeObject>();
+    return &global->getPrototype(JSProto_String).toObject();
   }
 
-  static NativeObject* getOrCreateSymbolPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreateSymbolPrototype(JSContext* cx,
+                                              Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_Symbol)) {
       return nullptr;
     }
-    return &global->getPrototype(JSProto_Symbol).toObject().as<NativeObject>();
+    return &global->getPrototype(JSProto_Symbol).toObject();
   }
 
-  static NativeObject* getOrCreateBigIntPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreateBigIntPrototype(JSContext* cx,
+                                              Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_BigInt)) {
       return nullptr;
     }
-    return &global->getPrototype(JSProto_BigInt).toObject().as<NativeObject>();
+    return &global->getPrototype(JSProto_BigInt).toObject();
   }
 
-  static NativeObject* getOrCreatePromisePrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreatePromisePrototype(JSContext* cx,
+                                               Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_Promise)) {
       return nullptr;
     }
-    return &global->getPrototype(JSProto_Promise).toObject().as<NativeObject>();
+    return &global->getPrototype(JSProto_Promise).toObject();
   }
 
-  static NativeObject* getOrCreateRegExpPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreateRegExpPrototype(JSContext* cx,
+                                              Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_RegExp)) {
       return nullptr;
     }
-    return &global->getPrototype(JSProto_RegExp).toObject().as<NativeObject>();
+    return &global->getPrototype(JSProto_RegExp).toObject();
   }
 
   JSObject* maybeGetRegExpPrototype() {
     if (classIsInitialized(JSProto_RegExp)) {
       return &getPrototype(JSProto_RegExp).toObject();
     }
     return nullptr;
   }
 
-  static NativeObject* getOrCreateSavedFramePrototype(
+  static JSObject* getOrCreateSavedFramePrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_SavedFrame)) {
       return nullptr;
     }
-    return &global->getPrototype(JSProto_SavedFrame)
-                .toObject()
-                .as<NativeObject>();
+    return &global->getPrototype(JSProto_SavedFrame).toObject();
   }
 
-  static JSFunction* getOrCreateArrayBufferConstructor(
+  static JSObject* getOrCreateArrayBufferConstructor(
       JSContext* cx, Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_ArrayBuffer)) {
       return nullptr;
     }
-    return &global->getConstructor(JSProto_ArrayBuffer)
-                .toObject()
-                .as<JSFunction>();
+    return &global->getConstructor(JSProto_ArrayBuffer).toObject();
   }
 
   static JSObject* getOrCreateArrayBufferPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_ArrayBuffer)) {
       return nullptr;
     }
     return &global->getPrototype(JSProto_ArrayBuffer).toObject();
@@ -471,24 +449,16 @@ class GlobalObject : public NativeObject
   static NativeObject* getOrCreateWeakSetPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_WeakSet)) {
       return nullptr;
     }
     return &global->getPrototype(JSProto_WeakSet).toObject().as<NativeObject>();
   }
 
-#if ENABLE_INTL_API
-  static JSObject* getOrCreateIntlObject(JSContext* cx,
-                                         Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, APPLICATION_SLOTS + JSProto_Intl,
-                             initIntlObject);
-  }
-#endif
-
   static JSObject* getOrCreateTypedObjectModule(JSContext* cx,
                                                 Handle<GlobalObject*> global) {
     return getOrCreateObject(cx, global,
                              APPLICATION_SLOTS + JSProto_TypedObject,
                              initTypedObjectModule);
   }
 
   static TypeDescr* getOrCreateScalarTypeDescr(JSContext* cx,
@@ -496,64 +466,16 @@ class GlobalObject : public NativeObject
                                                Scalar::Type scalarType);
 
   static TypeDescr* getOrCreateReferenceTypeDescr(JSContext* cx,
                                                   Handle<GlobalObject*> global,
                                                   ReferenceType type);
 
   TypedObjectModuleObject& getTypedObjectModule() const;
 
-#if ENABLE_INTL_API
-  static JSObject* getOrCreateCollatorPrototype(JSContext* cx,
-                                                Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, COLLATOR_PROTO, initIntlObject);
-  }
-
-  static JSFunction* getOrCreateNumberFormatConstructor(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    JSObject* obj =
-        getOrCreateObject(cx, global, NUMBER_FORMAT, initIntlObject);
-    return obj ? &obj->as<JSFunction>() : nullptr;
-  }
-
-  static JSObject* getOrCreateNumberFormatPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, NUMBER_FORMAT_PROTO, initIntlObject);
-  }
-
-  static JSFunction* getOrCreateDateTimeFormatConstructor(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    JSObject* obj =
-        getOrCreateObject(cx, global, DATE_TIME_FORMAT, initIntlObject);
-    return obj ? &obj->as<JSFunction>() : nullptr;
-  }
-
-  static JSObject* getOrCreateDateTimeFormatPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, DATE_TIME_FORMAT_PROTO,
-                             initIntlObject);
-  }
-
-  static JSObject* getOrCreatePluralRulesPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, PLURAL_RULES_PROTO, initIntlObject);
-  }
-
-  static JSObject* getOrCreateRelativeTimeFormatPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, RELATIVE_TIME_FORMAT_PROTO,
-                             initIntlObject);
-  }
-
-  static JSObject* getOrCreateLocalePrototype(JSContext* cx,
-                                              Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, LOCALE_PROTO, initIntlObject);
-  }
-#endif  // ENABLE_INTL_API
-
   static bool ensureModulePrototypesCreated(JSContext* cx,
                                             Handle<GlobalObject*> global);
 
   static JSObject* getOrCreateModulePrototype(JSContext* cx,
                                               Handle<GlobalObject*> global) {
     return getOrCreateObject(cx, global, MODULE_PROTO, initModuleProto);
   }
 
@@ -606,105 +528,141 @@ class GlobalObject : public NativeObject
 
     return createObject(cx, global, slot, init);
   }
 
   static JSObject* createObject(JSContext* cx, Handle<GlobalObject*> global,
                                 unsigned slot, ObjectInitOp init);
 
  public:
-  static NativeObject* getOrCreateIteratorPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    return MaybeNativeObject(
-        getOrCreateObject(cx, global, ITERATOR_PROTO, initIteratorProto));
+  static JSObject* getOrCreateIteratorPrototype(JSContext* cx,
+                                                Handle<GlobalObject*> global) {
+    return getOrCreateObject(cx, global, ITERATOR_PROTO, initIteratorProto);
   }
 
   static NativeObject* getOrCreateArrayIteratorPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
     return MaybeNativeObject(getOrCreateObject(cx, global, ARRAY_ITERATOR_PROTO,
                                                initArrayIteratorProto));
   }
 
   NativeObject* maybeGetArrayIteratorPrototype() {
     Value v = getSlotRef(ARRAY_ITERATOR_PROTO);
     if (v.isObject()) {
       return &v.toObject().as<NativeObject>();
     }
     return nullptr;
   }
 
-  static NativeObject* getOrCreateStringIteratorPrototype(
+  static JSObject* getOrCreateStringIteratorPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
-    return MaybeNativeObject(getOrCreateObject(
-        cx, global, STRING_ITERATOR_PROTO, initStringIteratorProto));
+    return getOrCreateObject(cx, global, STRING_ITERATOR_PROTO,
+                             initStringIteratorProto);
   }
 
-  static NativeObject* getOrCreateRegExpStringIteratorPrototype(
+  static JSObject* getOrCreateRegExpStringIteratorPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
-    return MaybeNativeObject(getOrCreateObject(cx, global,
-                                               REGEXP_STRING_ITERATOR_PROTO,
-                                               initRegExpStringIteratorProto));
+    return getOrCreateObject(cx, global, REGEXP_STRING_ITERATOR_PROTO,
+                             initRegExpStringIteratorProto);
   }
 
-  static NativeObject* getOrCreateGeneratorObjectPrototype(
+  void setGeneratorObjectPrototype(JSObject* obj) {
+    setSlot(GENERATOR_OBJECT_PROTO, ObjectValue(*obj));
+  }
+
+  static JSObject* getOrCreateGeneratorObjectPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
-    return MaybeNativeObject(
-        getOrCreateObject(cx, global, GENERATOR_OBJECT_PROTO, initGenerators));
+    if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) {
+      return nullptr;
+    }
+    return &global->getSlot(GENERATOR_OBJECT_PROTO).toObject();
   }
 
   static JSObject* getOrCreateGeneratorFunctionPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, GENERATOR_FUNCTION_PROTO,
-                             initGenerators);
+    if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) {
+      return nullptr;
+    }
+    return &global->getPrototype(JSProto_GeneratorFunction).toObject();
   }
 
   static JSObject* getOrCreateGeneratorFunction(JSContext* cx,
                                                 Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, GENERATOR_FUNCTION, initGenerators);
+    if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) {
+      return nullptr;
+    }
+    return &global->getConstructor(JSProto_GeneratorFunction).toObject();
   }
 
-  static NativeObject* getOrCreateAsyncFunctionPrototype(
+  static JSObject* getOrCreateAsyncFunctionPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
-    return MaybeNativeObject(
-        getOrCreateObject(cx, global, ASYNC_FUNCTION_PROTO, initAsyncFunction));
+    if (!ensureConstructor(cx, global, JSProto_AsyncFunction)) {
+      return nullptr;
+    }
+    return &global->getPrototype(JSProto_AsyncFunction).toObject();
   }
 
   static JSObject* getOrCreateAsyncFunction(JSContext* cx,
                                             Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, ASYNC_FUNCTION, initAsyncFunction);
+    if (!ensureConstructor(cx, global, JSProto_AsyncFunction)) {
+      return nullptr;
+    }
+    return &global->getConstructor(JSProto_AsyncFunction).toObject();
   }
 
-  static NativeObject* getOrCreateAsyncIteratorPrototype(
-      JSContext* cx, Handle<GlobalObject*> global) {
-    return MaybeNativeObject(getOrCreateObject(cx, global, ASYNC_ITERATOR_PROTO,
-                                               initAsyncGenerators));
+  void setAsyncIteratorPrototype(JSObject* obj) {
+    MOZ_ASSERT(getReservedSlot(ASYNC_ITERATOR_PROTO).isUndefined());
+    MOZ_ASSERT(obj != nullptr);
+    setSlot(ASYNC_ITERATOR_PROTO, ObjectValue(*obj));
+  }
+
+  void setAsyncFromSyncIteratorPrototype(JSObject* obj) {
+    MOZ_ASSERT(getReservedSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO).isUndefined());
+    MOZ_ASSERT(obj != nullptr);
+    setSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO, ObjectValue(*obj));
   }
 
-  static NativeObject* getOrCreateAsyncFromSyncIteratorPrototype(
+  static JSObject* getOrCreateAsyncIteratorPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
-    return MaybeNativeObject(getOrCreateObject(
-        cx, global, ASYNC_FROM_SYNC_ITERATOR_PROTO, initAsyncGenerators));
+    return getOrCreateObject(cx, global, ASYNC_ITERATOR_PROTO,
+                             initAsyncIteratorProto);
   }
 
-  static NativeObject* getOrCreateAsyncGenerator(JSContext* cx,
-                                                 Handle<GlobalObject*> global) {
-    return MaybeNativeObject(
-        getOrCreateObject(cx, global, ASYNC_GENERATOR, initAsyncGenerators));
+  static JSObject* getOrCreateAsyncFromSyncIteratorPrototype(
+      JSContext* cx, Handle<GlobalObject*> global) {
+    return getOrCreateObject(cx, global, ASYNC_FROM_SYNC_ITERATOR_PROTO,
+                             initAsyncFromSyncIteratorProto);
+  }
+
+  static JSObject* getOrCreateAsyncGenerator(JSContext* cx,
+                                             Handle<GlobalObject*> global) {
+    if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
+      return nullptr;
+    }
+    return &global->getPrototype(JSProto_AsyncGeneratorFunction).toObject();
   }
 
   static JSObject* getOrCreateAsyncGeneratorFunction(
       JSContext* cx, Handle<GlobalObject*> global) {
-    return getOrCreateObject(cx, global, ASYNC_GENERATOR_FUNCTION,
-                             initAsyncGenerators);
+    if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
+      return nullptr;
+    }
+    return &global->getConstructor(JSProto_AsyncGeneratorFunction).toObject();
   }
 
-  static NativeObject* getOrCreateAsyncGeneratorPrototype(
+  void setAsyncGeneratorPrototype(JSObject* obj) {
+    setSlot(ASYNC_GENERATOR_PROTO, ObjectValue(*obj));
+  }
+
+  static JSObject* getOrCreateAsyncGeneratorPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
-    return MaybeNativeObject(getOrCreateObject(
-        cx, global, ASYNC_GENERATOR_PROTO, initAsyncGenerators));
+    if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
+      return nullptr;
+    }
+    return &global->getSlot(ASYNC_GENERATOR_PROTO).toObject();
   }
 
   static JSObject* getOrCreateMapIteratorPrototype(
       JSContext* cx, Handle<GlobalObject*> global) {
     return getOrCreateObject(cx, global, MAP_ITERATOR_PROTO,
                              initMapIteratorProto);
   }
 
@@ -717,22 +675,22 @@ class GlobalObject : public NativeObject
   static JSObject* getOrCreateDataViewPrototype(JSContext* cx,
                                                 Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_DataView)) {
       return nullptr;
     }
     return &global->getPrototype(JSProto_DataView).toObject();
   }
 
-  static JSFunction* getOrCreatePromiseConstructor(
-      JSContext* cx, Handle<GlobalObject*> global) {
+  static JSObject* getOrCreatePromiseConstructor(JSContext* cx,
+                                                 Handle<GlobalObject*> global) {
     if (!ensureConstructor(cx, global, JSProto_Promise)) {
       return nullptr;
     }
-    return &global->getConstructor(JSProto_Promise).toObject().as<JSFunction>();
+    return &global->getConstructor(JSProto_Promise).toObject();
   }
 
   static NativeObject* getIntrinsicsHolder(JSContext* cx,
                                            Handle<GlobalObject*> global);
 
   bool maybeExistingIntrinsicValue(PropertyName* name, Value* vp) {
     Value slot = getReservedSlot(INTRINSICS);
     // If we're in the self-hosting compartment itself, the
@@ -832,35 +790,26 @@ class GlobalObject : public NativeObject
   static bool initIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
   static bool initArrayIteratorProto(JSContext* cx,
                                      Handle<GlobalObject*> global);
   static bool initStringIteratorProto(JSContext* cx,
                                       Handle<GlobalObject*> global);
   static bool initRegExpStringIteratorProto(JSContext* cx,
                                             Handle<GlobalObject*> global);
 
-  // Implemented in vm/GeneratorObject.cpp.
-  static bool initGenerators(JSContext* cx, Handle<GlobalObject*> global);
-
-  static bool initAsyncFunction(JSContext* cx, Handle<GlobalObject*> global);
-
-  static bool initAsyncGenerators(JSContext* cx, Handle<GlobalObject*> global);
+  // Implemented in vm/AsyncIteration.cpp.
+  static bool initAsyncIteratorProto(JSContext* cx,
+                                     Handle<GlobalObject*> global);
+  static bool initAsyncFromSyncIteratorProto(JSContext* cx,
+                                             Handle<GlobalObject*> global);
 
   // Implemented in builtin/MapObject.cpp.
   static bool initMapIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
   static bool initSetIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
 
-#ifdef ENABLE_INTL_API
-  // Implemented in builtin/intl/IntlObject.cpp.
-  static bool initIntlObject(JSContext* cx, Handle<GlobalObject*> global);
-
-  // Implemented in builtin/intl/Locale.cpp.
-  static bool addLocaleConstructor(JSContext* cx, HandleObject intl);
-#endif
-
   // Implemented in builtin/ModuleObject.cpp
   static bool initModuleProto(JSContext* cx, Handle<GlobalObject*> global);
   static bool initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
   static bool initExportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
   static bool initRequestedModuleProto(JSContext* cx,
                                        Handle<GlobalObject*> global);
 
   // Implemented in builtin/TypedObject.cpp
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -837,25 +837,25 @@ static bool EnsureParserCreatedClasses(J
   if (!EnsureConstructor(cx, global, JSProto_Array)) {
     return false;  // needed by array literals
   }
 
   if (!EnsureConstructor(cx, global, JSProto_RegExp)) {
     return false;  // needed by regular expression literals
   }
 
-  if (!GlobalObject::initGenerators(cx, global)) {
+  if (!EnsureConstructor(cx, global, JSProto_GeneratorFunction)) {
     return false;  // needed by function*() {}
   }
 
-  if (!GlobalObject::initAsyncFunction(cx, global)) {
+  if (!EnsureConstructor(cx, global, JSProto_AsyncFunction)) {
     return false;  // needed by async function() {}
   }
 
-  if (!GlobalObject::initAsyncGenerators(cx, global)) {
+  if (!EnsureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
     return false;  // needed by async function*() {}
   }
 
   if (kind == ParseTaskKind::Module &&
       !GlobalObject::ensureModulePrototypesCreated(cx, global)) {
     return false;
   }
 
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -4491,17 +4491,17 @@ bool js::GetProperty(JSContext* cx, Hand
     if (GetLengthProperty(v, vp)) {
       return true;
     }
   }
 
   // Optimize common cases like (2).toString() or "foo".valueOf() to not
   // create a wrapper object.
   if (v.isPrimitive() && !v.isNullOrUndefined()) {
-    NativeObject* proto;
+    JSObject* proto;
 
     switch (v.type()) {
       case ValueType::Double:
       case ValueType::Int32:
         proto = GlobalObject::getOrCreateNumberPrototype(cx, cx->global());
         break;
       case ValueType::Boolean:
         proto = GlobalObject::getOrCreateBooleanPrototype(cx, cx->global());
--- a/js/src/vm/JSFunction.cpp
+++ b/js/src/vm/JSFunction.cpp
@@ -1936,35 +1936,38 @@ static bool CreateDynamicFunction(JSCont
   SourceOwnership ownership = stableChars.maybeGiveOwnershipToCaller()
                                   ? SourceOwnership::TakeOwnership
                                   : SourceOwnership::Borrowed;
   SourceText<char16_t> srcBuf;
   if (!srcBuf.init(cx, chars.begin().get(), chars.length(), ownership)) {
     return false;
   }
 
-  JSProtoKey protoKey = JSProto_Null;
+  JSProtoKey protoKey;
   if (isAsync) {
     if (isGenerator) {
       if (!CompileStandaloneAsyncGenerator(cx, &fun, options, srcBuf,
                                            parameterListEnd)) {
         return false;
       }
+      protoKey = JSProto_AsyncGeneratorFunction;
     } else {
       if (!CompileStandaloneAsyncFunction(cx, &fun, options, srcBuf,
                                           parameterListEnd)) {
         return false;
       }
+      protoKey = JSProto_AsyncFunction;
     }
   } else {
     if (isGenerator) {
       if (!CompileStandaloneGenerator(cx, &fun, options, srcBuf,
                                       parameterListEnd)) {
         return false;
       }
+      protoKey = JSProto_GeneratorFunction;
     } else {
       if (!CompileStandaloneFunction(cx, &fun, options, srcBuf,
                                      parameterListEnd)) {
         return false;
       }
       protoKey = JSProto_Function;
     }
   }
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -531,18 +531,18 @@ SavedFrame* SavedFrame::create(JSContext
   RootedGlobalObject global(cx, cx->global());
   cx->check(global);
 
   // Ensure that we don't try to capture the stack again in the
   // `SavedStacksMetadataBuilder` for this new SavedFrame object, and
   // accidentally cause O(n^2) behavior.
   SavedStacks::AutoReentrancyGuard guard(cx->realm()->savedStacks());
 
-  RootedNativeObject proto(
-      cx, GlobalObject::getOrCreateSavedFramePrototype(cx, global));
+  RootedObject proto(cx,
+                     GlobalObject::getOrCreateSavedFramePrototype(cx, global));
   if (!proto) {
     return nullptr;
   }
   cx->check(proto);
 
   return NewObjectWithGivenProto<SavedFrame>(cx, proto, TenuredObject);
 }
 
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1788,34 +1788,16 @@ static bool intrinsic_IsRuntimeDefaultLo
             : EqualChars(str->twoByteChars(nogc), latin1Locale, str->length());
   } else {
     equals = false;
   }
 
   args.rval().setBoolean(equals);
   return true;
 }
-
-using GetOrCreateIntlConstructor = JSFunction* (*)(JSContext*,
-                                                   Handle<GlobalObject*>);
-
-template <GetOrCreateIntlConstructor getOrCreateIntlConstructor>
-static bool intrinsic_GetBuiltinIntlConstructor(JSContext* cx, unsigned argc,
-                                                Value* vp) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-  MOZ_ASSERT(args.length() == 0);
-
-  JSFunction* constructor = getOrCreateIntlConstructor(cx, cx->global());
-  if (!constructor) {
-    return false;
-  }
-
-  args.rval().setObject(*constructor);
-  return true;
-}
 #endif  // ENABLE_INTL_API
 
 static bool intrinsic_ThrowArgTypeNotObject(JSContext* cx, unsigned argc,
                                             Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   MOZ_ASSERT(args.length() == 2);
   MOZ_ASSERT(args[0].isNumber());
   MOZ_ASSERT(!args[1].isObject());
@@ -2479,24 +2461,16 @@ static const JSFunctionSpec intrinsic_fu
           CallNonGenericSelfhostedMethod<Is<DateTimeFormatObject>>, 2, 0),
     JS_FN("CallNumberFormatMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<NumberFormatObject>>, 2, 0),
     JS_FN("CallPluralRulesMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<PluralRulesObject>>, 2, 0),
     JS_FN("CallRelativeTimeFormatMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<RelativeTimeFormatObject>>, 2, 0),
 
-    JS_FN("GetDateTimeFormatConstructor",
-          intrinsic_GetBuiltinIntlConstructor<
-              GlobalObject::getOrCreateDateTimeFormatConstructor>,
-          0, 0),
-    JS_FN("GetNumberFormatConstructor",
-          intrinsic_GetBuiltinIntlConstructor<
-              GlobalObject::getOrCreateNumberFormatConstructor>,
-          0, 0),
     JS_FN("RuntimeDefaultLocale", intrinsic_RuntimeDefaultLocale, 0, 0),
     JS_FN("IsRuntimeDefaultLocale", intrinsic_IsRuntimeDefaultLocale, 1, 0),
 #endif  // ENABLE_INTL_API
 
     JS_FN("GetOwnPropertyDescriptorToArray", GetOwnPropertyDescriptorToArray, 2,
           0),
 
     JS_INLINABLE_FN("IsRegExpObject",
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -1168,17 +1168,17 @@ TypedArrayObject* js::NewTypedArrayWithT
 // byteLength = count * BYTES_PER_ELEMENT
 template <typename T>
 /* static */ bool TypedArrayObjectTemplate<T>::AllocateArrayBuffer(
     JSContext* cx, HandleObject ctor, uint32_t count,
     MutableHandle<ArrayBufferObject*> buffer) {
   // 24.1.1.1 step 1 (partially).
   RootedObject proto(cx);
 
-  JSFunction* arrayBufferCtor =
+  JSObject* arrayBufferCtor =
       GlobalObject::getOrCreateArrayBufferConstructor(cx, cx->global());
   if (!arrayBufferCtor) {
     return false;
   }
 
   // As an optimization, skip the "prototype" lookup for %ArrayBuffer%.
   if (ctor != arrayBufferCtor) {
     // 9.1.13 OrdinaryCreateFromConstructor, steps 1-2.
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -854,17 +854,26 @@ bool ModuleGenerator::compileFuncDef(uin
   MOZ_ASSERT(funcIndex < env_->numFuncs());
 
   uint32_t threshold;
   switch (tier()) {
     case Tier::Baseline:
       threshold = JitOptions.wasmBatchBaselineThreshold;
       break;
     case Tier::Optimized:
-      threshold = JitOptions.wasmBatchIonThreshold;
+      switch (env_->optimizedBackend()) {
+        case OptimizedBackend::Ion:
+          threshold = JitOptions.wasmBatchIonThreshold;
+          break;
+        case OptimizedBackend::Cranelift:
+          threshold = JitOptions.wasmBatchCraneliftThreshold;
+          break;
+        default:
+          MOZ_CRASH("Invalid optimizedBackend value");
+      }
       break;
     default:
       MOZ_CRASH("Invalid tier value");
       break;
   }
 
   uint32_t funcBytecodeLength = end - begin;
 
--- a/layout/inspector/tests/test_bug522601-shadow.xhtml
+++ b/layout/inspector/tests/test_bug522601-shadow.xhtml
@@ -14,19 +14,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   <span slot="foo" id="s">This is some text</span>
   More text
   <b id="b">Even more <i id="i1">Italic</i>text<i id="i2">And more italic</i></b></custom-element>
 <div id="content" style="display: none">
 </div>
 <div id="subdoc">
   <iframe id="frame1" src="file_bug522601.html">frame text</iframe>
 </div>
-<div id="test-shadow">
-  <h2 id="h2">light child</h2>
-</div>
 <pre id="test">
 <script type="application/javascript">
 <![CDATA[
 
 /** Test for Bug 522601 **/
 SimpleTest.waitForExplicitFinish();
 
 customElements.define("custom-element", class extends HTMLElement {
@@ -244,46 +241,16 @@ addLoadEvent(function() {
   testFunc(walkerAnon, "previousNode", $("s").previousSibling,
            "step back to some text (anon)");
   testFunc(walkerAnon, "previousNode", slot, "steb back to slot");
   testFunc(walkerAnon, "previousNode", anonDiv,
            "step back to anonymous div");
   testFunc(walkerAnon, "previousNode", $("display"), "step back to root (anon)");
   testFunc(walkerAnon, "previousNode", null, "step back past root (anon)");
 
-  //XXXsmaug update this test for Shadow DOM v1! bug 1421539
-  /*if (Element.prototype.createShadowRoot) {
-    var shadowdiv = document.querySelector('#test-shadow');
-    var shadowRoot = shadowdiv.createShadowRoot();
-    var h = document.createElement("header");
-    var c = document.createElement("content");
-    c.setAttribute("select", "h2");
-    h.appendChild(c);
-    shadowRoot.appendChild(h);
-
-    var walkerShadow =
-        SpecialPowers.Cc["@mozilla.org/inspector/deep-tree-walker;1"]
-                     .createInstance(SpecialPowers.Ci.inIDeepTreeWalker);
-    walkerShadow.showAnonymousContent = true;
-    walkerShadow.init($("test-shadow"), NodeFilter.SHOW_ALL);
-    var c1 = walkerShadow.nextNode();
-    var c2 = walkerShadow.nextNode();
-    var c3 = walkerShadow.nextNode();
-
-    walkerShadow.currentNode = c1;
-    is(SpecialPowers.unwrap(walkerShadow.currentNode), h,
-       "Unexpected shadow element 1");
-    walkerShadow.currentNode = c2;
-    is(SpecialPowers.unwrap(walkerShadow.currentNode), $("h2"),
-       "Unexpected shadow element 2");
-    walkerShadow.currentNode = c3;
-    is(SpecialPowers.unwrap(walkerShadow.currentNode), $("h2").firstChild,
-       "Unexpected shadow element 3");
-  }*/
-
   SimpleTest.finish();
 });
 
 ]]>
 </script>
 </pre>
 </body>
 </html>
--- a/layout/inspector/tests/test_bug522601.xhtml
+++ b/layout/inspector/tests/test_bug522601.xhtml
@@ -20,19 +20,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   More text
   <b id="b">Even more <i id="i1">Italic</i>text<i id="i2">And more italic</i></b></p>
 <div id="content" style="display: none">
   
 </div>
 <div id="subdoc">
   <iframe id="frame1" src="file_bug522601.html">frame text</iframe>
 </div>
-<div id="test-shadow">
-  <h2 id="h2">light child</h2>
-</div>
 <pre id="test">
 <script type="application/javascript">
 <![CDATA[
 
 /** Test for Bug 522601 **/
 SimpleTest.waitForExplicitFinish();
 
 function testFunc(walker, func, expectedNode, str) {
@@ -232,46 +229,16 @@ addLoadEvent(function() {
   testFunc(walkerAnon, "previousNode", $("s").nextSibling, "step back to more text (anon)");
   testFunc(walkerAnon, "previousNode", $("s").previousSibling,
            "step back to some text (anon)");
   testFunc(walkerAnon, "previousNode", anonDiv,
            "step back to anonymous div");
   testFunc(walkerAnon, "previousNode", $("display"), "step back to root (anon)");
   testFunc(walkerAnon, "previousNode", null, "step back past root (anon)");
 
-  //XXXsmaug update this test for Shadow DOM v1! bug 1421539
-  /*if (Element.prototype.createShadowRoot) {
-    var shadowdiv = document.querySelector('#test-shadow');
-    var shadowRoot = shadowdiv.createShadowRoot();
-    var h = document.createElement("header");
-    var c = document.createElement("content");
-    c.setAttribute("select", "h2");
-    h.appendChild(c);
-    shadowRoot.appendChild(h);
-
-    var walkerShadow =
-        SpecialPowers.Cc["@mozilla.org/inspector/deep-tree-walker;1"]
-                     .createInstance(SpecialPowers.Ci.inIDeepTreeWalker);
-    walkerShadow.showAnonymousContent = true;
-    walkerShadow.init($("test-shadow"), NodeFilter.SHOW_ALL);
-    var c1 = walkerShadow.nextNode();
-    var c2 = walkerShadow.nextNode();
-    var c3 = walkerShadow.nextNode();
-
-    walkerShadow.currentNode = c1;
-    is(SpecialPowers.unwrap(walkerShadow.currentNode), h,
-       "Unexpected shadow element 1");
-    walkerShadow.currentNode = c2;
-    is(SpecialPowers.unwrap(walkerShadow.currentNode), $("h2"),
-       "Unexpected shadow element 2");
-    walkerShadow.currentNode = c3;
-    is(SpecialPowers.unwrap(walkerShadow.currentNode), $("h2").firstChild,
-       "Unexpected shadow element 3");
-  }*/
-
   SimpleTest.finish();
 });
 
 ]]>
 </script>
 </pre>
 </body>
 </html>
--- a/layout/mathml/nsMathMLmmultiscriptsFrame.cpp
+++ b/layout/mathml/nsMathMLmmultiscriptsFrame.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsMathMLmmultiscriptsFrame.h"
 
 #include "mozilla/PresShell.h"
+#include "mozilla/StaticPrefs_mathml.h"
 #include "nsPresContext.h"
 #include <algorithm>
 #include "gfxContext.h"
 #include "gfxMathTable.h"
 
 using namespace mozilla;
 
 //
@@ -89,51 +90,53 @@ nsMathMLmmultiscriptsFrame::TransmitAuto
 /* virtual */
 nsresult nsMathMLmmultiscriptsFrame::Place(DrawTarget* aDrawTarget,
                                            bool aPlaceOrigin,
                                            ReflowOutput& aDesiredSize) {
   nscoord subScriptShift = 0;
   nscoord supScriptShift = 0;
   float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
 
-  // subscriptshift
-  //
-  // "Specifies the minimum amount to shift the baseline of subscript down; the
-  // default is for the rendering agent to use its own positioning rules."
-  //
-  // values: length
-  // default: automatic
-  //
-  // We use 0 as the default value so unitless values can be ignored.
-  // As a minimum, negative values can be ignored.
-  //
-  nsAutoString value;
-  if (!mContent->IsMathMLElement(nsGkAtoms::msup_)) {
-    mContent->AsElement()->GetAttr(kNameSpaceID_None,
-                                   nsGkAtoms::subscriptshift_, value);
-    if (!value.IsEmpty()) {
+  if (!StaticPrefs::mathml_script_shift_attributes_disabled()) {
+    // subscriptshift
+    //
+    // "Specifies the minimum amount to shift the baseline of subscript down;
+    // the default is for the rendering agent to use its own positioning rules."
+    //
+    // values: length
+    // default: automatic
+    //
+    // We use 0 as the default value so unitless values can be ignored.
+    // As a minimum, negative values can be ignored.
+    //
+    nsAutoString value;
+    if (!mContent->IsMathMLElement(nsGkAtoms::msup_) &&
+        mContent->AsElement()->GetAttr(kNameSpaceID_None,
+                                       nsGkAtoms::subscriptshift_, value)) {
+      mContent->OwnerDoc()->WarnOnceAbout(
+          dom::Document::eMathML_DeprecatedScriptShiftAttributes);
       ParseNumericValue(value, &subScriptShift, 0, PresContext(),
                         mComputedStyle, fontSizeInflation);
     }
-  }
-  // superscriptshift
-  //
-  // "Specifies the minimum amount to shift the baseline of superscript up; the
-  // default is for the rendering agent to use its own positioning rules."
-  //
-  // values: length
-  // default: automatic
-  //
-  // We use 0 as the default value so unitless values can be ignored.
-  // As a minimum, negative values can be ignored.
-  //
-  if (!mContent->IsMathMLElement(nsGkAtoms::msub_)) {
-    mContent->AsElement()->GetAttr(kNameSpaceID_None,
-                                   nsGkAtoms::superscriptshift_, value);
-    if (!value.IsEmpty()) {
+    // superscriptshift
+    //
+    // "Specifies the minimum amount to shift the baseline of superscript up;
+    // the default is for the rendering agent to use its own positioning rules."
+    //
+    // values: length
+    // default: automatic
+    //
+    // We use 0 as the default value so unitless values can be ignored.
+    // As a minimum, negative values can be ignored.
+    //
+    if (!mContent->IsMathMLElement(nsGkAtoms::msub_) &&
+        mContent->AsElement()->GetAttr(kNameSpaceID_None,
+                                       nsGkAtoms::superscriptshift_, value)) {
+      mContent->OwnerDoc()->WarnOnceAbout(
+          dom::Document::eMathML_DeprecatedScriptShiftAttributes);
       ParseNumericValue(value, &supScriptShift, 0, PresContext(),
                         mComputedStyle, fontSizeInflation);
     }
   }
   return PlaceMultiScript(PresContext(), aDrawTarget, aPlaceOrigin,
                           aDesiredSize, this, subScriptShift, supScriptShift,
                           fontSizeInflation);
 }
--- a/layout/mathml/tests/test_bug827713.html
+++ b/layout/mathml/tests/test_bug827713.html
@@ -29,33 +29,35 @@ https://bugzilla.mozilla.org/show_bug.cg
     <msubsup subscriptshift="50px" superscriptshift="50px">
       <mspace width="50px" height="25px" depth="25px" mathbackground="blue" id="ssbase"></mspace>
       <mspace width="50px" height="25px" depth="25px" mathbackground="red" id="sssub"></mspace>
       <mspace width="50px" height="25px" depth="25px" mathbackground="green" id="sssup"></mspace>
     </msubsup>
   </math></p>
 <pre id="test">
 <script type="application/javascript">
-
     /** Test for the scriptshift aspect of bug 827713 **/
     SimpleTest.waitForExplicitFinish();
 
-    subBaseRect = $("subbase").getBoundingClientRect();
-    subSubRect = $("subsub").getBoundingClientRect();
-    is(subBaseRect.bottom, subSubRect.top, "Bad subscript shift for msub");
+    if (SpecialPowers.getBoolPref('mathml.script_shift_attributes.disabled')) {
+      ok(true, "Script shifts disabled");
+    } else {
+      subBaseRect = $("subbase").getBoundingClientRect();
+      subSubRect = $("subsub").getBoundingClientRect();
+      is(subBaseRect.bottom, subSubRect.top, "Bad subscript shift for msub");
 
-    supBaseRect = $("supbase").getBoundingClientRect();
-    supSupRect = $("supsup").getBoundingClientRect();
-    is(supBaseRect.top, supSupRect.bottom, "Bad superscript shift for msup");
+      supBaseRect = $("supbase").getBoundingClientRect();
+      supSupRect = $("supsup").getBoundingClientRect();
+      is(supBaseRect.top, supSupRect.bottom, "Bad superscript shift for msup");
 
-    ssBaseRect = $("ssbase").getBoundingClientRect();
-    ssSubRect = $("sssub").getBoundingClientRect();
-    ssSupRect = $("sssup").getBoundingClientRect();
-    is(ssBaseRect.bottom, ssSubRect.top, "Bad subscript shift for msubusp");
-    is(ssBaseRect.top, ssSupRect.bottom, "Bad superscript shift for msubusp");
-
+      ssBaseRect = $("ssbase").getBoundingClientRect();
+      ssSubRect = $("sssub").getBoundingClientRect();
+      ssSupRect = $("sssup").getBoundingClientRect();
+      is(ssBaseRect.bottom, ssSubRect.top, "Bad subscript shift for msubusp");
+      is(ssBaseRect.top, ssSupRect.bottom, "Bad superscript shift for msubusp");
+    }
 
     SimpleTest.finish();
 
 </script>
 </pre>
 </body>
 </html>
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -791,18 +791,18 @@ class MOZ_NON_PARAM Vector final : priva
   /**
    * Removes the element |aT|, which must fall in the bounds [begin, end),
    * shifting existing elements from |aT + 1| onward one position lower.
    */
   void erase(T* aT);
 
   /**
    * Removes the elements [|aBegin|, |aEnd|), which must fall in the bounds
-   * [begin, end), shifting existing elements from |aEnd + 1| onward to aBegin's
-   * old position.
+   * [begin, end), shifting existing elements from |aEnd| onward to aBegin's old
+   * position.
    */
   void erase(T* aBegin, T* aEnd);
 
   /**
    * Removes all elements that satisfy the predicate, shifting existing elements
    * lower to fill erased gaps.
    */
   template <typename Pred>
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -177,16 +177,22 @@
   value: false
   mirror: always
 
 - name: accessibility.AOM.enabled
   type: bool
   value: false
   mirror: always
 
+# Whether the changes in https://github.com/whatwg/html/issues/5002 are in effect.
+- name: accessibility.heading-element-level-changes.enabled
+  type: RelaxedAtomicBool
+  value: @IS_NIGHTLY_BUILD@
+  mirror: always
+
 #ifdef ANDROID
   #---------------------------------------------------------------------------
   # Prefs starting with "android."
   #---------------------------------------------------------------------------
 
   # On Android, we want an opaque background to be visible under the page,
   # so layout should not force a default background.
 -   name: android.widget_paints_background
@@ -5359,16 +5365,22 @@
   mirror: always
 
 # Whether to disable deprecated numalign/denomalign/align attributes
 - name: mathml.deprecated_alignment_attributes.disabled
   type: bool
   value: @IS_NIGHTLY_BUILD@
   mirror: always
 
+# Whether to disable subscriptshift and superscriptshift attributes.
+- name: mathml.script_shift_attributes.disabled
+  type: bool
+  value: @IS_NIGHTLY_BUILD@
+  mirror: always
+
 # Whether to disable support for XLink on MathML elements.
 - name: mathml.xlink.disabled
   type: bool
   value: @IS_NIGHTLY_BUILD@
   mirror: always
 
 #---------------------------------------------------------------------------
 # Prefs starting with "media."
new file mode 100644
--- /dev/null
+++ b/python/l10n/fluent_migrations/bug_1588925_aboutSupport_crash_guard_typo.py
@@ -0,0 +1,27 @@
+# coding=utf8
+
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+from __future__ import absolute_import
+import fluent.syntax.ast as FTL
+from fluent.migrate.helpers import transforms_from
+from fluent.migrate import COPY_PATTERN
+
+TARGET_FILE = "toolkit/toolkit/about/aboutSupport.ftl"
+SOURCE_FILE = TARGET_FILE
+
+
+def migrate(ctx):
+    """Bug 1588925 - Fix broken identifier for about:support d3d9 video crash guard string, part {index}"""
+
+
+    ctx.add_transforms(
+        TARGET_FILE,
+        SOURCE_FILE,
+        transforms_from(
+"""
+d3d9video-crash-guard = {COPY_PATTERN(from_path, "d3d9video-crash-buard")}
+""",
+        from_path=SOURCE_FILE),
+    )
deleted file mode 100644
--- a/taskcluster/ci/test/browsertime-fenix.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
----
-job-defaults:
-    max-run-time: 1800
-    suite: raptor
-    workdir: /builds/worker
-    run-on-projects: []
-    tier: 3
-    target:
-        by-test-platform:
-            android-hw.*-aarch64.*/.*:
-                index: project.mobile.fenix.v2.performance-test.latest.aarch64
-                name: target.apk
-            default:
-                index: project.mobile.fenix.v2.performance-test.latest.arm
-                name: target.apk
-    e10s: true
-    virtualization: hardware
-    mozharness:
-        script: raptor_script.py
-        config:
-            - raptor/android_hw_config.py
-
-browsertime-tp6m-1-fenix:
-    description: "Raptor (browsertime) tp6m-1 on Fenix"
-    treeherder-symbol: Btime-fenix(tp6m-1)
-    mozharness:
-        extra-options:
-            - --browsertime
-            - --app=fenix
-            - --binary-path=org.mozilla.fenix.performancetest
-            - --activity=org.mozilla.fenix.IntentReceiverActivity
-            - --test=raptor-tp6m-1
-
-browsertime-tp6m-1-fenix-cold:
-    description: "Raptor (browsertime) tp6m-1 cold page-load on Fenix"
-    treeherder-symbol: Btime-fenix(tp6m-c-1)
-    mozharness:
-        extra-options:
-            - --browsertime
-            - --app=fenix
-            - --binary-path=org.mozilla.fenix.performancetest
-            - --activity=org.mozilla.fenix.IntentReceiverActivity
-            - --test=raptor-tp6m-cold-1
deleted file mode 100644
--- a/taskcluster/ci/test/browsertime-gve.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
----
-job-defaults:
-    max-run-time: 1800
-    suite: raptor
-    workdir: /builds/worker
-    run-on-projects: ['integration', 'try']
-    tier: 3
-    target: geckoview_example.apk
-    e10s: true
-    virtualization: hardware
-    mozharness:
-        script: raptor_script.py
-        config:
-            - raptor/android_hw_config.py
-
-browsertime-tp6m-1-geckoview:
-    description: "Raptor (browsertime) tp6m-1 on GeckoView Example"
-    treeherder-symbol: Btime(tp6m-1)
-    mozharness:
-        extra-options:
-            - --browsertime
-            - --app=geckoview
-            - --binary=org.mozilla.geckoview_example
-            - --activity=org.mozilla.geckoview_example.GeckoViewActivity
-            - --test=raptor-tp6m-1
-
-browsertime-tp6m-1-geckoview-cold:
-    description: "Raptor (browsertime) tp6m-1 cold page-load on GeckoView Example"
-    max-run-time: 2700
-    treeherder-symbol: Btime(tp6m-c-1)
-    mozharness:
-        extra-options:
-            - --browsertime
-            - --app=geckoview
-            - --binary=org.mozilla.geckoview_example
-            - --activity=org.mozilla.geckoview_example.GeckoViewActivity
-            - --test=raptor-tp6m-cold-1
new file mode 100644
--- /dev/null
+++ b/taskcluster/ci/test/browsertime-mobile.yml
@@ -0,0 +1,58 @@
+# 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/.
+---
+job-defaults:
+    max-run-time: 1800
+    suite: raptor
+    workdir: /builds/worker
+    run-on-projects:
+        by-app:
+            fenix: []
+            geckoview: ["integration", "try"]
+            refbrow: []
+    tier: 3
+    target:
+        by-app:
+            fenix:
+                by-test-platform:
+                    android-hw.*-aarch64.*/.*:
+                        index: project.mobile.fenix.v2.performance-test.latest.aarch64
+                        name: target.apk
+                    default:
+                        index: project.mobile.fenix.v2.performance-test.latest.arm
+                        name: target.apk
+            geckoview: geckoview_example.apk
+            refbrow:
+                by-test-platform:
+                    android-hw.*-aarch64.*/.*:
+                        index: project.mobile.reference-browser.v2.raptor.latest.aarch64
+                        name: target.apk
+                    default:
+                        index: project.mobile.reference-browser.v2.raptor.latest.arm
+                        name: target.apk
+    e10s: true
+    virtualization: hardware
+    activity:
+        by-app:
+            fenix: org.mozilla.fenix.IntentReceiverActivity
+            geckoview: org.mozilla.geckoview_example.GeckoViewActivity
+            refbrow: org.mozilla.reference.browser.BrowserTestActivity
+    binary-path:
+        by-app:
+            fenix: org.mozilla.fenix.performancetest
+            geckoview: org.mozilla.geckoview_example
+            refbrow: org.mozilla.reference.browser.raptor
+    mozharness:
+        script: raptor_script.py
+        config:
+            - raptor/android_hw_config.py
+        extra-options:
+            - --browsertime
+
+browsertime-tp6m-1:
+    description: "Raptor (browsertime) tp6m-1"
+    apps: ["fenix", "geckoview", "refbrow"]
+    cold: true
+    treeherder-symbol: Btime(tp6m-1)
+    raptor-test: raptor-tp6m-1
deleted file mode 100644
--- a/taskcluster/ci/test/browsertime-refbrow.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
----
-job-defaults:
-    max-run-time: 1800
-    suite: raptor
-    workdir: /builds/worker
-    run-on-projects: []
-    tier: 3
-    target:
-        by-test-platform:
-            android-hw.*-aarch64.*/.*:
-                index: project.mobile.reference-browser.v2.raptor.latest.aarch64
-                name: target.apk
-            default:
-                index: project.mobile.reference-browser.v2.raptor.latest.arm
-                name: target.apk
-    e10s: true
-    virtualization: hardware
-    mozharness:
-        script: raptor_script.py
-        config:
-            - raptor/android_hw_config.py
-
-browsertime-tp6m-1-refbrow:
-    description: "Raptor (browsertime) tp6m-1 on the reference browser"
-    treeherder-symbol: Btime-refbrow(tp6m-1)
-    mozharness:
-        extra-options:
-            - --browsertime
-            - --app=refbrow
-            - --binary-path=org.mozilla.reference.browser.raptor
-            - --activity=org.mozilla.reference.browser.BrowserTestActivity
-            - --test=raptor-tp6m-1
-
-browsertime-tp6m-1-refbrow-cold:
-    description: "Raptor (browsertime) tp6m-1 cold page-load on the reference browser"
-    treeherder-symbol: Btime-refbrow(tp6m-c-1)
-    mozharness:
-        extra-options:
-            - --browsertime
-            - --app=refbrow
-            - --binary-path=org.mozilla.reference.browser.raptor
-            - --activity=org.mozilla.reference.browser.BrowserTestActivity
-            - --test=raptor-tp6m-cold-1
--- a/taskcluster/ci/test/kind.yml
+++ b/taskcluster/ci/test/kind.yml
@@ -22,19 +22,17 @@ transforms:
 # `taskcluster/taskgraph/transforms/tests.py` for a description of the fields
 # used in these files.
 
 # Adding a new test type or running tests on a new platform? Be sure to review
 # https://wiki.mozilla.org/Sheriffing/Job_Visibility_Policy
 
 jobs-from:
     - awsy.yml
-    - browsertime-fenix.yml
-    - browsertime-gve.yml
-    - browsertime-refbrow.yml
+    - browsertime-mobile.yml
     - compiled.yml
     - firefox-ui.yml
     - marionette.yml
     - misc.yml
     - mochitest.yml
     - raptor.yml
     - raptor-chrome.yml
     - raptor-chromium.yml
--- a/taskcluster/ci/test/raptor-chrome.yml
+++ b/taskcluster/ci/test/raptor-chrome.yml
@@ -224,278 +224,278 @@ raptor-wasm-godot-chrome:
             - --app=chrome
 
 raptor-tp6-1-chrome-cold:
     description: "Raptor tp6-1 cold page-load on Chrome"
     try-name: raptor-tp6-1-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-1)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-1
+            - --test=raptor-tp6-1-cold
             - --app=chrome
 
 raptor-tp6-2-chrome-cold:
     description: "Raptor tp6-2 cold page-load on Chrome"
     try-name: raptor-tp6-2-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-2)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-2
+            - --test=raptor-tp6-2-cold
             - --app=chrome
 
 raptor-tp6-3-chrome-cold:
     description: "Raptor tp6-3 cold page-load on Chrome"
     try-name: raptor-tp6-3-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-3)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-3
+            - --test=raptor-tp6-3-cold
             - --app=chrome
 
 raptor-tp6-4-chrome-cold:
     description: "Raptor tp6-4 cold page-load on Chrome"
     try-name: raptor-tp6-4-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-4)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-4
+            - --test=raptor-tp6-4-cold
             - --app=chrome
 
 raptor-tp6-5-chrome-cold:
     description: "Raptor tp6-5 cold page-load on Chrome"
     try-name: raptor-tp6-5-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-5)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-5
+            - --test=raptor-tp6-5-cold
             - --app=chrome
 
 raptor-tp6-6-chrome-cold:
     description: "Raptor tp6-6 cold page-load on Chrome"
     try-name: raptor-tp6-6-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-6)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-6
+            - --test=raptor-tp6-6-cold
             - --app=chrome
 
 raptor-tp6-7-chrome-cold:
     description: "Raptor tp6-7 cold page-load on Chrome"
     try-name: raptor-tp6-7-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-7)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-7
+            - --test=raptor-tp6-7-cold
             - --app=chrome
 
 raptor-tp6-8-chrome-cold:
     description: "Raptor tp6-8 cold page-load on Chrome"
     try-name: raptor-tp6-8-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-8)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-8
+            - --test=raptor-tp6-8-cold
             - --app=chrome
 
 raptor-tp6-9-chrome-cold:
     description: "Raptor tp6-9 cold page-load on Chrome"
     try-name: raptor-tp6-9-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-9)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-9
+            - --test=raptor-tp6-9-cold
             - --app=chrome
 
 raptor-tp6-10-chrome-cold:
     description: "Raptor tp6-10 cold page-load on Chrome"
     try-name: raptor-tp6-10-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-10)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-10
+            - --test=raptor-tp6-10-cold
             - --app=chrome
 
 raptor-tp6-11-chrome-cold:
     description: "Raptor tp6-11 cold page-load on Chrome"
     try-name: raptor-tp6-11-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-11)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-11
+            - --test=raptor-tp6-11-cold
             - --app=chrome
 
 raptor-tp6-12-chrome-cold:
     description: "Raptor tp6-12 cold page-load on Chrome"
     try-name: raptor-tp6-12-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-12)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-12
+            - --test=raptor-tp6-12-cold
             - --app=chrome
 
 raptor-tp6-13-chrome-cold:
     description: "Raptor tp6-13 cold page-load on Chrome"
     try-name: raptor-tp6-13-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-13)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-13
+            - --test=raptor-tp6-13-cold
             - --app=chrome
 
 raptor-tp6-14-chrome-cold:
     description: "Raptor tp6-14 cold page-load on Chrome"
     try-name: raptor-tp6-14-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-14)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-14
+            - --test=raptor-tp6-14-cold
             - --app=chrome
 
 raptor-tp6-15-chrome-cold:
     description: "Raptor tp6-15 cold page-load on Chrome"
     try-name: raptor-tp6-15-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-15)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-15
+            - --test=raptor-tp6-15-cold
             - --app=chrome
 
 raptor-tp6-16-chrome-cold:
     description: "Raptor tp6-16 cold page-load on Chrome"
     try-name: raptor-tp6-16-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-16)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-16
+            - --test=raptor-tp6-16-cold
             - --app=chrome
 
 raptor-tp6-17-chrome-cold:
     description: "Raptor tp6-17 cold page-load on Chrome"
     try-name: raptor-tp6-17-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-17)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-17
+            - --test=raptor-tp6-17-cold
             - --app=chrome
 
 raptor-tp6-18-chrome-cold:
     description: "Raptor tp6-18 cold page-load on Chrome"
     try-name: raptor-tp6-18-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-18)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-18
+            - --test=raptor-tp6-18-cold
             - --app=chrome
 
 raptor-tp6-19-chrome-cold:
     description: "Raptor tp6-19 cold page-load on Chrome"
     try-name: raptor-tp6-19-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-19)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-19
+            - --test=raptor-tp6-19-cold
             - --app=chrome
 
 raptor-tp6-20-chrome-cold:
     description: "Raptor tp6-20 cold page-load on Chrome"
     try-name: raptor-tp6-20-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-20)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-20
+            - --test=raptor-tp6-20-cold
             - --app=chrome
 
 raptor-tp6-21-chrome-cold:
     description: "Raptor tp6-21 cold page-load on Chrome"
     try-name: raptor-tp6-21-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-21)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-21
+            - --test=raptor-tp6-21-cold
             - --app=chrome
 
 raptor-tp6-22-chrome-cold:
     description: "Raptor tp6-22 cold page-load on Chrome"
     try-name: raptor-tp6-22-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-22)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-22
+            - --test=raptor-tp6-22-cold
             - --app=chrome
 
 raptor-tp6-23-chrome-cold:
     description: "Raptor tp6-23 cold page-load on Chrome"
     try-name: raptor-tp6-23-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-23)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-23
+            - --test=raptor-tp6-23-cold
             - --app=chrome
 
 raptor-tp6-24-chrome-cold:
     description: "Raptor tp6-24 cold page-load on Chrome"
     try-name: raptor-tp6-24-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-24)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-24
+            - --test=raptor-tp6-24-cold
             - --app=chrome
 
 raptor-tp6-25-chrome-cold:
     description: "Raptor tp6-25 cold page-load on Chrome"
     try-name: raptor-tp6-25-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-25)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-25
+            - --test=raptor-tp6-25-cold
             - --app=chrome
 
 raptor-tp6-26-chrome-cold:
     description: "Raptor tp6-26 cold page-load on Chrome"
     try-name: raptor-tp6-26-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-26)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-26
+            - --test=raptor-tp6-26-cold
             - --app=chrome
 
 raptor-tp6-27-chrome-cold:
     description: "Raptor tp6-27 cold page-load on Chrome"
     try-name: raptor-tp6-27-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-27)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-27
+            - --test=raptor-tp6-27-cold
             - --app=chrome
 
 raptor-tp6-28-chrome-cold:
     description: "Raptor tp6-28 cold page-load on Chrome"
     try-name: raptor-tp6-28-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-28)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-28
+            - --test=raptor-tp6-28-cold
             - --app=chrome
 
 raptor-tp6-29-chrome-cold:
     description: "Raptor tp6-29 cold page-load on Chrome"
     try-name: raptor-tp6-29-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-29)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-29
+            - --test=raptor-tp6-29-cold
             - --app=chrome
 
 raptor-tp6-30-chrome-cold:
     description: "Raptor tp6-30 cold page-load on Chrome"
     try-name: raptor-tp6-30-chrome-cold
     treeherder-symbol: Rap-ChR(tp6-c-30)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-30
+            - --test=raptor-tp6-30-cold
             - --app=chrome
 
 raptor-ares6-chrome:
     description: "Raptor Ares6 on Chrome"
     try-name: raptor-ares6-chrome
     treeherder-symbol: Rap-ChR(ares6)
     max-run-time: 2500
     tier: 3
--- a/taskcluster/ci/test/raptor-chromium.yml
+++ b/taskcluster/ci/test/raptor-chromium.yml
@@ -274,278 +274,278 @@ raptor-wasm-godot-chromium:
             - --app=chromium
 
 raptor-tp6-1-chromium-cold:
     description: "Raptor tp6-1 cold page-load on Chromium"
     try-name: raptor-tp6-1-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-1)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-1
+            - --test=raptor-tp6-1-cold
             - --app=chromium
 
 raptor-tp6-2-chromium-cold:
     description: "Raptor tp6-2 cold page-load on Chromium"
     try-name: raptor-tp6-2-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-2)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-2
+            - --test=raptor-tp6-2-cold
             - --app=chromium
 
 raptor-tp6-3-chromium-cold:
     description: "Raptor tp6-3 cold page-load on Chromium"
     try-name: raptor-tp6-3-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-3)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-3
+            - --test=raptor-tp6-3-cold
             - --app=chromium
 
 raptor-tp6-4-chromium-cold:
     description: "Raptor tp6-4 cold page-load on Chromium"
     try-name: raptor-tp6-4-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-4)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-4
+            - --test=raptor-tp6-4-cold
             - --app=chromium
 
 raptor-tp6-5-chromium-cold:
     description: "Raptor tp6-5 cold page-load on Chromium"
     try-name: raptor-tp6-5-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-5)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-5
+            - --test=raptor-tp6-5-cold
             - --app=chromium
 
 raptor-tp6-6-chromium-cold:
     description: "Raptor tp6-6 cold page-load on Chromium"
     try-name: raptor-tp6-6-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-6)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-6
+            - --test=raptor-tp6-6-cold
             - --app=chromium
 
 raptor-tp6-7-chromium-cold:
     description: "Raptor tp6-7 cold page-load on Chromium"
     try-name: raptor-tp6-7-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-7)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-7
+            - --test=raptor-tp6-7-cold
             - --app=chromium
 
 raptor-tp6-8-chromium-cold:
     description: "Raptor tp6-8 cold page-load on Chromium"
     try-name: raptor-tp6-8-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-8)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-8
+            - --test=raptor-tp6-8-cold
             - --app=chromium
 
 raptor-tp6-9-chromium-cold:
     description: "Raptor tp6-9 cold page-load on Chromium"
     try-name: raptor-tp6-9-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-9)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-9
+            - --test=raptor-tp6-9-cold
             - --app=chromium
 
 raptor-tp6-10-chromium-cold:
     description: "Raptor tp6-10 cold page-load on Chromium"
     try-name: raptor-tp6-10-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-10)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-10
+            - --test=raptor-tp6-10-cold
             - --app=chromium
 
 raptor-tp6-11-chromium-cold:
     description: "Raptor tp6-11 cold page-load on Chromium"
     try-name: raptor-tp6-11-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-11)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-11
+            - --test=raptor-tp6-11-cold
             - --app=chromium
 
 raptor-tp6-12-chromium-cold:
     description: "Raptor tp6-12 cold page-load on Chromium"
     try-name: raptor-tp6-12-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-12)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-12
+            - --test=raptor-tp6-12-cold
             - --app=chromium
 
 raptor-tp6-13-chromium-cold:
     description: "Raptor tp6-13 cold page-load on Chromium"
     try-name: raptor-tp6-13-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-13)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-13
+            - --test=raptor-tp6-13-cold
             - --app=chromium
 
 raptor-tp6-14-chromium-cold:
     description: "Raptor tp6-14 cold page-load on Chromium"
     try-name: raptor-tp6-14-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-14)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-14
+            - --test=raptor-tp6-14-cold
             - --app=chromium
 
 raptor-tp6-15-chromium-cold:
     description: "Raptor tp6-15 cold page-load on Chromium"
     try-name: raptor-tp6-15-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-15)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-15
+            - --test=raptor-tp6-15-cold
             - --app=chromium
 
 raptor-tp6-16-chromium-cold:
     description: "Raptor tp6-16 cold page-load on Chromium"
     try-name: raptor-tp6-16-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-16)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-16
+            - --test=raptor-tp6-16-cold
             - --app=chromium
 
 raptor-tp6-17-chromium-cold:
     description: "Raptor tp6-17 cold page-load on Chromium"
     try-name: raptor-tp6-17-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-17)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-17
+            - --test=raptor-tp6-17-cold
             - --app=chromium
 
 raptor-tp6-18-chromium-cold:
     description: "Raptor tp6-18 cold page-load on Chromium"
     try-name: raptor-tp6-18-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-18)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-18
+            - --test=raptor-tp6-18-cold
             - --app=chromium
 
 raptor-tp6-19-chromium-cold:
     description: "Raptor tp6-19 cold page-load on Chromium"
     try-name: raptor-tp6-19-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-19)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-19
+            - --test=raptor-tp6-19-cold
             - --app=chromium
 
 raptor-tp6-20-chromium-cold:
     description: "Raptor tp6-20 cold page-load on Chromium"
     try-name: raptor-tp6-20-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-20)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-20
+            - --test=raptor-tp6-20-cold
             - --app=chromium
 
 raptor-tp6-21-chromium-cold:
     description: "Raptor tp6-21 cold page-load on Chromium"
     try-name: raptor-tp6-21-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-21)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-21
+            - --test=raptor-tp6-21-cold
             - --app=chromium
 
 raptor-tp6-22-chromium-cold:
     description: "Raptor tp6-22 cold page-load on Chromium"
     try-name: raptor-tp6-22-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-22)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-22
+            - --test=raptor-tp6-22-cold
             - --app=chromium
 
 raptor-tp6-23-chromium-cold:
     description: "Raptor tp6-23 cold page-load on Chromium"
     try-name: raptor-tp6-23-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-23)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-23
+            - --test=raptor-tp6-23-cold
             - --app=chromium
 
 raptor-tp6-24-chromium-cold:
     description: "Raptor tp6-24 cold page-load on Chromium"
     try-name: raptor-tp6-24-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-24)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-24
+            - --test=raptor-tp6-24-cold
             - --app=chromium
 
 raptor-tp6-25-chromium-cold:
     description: "Raptor tp6-25 cold page-load on Chromium"
     try-name: raptor-tp6-25-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-25)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-25
+            - --test=raptor-tp6-25-cold
             - --app=chromium
 
 raptor-tp6-26-chromium-cold:
     description: "Raptor tp6-26 cold page-load on Chromium"
     try-name: raptor-tp6-26-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-26)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-26
+            - --test=raptor-tp6-26-cold
             - --app=chromium
 
 raptor-tp6-27-chromium-cold:
     description: "Raptor tp6-27 cold page-load on Chromium"
     try-name: raptor-tp6-27-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-27)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-27
+            - --test=raptor-tp6-27-cold
             - --app=chromium
 
 raptor-tp6-28-chromium-cold:
     description: "Raptor tp6-28 cold page-load on Chromium"
     try-name: raptor-tp6-28-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-28)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-28
+            - --test=raptor-tp6-28-cold
             - --app=chromium
 
 raptor-tp6-29-chromium-cold:
     description: "Raptor tp6-29 cold page-load on Chromium"
     try-name: raptor-tp6-29-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-29)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-29
+            - --test=raptor-tp6-29-cold
             - --app=chromium
 
 raptor-tp6-30-chromium-cold:
     description: "Raptor tp6-30 cold page-load on Chromium"
     try-name: raptor-tp6-30-chromium-cold
     treeherder-symbol: Rap-Cr(tp6-c-30)
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-30
+            - --test=raptor-tp6-30-cold
             - --app=chromium
 
 raptor-ares6-chromium:
     description: "Raptor Ares6 on Chromium"
     try-name: raptor-ares6-chromium
     treeherder-symbol: Rap-Cr(ares6)
     max-run-time: 2500
     tier: 3
--- a/taskcluster/ci/test/raptor-fenix.yml
+++ b/taskcluster/ci/test/raptor-fenix.yml
@@ -172,395 +172,395 @@ raptor-tp6m-1-fenix-cold:
     description: "Raptor tp6m-1 cold page-load on Fenix"
     try-name: raptor-tp6m-1-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-1)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-1
+            - --test=raptor-tp6m-1-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-2-fenix-cold:
     description: "Raptor tp6m-2 cold page-load on Fenix"
     try-name: raptor-tp6m-2-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-2)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-2
+            - --test=raptor-tp6m-2-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-3-fenix-cold:
     description: "Raptor tp6m-3 cold page-load on Fenix"
     try-name: raptor-tp6m-3-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-3)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-3
+            - --test=raptor-tp6m-3-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-4-fenix-cold:
     description: "Raptor tp6m-4 cold page-load on Fenix"
     try-name: raptor-tp6m-4-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-4)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-4
+            - --test=raptor-tp6m-4-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-5-fenix-cold:
     description: "Raptor tp6m-5 cold page-load on Fenix"
     try-name: raptor-tp6m-5-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-5)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-5
+            - --test=raptor-tp6m-5-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-6-fenix-cold:
     description: "Raptor tp6m-6 cold page-load on Fenix"
     try-name: raptor-tp6m-6-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-6)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-6
+            - --test=raptor-tp6m-6-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-7-fenix-cold:
     description: "Raptor tp6m-7 cold page-load on Fenix"
     try-name: raptor-tp6m-7-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-7)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-7
+            - --test=raptor-tp6m-7-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-8-fenix-cold:
     description: "Raptor tp6m-8 cold page-load on Fenix"
     try-name: raptor-tp6m-8-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-8)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-8
+            - --test=raptor-tp6m-8-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-9-fenix-cold:
     description: "Raptor tp6m-9 cold page-load on Fenix"
     try-name: raptor-tp6m-9-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-9)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-9
+            - --test=raptor-tp6m-9-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-10-fenix-cold:
     description: "Raptor tp6m-10 cold page-load on Fenix"
     try-name: raptor-tp6m-10-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-10)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-10
+            - --test=raptor-tp6m-10-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-11-fenix-cold:
     description: "Raptor tp6m-11 cold page-load on Fenix"
     try-name: raptor-tp6m-11-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-11)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-11
+            - --test=raptor-tp6m-11-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-12-fenix-cold:
     description: "Raptor tp6m-12 cold page-load on Fenix"
     try-name: raptor-tp6m-12-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-12)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-12
+            - --test=raptor-tp6m-12-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-13-fenix-cold:
     description: "Raptor tp6m-13 cold page-load on Fenix"
     try-name: raptor-tp6m-13-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-13)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-13
+            - --test=raptor-tp6m-13-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-14-fenix-cold:
     description: "Raptor tp6m-14 cold page-load on Fenix"
     try-name: raptor-tp6m-14-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-14)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-14
+            - --test=raptor-tp6m-14-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-15-fenix-cold:
     description: "Raptor tp6m-15 cold page-load on Fenix"
     try-name: raptor-tp6m-15-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-15)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-15
+            - --test=raptor-tp6m-15-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-16-fenix-cold:
     description: "Raptor tp6m-16 cold page-load on Fenix"
     try-name: raptor-tp6m-16-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-16)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-16
+            - --test=raptor-tp6m-16-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-17-fenix-cold:
     description: "Raptor tp6m-17 cold page-load on Fenix"
     try-name: raptor-tp6m-17-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-17)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-17
+            - --test=raptor-tp6m-17-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-18-fenix-cold:
     description: "Raptor tp6m-18 cold page-load on Fenix"
     try-name: raptor-tp6m-18-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-18)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-18
+            - --test=raptor-tp6m-18-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-19-fenix-cold:
     description: "Raptor tp6m-19 cold page-load on Fenix"
     try-name: raptor-tp6m-19-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-19)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-19
+            - --test=raptor-tp6m-19-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-20-fenix-cold:
     description: "Raptor tp6m-20 cold page-load on Fenix"
     try-name: raptor-tp6m-20-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-20)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-20
+            - --test=raptor-tp6m-20-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-21-fenix-cold:
     description: "Raptor tp6m-21 cold page-load on Fenix"
     try-name: raptor-tp6m-21-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-21)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-21
+            - --test=raptor-tp6m-21-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-22-fenix-cold:
     description: "Raptor tp6m-22 cold page-load on Fenix"
     try-name: raptor-tp6m-22-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-22)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-22
+            - --test=raptor-tp6m-22-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-23-fenix-cold:
     description: "Raptor tp6m-23 cold page-load on Fenix"
     try-name: raptor-tp6m-23-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-23)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-23
+            - --test=raptor-tp6m-23-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-24-fenix-cold:
     description: "Raptor tp6m-24 cold page-load on Fenix"
     try-name: raptor-tp6m-24-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-24)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-24
+            - --test=raptor-tp6m-24-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-25-fenix-cold:
     description: "Raptor tp6m-25 cold page-load on Fenix"
     try-name: raptor-tp6m-25-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-25)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-25
+            - --test=raptor-tp6m-25-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-26-fenix-cold:
     description: "Raptor tp6m-26 cold page-load on Fenix"
     try-name: raptor-tp6m-26-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-26)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-26
+            - --test=raptor-tp6m-26-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-27-fenix-cold:
     description: "Raptor tp6m-27 cold page-load on Fenix"
     try-name: raptor-tp6m-27-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-27)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-27
+            - --test=raptor-tp6m-27-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-tp6m-28-fenix-cold:
     description: "Raptor tp6m-28 cold page-load on Fenix"
     try-name: raptor-tp6m-28-fenix-cold
     treeherder-symbol: Rap-fenix(tp6m-c-28)
     run-on-projects: []
     e10s: true
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-28
+            - --test=raptor-tp6m-28-cold
             - --app=fenix
             - --binary-path=org.mozilla.fenix.performancetest
             - --activity=org.mozilla.fenix.IntentReceiverActivity
 
 raptor-scn-power-idle-fenix:
     description: "Raptor idle-browser power-usage test on Fenix"
     try-name: raptor-scn-power-idle-fenix
     treeherder-symbol: Rap-fenix(idl-p)
--- a/taskcluster/ci/test/raptor-fennec68.yml
+++ b/taskcluster/ci/test/raptor-fennec68.yml
@@ -124,154 +124,154 @@ raptor-tp6m-10-fennec68:
 
 raptor-tp6m-1-fennec68-cold:
     description: "Raptor tp6m-1 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-1-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-1-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-1-fennec68
+            - --test=raptor-tp6m-1-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-2-fennec68-cold:
     description: "Raptor tp6m-2 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-2-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-2-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-2-fennec68
+            - --test=raptor-tp6m-2-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-3-fennec68-cold:
     description: "Raptor tp6m-3 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-3-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-3-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-3-fennec68
+            - --test=raptor-tp6m-3-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-4-fennec68-cold:
     description: "Raptor tp6m-4 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-4-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-4-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-4-fennec68
+            - --test=raptor-tp6m-4-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-5-fennec68-cold:
     description: "Raptor tp6m-5 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-5-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-5-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-5-fennec68
+            - --test=raptor-tp6m-5-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-6-fennec68-cold:
     description: "Raptor tp6m-6 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-6-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-6-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-6-fennec68
+            - --test=raptor-tp6m-6-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-7-fennec68-cold:
     description: "Raptor tp6m-7 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-7-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-7-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-7-fennec68
+            - --test=raptor-tp6m-7-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-8-fennec68-cold:
     description: "Raptor tp6m-8 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-8-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-8-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-8-fennec68
+            - --test=raptor-tp6m-8-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-9-fennec68-cold:
     description: "Raptor tp6m-9 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-9-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-9-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-9-fennec68
+            - --test=raptor-tp6m-9-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-10-fennec68-cold:
     description: "Raptor tp6m-10 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-10-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-10-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-10-fennec68
+            - --test=raptor-tp6m-10-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-11-fennec68-cold:
     description: "Raptor tp6m-11 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-11-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-11-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-11-fennec68
+            - --test=raptor-tp6m-11-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-12-fennec68-cold:
     description: "Raptor tp6m-12 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-12-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-12-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-12-fennec68
+            - --test=raptor-tp6m-12-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-13-fennec68-cold:
     description: "Raptor tp6m-13 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-13-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-13-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-13-fennec68
+            - --test=raptor-tp6m-13-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
 
 raptor-tp6m-14-fennec68-cold:
     description: "Raptor tp6m-14 cold page-load on Fennec68"
     max-run-time: 3600
     try-name: raptor-tp6m-14-fennec68-cold
     treeherder-symbol: Rap(tp6m-c-14-f68)
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-14-fennec68
+            - --test=raptor-tp6m-14-fennec68-cold
             - --app=fennec
             - --binary=org.mozilla.firefox
--- a/taskcluster/ci/test/raptor-gve.yml
+++ b/taskcluster/ci/test/raptor-gve.yml
@@ -346,17 +346,17 @@ raptor-tp6m-1-geckoview-cold:
     e10s: true
     tier:
         by-test-platform:
             android-hw-p2-8-0-arm7.*: 2
             android-hw-g5.*: 2
             default: 1
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-1
+            - --test=raptor-tp6m-1-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-2-geckoview-cold:
     description: "Raptor tp6m-2 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-2-geckoview-cold
@@ -370,17 +370,17 @@ raptor-tp6m-2-geckoview-cold:
     e10s: true
     tier:
         by-test-platform:
             android-hw-p2-8-0-arm7.*: 2
             android-hw-g5.*: 2
             default: 1
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-2
+            - --test=raptor-tp6m-2-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-3-geckoview-cold:
     description: "Raptor tp6m-3 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-3-geckoview-cold
@@ -394,17 +394,17 @@ raptor-tp6m-3-geckoview-cold:
     e10s: true
     tier:
         by-test-platform:
             android-hw-p2-8-0-arm7.*: 2
             android-hw-g5.*: 2
             default: 1
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-3
+            - --test=raptor-tp6m-3-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-4-geckoview-cold:
     description: "Raptor tp6m-4 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-4-geckoview-cold
@@ -418,17 +418,17 @@ raptor-tp6m-4-geckoview-cold:
     e10s: true
     tier:
         by-test-platform:
             android-hw-p2-8-0-arm7.*: 2
             android-hw-g5.*: 2
             default: 1
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-4
+            - --test=raptor-tp6m-4-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-5-geckoview-cold:
     description: "Raptor tp6m-5 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-5-geckoview-cold
@@ -442,17 +442,17 @@ raptor-tp6m-5-geckoview-cold:
     e10s: true
     tier:
         by-test-platform:
             android-hw-p2-8-0-arm7.*: 2
             android-hw-g5.*: 2
             default: 1
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-5
+            - --test=raptor-tp6m-5-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-6-geckoview-cold:
     description: "Raptor tp6m-6 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-6-geckoview-cold
@@ -466,17 +466,17 @@ raptor-tp6m-6-geckoview-cold:
     e10s: true
     tier:
         by-test-platform:
             android-hw-p2-8-0-arm7.*: 2
             android-hw-g5.*: 2
             default: 1
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-6
+            - --test=raptor-tp6m-6-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-7-geckoview-cold:
     description: "Raptor tp6m-7 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-7-geckoview-cold
@@ -485,17 +485,17 @@ raptor-tp6m-7-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-7
+            - --test=raptor-tp6m-7-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-8-geckoview-cold:
     description: "Raptor tp6m-8 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-8-geckoview-cold
@@ -504,17 +504,17 @@ raptor-tp6m-8-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-8
+            - --test=raptor-tp6m-8-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-9-geckoview-cold:
     description: "Raptor tp6m-9 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-9-geckoview-cold
@@ -523,17 +523,17 @@ raptor-tp6m-9-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-9
+            - --test=raptor-tp6m-9-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-10-geckoview-cold:
     description: "Raptor tp6m-10 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-10-geckoview-cold
@@ -542,17 +542,17 @@ raptor-tp6m-10-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-10
+            - --test=raptor-tp6m-10-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-11-geckoview-cold:
     description: "Raptor tp6m-11 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-11-geckoview-cold
@@ -561,17 +561,17 @@ raptor-tp6m-11-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-11
+            - --test=raptor-tp6m-11-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-12-geckoview-cold:
     description: "Raptor tp6m-12 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-12-geckoview-cold
@@ -580,17 +580,17 @@ raptor-tp6m-12-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-12
+            - --test=raptor-tp6m-12-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-13-geckoview-cold:
     description: "Raptor tp6m-13 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-13-geckoview-cold
@@ -599,17 +599,17 @@ raptor-tp6m-13-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-13
+            - --test=raptor-tp6m-13-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-14-geckoview-cold:
     description: "Raptor tp6m-14 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-14-geckoview-cold
@@ -618,17 +618,17 @@ raptor-tp6m-14-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-14
+            - --test=raptor-tp6m-14-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-15-geckoview-cold:
     description: "Raptor tp6m-15 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-15-geckoview-cold
@@ -637,17 +637,17 @@ raptor-tp6m-15-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-15
+            - --test=raptor-tp6m-15-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-16-geckoview-cold:
     description: "Raptor tp6m-16 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-16-geckoview-cold
@@ -656,17 +656,17 @@ raptor-tp6m-16-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-16
+            - --test=raptor-tp6m-16-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-17-geckoview-cold:
     description: "Raptor tp6m-17 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-17-geckoview-cold
@@ -675,17 +675,17 @@ raptor-tp6m-17-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-17
+            - --test=raptor-tp6m-17-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-18-geckoview-cold:
     description: "Raptor tp6m-18 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-18-geckoview-cold
@@ -694,17 +694,17 @@ raptor-tp6m-18-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-18
+            - --test=raptor-tp6m-18-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-19-geckoview-cold:
     description: "Raptor tp6m-19 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-19-geckoview-cold
@@ -713,17 +713,17 @@ raptor-tp6m-19-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-19
+            - --test=raptor-tp6m-19-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-20-geckoview-cold:
     description: "Raptor tp6m-20 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-20-geckoview-cold
@@ -732,17 +732,17 @@ raptor-tp6m-20-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-20
+            - --test=raptor-tp6m-20-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-21-geckoview-cold:
     description: "Raptor tp6m-21 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-21-geckoview-cold
@@ -751,17 +751,17 @@ raptor-tp6m-21-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-21
+            - --test=raptor-tp6m-21-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-22-geckoview-cold:
     description: "Raptor tp6m-22 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-22-geckoview-cold
@@ -770,17 +770,17 @@ raptor-tp6m-22-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-22
+            - --test=raptor-tp6m-22-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-23-geckoview-cold:
     description: "Raptor tp6m-23 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-23-geckoview-cold
@@ -789,17 +789,17 @@ raptor-tp6m-23-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-23
+            - --test=raptor-tp6m-23-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-24-geckoview-cold:
     description: "Raptor tp6m-24 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-24-geckoview-cold
@@ -808,17 +808,17 @@ raptor-tp6m-24-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-24
+            - --test=raptor-tp6m-24-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-25-geckoview-cold:
     description: "Raptor tp6m-25 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-25-geckoview-cold
@@ -827,17 +827,17 @@ raptor-tp6m-25-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-25
+            - --test=raptor-tp6m-25-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-26-geckoview-cold:
     description: "Raptor tp6m-26 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-26-geckoview-cold
@@ -846,17 +846,17 @@ raptor-tp6m-26-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-26
+            - --test=raptor-tp6m-26-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-27-geckoview-cold:
     description: "Raptor tp6m-27 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-27-geckoview-cold
@@ -865,17 +865,17 @@ raptor-tp6m-27-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-27
+            - --test=raptor-tp6m-27-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
 
 raptor-tp6m-28-geckoview-cold:
     description: "Raptor tp6m-28 cold page-load on GeckoView Example"
     max-run-time: 2700
     try-name: raptor-tp6m-28-geckoview-cold
@@ -884,12 +884,12 @@ raptor-tp6m-28-geckoview-cold:
         by-test-platform:
             android-hw-.*/opt: ['mozilla-central']
             android-hw-p2-.*-api-16/pgo: ['trunk']
             android-hw-p2-.*aarch64.*/pgo: ['trunk', 'mozilla-beta']
             default: ['trunk', 'mozilla-beta']
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-28
+            - --test=raptor-tp6m-28-cold
             - --app=geckoview
             - --binary=org.mozilla.geckoview_example
             - --activity=org.mozilla.geckoview_example.GeckoViewActivity
--- a/taskcluster/ci/test/raptor-refbrow.yml
+++ b/taskcluster/ci/test/raptor-refbrow.yml
@@ -241,337 +241,337 @@ raptor-unity-webgl-refbrow:
 
 raptor-tp6m-1-refbrow-cold:
     description: "Raptor tp6m-1 cold page-load on the reference browser"
     try-name: raptor-tp6m-1-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-1)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-1
+            - --test=raptor-tp6m-1-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 
 raptor-tp6m-2-refbrow-cold:
     description: "Raptor tp6m-2 cold page-load on the reference browser"
     try-name: raptor-tp6m-2-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-2)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-2
+            - --test=raptor-tp6m-2-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-3-refbrow-cold:
     description: "Raptor tp6m-3 cold page-load on the reference browser"
     try-name: raptor-tp6m-3-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-3)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-3
+            - --test=raptor-tp6m-3-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-4-refbrow-cold:
     description: "Raptor tp6m-4 cold page-load on the reference browser"
     try-name: raptor-tp6m-4-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-4)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-4
+            - --test=raptor-tp6m-4-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-5-refbrow-cold:
     description: "Raptor tp6m-5 cold page-load on the reference browser"
     try-name: raptor-tp6m-5-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-5)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-5
+            - --test=raptor-tp6m-5-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-6-refbrow-cold:
     description: "Raptor tp6m-6 cold page-load on the reference browser"
     try-name: raptor-tp6m-6-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-6)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-6
+            - --test=raptor-tp6m-6-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-7-refbrow-cold:
     description: "Raptor tp6m-7 cold page-load on the reference browser"
     try-name: raptor-tp6m-7-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-7)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-7
+            - --test=raptor-tp6m-7-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-8-refbrow-cold:
     description: "Raptor tp6m-8 cold page-load on the reference browser"
     try-name: raptor-tp6m-8-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-8)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-8
+            - --test=raptor-tp6m-8-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-9-refbrow-cold:
     description: "Raptor tp6m-9 cold page-load on the reference browser"
     try-name: raptor-tp6m-9-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-9)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-9
+            - --test=raptor-tp6m-9-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-10-refbrow-cold:
     description: "Raptor tp6m-10 cold page-load on the reference browser"
     try-name: raptor-tp6m-10-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-10)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-10
+            - --test=raptor-tp6m-10-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-11-refbrow-cold:
     description: "Raptor tp6m-11 cold page-load on the reference browser"
     try-name: raptor-tp6m-11-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-11)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-11
+            - --test=raptor-tp6m-11-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-12-refbrow-cold:
     description: "Raptor tp6m-12 cold page-load on the reference browser"
     try-name: raptor-tp6m-12-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-12)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-12
+            - --test=raptor-tp6m-12-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-13-refbrow-cold:
     description: "Raptor tp6m-13 cold page-load on the reference browser"
     try-name: raptor-tp6m-13-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-13)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-13
+            - --test=raptor-tp6m-13-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-14-refbrow-cold:
     description: "Raptor tp6m-14 cold page-load on the reference browser"
     try-name: raptor-tp6m-14-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-14)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-14
+            - --test=raptor-tp6m-14-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-15-refbrow-cold:
     description: "Raptor tp6m-15 cold page-load on the reference browser"
     try-name: raptor-tp6m-15-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-15)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-15
+            - --test=raptor-tp6m-15-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-16-refbrow-cold:
     description: "Raptor tp6m-16 cold page-load on the reference browser"
     try-name: raptor-tp6m-16-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-16)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-16
+            - --test=raptor-tp6m-16-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-17-refbrow-cold:
     description: "Raptor tp6m-17 cold page-load on the reference browser"
     try-name: raptor-tp6m-17-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-17)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-17
+            - --test=raptor-tp6m-17-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-18-refbrow-cold:
     description: "Raptor tp6m-18 cold page-load on the reference browser"
     try-name: raptor-tp6m-18-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-18)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-18
+            - --test=raptor-tp6m-18-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-19-refbrow-cold:
     description: "Raptor tp6m-19 cold page-load on the reference browser"
     try-name: raptor-tp6m-19-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-19)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-19
+            - --test=raptor-tp6m-19-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-20-refbrow-cold:
     description: "Raptor tp6m-20 cold page-load on the reference browser"
     try-name: raptor-tp6m-20-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-20)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-20
+            - --test=raptor-tp6m-20-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-21-refbrow-cold:
     description: "Raptor tp6m-21 cold page-load on the reference browser"
     try-name: raptor-tp6m-21-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-21)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-21
+            - --test=raptor-tp6m-21-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-22-refbrow-cold:
     description: "Raptor tp6m-22 cold page-load on the reference browser"
     try-name: raptor-tp6m-22-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-22)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-22
+            - --test=raptor-tp6m-22-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-23-refbrow-cold:
     description: "Raptor tp6m-23 cold page-load on the reference browser"
     try-name: raptor-tp6m-23-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-23)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-23
+            - --test=raptor-tp6m-23-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivityy
 
 raptor-tp6m-24-refbrow-cold:
     description: "Raptor tp6m-24 cold page-load on the reference browser"
     try-name: raptor-tp6m-24-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-24)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-24
+            - --test=raptor-tp6m-24-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-25-refbrow-cold:
     description: "Raptor tp6m-25 cold page-load on the reference browser"
     try-name: raptor-tp6m-25-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-25)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-25
+            - --test=raptor-tp6m-25-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-26-refbrow-cold:
     description: "Raptor tp6m-26 cold page-load on the reference browser"
     try-name: raptor-tp6m-26-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-26)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-26
+            - --test=raptor-tp6m-26-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-27-refbrow-cold:
     description: "Raptor tp6m-27 cold page-load on the reference browser"
     try-name: raptor-tp6m-27-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-27)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-27
+            - --test=raptor-tp6m-27-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
 
 raptor-tp6m-28-refbrow-cold:
     description: "Raptor tp6m-28 cold page-load on the reference browser"
     try-name: raptor-tp6m-28-refbrow-cold
     treeherder-symbol: Rap-refbrow(tp6m-c-28)
     e10s: true
     mozharness:
         extra-options:
-            - --test=raptor-tp6m-cold-28
+            - --test=raptor-tp6m-28-cold
             - --app=refbrow
             - --binary-path=org.mozilla.reference.browser.raptor
             - --activity=org.mozilla.reference.browser.BrowserTestActivity
--- a/taskcluster/ci/test/raptor.yml
+++ b/taskcluster/ci/test/raptor.yml
@@ -685,279 +685,279 @@ raptor-youtube-playback-h264-power-firef
 
 raptor-tp6-1-firefox-cold:
     description: "Raptor tp6-1 cold page-load on Firefox"
     try-name: raptor-tp6-1-firefox-cold
     treeherder-symbol: Rap(tp6-c-1)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-1
+            - --test=raptor-tp6-1-cold
 
 raptor-tp6-2-firefox-cold:
     description: "Raptor tp6-2 cold page-load on Firefox"
     try-name: raptor-tp6-2-firefox-cold
     treeherder-symbol: Rap(tp6-c-2)
     max-run-time: 2700
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-2
+            - --test=raptor-tp6-2-cold
 
 raptor-tp6-3-firefox-cold:
     description: "Raptor tp6-3 cold page-load on Firefox"
     try-name: raptor-tp6-3-firefox-cold
     treeherder-symbol: Rap(tp6-c-3)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-3
+            - --test=raptor-tp6-3-cold
 
 raptor-tp6-4-firefox-cold:
     description: "Raptor tp6-4 cold page-load on Firefox"
     try-name: raptor-tp6-4-firefox-cold
     treeherder-symbol: Rap(tp6-c-4)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-4
+            - --test=raptor-tp6-4-cold
 
 raptor-tp6-5-firefox-cold:
     description: "Raptor tp6-5 cold page-load on Firefox"
     try-name: raptor-tp6-5-firefox-cold
     treeherder-symbol: Rap(tp6-c-5)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-5
+            - --test=raptor-tp6-5-cold
 
 raptor-tp6-6-firefox-cold:
     description: "Raptor tp6-6 cold page-load on Firefox"
     try-name: raptor-tp6-6-firefox-cold
     treeherder-symbol: Rap(tp6-c-6)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-6
+            - --test=raptor-tp6-6-cold
 
 raptor-tp6-7-firefox-cold:
     description: "Raptor tp6-7 cold page-load on Firefox"
     try-name: raptor-tp6-7-firefox-cold
     treeherder-symbol: Rap(tp6-c-7)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-7
+            - --test=raptor-tp6-7-cold
 
 raptor-tp6-8-firefox-cold:
     description: "Raptor tp6-8 cold page-load on Firefox"
     try-name: raptor-tp6-8-firefox-cold
     treeherder-symbol: Rap(tp6-c-8)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-8
+            - --test=raptor-tp6-8-cold
 
 raptor-tp6-9-firefox-cold:
     description: "Raptor tp6-9 cold page-load on Firefox"
     try-name: raptor-tp6-9-firefox-cold
     treeherder-symbol: Rap(tp6-c-9)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-9
+            - --test=raptor-tp6-9-cold
 
 raptor-tp6-10-firefox-cold:
     description: "Raptor tp6-10 cold page-load on Firefox"
     try-name: raptor-tp6-10-firefox-cold
     treeherder-symbol: Rap(tp6-c-10)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-10
+            - --test=raptor-tp6-10-cold
 
 raptor-tp6-11-firefox-cold:
     description: "Raptor tp6-11 cold page-load on Firefox"
     try-name: raptor-tp6-11-firefox-cold
     treeherder-symbol: Rap(tp6-c-11)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-11
+            - --test=raptor-tp6-11-cold
 
 raptor-tp6-12-firefox-cold:
     description: "Raptor tp6-12 cold page-load on Firefox"
     try-name: raptor-tp6-12-firefox-cold
     treeherder-symbol: Rap(tp6-c-12)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-12
+            - --test=raptor-tp6-12-cold
 
 raptor-tp6-13-firefox-cold:
     description: "Raptor tp6-13 cold page-load on Firefox"
     try-name: raptor-tp6-13-firefox-cold
     treeherder-symbol: Rap(tp6-c-13)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-13
+            - --test=raptor-tp6-13-cold
 
 raptor-tp6-14-firefox-cold:
     description: "Raptor tp6-14 cold page-load on Firefox"
     try-name: raptor-tp6-14-firefox-cold
     treeherder-symbol: Rap(tp6-c-14)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-14
+            - --test=raptor-tp6-14-cold
 
 raptor-tp6-15-firefox-cold:
     description: "Raptor tp6-15 cold page-load on Firefox"
     try-name: raptor-tp6-15-firefox-cold
     treeherder-symbol: Rap(tp6-c-15)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-15
+            - --test=raptor-tp6-15-cold
 
 raptor-tp6-16-firefox-cold:
     description: "Raptor tp6-16 cold page-load on Firefox"
     try-name: raptor-tp6-16-firefox-cold
     treeherder-symbol: Rap(tp6-c-16)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-16
+            - --test=raptor-tp6-16-cold
 
 raptor-tp6-17-firefox-cold:
     description: "Raptor tp6-17 cold page-load on Firefox"
     try-name: raptor-tp6-17-firefox-cold
     treeherder-symbol: Rap(tp6-c-17)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-17
+            - --test=raptor-tp6-17-cold
 
 raptor-tp6-18-firefox-cold:
     description: "Raptor tp6-18 cold page-load on Firefox"
     try-name: raptor-tp6-18-firefox-cold
     treeherder-symbol: Rap(tp6-c-18)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-18
+            - --test=raptor-tp6-18-cold
 
 raptor-tp6-19-firefox-cold:
     description: "Raptor tp6-19 cold page-load on Firefox"
     try-name: raptor-tp6-19-firefox-cold
     treeherder-symbol: Rap(tp6-c-19)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-19
+            - --test=raptor-tp6-19-cold
 
 raptor-tp6-20-firefox-cold:
     description: "Raptor tp6-20 cold page-load on Firefox"
     try-name: raptor-tp6-20-firefox-cold
     treeherder-symbol: Rap(tp6-c-20)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-20
+            - --test=raptor-tp6-20-cold
 
 raptor-tp6-21-firefox-cold:
     description: "Raptor tp6-21 cold page-load on Firefox"
     try-name: raptor-tp6-21-firefox-cold
     treeherder-symbol: Rap(tp6-c-21)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-21
+            - --test=raptor-tp6-21-cold
 
 raptor-tp6-22-firefox-cold:
     description: "Raptor tp6-22 cold page-load on Firefox"
     try-name: raptor-tp6-22-firefox-cold
     treeherder-symbol: Rap(tp6-c-22)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-22
+            - --test=raptor-tp6-22-cold
 
 raptor-tp6-23-firefox-cold:
     description: "Raptor tp6-23 cold page-load on Firefox"
     try-name: raptor-tp6-23-firefox-cold
     treeherder-symbol: Rap(tp6-c-23)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-23
+            - --test=raptor-tp6-23-cold
 
 raptor-tp6-24-firefox-cold:
     description: "Raptor tp6-24 cold page-load on Firefox"
     try-name: raptor-tp6-24-firefox-cold
     treeherder-symbol: Rap(tp6-c-24)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-24
+            - --test=raptor-tp6-24-cold
 
 raptor-tp6-25-firefox-cold:
     description: "Raptor tp6-25 cold page-load on Firefox"
     try-name: raptor-tp6-25-firefox-cold
     treeherder-symbol: Rap(tp6-c-25)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-25
+            - --test=raptor-tp6-25-cold
 
 raptor-tp6-26-firefox-cold:
     description: "Raptor tp6-26 cold page-load on Firefox"
     try-name: raptor-tp6-26-firefox-cold
     treeherder-symbol: Rap(tp6-c-26)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-26
+            - --test=raptor-tp6-26-cold
 
 raptor-tp6-27-firefox-cold:
     description: "Raptor tp6-27 cold page-load on Firefox"
     try-name: raptor-tp6-27-firefox-cold
     treeherder-symbol: Rap(tp6-c-27)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-27
+            - --test=raptor-tp6-27-cold
 
 raptor-tp6-28-firefox-cold:
     description: "Raptor tp6-28 cold page-load on Firefox"
     try-name: raptor-tp6-28-firefox-cold
     treeherder-symbol: Rap(tp6-c-28)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-28
+            - --test=raptor-tp6-28-cold
 
 raptor-tp6-29-firefox-cold:
     description: "Raptor tp6-29 cold page-load on Firefox"
     try-name: raptor-tp6-29-firefox-cold
     treeherder-symbol: Rap(tp6-c-29)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-29
+            - --test=raptor-tp6-29-cold
 
 raptor-tp6-30-firefox-cold:
     description: "Raptor tp6-30 cold page-load on Firefox"
     try-name: raptor-tp6-30-firefox-cold
     treeherder-symbol: Rap(tp6-c-30)
     tier: 2
     mozharness:
         extra-options:
-            - --test=raptor-tp6-cold-30
+            - --test=raptor-tp6-30-cold
 
 raptor-ares6-firefox:
     description: "Raptor Ares6 on Firefox"
     variants: ["fission"]
     try-name: raptor-ares6-firefox
     treeherder-symbol: Rap(ares6)
     max-run-time: 2500
     tier: 3
@@ -1008,33 +1008,24 @@ raptor-jetstream2-firefox-profiling:
     mozharness:
         extra-options:
             - --test=raptor-jetstream2
             - --gecko-profile
     fetches:
         fetch:
             - jetstream2
 
-browsertime-tp6-1-firefox:
-    description: "Raptor (browsertime) tp6-1 on Firefox"
+browsertime-tp6-1:
+    description: "Raptor (browsertime) tp6-1"
+    raptor-test: raptor-tp6-1
     run-on-projects: ['integration', 'try']
+    apps: ["firefox"]
     variants: ["fission"]
-    try-name: browsertime-tp6-1-firefox
+    cold:
+        by-app:
+            firefox: true
+            default: false
     treeherder-symbol: Btime(tp6-1)
     max-run-time: 3000
     tier: 3
     mozharness:
         extra-options:
             - --browsertime
-            - --test=raptor-tp6-1
-
-browsertime-tp6-1-firefox-cold:
-    description: "Raptor (browsertime) tp6-1 cold page-load on Firefox"
-    run-on-projects: ['integration', 'try']
-    variants: ["fission"]
-    try-name: browsertime-tp6-1-firefox-cold
-    treeherder-symbol: Btime(tp6-c-1)
-    max-run-time: 3000
-    tier: 3
-    mozharness:
-        extra-options:
-            - --browsertime
-            - --test=raptor-tp6-cold-1
--- a/taskcluster/ci/test/test-platforms.yml
+++ b/taskcluster/ci/test/test-platforms.yml
@@ -37,17 +37,17 @@ linux64/opt:
         - web-platform-tests
         - opt-only-tests
         - desktop-screenshot-capture
         - talos
         - awsy
         - mochitest-headless
         - linux-talos-flex
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - raptor-fetch-firefox
         - marionette-media-tests
 linux64-shippable/opt:
     build-platform: linux64-shippable/opt
     test-sets:
         - common-tests
         - web-platform-tests
         - web-platform-tests-wdspec-headless
@@ -57,17 +57,17 @@ linux64-shippable/opt:
         - awsy
         - mochitest-headless
         - marionette-headless
         - linux-talos-flex
         - raptor-chrome
         - raptor-chromium
         - raptor-fetch-chromium
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - raptor-fetch-firefox
         - raptor-profiling
         - raptor-fetch-profiling
 linux64-devedition/opt:
     build-platform: linux64-devedition-nightly/opt
     test-sets:
         - common-tests
         - web-platform-tests
@@ -91,27 +91,27 @@ linux64-stylo-sequential/opt:
 linux64-qr/opt:
     build-platform: linux64/opt
     test-sets:
         - linux-qr-tests
         - talos
         - awsy
         - web-platform-tests
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - raptor-fetch-firefox
 linux64-shippable-qr/opt:
     build-platform: linux64-shippable/opt
     test-sets:
         - linux-qr-tests
         - talos
         - awsy
         - web-platform-tests
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - raptor-fetch-firefox
 linux64-qr/debug:
     build-platform: linux64/debug
     test-sets:
         - linux-qr-tests
         - web-platform-tests
 linux64-asan-qr/opt:
     build-platform: linux64-asan/opt
@@ -143,32 +143,32 @@ windows7-32/opt:
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-reftest-gpu
         - windows-talos
         - windows-tests
         - web-platform-tests
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
 
 windows7-32-shippable/opt:
     build-platform: win32-shippable/opt
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-reftest-gpu
         - windows-talos
         - windows-tests
         - web-platform-tests
         - web-platform-tests-wdspec-headless
         - raptor-chrome
         - raptor-chromium
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
 
 windows7-32-devedition/opt:
     build-platform: win32-devedition-nightly/opt
     test-sets:
         - desktop-screenshot-capture
         - windows-reftest-gpu
         - windows-tests
         - web-platform-tests
@@ -199,50 +199,50 @@ windows10-64/opt:
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-talos
         - marionette-gpu-tests
         - windows-tests
         - web-platform-tests
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - marionette-media-tests
 
 windows10-aarch64/opt:
     build-platform: win64-aarch64-shippable/opt
     test-sets:
         - awsy
         - marionette-gpu-tests
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - windows-aarch64-tests
         - windows-talos
 
 windows10-64-ref-hw-2017/opt:
     build-platform: win64-shippable/opt
     test-sets:
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - talos-ref-hw
 
 windows10-64-shippable/opt:
     build-platform: win64-shippable/opt
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-talos
         - marionette-gpu-tests
         - windows-tests
         - web-platform-tests
         - web-platform-tests-wdspec-headless
         - raptor-chrome
         - raptor-chromium
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - raptor-profiling
 
 windows10-64-devedition/opt:
     build-platform: win64-devedition-nightly/opt
     test-sets:
         - desktop-screenshot-capture
         - marionette-gpu-tests
         - windows-tests
@@ -262,27 +262,27 @@ windows10-64-qr/debug:
 
 windows10-64-qr/opt:
     build-platform: win64/opt
     test-sets:
         - awsy
         - windows-qr-tests
         - windows-talos
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - web-platform-tests
 
 windows10-64-shippable-qr/opt:
     build-platform: win64-shippable/opt
     test-sets:
         - awsy
         - windows-qr-tests
         - windows-talos
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - web-platform-tests
 
 windows10-64-mingwclang/debug:
     build-platform: win64-mingwclang/debug
     test-sets:
         - mingwclang-tests-debug
 
 windows10-64-mingwclang/opt:
@@ -308,17 +308,17 @@ macosx1014-64-shippable/opt:
     test-sets:
         - macosx1014-64-tests
         - macosx64-talos
         - desktop-screenshot-capture
         - awsy
         - raptor-chrome
         - raptor-chromium
         - raptor-firefox
-        - browsertime-firefox
+        - browsertime
         - raptor-firefox-power
         - raptor-profiling
         - marionette-media-tests
         - web-platform-tests-wdspec-headless
 
 macosx1014-64/debug:
     build-platform: macosx64/debug
     test-sets:
--- a/taskcluster/ci/test/test-sets.yml
+++ b/taskcluster/ci/test/test-sets.yml
@@ -884,27 +884,16 @@ android-hw-arm7-raptor-nightly:
     - raptor-tp6m-4-fennec68
     - raptor-tp6m-5-fennec68
     - raptor-tp6m-6-fennec68
     - raptor-tp6m-7-fennec68
     - raptor-tp6m-8-fennec68
     - raptor-tp6m-9-fennec68
     - raptor-tp6m-10-fennec68
 
-browsertime-firefox:
-    - browsertime-tp6-1-firefox
-    - browsertime-tp6-1-firefox-cold
+browsertime:
+    - browsertime-tp6-1
 
 android-hw-aarch64-browsertime:
-    - browsertime-tp6m-1-fenix
-    - browsertime-tp6m-1-geckoview
-    - browsertime-tp6m-1-refbrow
-    - browsertime-tp6m-1-fenix-cold
-    - browsertime-tp6m-1-geckoview-cold
-    - browsertime-tp6m-1-refbrow-cold
+    - browsertime-tp6m-1
 
 android-hw-arm7-browsertime:
-    - browsertime-tp6m-1-fenix
-    - browsertime-tp6m-1-geckoview
-    - browsertime-tp6m-1-refbrow
-    - browsertime-tp6m-1-fenix-cold
-    - browsertime-tp6m-1-geckoview-cold
-    - browsertime-tp6m-1-refbrow-cold
+    - browsertime-tp6m-1
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/transforms/raptor.py
@@ -0,0 +1,202 @@
+# 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/.
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+from copy import deepcopy
+
+from voluptuous import (
+    Optional,
+    Required,
+    Extra,
+)
+
+from taskgraph.transforms.base import TransformSequence
+from taskgraph.transforms.tests import test_description_schema
+from taskgraph.util.schema import optionally_keyed_by, resolve_keyed_by, Schema
+from taskgraph.util.treeherder import split_symbol, join_symbol
+
+transforms = TransformSequence()
+
+
+raptor_description_schema = Schema({
+    # Raptor specific configs.
+    Optional('apps'): optionally_keyed_by(
+        'test-platform',
+        [basestring]
+    ),
+    Optional('raptor-test'): basestring,
+    Optional('activity'): optionally_keyed_by(
+        'app',
+        basestring
+    ),
+    Optional('binary-path'): optionally_keyed_by(
+        'app',
+        basestring
+    ),
+    Optional('cold'): optionally_keyed_by(
+        'test-platform', 'app',
+        bool,
+    ),
+    # Configs defined in the 'test_description_schema'.
+    Optional('max-run-time'): optionally_keyed_by(
+        'app',
+        test_description_schema['max-run-time']
+    ),
+    Optional('run-on-projects'): optionally_keyed_by(
+        'app',
+        test_description_schema['run-on-projects']
+    ),
+    Optional('target'): optionally_keyed_by(
+        'app',
+        test_description_schema['target']
+    ),
+    Required('test-name'): test_description_schema['test-name'],
+    Required('test-platform'): test_description_schema['test-platform'],
+    Required('require-signed-extensions'): test_description_schema['require-signed-extensions'],
+    Required('treeherder-symbol'): test_description_schema['treeherder-symbol'],
+    # Any unrecognized keys will be validated against the test_description_schema.
+    Extra: object,
+})
+
+transforms.add_validate(raptor_description_schema)
+
+
+@transforms.add
+def split_apps(config, tests):
+    app_symbols = {
+        'chrome': 'Chr',
+        'chromium': 'Cr',
+        'fenix': 'fenix',
+        'refbrow': 'refbrow',
+    }
+
+    for test in tests:
+        apps = test.pop('apps', None)
+        if not apps:
+            yield test
+            continue
+
+        for app in apps:
+            atest = deepcopy(test)
+            suffix = "-{}".format(app)
+            atest['app'] = app
+            atest['description'] += " on {}".format(app.capitalize())
+
+            name = atest['test-name']
+            if name.endswith('-cold'):
+                name = atest['test-name'][:-len('-cold')] + suffix + '-cold'
+            else:
+                name += suffix
+
+            atest['test-name'] = name
+            atest['try-name'] = name
+
+            if app in app_symbols:
+                group, symbol = split_symbol(atest['treeherder-symbol'])
+                group += "-{}".format(app_symbols[app])
+                atest['treeherder-symbol'] = join_symbol(group, symbol)
+
+            yield atest
+
+
+@transforms.add
+def handle_keyed_by_app(config, tests):
+    fields = [
+        'activity',
+        'binary-path',
+        'cold',
+        'max-run-time',
+        'run-on-projects',
+        'target',
+    ]
+    for test in tests:
+        for field in fields:
+            resolve_keyed_by(test, field, item_name=test['test-name'])
+        yield test
+
+
+@transforms.add
+def split_cold(config, tests):
+    for test in tests:
+        cold = test.pop('cold', False)
+
+        if not cold:
+            yield test
+            continue
+
+        orig = deepcopy(test)
+        yield orig
+
+        assert 'raptor-test' in test
+        test['description'] += " using cold pageload"
+        test['raptor-test'] += '-cold'
+        test['max-run-time'] = 3000
+        test['test-name'] += '-cold'
+        test['try-name'] += '-cold'
+
+        group, symbol = split_symbol(test['treeherder-symbol'])
+        symbol += '-c'
+        test['treeherder-symbol'] = join_symbol(group, symbol)
+        yield test
+
+
+@transforms.add
+def add_extra_options(config, tests):
+    for test in tests:
+        extra_options = test.setdefault('mozharness', {}).setdefault('extra-options', [])
+
+        if 'app' in test:
+            extra_options.append('--app={}'.format(test.pop('app')))
+
+        if 'activity' in test:
+            extra_options.append('--activity={}'.format(test.pop('activity')))
+
+        if 'binary-path' in test:
+            extra_options.append('--binary-path={}'.format(test.pop('binary-path')))
+
+        if 'raptor-test' in test:
+            extra_options.append('--test={}'.format(test.pop('raptor-test')))
+
+        if test['require-signed-extensions']:
+            extra_options.append('--is-release-build')
+
+        # add urlparams based on platform, test names and projects
+        testurlparams_by_platform_and_project = {
+            "android-hw-g5": [
+                {
+                    "branches": [],  # For all branches
+                    "testnames": ["youtube-playback"],
+                    "urlparams": [
+                        # param used for excluding youtube-playback tests from executing
+                        # it excludes the tests with videos >1080p
+                        "exclude=1,2,9,10,17,18,21,22,26,28,30,32,39,40,47,"
+                        "48,55,56,63,64,71,72,79,80,83,84,89,90,95,96",
+                    ]
+                },
+            ]
+        }
+
+        for platform, testurlparams_by_project_definitions \
+                in testurlparams_by_platform_and_project.items():
+
+            if test['test-platform'].startswith(platform):
+                # For every platform it may have several definitions
+                for testurlparams_by_project in testurlparams_by_project_definitions:
+                    # The test should contain at least one defined testname
+                    if any(
+                        testname in test['test-name']
+                        for testname in testurlparams_by_project['testnames']
+                    ):
+                        branches = testurlparams_by_project['branches']
+                        if (
+                            branches == [] or
+                            config.params.get('project') in branches or
+                            config.params.is_try() and 'try' in branches
+                        ):
+                            params_query = '&'.join(testurlparams_by_project['urlparams'])
+                            add_extra_params_option = "--test-url-params={}".format(params_query)
+                            extra_options.append(add_extra_params_option)
+
+        yield test
--- a/taskcluster/taskgraph/transforms/tests.py
+++ b/taskcluster/taskgraph/transforms/tests.py
@@ -14,16 +14,20 @@ This is a good place to translate a test
 The test description should be fully formed by the time it reaches these
 transforms, and these transforms should not embody any specific knowledge about
 what should run where. this is the wrong place for special-casing platforms,
 for example - use `all_tests.py` instead.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
+import copy
+import logging
+import os
+
 from taskgraph.transforms.base import TransformSequence
 from taskgraph.util.attributes import match_run_on_projects
 from taskgraph.util.keyed_by import evaluate_keyed_by
 from taskgraph.util.schema import resolve_keyed_by, OptimizationSchema
 from taskgraph.util.templates import merge
 from taskgraph.util.treeherder import split_symbol, join_symbol, add_suffix
 from taskgraph.util.platforms import platform_family
 from taskgraph.util.schema import (
@@ -40,18 +44,17 @@ from taskgraph.util.perfile import perfi
 
 from voluptuous import (
     Any,
     Optional,
     Required,
     Exclusive,
 )
 
-import copy
-import logging
+here = os.path.abspath(os.path.dirname(__file__))
 
 # default worker types keyed by instance-size
 LINUX_WORKER_TYPES = {
     'large': 't-linux-large',
     'xlarge': 't-linux-xlarge',
     'default': 't-linux-large',
 }
 
@@ -566,33 +569,47 @@ def set_defaults(config, tests):
         test['mozharness'].setdefault('requires-signed-builds', False)
         test['mozharness'].setdefault('tooltool-downloads', 'public')
         test['mozharness'].setdefault('set-moz-node-path', False)
         test['mozharness'].setdefault('chunked', False)
         test['mozharness'].setdefault('chunking-args', 'this-chunk')
         yield test
 
 
-transforms.add_validate(test_description_schema)
-
-
 @transforms.add
 def resolve_keys(config, tests):
     for test in tests:
         resolve_keyed_by(
             test, 'require-signed-extensions',
             item_name=test['test-name'],
             **{
                 'release-type': config.params['release_type'],
             }
         )
         yield test
 
 
 @transforms.add
+def setup_raptor(config, tests):
+    """Add options that are specific to raptor jobs (identified by suite=raptor)"""
+    from taskgraph.transforms.raptor import transforms as raptor_transforms
+
+    for test in tests:
+        if test['suite'] != 'raptor':
+            yield test
+            continue
+
+        for t in raptor_transforms(config, [test]):
+            yield t
+
+
+transforms.add_validate(test_description_schema)
+
+
+@transforms.add
 def handle_suite_category(config, tests):
     for test in tests:
         test.setdefault('suite', {})
 
         if isinstance(test['suite'], basestring):
             test['suite'] = {'name': test['suite']}
 
         suite = test['suite'].setdefault('name', test['test-name'])
@@ -637,69 +654,16 @@ def setup_talos(config, tests):
         if test['build-platform'].startswith('win32'):
             extra_options.append('--add-option')
             extra_options.append('--setpref,gfx.direct2d.disabled=true')
 
         yield test
 
 
 @transforms.add
-def setup_raptor(config, tests):
-    """Add options that are specific to raptor jobs (identified by suite=raptor)"""
-    for test in tests:
-        if test['suite'] != 'raptor':
-            yield test
-            continue
-
-        extra_options = test.setdefault('mozharness', {}).setdefault('extra-options', [])
-
-        if test['require-signed-extensions']:
-            extra_options.append('--is-release-build')
-
-        # add urlparams based on platform, test names and projects
-        testurlparams_by_platform_and_project = {
-            "android-hw-g5": [
-                {
-                    "branches": [],  # For all branches
-                    "testnames": ["youtube-playback"],
-                    "urlparams": [
-                        # param used for excluding youtube-playback tests from executing
-                        # it excludes the tests with videos >1080p
-                        "exclude=1,2,9,10,17,18,21,22,26,28,30,32,39,40,47,"
-                        "48,55,56,63,64,71,72,79,80,83,84,89,90,95,96",
-                    ]
-                },
-            ]
-        }
-
-        for platform, testurlparams_by_project_definitions \
-                in testurlparams_by_platform_and_project.items():
-
-            if test['test-platform'].startswith(platform):
-                # For every platform it may have several definitions
-                for testurlparams_by_project in testurlparams_by_project_definitions:
-                    # The test should contain at least one defined testname
-                    if any(
-                        testname in test['test-name']
-                        for testname in testurlparams_by_project['testnames']
-                    ):
-                        branches = testurlparams_by_project['branches']
-                        if (
-                            branches == [] or
-                            config.params.get('project') in branches or
-                            config.params.is_try() and 'try' in branches
-                        ):
-                            params_query = '&'.join(testurlparams_by_project['urlparams'])
-                            add_extra_params_option = "--test-url-params={}".format(params_query)
-                            extra_options.append(add_extra_params_option)
-
-        yield test
-
-
-@transforms.add
 def setup_browsertime_flag(config, tests):
     """Optionally add `--browsertime` flag to Raptor pageload tests."""
 
     browsertime_flag = config.params['try_task_config'].get('browsertime', False)
 
     for test in tests:
         if not browsertime_flag or test['suite'] != 'raptor':
             yield test
@@ -1122,17 +1086,17 @@ def handle_run_on_projects(config, tests
         if test['run-on-projects'] == 'built-projects':
             test['run-on-projects'] = test['build-attributes'].get('run_on_projects', ['all'])
         yield test
 
 
 @transforms.add
 def split_variants(config, tests):
     for test in tests:
-        variants = test.pop('variants') or []
+        variants = test.pop('variants', [])
 
         yield copy.deepcopy(test)
 
         for name in variants:
             testv = copy.deepcopy(test)
             variant = TEST_VARIANTS[name]
 
             if 'filterfn' in variant and not variant['filterfn'](testv):
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -1281,38 +1281,44 @@ class TestInfoCommand(MachCommandBase):
             manifest_paths.add(t['manifest'])
         manifest_count = len(manifest_paths)
         print("Resolver found {} tests, {} manifests".format(len(tests), manifest_count))
 
         if show_manifests:
             by_component['manifests'] = {}
             manifest_paths = list(manifest_paths)
             manifest_paths.sort()
+            relpaths = []
             for manifest_path in manifest_paths:
                 relpath = mozpath.relpath(manifest_path, self.topsrcdir)
-                print("  {}".format(relpath))
                 if mozpath.commonprefix((manifest_path, self.topsrcdir)) != self.topsrcdir:
                     continue
-                reader = self.mozbuild_reader(config_mode='empty')
+                relpaths.append(relpath)
+            reader = self.mozbuild_reader(config_mode='empty')
+            files_info = reader.files_info(relpaths)
+            for manifest_path in manifest_paths:
+                relpath = mozpath.relpath(manifest_path, self.topsrcdir)
+                if mozpath.commonprefix((manifest_path, self.topsrcdir)) != self.topsrcdir:
+                    continue
+                print("  {}".format(relpath))
                 manifest_info = None
-                for info_path, info in reader.files_info([manifest_path]).items():
-                    bug_component = info.get('BUG_COMPONENT')
+                if relpath in files_info:
+                    bug_component = files_info[relpath].get('BUG_COMPONENT')
                     key = "{}::{}".format(bug_component.product, bug_component.component)
-                    if (info_path == relpath) and ((not components) or (key in components)):
+                    if (not components) or (key in components):
                         manifest_info = {
                             'manifest': relpath,
                             'tests': 0,
                             'skipped': 0
                         }
                         rkey = key if show_components else 'all'
                         if rkey in by_component['manifests']:
                             by_component['manifests'][rkey].append(manifest_info)
                         else:
                             by_component['manifests'][rkey] = [manifest_info]
-                        break
                 if manifest_info:
                     for t in tests:
                         if t['manifest'] == manifest_path:
                             manifest_info['tests'] += 1
                             if t.get('skip-if'):
                                 manifest_info['skipped'] += 1
             for key in by_component['manifests']:
                 by_component['manifests'][key].sort()
@@ -1320,43 +1326,47 @@ class TestInfoCommand(MachCommandBase):
         if show_tests:
             by_component['tests'] = {}
 
         if show_tests or show_summary:
             test_count = 0
             failed_count = 0
             skipped_count = 0
             component_set = set()
+            relpaths = []
             for t in tests:
-                reader = self.mozbuild_reader(config_mode='empty')
+                relpath = t.get('srcdir_relpath')
+                relpaths.append(relpath)
+            reader = self.mozbuild_reader(config_mode='empty')
+            files_info = reader.files_info(relpaths)
+            for t in tests:
                 if not matches_filters(t):
                     continue
                 test_count += 1
                 relpath = t.get('srcdir_relpath')
-                for info_path, info in reader.files_info([relpath]).items():
-                    bug_component = info.get('BUG_COMPONENT')
+                if relpath in files_info:
+                    bug_component = files_info[relpath].get('BUG_COMPONENT')
                     key = "{}::{}".format(bug_component.product, bug_component.component)
-                    if (info_path == relpath) and ((not components) or (key in components)):
+                    if (not components) or (key in components):
                         component_set.add(key)
                         test_info = {'test': relpath}
                         for test_key in ['skip-if', 'fail-if']:
                             value = t.get(test_key)
                             if value:
                                 test_info[test_key] = value
                         if t.get('fail-if'):
                             failed_count += 1
                         if t.get('skip-if'):
                             skipped_count += 1
                         if show_tests:
                             rkey = key if show_components else 'all'
                             if rkey in by_component['tests']:
                                 by_component['tests'][rkey].append(test_info)
                             else:
                                 by_component['tests'][rkey] = [test_info]
-                        break
             if show_tests:
                 for key in by_component['tests']:
                     by_component['tests'][key].sort(key=lambda k: k['test'])
 
         if show_summary:
             by_component['summary'] = {}
             by_component['summary']['components'] = len(component_set)
             by_component['summary']['manifests'] = manifest_count
--- a/testing/mozharness/mozharness/mozilla/testing/unittest.py
+++ b/testing/mozharness/mozharness/mozilla/testing/unittest.py
@@ -145,23 +145,23 @@ class DesktopUnittestOutputParser(Output
                         message += '\n One or more unittests failed.'
                         log_level = WARNING
                 # If self.summary_suite_re['known_fail_group'] == None,
                 # then r should not match it, # so this test is fine as is.
                 elif self.summary_suite_re['known_fail_group'] in r:
                     self.known_fail_count = int(summary_match_list[-1])
                 self.log(message, log_level)
                 return  # skip harness check and base parse_single_line
-        harness_match = self.harness_error_re.match(line)
+        harness_match = self.harness_error_re.search(line)
         if harness_match:
             self.warning(' %s' % line)
             self.worst_log_level = self.worst_level(WARNING, self.worst_log_level)
             self.tbpl_status = self.worst_level(TBPL_WARNING, self.tbpl_status,
                                                 levels=TBPL_WORST_LEVEL_TUPLE)
-            full_harness_match = self.full_harness_error_re.match(line)
+            full_harness_match = self.full_harness_error_re.search(line)
             if full_harness_match:
                 r = full_harness_match.group(1)
                 if r == "application crashed":
                     self.crashed = True
                 elif r == "missing output line for total leaks!":
                     self.leaked = None
                 else:
                     self.leaked = True
--- a/testing/raptor/raptor/raptor.ini
+++ b/testing/raptor/raptor/raptor.ini
@@ -6,46 +6,46 @@
 [include:tests/tp6/desktop/raptor-tp6-5.ini]
 [include:tests/tp6/desktop/raptor-tp6-6.ini]
 [include:tests/tp6/desktop/raptor-tp6-7.ini]
 [include:tests/tp6/desktop/raptor-tp6-8.ini]
 [include:tests/tp6/desktop/raptor-tp6-9.ini]
 [include:tests/tp6/desktop/raptor-tp6-10.ini]
 
 # raptor cold pageload tests desktop
-[include:tests/tp6/desktop/raptor-tp6-cold-1.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-2.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-3.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-4.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-5.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-6.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-7.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-8.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-9.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-10.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-11.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-12.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-13.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-14.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-15.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-16.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-17.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-18.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-19.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-20.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-21.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-22.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-23.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-24.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-25.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-26.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-27.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-28.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-29.ini]
-[include:tests/tp6/desktop/raptor-tp6-cold-30.ini]
+[include:tests/tp6/desktop/raptor-tp6-1-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-2-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-3-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-4-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-5-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-6-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-7-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-8-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-9-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-10-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-11-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-12-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-13-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-14-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-15-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-16-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-17-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-18-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-19-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-20-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-21-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-22-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-23-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-24-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-25-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-26-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-27-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-28-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-29-cold.ini]
+[include:tests/tp6/desktop/raptor-tp6-30-cold.ini]
 
 # raptor pageload binast tests desktop
 [include:tests/tp6/desktop/raptor-tp6-binast-1.ini]
 
 # raptor warm pageload tests mobile
 [include:tests/tp6/mobile/raptor-tp6m-1.ini]
 [include:tests/tp6/mobile/raptor-tp6m-2.ini]
 [include:tests/tp6/mobile/raptor-tp6m-3.ini]
@@ -63,58 +63,58 @@
 [include:tests/tp6/mobile/raptor-tp6m-5-fennec68.ini]
 [include:tests/tp6/mobile/raptor-tp6m-6-fennec68.ini]
 [include:tests/tp6/mobile/raptor-tp6m-7-fennec68.ini]
 [include:tests/tp6/mobile/raptor-tp6m-8-fennec68.ini]
 [include:tests/tp6/mobile/raptor-tp6m-9-fennec68.ini]
 [include:tests/tp6/mobile/raptor-tp6m-10-fennec68.ini]
 
 # raptor cold pageload tests mobile
-[include:tests/tp6/mobile/raptor-tp6m-cold-1.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-2.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-3.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-4.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-5.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-6.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-7.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-8.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-9.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-10.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-11.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-12.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-13.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-14.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-15.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-16.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-17.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-18.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-19.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-20.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-21.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-22.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-23.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-24.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-25.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-26.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-27.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-28.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-1-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-2-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-3-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-4-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-5-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-6-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-7-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-8-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-9-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-10-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-11-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-12-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-13-fennec68.ini]
-[include:tests/tp6/mobile/raptor-tp6m-cold-14-fennec68.ini]
+[include:tests/tp6/mobile/raptor-tp6m-1-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-2-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-3-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-4-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-5-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-6-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-7-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-8-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-9-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-10-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-11-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-12-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-13-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-14-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-15-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-16-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-17-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-18-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-19-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-20-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-21-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-22-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-23-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-24-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-25-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-26-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-27-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-28-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-1-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-2-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-3-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-4-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-5-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-6-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-7-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-8-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-9-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-10-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-11-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-12-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-13-fennec68-cold.ini]
+[include:tests/tp6/mobile/raptor-tp6m-14-fennec68-cold.ini]
 
 # raptor benchmark tests
 [include:tests/benchmarks/raptor-assorted-dom.ini]
 [include:tests/benchmarks/raptor-ares6.ini]
 [include:tests/benchmarks/raptor-jetstream2.ini]
 [include:tests/benchmarks/raptor-motionmark-animometer.ini]
 [include:tests/benchmarks/raptor-motionmark-htmlsuite.ini]
 [include:tests/benchmarks/raptor-speedometer.ini]
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-1.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-1-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-10.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-10-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-11.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-11-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-12.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-12-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-13.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-13-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-14.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-14-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-15.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-15-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-16.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-16-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-17.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-17-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-18.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-18-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-19.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-19-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-2.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-2-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-20.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-20-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-21.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-21-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-22.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-22-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-23.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-23-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-24.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-24-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-25.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-25-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-26.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-26-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-27.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-27-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-28.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-28-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-29.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-29-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-3.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-3-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-30.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-30-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-4.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-4-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-5.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-5-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-6.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-6-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-7.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-7-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-8.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-8-cold.ini
rename from testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-cold-9.ini
rename to testing/raptor/raptor/tests/tp6/desktop/raptor-tp6-9-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-1.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-1-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-1-fennec68.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-1-fennec68-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-10.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-10-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-10-fennec68.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-10-fennec68-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-11.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-11-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-11-fennec68.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-11-fennec68-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-12.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-12-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-12-fennec68.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-12-fennec68-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-13.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-13-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-13-fennec68.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-13-fennec68-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-14.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-14-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-14-fennec68.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-14-fennec68-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-15.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-15-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-16.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-16-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-17.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-17-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-18.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-18-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-19.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-19-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-2.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-2-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-2-fennec68.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-2-fennec68-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-20.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-20-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-21.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-21-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-22.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-22-cold.ini
rename from testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-cold-23.ini
rename to testing/raptor/raptor/tests/tp6/mobile/raptor-tp6m-23