Merge mozilla-central to inbound. a=merge CLOSED TREE
authorMargareta Eliza Balazs <ebalazs@mozilla.com>
Thu, 01 Nov 2018 11:46:09 +0200
changeset 443965 3a81ecf22e6fe82dc808fb986e559e9222134386
parent 443964 bb810bff5427a3356a8200de53a46177926e1262 (current diff)
parent 443898 3cff4bff1c9d8e65e73a966fe09c4e5aa1ed734a (diff)
child 443966 8c0ff4d45ea0a2972bdf1d4092eda895c2932a7a
push id34977
push userdvarga@mozilla.com
push dateThu, 01 Nov 2018 22:29:07 +0000
treeherdermozilla-central@2dd516cee24f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to inbound. a=merge CLOSED TREE
devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css
taskcluster/taskgraph/transforms/job/mozharness_test.py
xpcom/base/nsWeakPtr.h
--- a/browser/config/mozconfigs/win64/debug-searchfox
+++ b/browser/config/mozconfigs/win64/debug-searchfox
@@ -4,15 +4,19 @@ MOZ_AUTOMATION_L10N_CHECK=0
 
 . "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/common"
 . "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
 
 ac_add_options --enable-optimize
 ac_add_options --enable-debug
 
+# Save rust analysis (this requires unlocking the unstable features,
+# which is done in the taskcluster task definition via RUSTC_BOOTSTRAP)
+export RUSTFLAGS="-Zsave-analysis"
+
 ac_add_options --enable-clang-plugin
 ac_add_options --enable-mozsearch-plugin
 
 . $topsrcdir/build/win64/mozconfig.vs-latest
 
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.clang-cl"
--- a/build/build-clang/clang-win64.json
+++ b/build/build-clang/clang-win64.json
@@ -14,11 +14,12 @@
     "cxx": "cl.exe",
     "ml": "ml64.exe",
     "patches": [
       "workaround-issue38586.patch",
       "r342649-hotpatch-8-byte-nops.patch",
       "r342652-unpoison-thread-stacks.patch",
       "r343123-pin-asan-dll.patch",
       "aarch64-vastart-checking.patch",
+      "downgrade-mangling-error.patch",
       "loosen-msvc-detection.patch"
     ]
 }
new file mode 100644
--- /dev/null
+++ b/build/build-clang/downgrade-mangling-error.patch
@@ -0,0 +1,33 @@
+Downgrade unimplemented mangling diagnostic from error to note.
+This codepath is exercised by MozsearchIndexer.cpp (the searchfox
+indexer) when indexing on Windows. We can do without having the
+unimplemented bits for now as long the compiler doesn't fail the
+build. See also https://bugs.llvm.org/show_bug.cgi?id=39294
+
+diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
+index b483187394..fb01348ebb 100644
+--- a/clang/lib/AST/ItaniumMangle.cpp
++++ b/clang/lib/AST/ItaniumMangle.cpp
+@@ -3557,20 +3557,21 @@ recurse:
+   case Expr::AsTypeExprClass:
+   case Expr::PseudoObjectExprClass:
+   case Expr::AtomicExprClass:
+   case Expr::FixedPointLiteralClass:
+   {
+     if (!NullOut) {
+       // As bad as this diagnostic is, it's better than crashing.
+       DiagnosticsEngine &Diags = Context.getDiags();
+-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
++      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Remark,
+                                        "cannot yet mangle expression type %0");
+       Diags.Report(E->getExprLoc(), DiagID)
+         << E->getStmtClassName() << E->getSourceRange();
++      Out << "MOZ_WE_HACKED_AROUND_BUG_1418415";
+     }
+     break;
+   }
+ 
+   case Expr::CXXUuidofExprClass: {
+     const CXXUuidofExpr *UE = cast<CXXUuidofExpr>(E);
+     if (UE->isTypeOperand()) {
+       QualType UuidT = UE->getTypeOperand(Context.getASTContext());
--- a/build/clang-plugin/mozsearch-plugin/FileOperations.cpp
+++ b/build/clang-plugin/mozsearch-plugin/FileOperations.cpp
@@ -55,19 +55,21 @@ AutoLockFile::AutoLockFile(const std::st
   std::string MutexName = std::string("Local\\searchfox-") + Hash;
   std::wstring WideMutexName;
   WideMutexName.assign(MutexName.begin(), MutexName.end());
   Handle = CreateMutex(nullptr, false, WideMutexName.c_str());
   if (Handle == NULL) {
     return;
   }
 
-  WaitForSingleObject(Handle, INFINITE);
+  if (WaitForSingleObject(Handle, INFINITE) != WAIT_OBJECT_0) {
+    return;
+  }
 
-  FileDescriptor = _open(Filename.c_str(), _O_RDWR | _O_CREAT, 0666);
+  FileDescriptor = _open(Filename.c_str(), _O_RDWR | _O_CREAT | _O_BINARY, 0666);
 }
 
 AutoLockFile::~AutoLockFile() {
   _close(FileDescriptor);
 
   ReleaseMutex(Handle);
   CloseHandle(Handle);
 }
--- a/build/clang-plugin/mozsearch-plugin/MozsearchIndexer.cpp
+++ b/build/clang-plugin/mozsearch-plugin/MozsearchIndexer.cpp
@@ -474,27 +474,28 @@ public:
 
       ensurePath(Filename);
 
       // We lock the output file in case some other clang process is trying to
       // write to it at the same time.
       AutoLockFile Lock(Filename);
 
       if (!Lock.success()) {
-        continue;
+        fprintf(stderr, "Unable to lock file %s\n", Filename.c_str());
+        exit(1);
       }
 
       std::vector<std::string> Lines;
 
       // Read all the existing lines in from the output file. Rather than
       // overwrite them, we want to merge our results with what was already
       // there. This ensures that header files that are included multiple times
       // in different ways are analyzed completely.
       char Buffer[65536];
-      FILE *Fp = Lock.openFile("r");
+      FILE *Fp = Lock.openFile("rb");
       if (!Fp) {
         fprintf(stderr, "Unable to open input file %s\n", Filename.c_str());
         exit(1);
       }
       while (fgets(Buffer, sizeof(Buffer), Fp)) {
         Lines.push_back(std::string(Buffer));
       }
       fclose(Fp);
@@ -504,17 +505,17 @@ public:
       Lines.insert(Lines.end(), Info.Output.begin(), Info.Output.end());
       std::sort(Lines.begin(), Lines.end());
 
       std::vector<std::string> Nodupes;
       std::unique_copy(Lines.begin(), Lines.end(), std::back_inserter(Nodupes));
 
       // Overwrite the output file with the merged data. Since we have the lock,
       // this will happen atomically.
-      Fp = Lock.openFile("w");
+      Fp = Lock.openFile("wb");
       if (!Fp) {
         fprintf(stderr, "Unable to open output file %s\n", Filename.c_str());
         exit(1);
       }
       size_t Length = 0;
       for (std::string &Line : Nodupes) {
         Length += Line.length();
         if (fwrite(Line.c_str(), Line.length(), 1, Fp) != 1) {
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -42,16 +42,17 @@ MACH_MODULES = [
     'python/safety/mach_commands.py',
     'python/mach/mach/commands/commandinfo.py',
     'python/mach/mach/commands/settings.py',
     'python/mozboot/mozboot/mach_commands.py',
     'python/mozbuild/mozbuild/mach_commands.py',
     'python/mozbuild/mozbuild/backend/mach_commands.py',
     'python/mozbuild/mozbuild/compilation/codecomplete.py',
     'python/mozbuild/mozbuild/frontend/mach_commands.py',
+    'python/mozrelease/mozrelease/mach_commands.py',
     'taskcluster/mach_commands.py',
     'testing/awsy/mach_commands.py',
     'testing/firefox-ui/mach_commands.py',
     'testing/geckodriver/mach_commands.py',
     'testing/mach_commands.py',
     'testing/marionette/mach_commands.py',
     'testing/mochitest/mach_commands.py',
     'testing/mozharness/mach_commands.py',
@@ -84,40 +85,45 @@ CATEGORIES = {
     'testing': {
         'short': 'Testing',
         'long': 'Run tests.',
         'priority': 60,
     },
     'ci': {
         'short': 'CI',
         'long': 'Taskcluster commands',
-        'priority': 59
+        'priority': 59,
     },
     'devenv': {
         'short': 'Development Environment',
         'long': 'Set up and configure your development environment.',
         'priority': 50,
     },
     'build-dev': {
         'short': 'Low-level Build System Interaction',
         'long': 'Interact with specific parts of the build system.',
         'priority': 20,
     },
     'misc': {
         'short': 'Potpourri',
         'long': 'Potent potables and assorted snacks.',
         'priority': 10,
     },
+    'release': {
+        'short': 'Release automation',
+        'long': 'Commands for used in release automation.',
+        'priority': 5,
+    },
     'disabled': {
         'short': 'Disabled',
         'long': 'The disabled commands are hidden by default. Use -v to display them. '
         'These commands are unavailable for your current context, '
         'run "mach <command>" to see why.',
         'priority': 0,
-    }
+    },
 }
 
 
 # We submit data to telemetry approximately every this many mach invocations
 TELEMETRY_SUBMISSION_FREQUENCY = 10
 
 
 def search_path(mozilla_dir, packages_txt):
@@ -230,31 +236,49 @@ def bootstrap(topsrcdir, mozilla_dir=Non
             return True
 
         # The environment is likely a machine invocation.
         if sys.stdin.closed or not sys.stdin.isatty():
             return True
 
         return False
 
-    def post_dispatch_handler(context, handler, args):
+    def post_dispatch_handler(context, handler, instance, result,
+                              start_time, end_time, args):
         """Perform global operations after command dispatch.
 
 
         For now,  we will use this to handle build system telemetry.
         """
         # Don't do anything when...
         if should_skip_dispatch(context, handler):
             return
 
         # We have not opted-in to telemetry
         if not context.settings.build.telemetry:
             return
 
-        # Every n-th operation
+        from mozbuild.telemetry import gather_telemetry
+        from mozbuild.base import MozbuildObject
+
+        if not isinstance(instance, MozbuildObject):
+            instance = MozbuildObject.from_environment()
+
+        try:
+            substs = instance.substs
+        except Exception:
+            substs = {}
+
+        # We gather telemetry for every operation...
+        gather_telemetry(command=handler.name, success=(result == 0),
+                         start_time=start_time, end_time=end_time,
+                         mach_context=context, substs=substs,
+                         paths=[instance.topsrcdir, instance.topobjdir])
+
+        # But only submit about every n-th operation
         if random.randint(1, TELEMETRY_SUBMISSION_FREQUENCY) != 1:
             return
 
         with open(os.devnull, 'wb') as devnull:
             subprocess.Popen([sys.executable,
                               os.path.join(topsrcdir, 'build',
                                            'submit_telemetry_data.py'),
                               get_state_dir()[0]],
--- a/devtools/client/aboutdebugging-new/aboutdebugging.css
+++ b/devtools/client/aboutdebugging-new/aboutdebugging.css
@@ -7,17 +7,16 @@
 */
 @import "resource://devtools/client/themes/variables.css";
 @import "resource://devtools/client/aboutdebugging-new/src/base.css";
 
 /*
 * Components
 */
 @import "resource://devtools/client/aboutdebugging-new/src/components/App.css";
-@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/RuntimePage.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/connect/ConnectPage.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/connect/ConnectSteps.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsList.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetList.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetPane.css";
--- a/devtools/client/aboutdebugging-new/src/base.css
+++ b/devtools/client/aboutdebugging-new/src/base.css
@@ -44,16 +44,20 @@
   --base-line-height: 1.8;
   --micro-font-size: 11px;
 
   /*
   * Variables particular to about:debugging
   */
   --alt-heading-icon-size: calc(var(--base-distance) * 6);
   --alt-heading-icon-gap: var(--base-distance);
+  --main-heading-icon-size: calc(var(--base-distance) * 16);
+  --main-heading-icon-gap: calc(var(--base-distance) * 3);
+  --main-subheading-icon-size: calc(var(--base-distance) * 5);
+  --main-subheading-heading-icon-gap: calc(var(--base-distance) * 2);
 }
 
 /*
 * Reset some tags
 */
 
 html {
   font: var(--base-font-style);
@@ -101,29 +105,59 @@ a:active {
   white-space: nowrap;
 }
 
 /*
 * Typography
 */
 
 /* Main style for heading (i.e. h1) */
+/* +--------+-------------+
+*  | [Icon] | Lorem ipsum |
+*  +--------+-------------+
+*/
 .main-heading {
   font-size: 2.5em;
   font-weight: lighter;
   line-height: 1.2;
   color: var(--in-content-text-color);
   margin: 0;
   margin-bottom: .5em;
+
+  display: grid;
+  grid-template-columns: var(--main-heading-icon-size) 1fr;
+  grid-column-gap: var(--main-heading-icon-gap);
+  align-items: center;
+}
+
+.main-heading__icon {
+  width: 100%;
 }
 
-/* Main style for a subheading (i.e. h2) */
+/* Main style for a subheading (i.e. h2). It features an icon */
+/* +--------+-------------+
+*  | [Icon] | Lorem ipsum |
+*  +--------+-------------+
+*/
 .main-subheading {
-  line-height: 1.4em;
+  margin-block-start: calc(var(--base-distance) * 4);
   font-weight: 600;
+  font-size: 1.46em; /* import from .header-name in common.inc.css */
+  line-height: 1.3em; /* import from .header-name in common.inc.css */
+
+  display: grid;
+  grid-template-columns: var(--main-subheading-icon-size) 1fr;
+  grid-column-gap: var(--main-subheading-heading-icon-gap);
+  align-items: center;
+}
+
+.main-subheading__icon {
+  width: 100%;
+  fill: currentColor;
+  -moz-context-properties: fill;
 }
 
 /* Alternative style for a heading (i.e. h1) */
 .alt-heading {
   font-weight: 300;
   font-size: 1.46em;
   line-height: 1.2; /* odd value - from common.inc.css */
 
@@ -249,8 +283,14 @@ Form controls
 
 .badge--warning {
   background: var(--warning-50);
 }
 
 .badge--error {
   background: var(--error-50);
 }
+
+.undecorated-link,
+.undecorated-link:hover {
+  text-decoration: none;
+  color: currentColor;
+}
--- a/devtools/client/aboutdebugging-new/src/components/App.css
+++ b/devtools/client/aboutdebugging-new/src/components/App.css
@@ -45,15 +45,15 @@
   padding-block-start: var(--app-top-padding);
   padding-block-end: var(--app-bottom-padding);
 
   /* we want to scroll only the main content, not the sidebar */
   overflow-y: auto;
 }
 
 .page {
-  width: var(--page-width);
+  max-width: var(--page-width);
 }
 
 .page__section {
   margin-block-end: calc(var(--base-distance) * 12);
   --section-inline-margin: calc(var(--alt-heading-icon-size) + var(--alt-heading-icon-gap));
 }
deleted file mode 100644
--- a/devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css
+++ /dev/null
@@ -1,18 +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/. */
-
- /* NOTE: refactor these two rules into a more generic component if we ever need
-          a main heading with an icon */
-
-.runtime-info {
-  align-items: center;
-  display: flex;
-  white-space: nowrap;
-}
-
-.runtime-info__icon {
-  height: 64px;
-  margin-inline-end: 12px;
-  width: 64px;
-}
--- a/devtools/client/aboutdebugging-new/src/components/RuntimeInfo.js
+++ b/devtools/client/aboutdebugging-new/src/components/RuntimeInfo.js
@@ -24,21 +24,21 @@ class RuntimeInfo extends PureComponent 
     };
   }
 
   render() {
     const { icon, deviceName, name, version } = this.props;
 
     return dom.h1(
       {
-        className: "main-heading runtime-info",
+        className: "main-heading",
       },
       dom.img(
         {
-          className: "runtime-info__icon",
+          className: "main-heading__icon",
           src: icon,
         }
       ),
       Localized(
         {
           id: deviceName ? "about-debugging-runtime-info-with-model"
                           : "about-debugging-runtime-info",
           $name: name,
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.css
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.css
@@ -1,39 +1,43 @@
 /* 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/. */
 
 /*
  * The current layout of debug target item is
  *
  *  +--------+-----------------------------+----------------+
- *  |  Icon  | Information                 | Inspect button |
- *  |        |+---------------------------+|                |
- *  |        || Name                      ||                |
- *  |        |+---------------------------+|                |
- *  |        || Detail                    ||                |
- *  |        |+---------------------------+|                |
+ *  | [Icon] | Name                        | Action button  |
  *  +--------+-----------------------------+----------------+
+ *  |        | Detail                                       |
+ *  |        |                                              |
+ *  +--------+----------------------------------------------+
  */
 .debug-target-item {
   display: grid;
-  grid-template-columns: calc(var(--base-distance) * 10) auto max-content;
-  grid-template-rows: auto auto;
-  grid-row-gap: calc(var(--base-distance) * 5);
+  grid-template-columns: calc(var(--base-distance) * 9) 1fr max-content;
   grid-column-gap: calc(var(--base-distance) * 2);
+  grid-template-areas: "icon name   action"
+                       ".    detail detail";
+  margin-block-end: calc(var(--base-distance) * 4);
 }
 
 .debug-target-item__icon {
-  height: 36px;
-  width: 36px;
-  justify-self: center;
+  grid-area: icon;
+  width: 100%;
 }
 
-.debug-target-item__info {
+.debug-target-item__name {
+  grid-area: name;
   /* so as to ellipsis */
   min-width: 0;
+  font-size: calc(var(--base-distance) * 5);
 }
 
-.debug-target-item__info__name {
-  font-size: 20px;
-  margin-block-end: 2px;
+.debug-target-item__action {
+  grid-area: action;
+  align-self: center;
 }
+
+.debug-target-item__detail {
+  grid-area: detail;
+}
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.js
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.js
@@ -18,52 +18,57 @@ class DebugTargetItem extends PureCompon
       detailComponent: PropTypes.any.isRequired,
       dispatch: PropTypes.func.isRequired,
       target: PropTypes.object.isRequired,
     };
   }
 
   renderAction() {
     const { actionComponent, dispatch, target } = this.props;
-    return actionComponent({ dispatch, target });
+    return dom.div(
+      {
+        className: "debug-target-item__action",
+      },
+      actionComponent({ dispatch, target }),
+    );
   }
 
   renderDetail() {
     const { detailComponent, target } = this.props;
-    return detailComponent({ target });
+    return dom.div(
+      {
+        className: "debug-target-item__detail",
+      },
+      detailComponent({ target }),
+    );
   }
 
   renderIcon() {
     return dom.img({
       className: "debug-target-item__icon",
       src: this.props.target.icon,
     });
   }
 
-  renderInfo() {
-    return dom.div(
+  renderName() {
+    return dom.span(
       {
-        className: "debug-target-item__info",
+        className: "debug-target-item__name ellipsis-text",
+        title: this.props.target.name,
       },
-      dom.div(
-        {
-          className: "debug-target-item__info__name ellipsis-text",
-          title: this.props.target.name,
-        },
-        this.props.target.name
-      ),
-      this.renderDetail(),
+      this.props.target.name,
     );
   }
 
   render() {
     return dom.li(
       {
         className: "debug-target-item js-debug-target-item",
       },
       this.renderIcon(),
-      this.renderInfo(),
+      this.renderName(),
       this.renderAction(),
+      this.renderDetail(),
     );
   }
 }
 
 module.exports = DebugTargetItem;
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetList.css
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetList.css
@@ -1,12 +1,12 @@
 /* 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/. */
 
 .debug-target-list {
-  margin-inline-start: 60px;
+  margin-inline-start: calc(var(--base-distance) * 6);
   overflow: hidden;
 }
 
 .debug-target-list--collapsed {
   max-height: 0;
 }
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetPane.css
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetPane.css
@@ -1,37 +1,11 @@
 /* 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/. */
 
-.debug-target-pane__title {
-  align-items: center;
-  display: flex;
+.debug-target-pane__icon {
+  transition: transform 150ms cubic-bezier(.07, .95, 0, 1);
 }
 
-.debug-target-pane__title::before {
-  background-image: url(chrome://devtools/skin/images/aboutdebugging-collapse-icon.svg);
-  background-position: center;
-  background-repeat: no-repeat;
-  background-size: contain;
-  content: "";
-  display: inline-block;
-  fill: currentColor;
-  height: 1em;
-  margin-inline-end: 0.5em;
-  transition: transform 150ms cubic-bezier(.07, .95, 0, 1);
-  width: 1em;
-  -moz-context-properties: fill;
-}
-
-.debug-target-pane__title,
-.debug-target-pane__title:active,
-.debug-target-pane__title:hover,
-.debug-target-pane__title:hover:active,
-.debug-target-pane__title:link,
-.debug-target-pane__title:visited {
-  text-decoration: none;
-  color: var(--text-color);
-}
-
-.debug-target-pane__title--collapsed::before {
+.debug-target-pane__icon--collapsed {
   transform: rotate(-90deg);
 }
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetPane.js
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetPane.js
@@ -42,27 +42,32 @@ class DebugTargetPane extends PureCompon
       name,
       targets,
     } = this.props;
 
     return dom.section(
       {
         className: "js-debug-target-pane",
       },
-      dom.h2(
-        { className: "main-subheading" },
-        dom.a(
-          {
-            className: "debug-target-pane__title js-debug-target-pane-title" +
-                       (isCollapsed ? " debug-target-pane__title--collapsed" : ""),
-            href: "#",
-            onClick: e => this.toggleCollapsibility(),
-          },
-          name,
-          isCollapsed ? dom.span({}, `(${ targets.length })`) : null,
+      dom.a(
+        {
+          className: "undecorated-link js-debug-target-pane-title",
+          href: "#",
+          onClick: e => this.toggleCollapsibility(),
+        },
+        dom.h2(
+          { className: "main-subheading" },
+          dom.img(
+            {
+              className: "main-subheading__icon debug-target-pane__icon" +
+                         (isCollapsed ? " debug-target-pane__icon--collapsed" : ""),
+              src: "chrome://devtools/skin/images/aboutdebugging-collapse-icon.svg",
+            }
+          ),
+          name + (isCollapsed ? ` (${ targets.length })` : ""),
         )
       ),
       DebugTargetList({
         actionComponent,
         detailComponent,
         dispatch,
         isCollapsed,
         targets,
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.css
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.css
@@ -2,24 +2,24 @@
  * 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/. */
 
 /*
  * The current layout of extension detail is
  *
  *  +----------------+--------------------+
  *  | detail name dt | detail value dd    |
- *  | (120px)        | (auto)             |
+ *  | (auto)         |                    |
  *  +----------------+--------------------+
  *  | detail name dt | detail value dd    |
  *  +----------------+--------------------+
  *  | detail name dt | detail value dd    |
  *  +----------------+--------------------+
  */
 .extension-detail {
   display: grid;
-  grid-template-columns: 120px auto;
-  margin-block-start: 4px;
+  grid-template-columns: auto 1fr;
+  grid-column-gap: calc(var(--base-distance) * 2);
 }
 
 .extension-detail__manifest {
   margin-inline-start: 1ch;
 }
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/WorkerDetail.css
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/WorkerDetail.css
@@ -2,22 +2,22 @@
  * 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/. */
 
 /*
  * The current layout of worker detail is
  *
  *  +----------------+--------------------+
  *  | detail name dt | detail value dd    |
- *  | (60px )        | (auto)             |
+ *  | (auto )        |                    |
  *  +----------------+--------------------+
  *  | detail name dt | detail value dd    |
  *  +----------------+--------------------+
  *  | detail name dt | detail value dd    |
  *  +----------------+--------------------+
  *  | [status]       |
  *  +----------------+
  */
 .worker-detail {
   display: grid;
-  grid-template-columns: calc(var(--base-distance) * 15) auto;
-  margin-block-start: var(--base-distance);
+  grid-template-columns: auto 1fr;
+  grid-column-gap: var(--base-distance);
 }
--- a/devtools/client/aboutdebugging-new/src/components/moz.build
+++ b/devtools/client/aboutdebugging-new/src/components/moz.build
@@ -7,13 +7,12 @@ DIRS += [
     'debugtarget',
     'sidebar',
 ]
 
 DevToolsModules(
     'App.css',
     'App.js',
     'ConnectionPromptSetting.js',
-    'RuntimeInfo.css',
     'RuntimeInfo.js',
     'RuntimePage.css',
     'RuntimePage.js',
 )
--- a/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_debug-target-pane_collapsibilities_interaction.js
+++ b/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_debug-target-pane_collapsibilities_interaction.js
@@ -32,12 +32,12 @@ function assertCollapsibility(debugTarge
   const listEl = debugTargetPaneEl.querySelector(".js-debug-target-list");
   const assertHeight = shouldCollapsed ? is : isnot;
   assertHeight(listEl.clientHeight, 0, "Height of list element should correct");
 
   info("Check content of title");
   const titleEl = debugTargetPaneEl.querySelector(".js-debug-target-pane-title");
   const expectedTitle =
     shouldCollapsed
-      ? `${ title }(${ listEl.querySelectorAll(".js-debug-target-item").length })`
+      ? `${ title } (${ listEl.querySelectorAll(".js-debug-target-item").length })`
       : title;
   is(titleEl.textContent, expectedTitle, "Title should correct");
 }
--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -6341,16 +6341,17 @@ exports.CSS_PROPERTIES = {
     "isInherited": true,
     "subproperties": [
       "image-rendering"
     ],
     "supports": [],
     "values": [
       "-moz-crisp-edges",
       "auto",
+      "crisp-edges",
       "inherit",
       "initial",
       "optimizequality",
       "optimizespeed",
       "unset"
     ]
   },
   "ime-mode": {
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -3922,16 +3922,37 @@ nsDocShell::GetMessageManager(ContentFra
   } else if (nsPIDOMWindowOuter* win = GetWindow()) {
     mm = win->GetMessageManager();
   }
   mm.forget(aMessageManager);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDocShell::GetContentBlockingLog(Promise** aPromise)
+{
+  NS_ENSURE_ARG_POINTER(aPromise);
+
+  if (!mContentViewer) {
+    *aPromise = nullptr;
+    return NS_ERROR_FAILURE;
+  }
+
+  nsIDocument* doc = mContentViewer->GetDocument();
+  ErrorResult rv;
+  RefPtr<Promise> promise = Promise::Create(doc->GetOwnerGlobal(), rv);
+  if (NS_WARN_IF(rv.Failed())) {
+    return rv.StealNSResult();
+  }
+  promise->MaybeResolve(doc->GetContentBlockingLog()->Stringify());
+  promise.forget(aPromise);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDocShell::SetDeviceSizeIsPageSize(bool aValue)
 {
   if (mDeviceSizeIsPageSize != aValue) {
     mDeviceSizeIsPageSize = aValue;
     RefPtr<nsPresContext> presContext;
     GetPresContext(getter_AddRefs(presContext));
     if (presContext) {
       presContext->MediaFeatureValuesChanged({
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -1257,9 +1257,20 @@ interface nsIDocShell : nsIDocShellTreeI
    */
   attribute unsigned long displayMode;
 
   /**
    * The message manager for this docshell.  This does not throw, but
    * can return null if the docshell has no message manager.
    */
   [infallible] readonly attribute ContentFrameMessageManager messageManager;
+
+  /**
+   * Asynchronously retrieve a JSON string representing a log of the
+   * content blocking events happened so far in the current tab from the
+   * content process.
+   *
+   * This returns a Promise which resolves to a string on success, and is
+   * rejected on failure.  For documentation on the string format, please
+   * see nsISecureBrowserUI.contentBlockingLogJSON.
+   */
+  Promise getContentBlockingLog();
 };
--- a/docshell/shistory/nsSHEntryShared.h
+++ b/docshell/shistory/nsSHEntryShared.h
@@ -7,20 +7,20 @@
 #ifndef nsSHEntryShared_h__
 #define nsSHEntryShared_h__
 
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsExpirationTracker.h"
 #include "nsIBFCacheEntry.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsRect.h"
 #include "nsString.h"
 #include "nsStubMutationObserver.h"
-#include "nsWeakPtr.h"
 
 #include "mozilla/Attributes.h"
 
 class nsSHEntry;
 class nsISHEntry;
 class nsIDocument;
 class nsIContentViewer;
 class nsIDocShellTreeItem;
--- a/dom/animation/PendingAnimationTracker.cpp
+++ b/dom/animation/PendingAnimationTracker.cpp
@@ -5,16 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PendingAnimationTracker.h"
 
 #include "mozilla/dom/AnimationTimeline.h"
 #include "mozilla/dom/Nullable.h"
 #include "nsIFrame.h"
 #include "nsIPresShell.h"
+#include "nsTransitionManager.h" // For CSSTransition
 
 using mozilla::dom::Nullable;
 
 namespace mozilla {
 
 NS_IMPL_CYCLE_COLLECTION(PendingAnimationTracker,
                          mPlayPendingSet,
                          mPausePendingSet,
@@ -103,63 +104,89 @@ PendingAnimationTracker::TriggerPendingA
   };
 
   triggerAndClearAnimations(mPlayPendingSet);
   triggerAndClearAnimations(mPausePendingSet);
 
   mHasPlayPendingGeometricAnimations = CheckState::Absent;
 }
 
+static bool
+IsTransition(const Animation& aAnimation) {
+  const dom::CSSTransition* transition = aAnimation.AsCSSTransition();
+  return transition && transition->IsTiedToMarkup();
+}
+
 void
 PendingAnimationTracker::MarkAnimationsThatMightNeedSynchronization()
 {
-  // We only ever set mHasPlayPendingGeometricAnimations to 'present' in
-  // HasPlayPendingGeometricAnimations(). So, if it is 'present' already,
-  // (i.e. before calling HasPlayPendingGeometricAnimations()) we can assume
-  // that this method has already been called for the current set of
-  // play-pending animations and it is not necessary to run again.
+  // We only set mHasPlayPendingGeometricAnimations to "present" in this method
+  // and nowhere else. After setting the state to "present", if there is any
+  // change to the set of play-pending animations we will reset
+  // mHasPlayPendingGeometricAnimations to either "indeterminate" or "absent".
   //
-  // We can't make the same assumption about 'absent', but if this method
-  // was already called and the result was 'absent', then this method is
-  // a no-op anyway so it's ok to run again.
+  // As a result, if mHasPlayPendingGeometricAnimations is "present", we can
+  // assume that this method has already been called for the current set of
+  // play-pending animations and it is not necessary to run this method again.
+  //
+  // If mHasPlayPendingGeometricAnimations is "absent", then we can also skip
+  // the body of this method since there are no notifications to be sent.
+  //
+  // Therefore, the only case we need to be concerned about is the
+  // "indeterminate" case. For all other cases we can return early.
   //
   // Note that *without* this optimization, starting animations would become
-  // O(n^2) in that case where each animation is on a different element and
+  // O(n^2) in the case where each animation is on a different element and
   // contains a compositor-animatable property since we would end up iterating
   // over all animations in the play-pending set for each target element.
-  if (mHasPlayPendingGeometricAnimations == CheckState::Present) {
+  if (mHasPlayPendingGeometricAnimations != CheckState::Indeterminate) {
     return;
   }
 
-  if (!HasPlayPendingGeometricAnimations()) {
-    return;
-  }
-
-  for (auto iter = mPlayPendingSet.Iter(); !iter.Done(); iter.Next()) {
-    iter.Get()->GetKey()->NotifyGeometricAnimationsStartingThisFrame();
-  }
-}
-
-bool
-PendingAnimationTracker::HasPlayPendingGeometricAnimations()
-{
-  if (mHasPlayPendingGeometricAnimations != CheckState::Indeterminate) {
-    return mHasPlayPendingGeometricAnimations == CheckState::Present;
-  }
+  // We only synchronize CSS transitions with other CSS transitions (and we only
+  // synchronize non-transition animations with non-transition animations)
+  // since typically the author will not trigger both CSS animations and
+  // CSS transitions simultaneously and expect them to be synchronized.
+  //
+  // If we try to synchronize CSS transitions with non-transitions then for some
+  // content we will end up degrading performance by forcing animations to run
+  // on the main thread that really don't need to.
 
   mHasPlayPendingGeometricAnimations = CheckState::Absent;
   for (auto iter = mPlayPendingSet.ConstIter(); !iter.Done(); iter.Next()) {
     auto animation = iter.Get()->GetKey();
     if (animation->GetEffect() && animation->GetEffect()->AffectsGeometry()) {
-      mHasPlayPendingGeometricAnimations = CheckState::Present;
-      break;
+      mHasPlayPendingGeometricAnimations &= ~CheckState::Absent;
+      mHasPlayPendingGeometricAnimations |= IsTransition(*animation)
+                                            ? CheckState::TransitionsPresent
+                                            : CheckState::AnimationsPresent;
+
+      // If we have both transitions and animations we don't need to look any
+      // further.
+      if (mHasPlayPendingGeometricAnimations ==
+          (CheckState::TransitionsPresent | CheckState::AnimationsPresent)) {
+        break;
+      }
     }
   }
 
-  return mHasPlayPendingGeometricAnimations == CheckState::Present;
+  if (mHasPlayPendingGeometricAnimations == CheckState::Absent) {
+    return;
+  }
+
+  for (auto iter = mPlayPendingSet.Iter(); !iter.Done(); iter.Next()) {
+    auto animation = iter.Get()->GetKey();
+    bool isTransition = IsTransition(*animation);
+    if ((isTransition &&
+         mHasPlayPendingGeometricAnimations & CheckState::TransitionsPresent) ||
+        (!isTransition &&
+         mHasPlayPendingGeometricAnimations & CheckState::AnimationsPresent)) {
+      animation->NotifyGeometricAnimationsStartingThisFrame();
+    }
+  }
 }
 
 void
 PendingAnimationTracker::EnsurePaintIsScheduled()
 {
   if (!mDocument) {
     return;
   }
--- a/dom/animation/PendingAnimationTracker.h
+++ b/dom/animation/PendingAnimationTracker.h
@@ -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/. */
 
 #ifndef mozilla_dom_PendingAnimationTracker_h
 #define mozilla_dom_PendingAnimationTracker_h
 
 #include "mozilla/dom/Animation.h"
+#include "mozilla/TypedEnumBits.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDocument.h"
 #include "nsTHashtable.h"
 
 class nsIFrame;
 
 namespace mozilla {
 
@@ -77,33 +78,38 @@ public:
    * animations that affect geometric properties, notifies all play-pending
    * animations so that they can be synchronized, if needed.
    */
   void MarkAnimationsThatMightNeedSynchronization();
 
 private:
   ~PendingAnimationTracker() { }
 
-  bool HasPlayPendingGeometricAnimations();
   void EnsurePaintIsScheduled();
 
   typedef nsTHashtable<nsRefPtrHashKey<dom::Animation>> AnimationSet;
 
   void AddPending(dom::Animation& aAnimation, AnimationSet& aSet);
   void RemovePending(dom::Animation& aAnimation, AnimationSet& aSet);
   bool IsWaiting(const dom::Animation& aAnimation,
                  const AnimationSet& aSet) const;
 
   AnimationSet mPlayPendingSet;
   AnimationSet mPausePendingSet;
   nsCOMPtr<nsIDocument> mDocument;
 
+public:
   enum class CheckState {
-    Indeterminate,
-    Absent,
-    Present
+    Indeterminate = 0,
+    Absent = 1 << 0,
+    AnimationsPresent = 1 << 1,
+    TransitionsPresent = 1 << 2,
   };
+
+private:
   CheckState mHasPlayPendingGeometricAnimations = CheckState::Indeterminate;
 };
 
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PendingAnimationTracker::CheckState)
+
 } // namespace mozilla
 
 #endif // mozilla_dom_PendingAnimationTracker_h
--- a/dom/animation/test/chrome/test_animation_performance_warning.html
+++ b/dom/animation/test/chrome/test_animation_performance_warning.html
@@ -12,16 +12,20 @@
   width: 100px;
   height: 100px;
   background-color: white;
 }
 @keyframes fade {
   from { opacity: 1 }
   to   { opacity: 0 }
 }
+@keyframes translate {
+  from { transform: none }
+  to   { transform: translate(100px) }
+}
 </style>
 </head>
 <body>
 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1196114"
   target="_blank">Mozilla Bug 1196114</a>
 <div id="log"></div>
 <script>
 'use strict';
@@ -1002,16 +1006,40 @@ function testSynchronizedAnimations() {
             { property: 'opacity',
               runningOnCompositor: true
             } ]);
       });
   }, 'Opacity animations on the same element continue running on the'
      + ' compositor when transform animations are synchronized with geometric'
      + ' animations');
 
+  promise_test(async t => {
+    const transitionElem = addDiv(t, {
+      style: 'margin-left: 0px; transition: margin-left 100s',
+    });
+    getComputedStyle(transitionElem).marginLeft;
+
+    await waitForFrame();
+
+    transitionElem.style.marginLeft = '100px';
+    const cssTransition = transitionElem.getAnimations()[0];
+
+    const animationElem = addDiv(t, {
+      class: 'compositable',
+      style: 'animation: translate 100s',
+    });
+    const cssAnimation = animationElem.getAnimations()[0];
+
+    await Promise.all([cssTransition.ready, cssAnimation.ready]);
+
+    assert_animation_property_state_equals(cssAnimation.effect.getProperties(),
+      [{ property: 'transform',
+         runningOnCompositor: true }]);
+  }, 'CSS Animations are NOT synchronized with CSS Transitions');
+
   promise_test(t => {
     const elemA = addDiv(t, { class: 'compositable' });
     const elemB = addDiv(t, { class: 'compositable' });
 
     const animA = elemA.animate({ marginLeft: [ '0px', '100px' ] },
                                 100 * MS_PER_SEC);
     let animB;
 
--- a/dom/animation/test/mozilla/file_discrete_animations.html
+++ b/dom/animation/test/mozilla/file_discrete_animations.html
@@ -44,21 +44,16 @@ const gMozillaSpecificProperties = {
     from: "margin-box",
     to: "content-box"
   },
   "-moz-force-broken-image-icon": {
     // https://developer.mozilla.org/en/docs/Web/CSS/-moz-force-broken-image-icon
     from: "1",
     to: "0"
   },
-  "image-rendering": {
-    // https://drafts.csswg.org/css-images-3/#propdef-image-rendering
-    from: "-moz-crisp-edges",
-    to: "auto"
-  },
   "-moz-stack-sizing": {
     // https://developer.mozilla.org/en/docs/Web/CSS/-moz-stack-sizing
     from: "ignore",
     to: "stretch-to-fit"
   },
   "-moz-text-size-adjust": {
     // https://drafts.csswg.org/css-size-adjust/#propdef-text-size-adjust
     from: "none",
--- a/dom/audiochannel/AudioChannelAgent.h
+++ b/dom/audiochannel/AudioChannelAgent.h
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_audio_channel_agent_h__
 #define mozilla_dom_audio_channel_agent_h__
 
 #include "nsIAudioChannelAgent.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCOMPtr.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 
 class nsPIDOMWindowInner;
 class nsPIDOMWindowOuter;
 
 namespace mozilla {
 namespace dom {
 
 class AudioPlaybackConfig;
--- a/dom/base/EventSource.h
+++ b/dom/base/EventSource.h
@@ -17,17 +17,16 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "nsIObserver.h"
 #include "nsIStreamListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsITimer.h"
 #include "nsIHttpChannel.h"
-#include "nsWeakReference.h"
 #include "nsDeque.h"
 
 class nsPIDOMWindowInner;
 
 namespace mozilla {
 
 class ErrorResult;
 
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -12,17 +12,16 @@
 #include "mozilla/dom/Fetch.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/ErrorResult.h"
 #include "nsWrapperCache.h"
 #include "nsHashKeys.h"
 #include "nsInterfaceHashtable.h"
 #include "nsString.h"
 #include "nsTArray.h"
-#include "nsWeakPtr.h"
 #include "mozilla/dom/MediaKeySystemAccessManager.h"
 
 class nsPluginArray;
 class nsMimeTypeArray;
 class nsPIDOMWindowInner;
 class nsIDOMNavigatorSystemMessages;
 class nsINetworkProperties;
 class nsIPrincipal;
--- a/dom/base/WindowDestroyedEvent.h
+++ b/dom/base/WindowDestroyedEvent.h
@@ -3,19 +3,19 @@
 /* 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 WindowDestroyedEvent_h
 #define WindowDestroyedEvent_h
 
 #include "nsGlobalWindow.h"
+#include "nsIWeakReferenceUtils.h"
+#include "nsString.h"
 #include "nsThreadUtils.h"
-#include "nsWeakPtr.h"
-#include "nsString.h"
 
 namespace mozilla {
 
 class WindowDestroyedEvent final : public Runnable
 {
 public:
   WindowDestroyedEvent(nsGlobalWindowInner* aWindow,
                        uint64_t aID, const char* aTopic);
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -22,17 +22,17 @@
 #include "nsComponentManagerUtils.h"
 #include "nsArrayUtils.h"
 #include "nsIMutableArray.h"
 #include "nsContentPermissionHelper.h"
 #include "nsJSUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDocument.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 
 using mozilla::Unused;          // <snicker>
 using namespace mozilla::dom;
 using namespace mozilla;
 
 #define kVisibilityChange "visibilitychange"
 
 class VisibilityChangeListener final : public nsIDOMEventListener
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -12,18 +12,17 @@
 #define nsDocument_h___
 
 #include "nsIDocument.h"
 
 #include "jsfriendapi.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsCRT.h"
-#include "nsWeakReference.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsTArray.h"
 #include "nsIdentifierMapEntry.h"
 #include "nsStubDocumentObserver.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIContent.h"
 #include "nsIPrincipal.h"
 #include "nsIParser.h"
 #include "nsBindingManager.h"
--- a/dom/base/nsFrameMessageManager.h
+++ b/dom/base/nsFrameMessageManager.h
@@ -19,17 +19,17 @@
 #include "nsIPrincipal.h"
 #include "nsIXPConnect.h"
 #include "nsDataHashtable.h"
 #include "nsClassHashtable.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsIObserverService.h"
 #include "nsThreadUtils.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "mozilla/Attributes.h"
 #include "js/RootingAPI.h"
 #include "nsTObserverArray.h"
 #include "mozilla/TypedEnumBits.h"
 #include "mozilla/dom/CallbackObject.h"
 #include "mozilla/dom/SameProcessMessageQueue.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/jsipc/CpowHolder.h"
--- a/dom/base/nsHistory.h
+++ b/dom/base/nsHistory.h
@@ -57,12 +57,12 @@ protected:
   nsIDocShell* GetDocShell() const;
 
   void PushOrReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
                           const nsAString& aTitle, const nsAString& aUrl,
                           mozilla::ErrorResult& aRv, bool aReplace);
 
   already_AddRefed<mozilla::dom::ChildSHistory> GetSessionHistory() const;
 
-  nsCOMPtr<nsIWeakReference> mInnerWindow;
+  nsWeakPtr mInnerWindow;
 };
 
 #endif /* nsHistory_h___ */
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -26,23 +26,23 @@
 #include "nsIChannelEventSink.h"
 #include "nsIProgressEventSink.h"
 #include "nsISecurityEventSink.h"
 #include "nsIScriptGlobalObject.h"       // for member (in nsCOMPtr)
 #include "nsIServiceManager.h"
 #include "nsIURI.h"                      // for use in inline functions
 #include "nsIUUIDGenerator.h"
 #include "nsIWebProgressListener.h"      // for nsIWebProgressListener
+#include "nsIWeakReferenceUtils.h"       // for nsWeakPtr
 #include "nsPIDOMWindow.h"               // for use in inline functions
 #include "nsPropertyTable.h"             // for member
 #include "nsStringFwd.h"
 #include "nsTHashtable.h"                // for member
 #include "nsURIHashKey.h"
 #include "mozilla/net/ReferrerPolicy.h"  // for member
-#include "nsWeakReference.h"
 #include "mozilla/UseCounter.h"
 #include "mozilla/WeakPtr.h"
 #include "Units.h"
 #include "nsContentListDeclarations.h"
 #include "nsExpirationTracker.h"
 #include "nsClassHashtable.h"
 #include "mozilla/CORSMode.h"
 #include "mozilla/dom/ContentBlockingLog.h"
--- a/dom/base/nsPIWindowRoot.h
+++ b/dom/base/nsPIWindowRoot.h
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsPIWindowRoot_h__
 #define nsPIWindowRoot_h__
 
 #include "nsISupports.h"
 #include "mozilla/dom/EventTarget.h"
-#include "nsWeakReference.h"
 
 class nsPIDOMWindowOuter;
 class nsIControllers;
 class nsIController;
 class nsINode;
 
 namespace mozilla {
 namespace dom {
--- a/dom/commandhandler/nsBaseCommandController.cpp
+++ b/dom/commandhandler/nsBaseCommandController.cpp
@@ -1,22 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "nsString.h"
 #include "nsIComponentManager.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsBaseCommandController.h"
 #include "nsControllerCommandTable.h"
 
-#include "nsString.h"
-#include "nsWeakPtr.h"
-
 NS_IMPL_ADDREF(nsBaseCommandController)
 NS_IMPL_RELEASE(nsBaseCommandController)
 
 NS_INTERFACE_MAP_BEGIN(nsBaseCommandController)
   NS_INTERFACE_MAP_ENTRY(nsIController)
   NS_INTERFACE_MAP_ENTRY(nsICommandController)
   NS_INTERFACE_MAP_ENTRY(nsIControllerContext)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
--- a/dom/events/DOMEventTargetHelper.h
+++ b/dom/events/DOMEventTargetHelper.h
@@ -8,17 +8,16 @@
 #define mozilla_DOMEventTargetHelper_h_
 
 #include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsPIDOMWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
-#include "nsIWeakReferenceUtils.h"
 #include "MainThreadUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/dom/EventTarget.h"
 
 class nsIDocument;
 
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -22,21 +22,21 @@
 #include "nsAtom.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIFrame.h"
 #include "nsINode.h"
 #include "nsIPresShell.h"
 #include "nsISelectionController.h"
 #include "nsISupports.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsIWidget.h"
 #include "nsPresContext.h"
 #include "nsRange.h"
 #include "nsRefreshDriver.h"
-#include "nsWeakReference.h"
 #include "WritingModes.h"
 
 namespace mozilla {
 
 typedef ContentEventHandler::NodePosition NodePosition;
 typedef ContentEventHandler::NodePositionBefore NodePositionBefore;
 
 using namespace widget;
--- a/dom/geolocation/nsGeolocation.h
+++ b/dom/geolocation/nsGeolocation.h
@@ -10,19 +10,19 @@
 // Microsoft's API Name hackery sucks
 #undef CreateEvent
 
 #include "mozilla/StaticPtr.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsITimer.h"
 #include "nsIObserver.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsWrapperCache.h"
 
-#include "nsWeakPtr.h"
 #include "nsCycleCollectionParticipant.h"
 
 #include "nsGeoPosition.h"
 #include "nsIDOMGeoPosition.h"
 #include "nsIDOMGeoPositionCallback.h"
 #include "nsIDOMGeoPositionErrorCallback.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/GeolocationBinding.h"
--- a/dom/html/AutoplayPermissionManager.h
+++ b/dom/html/AutoplayPermissionManager.h
@@ -7,17 +7,16 @@
 #ifndef __AutoplayPermissionRequestManager_h__
 #define __AutoplayPermissionRequestManager_h__
 
 #include "mozilla/MozPromise.h"
 #include "mozilla/WeakPtr.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsISupports.h"
 #include "nsIWeakReferenceUtils.h"
-#include "nsWeakReference.h"
 
 class nsGlobalWindowInner;
 class nsIEventTarget;
 
 namespace mozilla {
 
 // Encapsulates requesting permission from the user to autoplay with a
 // doorhanger. The AutoplayPermissionManager is stored on the top level window,
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -59,17 +59,16 @@
 
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsITimer.h"
 #include "nsError.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIScriptContext.h"
 #include "nsStyleLinkElement.h"
 
-#include "nsWeakReference.h" // nsHTMLElementFactory supports weak references
 #include "nsIPrompt.h"
 #include "nsLayoutCID.h"
 #include "nsIDocShellTreeItem.h"
 
 #include "nsEscape.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozAutoDocUpdate.h"
--- a/dom/indexedDB/FileSnapshot.h
+++ b/dom/indexedDB/FileSnapshot.h
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_indexeddb_filesnapshot_h__
 #define mozilla_dom_indexeddb_filesnapshot_h__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/File.h"
 #include "nsISupports.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 
 #define FILEIMPLSNAPSHOT_IID \
   {0x0dfc11b1, 0x75d3, 0x473b, {0x8c, 0x67, 0xb7, 0x23, 0xf4, 0x67, 0xd6, 0x73}}
 
 class PIBlobImplSnapshot : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(FILEIMPLSNAPSHOT_IID)
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -40,16 +40,17 @@
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIScriptError.h"
 #include "nsISupportsPrimitives.h"
 #include "nsThreadUtils.h"
+#include "nsIWeakReferenceUtils.h"
 #include "ProfilerHelpers.h"
 #include "ReportInternalError.h"
 #include "ScriptErrorHelper.h"
 #include "nsQueryObject.h"
 
 // Include this last to avoid path problems on Windows.
 #include "ActorsChild.h"
 
@@ -913,17 +914,17 @@ IDBDatabase::GetOrCreateFileActorForBlob
   AssertIsOnOwningThread();
   MOZ_ASSERT(aBlob);
   MOZ_ASSERT(mBackgroundActor);
 
   // We use the File's nsIWeakReference as the key to the table because
   // a) it is unique per blob, b) it is reference-counted so that we can
   // guarantee that it stays alive, and c) it doesn't hold the actual File
   // alive.
-  nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(aBlob);
+  nsWeakPtr weakRef = do_GetWeakReference(aBlob);
   MOZ_ASSERT(weakRef);
 
   PBackgroundIDBDatabaseFileChild* actor = nullptr;
 
   if (!mFileActors.Get(weakRef, &actor)) {
     BlobImpl* blobImpl = aBlob->Impl();
     MOZ_ASSERT(blobImpl);
 
@@ -1069,17 +1070,17 @@ IDBDatabase::ExpireFileActors(bool aExpi
     for (auto iter = mFileActors.Iter(); !iter.Done(); iter.Next()) {
       nsISupports* key = iter.Key();
       PBackgroundIDBDatabaseFileChild* actor = iter.Data();
       MOZ_ASSERT(key);
       MOZ_ASSERT(actor);
 
       bool shouldExpire = aExpireAll;
       if (!shouldExpire) {
-        nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(key);
+        nsWeakPtr weakRef = do_QueryInterface(key);
         MOZ_ASSERT(weakRef);
 
         nsCOMPtr<nsISupports> referent = do_QueryReferent(weakRef);
         shouldExpire = !referent;
       }
 
       if (shouldExpire) {
         PBackgroundIDBDatabaseFileChild::Send__delete__(actor);
--- a/dom/interfaces/base/nsITabParent.idl
+++ b/dom/interfaces/base/nsITabParent.idl
@@ -120,9 +120,20 @@ interface nsITabParent : nsISupports
    */
   void stopApzAutoscroll(in nsViewID aScrollId, in uint32_t aPresShellId);
 
   /**
    * Save a recording of the associated content process' behavior to the
    * specified filename. Returns whether the process is being recorded.
    */
   bool saveRecording(in AString aFileName);
+
+  /**
+   * Asynchronously retrieve a JSON string representing a log of the
+   * content blocking events happened so far in the current tab from the
+   * content process.
+   *
+   * This returns a Promise which resolves to a string on success, and is
+   * rejected on failure.  For documentation on the string format, please
+   * see nsISecureBrowserUI.contentBlockingLogJSON.
+   */
+  Promise getContentBlockingLog();
 };
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -15,17 +15,16 @@
 #include "mozilla/dom/PContentChild.h"
 #include "mozilla/StaticPtr.h"
 #include "nsAutoPtr.h"
 #include "nsHashKeys.h"
 #include "nsIObserver.h"
 #include "nsTHashtable.h"
 #include "nsRefPtrHashtable.h"
 
-#include "nsWeakPtr.h"
 #include "nsIWindowProvider.h"
 
 #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
 #include "nsIFile.h"
 #endif
 
 struct ChromePackage;
 class nsIObserver;
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -885,16 +885,21 @@ child:
     async SetOriginAttributes(OriginAttributes aOriginAttributes);
 
     /**
      * Pass the current handle for the current native widget to the content
      * process, so it can be used by PuppetWidget.
      */
     async SetWidgetNativeData(WindowsHandle aHandle);
 
+    /**
+     * Requests the content blocking log, which is sent back in response.
+     */
+    async GetContentBlockingLog() returns(nsString log, bool success);
+
 /*
  * FIXME: write protocol!
 
 state LIVE:
     send LoadURL goto LIVE;
 //etc.
     send Destroy goto DYING;
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -88,17 +88,17 @@
 #include "nsPIWindowRoot.h"
 #include "nsPointerHashKeys.h"
 #include "nsLayoutUtils.h"
 #include "nsPrintfCString.h"
 #include "nsTHashtable.h"
 #include "nsThreadManager.h"
 #include "nsThreadUtils.h"
 #include "nsViewManager.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsWindowWatcher.h"
 #include "PermissionMessageUtils.h"
 #include "PuppetWidget.h"
 #include "StructuredCloneData.h"
 #include "nsViewportInfo.h"
 #include "nsILoadContext.h"
 #include "ipc/nsGUIEventIPC.h"
 #include "mozilla/gfx/Matrix.h"
@@ -3402,16 +3402,31 @@ TabChild::RecvSetOriginAttributes(const 
 
 mozilla::ipc::IPCResult
 TabChild::RecvSetWidgetNativeData(const WindowsHandle& aWidgetNativeData)
 {
   mWidgetNativeData = aWidgetNativeData;
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+TabChild::RecvGetContentBlockingLog(GetContentBlockingLogResolver&& aResolve)
+{
+  bool success = false;
+  nsAutoString result;
+
+  if (nsCOMPtr<nsIDocument> doc = GetDocument()) {
+    result = doc->GetContentBlockingLog()->Stringify();
+    success = true;
+  }
+
+  aResolve(Tuple<const nsString&, const bool&>(result, success));
+  return IPC_OK();
+}
+
 mozilla::plugins::PPluginWidgetChild*
 TabChild::AllocPPluginWidgetChild()
 {
 #ifdef XP_WIN
   return new mozilla::plugins::PluginWidgetChild();
 #else
   MOZ_ASSERT_UNREACHABLE("AllocPPluginWidgetChild only supports Windows");
   return nullptr;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -747,16 +747,18 @@ protected:
   virtual mozilla::ipc::IPCResult RecvSetWindowName(const nsString& aName) override;
 
   virtual mozilla::ipc::IPCResult RecvAllowScriptsToClose() override;
 
   virtual mozilla::ipc::IPCResult RecvSetOriginAttributes(const OriginAttributes& aOriginAttributes) override;
 
   virtual mozilla::ipc::IPCResult RecvSetWidgetNativeData(const WindowsHandle& aWidgetNativeData) override;
 
+  virtual mozilla::ipc::IPCResult RecvGetContentBlockingLog(GetContentBlockingLogResolver&& aResolve) override;
+
 private:
   void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
                        const ScrollableLayerGuid& aGuid);
 
   // Notify others that our TabContext has been updated.
   //
   // You should call this after calling TabContext::SetTabContext().  We also
   // call this during Init().
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2984,16 +2984,52 @@ TabParent::SaveRecording(const nsAString
   nsresult rv = NS_NewLocalFile(aFilename, false, getter_AddRefs(file));
   if (NS_FAILED(rv)) {
     return rv;
   }
   return Manager()->AsContentParent()->SaveRecording(file, aRetval);
 }
 
 NS_IMETHODIMP
+TabParent::GetContentBlockingLog(Promise** aPromise)
+{
+  NS_ENSURE_ARG_POINTER(aPromise);
+
+  *aPromise = nullptr;
+  if (!mFrameElement) {
+    return NS_ERROR_FAILURE;
+  }
+
+  ErrorResult rv;
+  RefPtr<Promise> jsPromise =
+    Promise::Create(mFrameElement->OwnerDoc()->GetOwnerGlobal(), rv);
+  if (rv.Failed()) {
+    return NS_ERROR_FAILURE;
+  }
+
+  RefPtr<Promise> copy(jsPromise);
+  copy.forget(aPromise);
+
+  auto cblPromise = SendGetContentBlockingLog();
+  cblPromise->Then(GetMainThreadSerialEventTarget(), __func__,
+                   [jsPromise] (Tuple<nsString, bool> aResult) {
+                     if (Get<1>(aResult)) {
+                       jsPromise->MaybeResolve(Get<0>(aResult));
+                     } else {
+                       jsPromise->MaybeRejectWithUndefined();
+                     }
+                   },
+                   [jsPromise] (ResponseRejectReason aReason) {
+                     jsPromise->MaybeRejectWithUndefined();
+                   });
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 TabParent::SuppressDisplayport(bool aEnabled)
 {
   if (IsDestroyed()) {
     return NS_OK;
   }
 
 #ifdef DEBUG
   if (aEnabled) {
--- a/dom/media/doctor/DecoderDoctorDiagnostics.cpp
+++ b/dom/media/doctor/DecoderDoctorDiagnostics.cpp
@@ -10,17 +10,16 @@
 #include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "nsIObserverService.h"
 #include "nsIScriptError.h"
 #include "nsITimer.h"
-#include "nsIWeakReference.h"
 #include "nsPluginHost.h"
 #include "nsPrintfCString.h"
 #include "VideoUtils.h"
 
 #if defined(MOZ_FFMPEG)
 #include "FFmpegRuntimeLinker.h"
 #endif
 
--- a/dom/media/gmp/GMPService.h
+++ b/dom/media/gmp/GMPService.h
@@ -13,17 +13,16 @@
 #include "mozilla/Atomics.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Monitor.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsIThread.h"
 #include "nsThreadUtils.h"
 #include "nsIDocument.h"
-#include "nsIWeakReference.h"
 #include "mozilla/AbstractThread.h"
 #include "nsClassHashtable.h"
 #include "nsISupportsImpl.h"
 #include "mozilla/MozPromise.h"
 #include "GMPContentParent.h"
 #include "GMPCrashHelper.h"
 #include "ChromiumCDMParent.h"
 #include "MediaResult.h"
--- a/dom/media/webaudio/AudioWorkletGlobalScope.cpp
+++ b/dom/media/webaudio/AudioWorkletGlobalScope.cpp
@@ -1,33 +1,35 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "AudioWorkletGlobalScope.h"
+
+#include "AudioWorkletImpl.h"
 #include "jsapi.h"
 #include "mozilla/dom/AudioWorkletGlobalScopeBinding.h"
 #include "mozilla/dom/WorkletPrincipal.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(AudioWorkletGlobalScope, WorkletGlobalScope,
                                    mNameToProcessorMap);
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AudioWorkletGlobalScope)
 NS_INTERFACE_MAP_END_INHERITING(WorkletGlobalScope)
 
 NS_IMPL_ADDREF_INHERITED(AudioWorkletGlobalScope, WorkletGlobalScope)
 NS_IMPL_RELEASE_INHERITED(AudioWorkletGlobalScope, WorkletGlobalScope)
 
-AudioWorkletGlobalScope::AudioWorkletGlobalScope(WorkletImpl* aImpl)
-  : WorkletGlobalScope(aImpl)
+AudioWorkletGlobalScope::AudioWorkletGlobalScope(AudioWorkletImpl* aImpl)
+  : mImpl(aImpl)
   , mCurrentFrame(0)
   , mCurrentTime(0)
   , mSampleRate(0.0)
 {}
 
 bool
 AudioWorkletGlobalScope::WrapGlobalObject(JSContext* aCx,
                                           JS::MutableHandle<JSObject*> aReflector)
@@ -184,16 +186,21 @@ AudioWorkletGlobalScope::RegisterProcess
    *     map of the associated BaseAudioContext.
    */
   // TODO: we don't have a proper mechanism to communicate with the
   // control thread currently. See
   // https://bugzilla.mozilla.org/show_bug.cgi?id=1473467#c3
   // and https://bugzilla.mozilla.org/show_bug.cgi?id=1492014
 }
 
+WorkletImpl* AudioWorkletGlobalScope::Impl() const
+{
+  return mImpl;
+}
+
 uint64_t AudioWorkletGlobalScope::CurrentFrame() const
 {
   return mCurrentFrame;
 }
 
 double AudioWorkletGlobalScope::CurrentTime() const
 {
   return mCurrentTime;
--- a/dom/media/webaudio/AudioWorkletGlobalScope.h
+++ b/dom/media/webaudio/AudioWorkletGlobalScope.h
@@ -8,47 +8,50 @@
 #define mozilla_dom_AudioWorkletGlobalScope_h
 
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/WorkletGlobalScope.h"
 #include "nsRefPtrHashtable.h"
 
 namespace mozilla {
 
-class WorkletImpl;
+class AudioWorkletImpl;
 
 namespace dom {
 
-
 class AudioWorkletGlobalScope final : public WorkletGlobalScope
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioWorkletGlobalScope, WorkletGlobalScope);
 
-  explicit AudioWorkletGlobalScope(WorkletImpl* aImpl);
+  explicit AudioWorkletGlobalScope(AudioWorkletImpl* aImpl);
 
   bool
   WrapGlobalObject(JSContext* aCx,
                    JS::MutableHandle<JSObject*> aReflector) override;
 
   void
   RegisterProcessor(JSContext* aCx, const nsAString& aName,
                     VoidFunction& aProcessorCtor,
                     ErrorResult& aRv);
 
+  WorkletImpl* Impl() const override;
+
   uint64_t CurrentFrame() const;
 
   double CurrentTime() const;
 
   float SampleRate() const;
 
 private:
   ~AudioWorkletGlobalScope() = default;
 
+  const RefPtr<AudioWorkletImpl> mImpl;
+
   uint64_t mCurrentFrame;
   double mCurrentTime;
   float mSampleRate;
 
   typedef nsRefPtrHashtable<nsStringHashKey, VoidFunction> NodeNameToProcessorDefinitionMap;
   NodeNameToProcessorDefinitionMap mNameToProcessorMap;
 };
 
--- a/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp
+++ b/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp
@@ -2,17 +2,16 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "nsISupports.h"
 #include "nsFakeSynthServices.h"
 #include "nsPrintfCString.h"
-#include "nsIWeakReferenceUtils.h"
 #include "SharedBuffer.h"
 #include "nsISimpleEnumerator.h"
 
 #include "mozilla/dom/nsSynthVoiceRegistry.h"
 #include "mozilla/dom/nsSpeechTask.h"
 
 #include "nsThreadUtils.h"
 #include "prenv.h"
--- a/dom/midi/MIDIAccessManager.h
+++ b/dom/midi/MIDIAccessManager.h
@@ -6,17 +6,16 @@
 
 #ifndef mozilla_dom_MIDIAccessManager_h
 #define mozilla_dom_MIDIAccessManager_h
 
 #include "nsPIDOMWindow.h"
 #include "nsIObserver.h"
 #include "mozilla/dom/MIDITypes.h"
 #include "mozilla/Observer.h"
-#include "nsWeakPtr.h"
 
 namespace mozilla {
 namespace dom {
 
 class MIDIAccess;
 class MIDIManagerChild;
 struct MIDIOptions;
 class MIDIPortChangeEvent;
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -11,19 +11,18 @@
 
 #include "nsIPluginHost.h"
 #include "nsIObserver.h"
 #include "nsCOMPtr.h"
 #include "prlink.h"
 #include "nsIPluginTag.h"
 #include "nsPluginsDir.h"
 #include "nsPluginDirServiceProvider.h"
-#include "nsWeakPtr.h"
+#include "nsWeakReference.h"
 #include "nsIPrompt.h"
-#include "nsWeakReference.h"
 #include "MainThreadUtils.h"
 #include "nsTArray.h"
 #include "nsINamed.h"
 #include "nsTObserverArray.h"
 #include "nsITimer.h"
 #include "nsPluginTags.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIIDNService.h"
--- a/dom/presentation/PresentationConnection.h
+++ b/dom/presentation/PresentationConnection.h
@@ -9,17 +9,17 @@
 
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/dom/PresentationConnectionBinding.h"
 #include "mozilla/dom/PresentationConnectionCloseEventBinding.h"
 #include "nsIPresentationListener.h"
 #include "nsIRequest.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 class Blob;
 class PresentationConnectionList;
 
 class PresentationConnection final : public DOMEventTargetHelper
--- a/dom/presentation/provider/MulticastDNSDeviceProvider.h
+++ b/dom/presentation/provider/MulticastDNSDeviceProvider.h
@@ -11,19 +11,19 @@
 #include "nsCOMPtr.h"
 #include "nsICancelable.h"
 #include "nsIDNSServiceDiscovery.h"
 #include "nsIObserver.h"
 #include "nsIPresentationDevice.h"
 #include "nsIPresentationDeviceProvider.h"
 #include "nsIPresentationControlService.h"
 #include "nsITimer.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsString.h"
 #include "nsTArray.h"
-#include "nsWeakPtr.h"
 
 class nsITCPDeviceInfo;
 
 namespace mozilla {
 namespace dom {
 namespace presentation {
 
 class DNSServiceWrappedListener;
--- a/dom/script/nsIScriptElement.h
+++ b/dom/script/nsIScriptElement.h
@@ -6,17 +6,17 @@
 
 #ifndef nsIScriptElement_h___
 #define nsIScriptElement_h___
 
 #include "nsISupports.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 #include "nsIScriptLoaderObserver.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsIParser.h"
 #include "nsIContent.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozilla/CORSMode.h"
 
 // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs
 #define NS_ISCRIPTELEMENT_IID \
 { 0xe60fca9b, 0x1b96, 0x4e4e, \
--- a/dom/security/nsCSPContext.h
+++ b/dom/security/nsCSPContext.h
@@ -12,17 +12,17 @@
 #include "mozilla/StaticPrefs.h"
 #include "nsIChannel.h"
 #include "nsIChannelEventSink.h"
 #include "nsIClassInfo.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsISerializable.h"
 #include "nsIStreamListener.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsXPCOM.h"
 
 #define NS_CSPCONTEXT_CONTRACTID "@mozilla.org/cspcontext;1"
  // 09d9ed1a-e5d4-4004-bfe0-27ceb923d9ac
 #define NS_CSPCONTEXT_CID \
 { 0x09d9ed1a, 0xe5d4, 0x4004, \
   { 0xbf, 0xe0, 0x27, 0xce, 0xb9, 0x23, 0xd9, 0xac } }
 
--- a/dom/storage/Storage.h
+++ b/dom/storage/Storage.h
@@ -6,17 +6,17 @@
 
 #ifndef mozilla_dom_Storage_h
 #define mozilla_dom_Storage_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/Maybe.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsWeakReference.h"
+#include "nsCOMPtr.h"
 #include "nsWrapperCache.h"
 #include "nsISupports.h"
 
 class nsIPrincipal;
 class nsPIDOMWindowInner;
 
 namespace mozilla {
 namespace dom {
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2021,20 +2021,16 @@ RuntimeService::CrashIfHanging()
 
 // This spins the event loop until all workers are finished and their threads
 // have been joined.
 void
 RuntimeService::Cleanup()
 {
   AssertIsOnMainThread();
 
-  if (!mShuttingDown) {
-    Shutdown();
-  }
-
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_WARNING_ASSERTION(obs, "Failed to get observer service?!");
 
   if (mIdleThreadTimer) {
     if (NS_FAILED(mIdleThreadTimer->Cancel())) {
       NS_WARNING("Failed to cancel idle timer!");
     }
     mIdleThreadTimer = nullptr;
--- a/dom/worklet/WorkletGlobalScope.cpp
+++ b/dom/worklet/WorkletGlobalScope.cpp
@@ -31,18 +31,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCA
 NS_IMPL_CYCLE_COLLECTING_ADDREF(WorkletGlobalScope)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(WorkletGlobalScope)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkletGlobalScope)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(WorkletGlobalScope)
 NS_INTERFACE_MAP_END
 
-WorkletGlobalScope::WorkletGlobalScope(WorkletImpl* aImpl)
-  : mImpl(aImpl)
+WorkletGlobalScope::WorkletGlobalScope()
 {
 }
 
 WorkletGlobalScope::~WorkletGlobalScope() = default;
 
 JSObject*
 WorkletGlobalScope::WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto)
@@ -50,17 +49,18 @@ WorkletGlobalScope::WrapObject(JSContext
   MOZ_CRASH("We should never get here!");
   return nullptr;
 }
 
 already_AddRefed<Console>
 WorkletGlobalScope::GetConsole(JSContext* aCx, ErrorResult& aRv)
 {
   if (!mConsole) {
-    const WorkletLoadInfo& loadInfo = mImpl->LoadInfo();
+    MOZ_ASSERT(Impl());
+    const WorkletLoadInfo& loadInfo = Impl()->LoadInfo();
     mConsole = Console::CreateForWorklet(aCx, this,
                                          loadInfo.OuterWindowID(),
                                          loadInfo.InnerWindowID(), aRv);
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
   }
 
--- a/dom/worklet/WorkletGlobalScope.h
+++ b/dom/worklet/WorkletGlobalScope.h
@@ -29,17 +29,17 @@ class WorkletGlobalScope : public nsIGlo
                          , public nsWrapperCache
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(WORKLET_IID)
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WorkletGlobalScope)
 
-  explicit WorkletGlobalScope(WorkletImpl* aImpl);
+  WorkletGlobalScope();
 
   nsIGlobalObject* GetParentObject() const
   {
     return nullptr;
   }
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@@ -51,26 +51,25 @@ public:
   GetGlobalJSObject() override
   {
     return GetWrapper();
   }
 
   already_AddRefed<Console>
   GetConsole(JSContext* aCx, ErrorResult& aRv);
 
-  WorkletImpl* Impl() const { return mImpl; }
+  virtual WorkletImpl* Impl() const = 0;
 
   void
   Dump(const Optional<nsAString>& aString) const;
 
 protected:
   ~WorkletGlobalScope();;
 
 private:
-  const RefPtr<WorkletImpl> mImpl;
   RefPtr<Console> mConsole;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(WorkletGlobalScope, WORKLET_IID)
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/xbl/nsXBLPrototypeBinding.h
+++ b/dom/xbl/nsXBLPrototypeBinding.h
@@ -8,17 +8,16 @@
 #define nsXBLPrototypeBinding_h__
 
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsInterfaceHashtable.h"
-#include "nsWeakReference.h"
 #include "nsXBLDocumentInfo.h"
 #include "nsXBLProtoImpl.h"
 #include "nsXBLProtoImplMethod.h"
 #include "nsXBLPrototypeHandler.h"
 #include "nsXBLPrototypeResources.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/StyleSheet.h"
--- a/dom/xbl/nsXBLPrototypeHandler.cpp
+++ b/dom/xbl/nsXBLPrototypeHandler.cpp
@@ -24,16 +24,17 @@
 #include "nsFocusManager.h"
 #include "nsIFormControl.h"
 #include "nsIDOMEventListener.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsIDOMWindow.h"
 #include "nsIServiceManager.h"
 #include "nsIScriptError.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsGkAtoms.h"
 #include "nsIXPConnect.h"
 #include "nsDOMCID.h"
 #include "nsUnicharUtils.h"
 #include "nsCRT.h"
 #include "nsXBLEventHandler.h"
@@ -869,17 +870,17 @@ nsXBLPrototypeHandler::ConstructPrototyp
                                           const char16_t* aPreventDefault,
                                           const char16_t* aAllowUntrusted)
 {
   mType = 0;
 
   if (aKeyElement) {
     mType |= NS_HANDLER_TYPE_XUL;
     MOZ_ASSERT(!mPrototypeBinding);
-    nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(aKeyElement);
+    nsWeakPtr weak = do_GetWeakReference(aKeyElement);
     if (!weak) {
       return;
     }
     weak.swap(mHandlerElement);
   }
   else {
     mType |= aCommand ? NS_HANDLER_TYPE_XBL_COMMAND : NS_HANDLER_TYPE_XBL_JS;
     mHandlerText = nullptr;
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -157,17 +157,17 @@ public:
   bool HasRequest(nsIURI* aURI, nsIContent* aBoundElement);
 
 private:
   ~nsXBLStreamListener();
 
   nsCOMPtr<nsIStreamListener> mInner;
   AutoTArray<nsXBLBindingRequest*, 8> mBindingRequests;
 
-  nsCOMPtr<nsIWeakReference> mBoundDocument;
+  nsWeakPtr mBoundDocument;
   nsCOMPtr<nsIXMLContentSink> mSink; // Only set until OnStartRequest
   nsCOMPtr<nsIDocument> mBindingDocument; // Only set until OnStartRequest
 };
 
 /* Implementation file */
 NS_IMPL_ISUPPORTS(nsXBLStreamListener,
                   nsIStreamListener,
                   nsIRequestObserver,
--- a/dom/xbl/nsXBLWindowKeyHandler.h
+++ b/dom/xbl/nsXBLWindowKeyHandler.h
@@ -4,18 +4,18 @@
  * 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 nsXBLWindowKeyHandler_h__
 #define nsXBLWindowKeyHandler_h__
 
 #include "mozilla/EventForwards.h"
 #include "mozilla/layers/KeyboardMap.h"
-#include "nsWeakPtr.h"
 #include "nsIDOMEventListener.h"
+#include "nsIWeakReferenceUtils.h"
 
 class nsAtom;
 class nsXBLPrototypeHandler;
 
 namespace mozilla {
 class EventListenerManager;
 class WidgetKeyboardEvent;
 struct IgnoreModifierState;
--- a/dom/xslt/xpath/XPathResult.h
+++ b/dom/xslt/xpath/XPathResult.h
@@ -5,17 +5,17 @@
 
 #ifndef mozilla_dom_XPathResult_h
 #define mozilla_dom_XPathResult_h
 
 #include "nsStubMutationObserver.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "nsString.h"
 #include "nsWrapperCache.h"
 #include "nsINode.h"
 
 class nsIDocument;
--- a/dom/xslt/xslt/txMozillaTextOutput.h
+++ b/dom/xslt/xslt/txMozillaTextOutput.h
@@ -3,17 +3,17 @@
  * 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 TRANSFRMX_MOZILLA_TEXT_OUTPUT_H
 #define TRANSFRMX_MOZILLA_TEXT_OUTPUT_H
 
 #include "txXMLEventHandler.h"
 #include "nsCOMPtr.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "txOutputFormat.h"
 
 class nsITransformObserver;
 class nsIDocument;
 class nsIContent;
 
 namespace mozilla {
 namespace dom {
--- a/dom/xul/nsXULContentSink.h
+++ b/dom/xul/nsXULContentSink.h
@@ -3,19 +3,19 @@
  * 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 nsXULContentSink_h__
 #define nsXULContentSink_h__
 
 #include "mozilla/Attributes.h"
 #include "nsIExpatSink.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsIXMLContentSink.h"
 #include "nsNodeInfoManager.h"
-#include "nsWeakPtr.h"
 #include "nsXULElement.h"
 #include "nsIDTD.h"
 
 class nsIDocument;
 class nsIScriptSecurityManager;
 class nsAttrName;
 class nsXULPrototypeDocument;
 class nsXULPrototypeElement;
--- a/dom/xul/nsXULControllers.h
+++ b/dom/xul/nsXULControllers.h
@@ -9,17 +9,16 @@
 
 */
 
 #ifndef nsXULControllers_h__
 #define nsXULControllers_h__
 
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
-#include "nsWeakPtr.h"
 #include "nsIControllers.h"
 #include "nsCycleCollectionParticipant.h"
 
 /* non-XPCOM class for holding controllers and their IDs */
 class nsXULControllerData final
 {
 public:
                             nsXULControllerData(uint32_t inControllerID, nsIController* inController)
--- a/editor/composer/ComposerCommandsUpdater.h
+++ b/editor/composer/ComposerCommandsUpdater.h
@@ -9,17 +9,16 @@
 
 #include "nsCOMPtr.h"                   // for already_AddRefed, nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDocumentStateListener.h"
 #include "nsINamed.h"
 #include "nsISupportsImpl.h"            // for NS_DECL_ISUPPORTS
 #include "nsITimer.h"                   // for NS_DECL_NSITIMERCALLBACK, etc
 #include "nsITransactionListener.h"     // for nsITransactionListener
-#include "nsIWeakReferenceUtils.h"      // for nsWeakPtr
 #include "nscore.h"                     // for NS_IMETHOD, nsresult, etc
 
 class nsIDocShell;
 class nsITransaction;
 class nsITransactionManager;
 class nsPIDOMWindowOuter;
 class nsPICommandUpdater;
 
--- a/editor/composer/nsEditingSession.h
+++ b/editor/composer/nsEditingSession.h
@@ -1,21 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
 
 #ifndef nsEditingSession_h__
 #define nsEditingSession_h__
 
-
-#ifndef nsWeakReference_h__
-#include "nsWeakReference.h"            // for nsSupportsWeakReference, etc
-#endif
-
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsISupportsImpl.h"            // for NS_DECL_ISUPPORTS
 #include "nsIWeakReferenceUtils.h"      // for nsWeakPtr
 #include "nsWeakReference.h"            // for nsSupportsWeakReference, etc
 #include "nscore.h"                     // for nsresult
 
 #ifndef __gen_nsIWebProgressListener_h__
 #include "nsIWebProgressListener.h"
--- a/editor/libeditor/PlaceholderTransaction.h
+++ b/editor/libeditor/PlaceholderTransaction.h
@@ -4,18 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef PlaceholderTransaction_h
 #define PlaceholderTransaction_h
 
 #include "EditAggregateTransaction.h"
 #include "mozilla/Maybe.h"
 #include "nsIAbsorbingTransaction.h"
-#include "nsCOMPtr.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 
 namespace mozilla {
 
 class CompositionTransaction;
 
 /**
  * An aggregate transaction that knows how to absorb all subsequent
  * transactions with the same name.  This transaction does not "Do" anything.
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -15,18 +15,18 @@
 #include "mozilla/layers/PCompositorBridgeChild.h"
 #include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
 #include "mozilla/layers/PaintThread.h" // for PaintThread
 #include "mozilla/webrender/WebRenderTypes.h"
 #include "nsClassHashtable.h"           // for nsClassHashtable
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsHashKeys.h"                 // for nsUint64HashKey
 #include "nsISupportsImpl.h"            // for NS_INLINE_DECL_REFCOUNTING
+#include "nsIWeakReferenceUtils.h"
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
-#include "nsWeakReference.h"
 
 #include <unordered_map>
 
 namespace mozilla {
 
 namespace dom {
 class TabChild;
 } // namespace dom
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -2546,17 +2546,17 @@ js::NewOpaqueTypedObject(JSContext* cx, 
 
 bool
 js::NewDerivedTypedObject(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 3);
     MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypeDescr>());
     MOZ_ASSERT(args[1].isObject() && args[1].toObject().is<TypedObject>());
-    MOZ_RELEASE_ASSERT(args[2].isInt32());
+    MOZ_ASSERT(args[2].isInt32());
 
     Rooted<TypeDescr*> descr(cx, &args[0].toObject().as<TypeDescr>());
     Rooted<TypedObject*> typedObj(cx, &args[1].toObject().as<TypedObject>());
     uint32_t offset = AssertedCast<uint32_t>(args[2].toInt32());
 
     Rooted<TypedObject*> obj(cx);
     obj = OutlineTypedObject::createDerived(cx, descr, typedObj, offset);
     if (!obj) {
@@ -2567,17 +2567,17 @@ js::NewDerivedTypedObject(JSContext* cx,
     return true;
 }
 
 bool
 js::AttachTypedObject(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 3);
-    MOZ_RELEASE_ASSERT(args[2].isInt32());
+    MOZ_ASSERT(args[2].isInt32());
 
     OutlineTypedObject& handle = args[0].toObject().as<OutlineTypedObject>();
     TypedObject& target = args[1].toObject().as<TypedObject>();
     MOZ_ASSERT(!handle.isAttached());
     uint32_t offset = AssertedCast<uint32_t>(args[2].toInt32());
 
     handle.attach(cx, target, offset);
 
@@ -2585,17 +2585,17 @@ js::AttachTypedObject(JSContext* cx, uns
 }
 
 bool
 js::SetTypedObjectOffset(JSContext*, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
     MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>());
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
+    MOZ_ASSERT(args[1].isInt32());
 
     OutlineTypedObject& typedObj = args[0].toObject().as<OutlineTypedObject>();
     int32_t offset = args[1].toInt32();
 
     MOZ_ASSERT(typedObj.isAttached());
     typedObj.resetOffset(offset);
     args.rval().setUndefined();
     return true;
@@ -2704,17 +2704,17 @@ js::GetTypedObjectModule(JSContext* cx, 
 
 #define JS_STORE_SCALAR_CLASS_IMPL(_constant, T, _name)                         \
 bool                                                                            \
 js::StoreScalar##T::Func(JSContext* cx, unsigned argc, Value* vp)               \
 {                                                                               \
     CallArgs args = CallArgsFromVp(argc, vp);                                   \
     MOZ_ASSERT(args.length() == 3);                                             \
     MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>());     \
-    MOZ_RELEASE_ASSERT(args[1].isInt32());                                      \
+    MOZ_ASSERT(args[1].isInt32());                                              \
     MOZ_ASSERT(args[2].isNumber());                                             \
                                                                                 \
     TypedObject& typedObj = args[0].toObject().as<TypedObject>();               \
     int32_t offset = args[1].toInt32();                                         \
                                                                                 \
     /* Should be guaranteed by the typed objects API: */                        \
     MOZ_ASSERT(offset % MOZ_ALIGNOF(T) == 0);                                   \
                                                                                 \
@@ -2728,17 +2728,17 @@ js::StoreScalar##T::Func(JSContext* cx, 
 
 #define JS_STORE_REFERENCE_CLASS_IMPL(_constant, T, _name)                      \
 bool                                                                            \
 js::StoreReference##_name::Func(JSContext* cx, unsigned argc, Value* vp)        \
 {                                                                               \
     CallArgs args = CallArgsFromVp(argc, vp);                                   \
     MOZ_ASSERT(args.length() == 4);                                             \
     MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>());     \
-    MOZ_RELEASE_ASSERT(args[1].isInt32());                                      \
+    MOZ_ASSERT(args[1].isInt32());                                              \
     MOZ_ASSERT(args[2].isString() || args[2].isNull());                         \
                                                                                 \
     TypedObject& typedObj = args[0].toObject().as<TypedObject>();               \
     int32_t offset = args[1].toInt32();                                         \
                                                                                 \
     jsid id = args[2].isString()                                                \
               ? IdToTypeId(AtomToId(&args[2].toString()->asAtom()))             \
               : JSID_VOID;                                                      \
@@ -2756,17 +2756,17 @@ js::StoreReference##_name::Func(JSContex
 
 #define JS_LOAD_SCALAR_CLASS_IMPL(_constant, T, _name)                                  \
 bool                                                                                    \
 js::LoadScalar##T::Func(JSContext* cx, unsigned argc, Value* vp)                        \
 {                                                                                       \
     CallArgs args = CallArgsFromVp(argc, vp);                                           \
     MOZ_ASSERT(args.length() == 2);                                                     \
     MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>());             \
-    MOZ_RELEASE_ASSERT(args[1].isInt32());                                              \
+    MOZ_ASSERT(args[1].isInt32());                                                      \
                                                                                         \
     TypedObject& typedObj = args[0].toObject().as<TypedObject>();                       \
     int32_t offset = args[1].toInt32();                                                 \
                                                                                         \
     /* Should be guaranteed by the typed objects API: */                                \
     MOZ_ASSERT(offset % MOZ_ALIGNOF(T) == 0);                                           \
                                                                                         \
     JS::AutoCheckCannotGC nogc(cx);                                                     \
@@ -2777,17 +2777,17 @@ js::LoadScalar##T::Func(JSContext* cx, u
 
 #define JS_LOAD_REFERENCE_CLASS_IMPL(_constant, T, _name)                       \
 bool                                                                            \
 js::LoadReference##_name::Func(JSContext* cx, unsigned argc, Value* vp)         \
 {                                                                               \
     CallArgs args = CallArgsFromVp(argc, vp);                                   \
     MOZ_ASSERT(args.length() == 2);                                             \
     MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>());     \
-    MOZ_RELEASE_ASSERT(args[1].isInt32());                                      \
+    MOZ_ASSERT(args[1].isInt32());                                              \
                                                                                 \
     TypedObject& typedObj = args[0].toObject().as<TypedObject>();               \
     int32_t offset = args[1].toInt32();                                         \
                                                                                 \
     /* Should be guaranteed by the typed objects API: */                        \
     MOZ_ASSERT(offset % MOZ_ALIGNOF(T) == 0);                                   \
                                                                                 \
     JS::AutoCheckCannotGC nogc(cx);                                             \
--- a/js/src/builtin/TypedObject.js
+++ b/js/src/builtin/TypedObject.js
@@ -60,79 +60,79 @@ function TypedObjectGet(descr, typedObj,
 
   assert(false, "Unhandled kind: " + DESCR_KIND(descr));
   return undefined;
 }
 
 function TypedObjectGetDerived(descr, typedObj, offset) {
   assert(!TypeDescrIsSimpleType(descr),
          "getDerived() used with simple type");
-  return NewDerivedTypedObject(descr, typedObj, offset | 0);
+  return NewDerivedTypedObject(descr, typedObj, offset);
 }
 
 function TypedObjectGetDerivedIf(descr, typedObj, offset, cond) {
   return (cond ? TypedObjectGetDerived(descr, typedObj, offset) : undefined);
 }
 
 function TypedObjectGetOpaque(descr, typedObj, offset) {
   assert(!TypeDescrIsSimpleType(descr),
          "getDerived() used with simple type");
   var opaqueTypedObj = NewOpaqueTypedObject(descr);
-  AttachTypedObject(opaqueTypedObj, typedObj, offset | 0);
+  AttachTypedObject(opaqueTypedObj, typedObj, offset);
   return opaqueTypedObj;
 }
 
 function TypedObjectGetOpaqueIf(descr, typedObj, offset, cond) {
   return (cond ? TypedObjectGetOpaque(descr, typedObj, offset) : undefined);
 }
 
 function TypedObjectGetScalar(descr, typedObj, offset) {
   var type = DESCR_TYPE(descr);
   switch (type) {
   case JS_SCALARTYPEREPR_INT8:
-    return Load_int8(typedObj, offset | 0);
+    return Load_int8(typedObj, offset);
 
   case JS_SCALARTYPEREPR_UINT8:
   case JS_SCALARTYPEREPR_UINT8_CLAMPED:
-    return Load_uint8(typedObj, offset | 0);
+    return Load_uint8(typedObj, offset);
 
   case JS_SCALARTYPEREPR_INT16:
-    return Load_int16(typedObj, offset | 0);
+    return Load_int16(typedObj, offset);
 
   case JS_SCALARTYPEREPR_UINT16:
-    return Load_uint16(typedObj, offset | 0);
+    return Load_uint16(typedObj, offset);
 
   case JS_SCALARTYPEREPR_INT32:
-    return Load_int32(typedObj, offset | 0);
+    return Load_int32(typedObj, offset);
 
   case JS_SCALARTYPEREPR_UINT32:
-    return Load_uint32(typedObj, offset | 0);
+    return Load_uint32(typedObj, offset);
 
   case JS_SCALARTYPEREPR_FLOAT32:
-    return Load_float32(typedObj, offset | 0);
+    return Load_float32(typedObj, offset);
 
   case JS_SCALARTYPEREPR_FLOAT64:
-    return Load_float64(typedObj, offset | 0);
+    return Load_float64(typedObj, offset);
   }
 
   assert(false, "Unhandled scalar type: " + type);
   return undefined;
 }
 
 function TypedObjectGetReference(descr, typedObj, offset) {
   var type = DESCR_TYPE(descr);
   switch (type) {
   case JS_REFERENCETYPEREPR_ANY:
-    return Load_Any(typedObj, offset | 0);
+    return Load_Any(typedObj, offset);
 
   case JS_REFERENCETYPEREPR_OBJECT:
-    return Load_Object(typedObj, offset | 0);
+    return Load_Object(typedObj, offset);
 
   case JS_REFERENCETYPEREPR_STRING:
-    return Load_string(typedObj, offset | 0);
+    return Load_string(typedObj, offset);
   }
 
   assert(false, "Unhandled scalar type: " + type);
   return undefined;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // Setting values
@@ -207,66 +207,66 @@ function TypedObjectSetArray(descr, leng
 
 // Sets `fromValue` to `this` assuming that `this` is a scalar type.
 function TypedObjectSetScalar(descr, typedObj, offset, fromValue) {
   assert(DESCR_KIND(descr) === JS_TYPEREPR_SCALAR_KIND,
          "Expected scalar type descriptor");
   var type = DESCR_TYPE(descr);
   switch (type) {
   case JS_SCALARTYPEREPR_INT8:
-    return Store_int8(typedObj, offset | 0,
+    return Store_int8(typedObj, offset,
                       TO_INT32(fromValue) & 0xFF);
 
   case JS_SCALARTYPEREPR_UINT8:
-    return Store_uint8(typedObj, offset | 0,
+    return Store_uint8(typedObj, offset,
                        TO_UINT32(fromValue) & 0xFF);
 
   case JS_SCALARTYPEREPR_UINT8_CLAMPED:
     var v = ClampToUint8(+fromValue);
-    return Store_int8(typedObj, offset | 0, v);
+    return Store_int8(typedObj, offset, v);
 
   case JS_SCALARTYPEREPR_INT16:
-    return Store_int16(typedObj, offset | 0,
+    return Store_int16(typedObj, offset,
                        TO_INT32(fromValue) & 0xFFFF);
 
   case JS_SCALARTYPEREPR_UINT16:
-    return Store_uint16(typedObj, offset | 0,
+    return Store_uint16(typedObj, offset,
                         TO_UINT32(fromValue) & 0xFFFF);
 
   case JS_SCALARTYPEREPR_INT32:
-    return Store_int32(typedObj, offset | 0,
+    return Store_int32(typedObj, offset,
                        TO_INT32(fromValue));
 
   case JS_SCALARTYPEREPR_UINT32:
-    return Store_uint32(typedObj, offset | 0,
+    return Store_uint32(typedObj, offset,
                         TO_UINT32(fromValue));
 
   case JS_SCALARTYPEREPR_FLOAT32:
-    return Store_float32(typedObj, offset | 0, +fromValue);
+    return Store_float32(typedObj, offset, +fromValue);
 
   case JS_SCALARTYPEREPR_FLOAT64:
-    return Store_float64(typedObj, offset | 0, +fromValue);
+    return Store_float64(typedObj, offset, +fromValue);
   }
 
   assert(false, "Unhandled scalar type: " + type);
   return undefined;
 }
 
 function TypedObjectSetReference(descr, typedObj, offset, name, fromValue) {
   var type = DESCR_TYPE(descr);
   switch (type) {
   case JS_REFERENCETYPEREPR_ANY:
-    return Store_Any(typedObj, offset | 0, name, fromValue);
+    return Store_Any(typedObj, offset, name, fromValue);
 
   case JS_REFERENCETYPEREPR_OBJECT:
     var value = (fromValue === null ? fromValue : ToObject(fromValue));
-    return Store_Object(typedObj, offset | 0, name, value);
+    return Store_Object(typedObj, offset, name, value);
 
   case JS_REFERENCETYPEREPR_STRING:
-    return Store_string(typedObj, offset | 0, name, ToString(fromValue));
+    return Store_string(typedObj, offset, name, ToString(fromValue));
   }
 
   assert(false, "Unhandled scalar type: " + type);
   return undefined;
 }
 
 // Sets `fromValue` to `this` assuming that `this` is a scalar type.
 ///////////////////////////////////////////////////////////////////////////
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -2924,24 +2924,22 @@ class ICUnaryArith_Fallback : public ICF
     friend class ICStubSpace;
 
     explicit ICUnaryArith_Fallback(JitCode* stubCode)
       : ICFallbackStub(UnaryArith_Fallback, stubCode)
     {
         extra_ = 0;
     }
 
-    static const uint16_t SAW_DOUBLE_RESULT_BIT = 0x1;
-
   public:
-    bool sawDoubleResult() const {
-        return extra_ & SAW_DOUBLE_RESULT_BIT;
+    bool sawDoubleResult() {
+        return extra_;
     }
     void setSawDoubleResult() {
-        extra_ |= SAW_DOUBLE_RESULT_BIT;
+        extra_ = 1;
     }
 
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
 
       public:
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -755,36 +755,28 @@ BaselineInspector::hasSeenNonStringIterM
     }
 
     const ICEntry& entry = icEntryFromPC(pc);
     ICStub* stub = entry.fallbackStub();
 
     return stub->toIteratorMore_Fallback()->hasNonStringResult();
 }
 
-// defaultIfEmpty: if we've not seen *anything* (neither double nor non-double),
-// return this value. This can happen with, for example, a never-taken branch
-// inside a hot loop.
 bool
-BaselineInspector::hasSeenDoubleResult(jsbytecode* pc, bool defaultIfEmpty)
+BaselineInspector::hasSeenDoubleResult(jsbytecode* pc)
 {
     if (!hasBaselineScript()) {
         return false;
     }
 
     const ICEntry& entry = icEntryFromPC(pc);
-    ICFallbackStub* stub = entry.fallbackStub();
+    ICStub* stub = entry.fallbackStub();
 
     MOZ_ASSERT(stub->isUnaryArith_Fallback() || stub->isBinaryArith_Fallback());
 
-    // If no attached stubs, and no failures, then this IC has never been executed.
-    if (stub->state().numOptimizedStubs() == 0 && !entry.fallbackStub()->state().hasFailures()) {
-        return defaultIfEmpty;
-    }
-
     if (stub->isUnaryArith_Fallback()) {
         return stub->toUnaryArith_Fallback()->sawDoubleResult();
     }
 
     return stub->toBinaryArith_Fallback()->sawDoubleResult();
 }
 
 JSObject*
--- a/js/src/jit/BaselineInspector.h
+++ b/js/src/jit/BaselineInspector.h
@@ -119,17 +119,17 @@ class BaselineInspector
 
     MIRType expectedResultType(jsbytecode* pc);
     MCompare::CompareType expectedCompareType(jsbytecode* pc);
     MIRType expectedBinaryArithSpecialization(jsbytecode* pc);
     MIRType expectedPropertyAccessInputType(jsbytecode* pc);
 
     bool hasSeenNegativeIndexGetElement(jsbytecode* pc);
     bool hasSeenAccessedGetter(jsbytecode* pc);
-    bool hasSeenDoubleResult(jsbytecode* pc, bool defaultIfEmpty);
+    bool hasSeenDoubleResult(jsbytecode* pc);
     bool hasSeenNonStringIterMore(jsbytecode* pc);
 
     MOZ_MUST_USE bool isOptimizableConstStringSplit(jsbytecode* pc, JSString** strOut,
                                                     JSString** sepOut, ArrayObject** objOut);
     JSObject* getTemplateObject(jsbytecode* pc);
     JSObject* getTemplateObjectForNative(jsbytecode* pc, Native native);
     JSObject* getTemplateObjectForClassHook(jsbytecode* pc, const Class* clasp);
 
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -93,17 +93,17 @@ MDefinition::PrintOpcodeName(GenericPrin
     size_t len = strlen(name);
     for (size_t i = 0; i < len; i++) {
         out.printf("%c", tolower(name[i]));
     }
 }
 #endif
 
 static MConstant*
-EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins)
+EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins, bool* ptypeChange = nullptr)
 {
     MDefinition* left = ins->getOperand(0);
     MDefinition* right = ins->getOperand(1);
 
     MOZ_ASSERT(IsTypeRepresentableAsDouble(left->type()));
     MOZ_ASSERT(IsTypeRepresentableAsDouble(right->type()));
 
     if (!left->isConstant() || !right->isConstant()) {
@@ -184,16 +184,19 @@ EvaluateConstantOperands(TempAllocator& 
     Value retVal;
     retVal.setNumber(JS::CanonicalizeNaN(ret));
 
     // If this was an int32 operation but the result isn't an int32 (for
     // example, a division where the numerator isn't evenly divisible by the
     // denominator), decline folding.
     MOZ_ASSERT(ins->type() == MIRType::Int32);
     if (!retVal.isInt32()) {
+        if (ptypeChange) {
+            *ptypeChange = true;
+        }
         return nullptr;
     }
 
     return MConstant::New(alloc, retVal);
 }
 
 static MMul*
 EvaluateExactReciprocal(TempAllocator& alloc, MDiv* ins)
@@ -2714,19 +2717,17 @@ MUrsh::infer(BaselineInspector* inspecto
     if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Object) ||
         getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol))
     {
         specialization_ = MIRType::None;
         setResultType(MIRType::Value);
         return;
     }
 
-    // defaultIfEmpty: if we haven't seen anything, assume no double has been seen:
-    // unsigned right shift only produces a double if the result overflows a signed int32, which is rare.
-    if (inspector->hasSeenDoubleResult(pc, /* defaultIfEmpty: */ false)) {
+    if (inspector->hasSeenDoubleResult(pc)) {
         specialization_ = MIRType::Double;
         setResultType(MIRType::Double);
         return;
     }
 
     specialization_ = MIRType::Int32;
     setResultType(MIRType::Int32);
 }
@@ -2934,40 +2935,32 @@ MBinaryArithInstruction::New(TempAllocat
 void
 MBinaryArithInstruction::setNumberSpecialization(TempAllocator& alloc, BaselineInspector* inspector,
                                                  jsbytecode* pc)
 {
     setSpecialization(MIRType::Double);
 
     // Try to specialize as int32.
     if (getOperand(0)->type() == MIRType::Int32 && getOperand(1)->type() == MIRType::Int32) {
-        // The defaultIfEmpty logic here is a little complex, so here's some pseudocode:
-        // If both arguments are integers, and this code/IC has never been ran:
-        //   If opcode is Div:
-        //     Assume the result is a double. (i.e. int/int division usually produces a double)
-        //   Else (if opcode is not Div):
-        //     Assume the result is an int. (i.e. int (op) int usually produces an int)
-
-        // Note, however, if we assume an int incorrectly (e.g. an int+int addition that
-        // overflows), we might bailout repeatedly. The "repeated bailout, let's not ion
-        // compile this" logic should catch this scenario.
-        bool defaultIfEmpty = op() == Opcode::Div;
-        bool seenDouble = inspector->hasSeenDoubleResult(pc, defaultIfEmpty);
-
+        bool seenDouble = inspector->hasSeenDoubleResult(pc);
+
+        // Use int32 specialization if the operation doesn't overflow on its
+        // constant operands and if the operation has never overflowed.
         if (!seenDouble && !constantDoubleResult(alloc)) {
             setInt32Specialization();
         }
     }
 }
 
 bool
 MBinaryArithInstruction::constantDoubleResult(TempAllocator& alloc)
 {
-    MConstant* constantResult = EvaluateConstantOperands(alloc, this);
-    return constantResult != nullptr && constantResult->type() == MIRType::Double;
+    bool typeChange = false;
+    EvaluateConstantOperands(alloc, this, &typeChange);
+    return typeChange;
 }
 
 MDefinition*
 MRsh::foldsTo(TempAllocator& alloc)
 {
     MDefinition* f = MBinaryBitwiseInstruction::foldsTo(alloc);
 
     if (f != this) {
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -309,18 +309,18 @@ intrinsic_GetBuiltinConstructor(JSContex
     return true;
 }
 
 static bool
 intrinsic_SubstringKernel(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args[0].isString());
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
-    MOZ_RELEASE_ASSERT(args[2].isInt32());
+    MOZ_ASSERT(args[1].isInt32());
+    MOZ_ASSERT(args[2].isInt32());
 
     RootedString str(cx, args[0].toString());
     int32_t begin = args[1].toInt32();
     int32_t length = args[2].toInt32();
 
     JSString* substr = SubstringKernel(cx, str, begin, length);
     if (!substr) {
         return false;
@@ -328,17 +328,16 @@ intrinsic_SubstringKernel(JSContext* cx,
 
     args.rval().setString(substr);
     return true;
 }
 
 static void
 ThrowErrorWithType(JSContext* cx, JSExnType type, const CallArgs& args)
 {
-    MOZ_RELEASE_ASSERT(args[0].isInt32());
     uint32_t errorNumber = args[0].toInt32();
 
 #ifdef DEBUG
     const JSErrorFormatString* efs = GetErrorMessage(nullptr, errorNumber);
     MOZ_ASSERT(efs->argCount == args.length() - 1);
     MOZ_ASSERT(efs->exnType == type, "error-throwing intrinsic and error number are inconsistent");
 #endif
 
@@ -403,17 +402,17 @@ intrinsic_ThrowInternalError(JSContext* 
     return false;
 }
 
 static bool
 intrinsic_GetErrorMessage(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
-    MOZ_RELEASE_ASSERT(args[0].isInt32());
+    MOZ_ASSERT(args[0].isInt32());
 
     const JSErrorFormatString* errorString = GetErrorMessage(nullptr, args[0].toInt32());
     MOZ_ASSERT(errorString);
 
     MOZ_ASSERT(errorString->argCount == 0);
     RootedString message(cx, JS_NewStringCopyZ(cx, errorString->format));
     if (!message) {
         return false;
@@ -424,18 +423,18 @@ intrinsic_GetErrorMessage(JSContext* cx,
 }
 
 static bool
 intrinsic_CreateModuleSyntaxError(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 4);
     MOZ_ASSERT(args[0].isObject());
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
-    MOZ_RELEASE_ASSERT(args[2].isInt32());
+    MOZ_ASSERT(args[1].isInt32());
+    MOZ_ASSERT(args[2].isInt32());
     MOZ_ASSERT(args[3].isString());
 
     RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
     RootedString filename(cx, JS_NewStringCopyZ(cx, module->script()->filename()));
     if (!filename) {
         return false;
     }
 
@@ -547,17 +546,17 @@ intrinsic_MakeDefaultConstructor(JSConte
 }
 
 static bool
 intrinsic_FinishBoundFunctionInit(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 3);
     MOZ_ASSERT(IsCallable(args[1]));
-    MOZ_RELEASE_ASSERT(args[2].isInt32());
+    MOZ_ASSERT(args[2].isInt32());
 
     RootedFunction bound(cx, &args[0].toObject().as<JSFunction>());
     RootedObject targetObj(cx, &args[1].toObject());
     int32_t argCount = args[2].toInt32();
 
     args.rval().setUndefined();
     return JSFunction::finishBoundFunctionInit(cx, bound, targetObj, argCount);
 }
@@ -570,17 +569,16 @@ intrinsic_FinishBoundFunctionInit(JSCont
  * The user must supply the argument number of the value in question; it
  * _cannot_ be automatically determined.
  */
 static bool
 intrinsic_DecompileArg(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
-    MOZ_RELEASE_ASSERT(args[0].isInt32());
 
     HandleValue value = args[1];
     JSString* str = DecompileArgument(cx, args[0].toInt32(), value);
     if (!str) {
         return false;
     }
     args.rval().setString(str);
     return true;
@@ -590,17 +588,16 @@ static bool
 intrinsic_DefineDataProperty(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     // When DefineDataProperty is called with 3 arguments, it's compiled to
     // JSOP_INITELEM in the bytecode emitter so we shouldn't get here.
     MOZ_ASSERT(args.length() == 4);
     MOZ_ASSERT(args[0].isObject());
-    MOZ_RELEASE_ASSERT(args[3].isInt32());
 
     RootedObject obj(cx, &args[0].toObject());
     RootedId id(cx);
     if (!ValueToId<CanGC>(cx, args[1], &id)) {
         return false;
     }
     RootedValue value(cx, args[2]);
 
@@ -639,17 +636,17 @@ intrinsic_DefineDataProperty(JSContext* 
 static bool
 intrinsic_DefineProperty(JSContext* cx, unsigned argc, Value* vp)
 {
     // _DefineProperty(object, propertyKey, attributes, valueOrGetter, setter, strict)
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 6);
     MOZ_ASSERT(args[0].isObject());
     MOZ_ASSERT(args[1].isString() || args[1].isNumber() || args[1].isSymbol());
-    MOZ_RELEASE_ASSERT(args[2].isInt32());
+    MOZ_ASSERT(args[2].isInt32());
     MOZ_ASSERT(args[5].isBoolean());
 
     RootedObject obj(cx, &args[0].toObject());
     RootedId id(cx);
     if (!ValueToId<CanGC>(cx, args[1], &id)) {
         return false;
     }
 
@@ -740,30 +737,30 @@ intrinsic_ObjectHasPrototype(JSContext* 
 }
 
 static bool
 intrinsic_UnsafeSetReservedSlot(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 3);
     MOZ_ASSERT(args[0].isObject());
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
+    MOZ_ASSERT(args[1].isInt32());
 
     args[0].toObject().as<NativeObject>().setReservedSlot(args[1].toPrivateUint32(), args[2]);
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 intrinsic_UnsafeGetReservedSlot(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
     MOZ_ASSERT(args[0].isObject());
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
+    MOZ_ASSERT(args[1].isInt32());
 
     args.rval().set(args[0].toObject().as<NativeObject>().getReservedSlot(args[1].toPrivateUint32()));
     return true;
 }
 
 static bool
 intrinsic_UnsafeGetObjectFromReservedSlot(JSContext* cx, unsigned argc, Value* vp)
 {
@@ -1010,19 +1007,16 @@ intrinsic_PossiblyWrappedArrayBufferByte
 }
 
 template<typename T>
 static bool
 intrinsic_ArrayBufferCopyData(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 6);
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
-    MOZ_RELEASE_ASSERT(args[3].isInt32());
-    MOZ_RELEASE_ASSERT(args[4].isInt32());
 
     bool isWrapped = args[5].toBoolean();
     Rooted<T*> toBuffer(cx);
     if (!isWrapped) {
         toBuffer = &args[0].toObject().as<T>();
     } else {
         JSObject* wrapped = &args[0].toObject();
         MOZ_ASSERT(wrapped->is<WrapperObject>());
@@ -1192,19 +1186,16 @@ intrinsic_PossiblyWrappedTypedArrayHasDe
     return true;
 }
 
 static bool
 intrinsic_MoveTypedArrayElements(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 4);
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
-    MOZ_RELEASE_ASSERT(args[2].isInt32());
-    MOZ_RELEASE_ASSERT(args[3].isInt32());
 
     Rooted<TypedArrayObject*> tarray(cx, &args[0].toObject().as<TypedArrayObject>());
     uint32_t to = uint32_t(args[1].toInt32());
     uint32_t from = uint32_t(args[2].toInt32());
     uint32_t count = uint32_t(args[3].toInt32());
 
     MOZ_ASSERT(count > 0,
                "don't call this method if copying no elements, because then "
@@ -1290,17 +1281,16 @@ DangerouslyUnwrapTypedArray(JSContext* c
 }
 
 // ES6 draft 20150403 22.2.3.22.2, steps 12-24, 29.
 static bool
 intrinsic_SetFromTypedArrayApproach(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 4);
-    MOZ_RELEASE_ASSERT(args[3].isInt32());
 
     Rooted<TypedArrayObject*> target(cx, &args[0].toObject().as<TypedArrayObject>());
     MOZ_ASSERT(!target->hasDetachedBuffer(),
                "something should have defended against a target viewing a "
                "detached buffer");
 
     // As directed by |DangerouslyUnwrapTypedArray|, sigil this pointer and all
     // variables derived from it to counsel extreme caution here.
@@ -1537,17 +1527,16 @@ js::SetDisjointTypedElements(TypedArrayO
                         unsafeSrcTypeCrossCompartment, count);
 }
 
 static bool
 intrinsic_SetDisjointTypedElements(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 3);
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
 
     Rooted<TypedArrayObject*> target(cx, &args[0].toObject().as<TypedArrayObject>());
     MOZ_ASSERT(!target->hasDetachedBuffer(),
                "a typed array viewing a detached buffer has no elements to "
                "set, so it's nonsensical to be setting them");
 
     uint32_t targetOffset = uint32_t(args[1].toInt32());
 
@@ -1565,17 +1554,16 @@ intrinsic_SetDisjointTypedElements(JSCon
     return true;
 }
 
 static bool
 intrinsic_SetOverlappingTypedElements(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 3);
-    MOZ_RELEASE_ASSERT(args[1].isInt32());
 
     Rooted<TypedArrayObject*> target(cx, &args[0].toObject().as<TypedArrayObject>());
     cx->check(target);
     MOZ_ASSERT(!target->hasDetachedBuffer(),
                "shouldn't set elements if underlying buffer is detached");
 
     uint32_t targetOffset = uint32_t(args[1].toInt32());
 
@@ -1649,18 +1637,18 @@ IsTypedArrayBitwiseSlice(Scalar::Type so
 
 static bool
 intrinsic_TypedArrayBitwiseSlice(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 4);
     MOZ_ASSERT(args[0].isObject());
     MOZ_ASSERT(args[1].isObject());
-    MOZ_RELEASE_ASSERT(args[2].isInt32());
-    MOZ_RELEASE_ASSERT(args[3].isInt32());
+    MOZ_ASSERT(args[2].isInt32());
+    MOZ_ASSERT(args[3].isInt32());
 
     Rooted<TypedArrayObject*> source(cx, &args[0].toObject().as<TypedArrayObject>());
     MOZ_ASSERT(!source->hasDetachedBuffer());
 
     // As directed by |DangerouslyUnwrapTypedArray|, sigil this pointer and all
     // variables derived from it to counsel extreme caution here.
     Rooted<TypedArrayObject*> unsafeTypedArrayCrossCompartment(cx);
     unsafeTypedArrayCrossCompartment = DangerouslyUnwrapTypedArray(cx, &args[1].toObject());
@@ -2020,37 +2008,35 @@ intrinsic_GetBuiltinIntlConstructor(JSCo
     return true;
 }
 
 static bool
 intrinsic_AddContentTelemetry(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
-    MOZ_RELEASE_ASSERT(args[0].isInt32());
 
     int id = args[0].toInt32();
     MOZ_ASSERT(id < JS_TELEMETRY_END);
     MOZ_ASSERT(id >= 0);
 
     if (!cx->realm()->isProbablySystemCode()) {
-        MOZ_RELEASE_ASSERT(args[1].isInt32());
         cx->runtime()->addTelemetry(id, args[1].toInt32());
     }
 
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 intrinsic_WarnDeprecatedStringMethod(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
-    MOZ_RELEASE_ASSERT(args[0].isInt32());
+    MOZ_ASSERT(args[0].isInt32());
     MOZ_ASSERT(args[1].isString());
 
     uint32_t id = uint32_t(args[0].toInt32());
     MOZ_ASSERT(id < STRING_GENERICS_METHODS_LIMIT);
 
     uint32_t mask = (1 << id);
     if (!(cx->realm()->warnedAboutStringGenericsMethods & mask)) {
         JSFlatString* name = args[1].toString()->ensureFlat(cx);
--- a/js/xpconnect/src/XPCJSWeakReference.h
+++ b/js/xpconnect/src/XPCJSWeakReference.h
@@ -3,27 +3,27 @@
 /* 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 xpcjsweakreference_h___
 #define xpcjsweakreference_h___
 
 #include "xpcIJSWeakReference.h"
-#include "nsIWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "mozilla/Attributes.h"
 
 class xpcJSWeakReference final : public xpcIJSWeakReference
 {
     ~xpcJSWeakReference() {}
 
 public:
     xpcJSWeakReference();
     nsresult Init(JSContext* cx, const JS::Value& object);
 
     NS_DECL_ISUPPORTS
     NS_DECL_XPCIJSWEAKREFERENCE
 
 private:
-    nsCOMPtr<nsIWeakReference> mReferent;
+    nsWeakPtr mReferent;
 };
 
 #endif // xpcjsweakreference_h___
--- a/layout/base/ZoomConstraintsClient.h
+++ b/layout/base/ZoomConstraintsClient.h
@@ -6,17 +6,16 @@
 
 #ifndef ZoomConstraintsClient_h_
 #define ZoomConstraintsClient_h_
 
 #include "FrameMetrics.h"
 #include "mozilla/Maybe.h"
 #include "nsIDOMEventListener.h"
 #include "nsIObserver.h"
-#include "nsWeakPtr.h"
 
 class nsIDocument;
 class nsIPresShell;
 
 namespace mozilla {
 namespace dom {
 class EventTarget;
 } // namespace dom
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -27,17 +27,16 @@
 #include "nsISelectionController.h"
 #include "nsQueryFrame.h"
 #include "nsStringFwd.h"
 #include "nsCoord.h"
 #include "nsColor.h"
 #include "nsFrameManager.h"
 #include "nsRect.h"
 #include "nsRegionFwd.h"
-#include "nsWeakReference.h"
 #include <stdio.h> // for FILE definition
 #include "nsChangeHint.h"
 #include "nsRefPtrHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsPresArena.h"
 #include "nsIImageLoadingContent.h"
 #include "nsMargin.h"
 #include "nsFrameState.h"
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -6545,17 +6545,17 @@ nsLayoutUtils::GetSamplingFilterForFrame
     sc = aForFrame->Style();
   }
 
   switch (sc->StyleVisibility()->mImageRendering) {
   case NS_STYLE_IMAGE_RENDERING_OPTIMIZESPEED:
     return SamplingFilter::POINT;
   case NS_STYLE_IMAGE_RENDERING_OPTIMIZEQUALITY:
     return SamplingFilter::LINEAR;
-  case NS_STYLE_IMAGE_RENDERING_CRISPEDGES:
+  case NS_STYLE_IMAGE_RENDERING_CRISP_EDGES:
     return SamplingFilter::POINT;
   default:
     return defaultFilter;
   }
 }
 
 /**
  * Given an image being drawn into an appunit coordinate system, and
--- a/layout/style/GeckoBindings.cpp
+++ b/layout/style/GeckoBindings.cpp
@@ -978,18 +978,17 @@ AttrEquals(Implementor* aElement, nsAtom
   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
     return aValue->Equals(aStr, aIgnoreCase ? eIgnoreCase : eCaseMatters);
   };
   return DoMatch(aElement, aNS, aName, match);
 }
 
 #define WITH_COMPARATOR(ignore_case_, c_, expr_)    \
     if (ignore_case_) {                             \
-      const nsCaseInsensitiveStringComparator c_    \
-          = nsCaseInsensitiveStringComparator();    \
+      const nsCaseInsensitiveStringComparator c_;   \
       return expr_;                                 \
     } else {                                        \
       const nsDefaultStringComparator c_;           \
       return expr_;                                 \
     }
 
 
 template <typename Implementor>
--- a/layout/style/PaintWorkletGlobalScope.cpp
+++ b/layout/style/PaintWorkletGlobalScope.cpp
@@ -1,24 +1,26 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "PaintWorkletGlobalScope.h"
+
 #include "mozilla/dom/WorkletPrincipal.h"
 #include "mozilla/dom/PaintWorkletGlobalScopeBinding.h"
 #include "mozilla/dom/FunctionBinding.h"
+#include "PaintWorkletImpl.h"
 
 namespace mozilla {
 namespace dom {
 
-PaintWorkletGlobalScope::PaintWorkletGlobalScope(WorkletImpl* aImpl)
-  : WorkletGlobalScope(aImpl)
+PaintWorkletGlobalScope::PaintWorkletGlobalScope(PaintWorkletImpl* aImpl)
+  : mImpl(aImpl)
 {
 }
 
 bool
 PaintWorkletGlobalScope::WrapGlobalObject(JSContext* aCx,
                                           JS::MutableHandle<JSObject*> aReflector)
 {
   JS::RealmOptions options;
@@ -30,10 +32,15 @@ PaintWorkletGlobalScope::WrapGlobalObjec
 
 void
 PaintWorkletGlobalScope::RegisterPaint(const nsAString& aType,
                                        VoidFunction& aProcessorCtor)
 {
   // Nothing to do here, yet.
 }
 
+WorkletImpl* PaintWorkletGlobalScope::Impl() const
+{
+  return mImpl;
+}
+
 } // dom namespace
 } // mozilla namespace
--- a/layout/style/PaintWorkletGlobalScope.h
+++ b/layout/style/PaintWorkletGlobalScope.h
@@ -6,34 +6,38 @@
 
 #ifndef mozilla_dom_PaintWorkletGlobalScope_h
 #define mozilla_dom_PaintWorkletGlobalScope_h
 
 #include "mozilla/dom/WorkletGlobalScope.h"
 
 namespace mozilla {
 
-class WorkletImpl;
+class PaintWorkletImpl;
 
 namespace dom {
 
 class VoidFunction;
 
 class PaintWorkletGlobalScope final : public WorkletGlobalScope
 {
 public:
-  explicit PaintWorkletGlobalScope(WorkletImpl* aImpl);
+  explicit PaintWorkletGlobalScope(PaintWorkletImpl* aImpl);
 
   bool
   WrapGlobalObject(JSContext* aCx,
                    JS::MutableHandle<JSObject*> aReflector) override;
 
   void
   RegisterPaint(const nsAString& aType, VoidFunction& aProcessorCtor);
 
+  WorkletImpl* Impl() const override;
+
 private:
   ~PaintWorkletGlobalScope() = default;
+
+  const RefPtr<PaintWorkletImpl> mImpl;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_PaintWorkletGlobalScope_h
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -983,17 +983,17 @@ enum class StyleWhiteSpace : uint8_t {
 #define NS_STYLE_DOMINANT_BASELINE_MIDDLE            9
 #define NS_STYLE_DOMINANT_BASELINE_TEXT_AFTER_EDGE  10
 #define NS_STYLE_DOMINANT_BASELINE_TEXT_BEFORE_EDGE 11
 
 // image-rendering
 #define NS_STYLE_IMAGE_RENDERING_AUTO             0
 #define NS_STYLE_IMAGE_RENDERING_OPTIMIZESPEED    1
 #define NS_STYLE_IMAGE_RENDERING_OPTIMIZEQUALITY  2
-#define NS_STYLE_IMAGE_RENDERING_CRISPEDGES       3
+#define NS_STYLE_IMAGE_RENDERING_CRISP_EDGES      3
 
 // mask-type
 #define NS_STYLE_MASK_TYPE_LUMINANCE            0
 #define NS_STYLE_MASK_TYPE_ALPHA                1
 
 // paint-order
 #define NS_STYLE_PAINT_ORDER_NORMAL             0
 #define NS_STYLE_PAINT_ORDER_FILL               1
--- a/layout/xul/nsXULTooltipListener.h
+++ b/layout/xul/nsXULTooltipListener.h
@@ -9,17 +9,17 @@
 
 #include "nsIDOMEventListener.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #ifdef MOZ_XUL
 #include "nsITreeBoxObject.h"
 #endif
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "mozilla/Attributes.h"
 
 class nsIContent;
 class nsTreeColumn;
 
 namespace mozilla {
 namespace dom {
 class Event;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -8,17 +8,16 @@
 #include <deque>
 #include <string>
 #include <vector>
 #include <map>
 #include <cmath>
 
 #include "prlock.h"
 #include "mozilla/RefPtr.h"
-#include "nsWeakPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIWeakReferenceUtils.h" // for the definition of nsWeakPtr
 #include "IPeerConnection.h"
 #include "sigslot.h"
 #include "nsComponentManagerUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsIUUIDGenerator.h"
 #include "nsIThread.h"
--- a/netwerk/base/nsDNSPrefetch.h
+++ b/netwerk/base/nsDNSPrefetch.h
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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/. */
 
 #ifndef nsDNSPrefetch_h___
 #define nsDNSPrefetch_h___
 
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsString.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/BasePrincipal.h"
 
 #include "nsIDNSListener.h"
 
 class nsIURI;
--- a/netwerk/base/nsIOService.h
+++ b/netwerk/base/nsIOService.h
@@ -5,19 +5,18 @@
 
 #ifndef nsIOService_h__
 #define nsIOService_h__
 
 #include "nsStringFwd.h"
 #include "nsIIOService.h"
 #include "nsTArray.h"
 #include "nsCOMPtr.h"
-#include "nsWeakPtr.h"
 #include "nsIObserver.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsINetUtil.h"
 #include "nsIChannelEventSink.h"
 #include "nsCategoryCache.h"
 #include "nsISpeculativeConnect.h"
 #include "nsDataHashtable.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/Attributes.h"
 #include "prtime.h"
--- a/netwerk/base/nsLoadGroup.h
+++ b/netwerk/base/nsLoadGroup.h
@@ -6,17 +6,16 @@
 #ifndef nsLoadGroup_h__
 #define nsLoadGroup_h__
 
 #include "nsILoadGroup.h"
 #include "nsILoadGroupChild.h"
 #include "nsPILoadGroupInternal.h"
 #include "nsAgg.h"
 #include "nsCOMPtr.h"
-#include "nsWeakPtr.h"
 #include "nsWeakReference.h"
 #include "nsISupportsPriority.h"
 #include "PLDHashTable.h"
 #include "mozilla/TimeStamp.h"
 
 class nsIRequestContext;
 class nsIRequestContextService;
 class nsITimedChannel;
--- a/netwerk/cache/nsDiskCacheDeviceSQL.cpp
+++ b/netwerk/cache/nsDiskCacheDeviceSQL.cpp
@@ -2376,17 +2376,17 @@ nsOfflineCacheDevice::CreateApplicationC
                                   gNextTemporaryClientID++));
 
   nsCOMPtr<nsIApplicationCache> cache = new nsApplicationCache(this,
                                                                group,
                                                                clientID);
   if (!cache)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(cache);
+  nsWeakPtr weak = do_GetWeakReference(cache);
   if (!weak)
     return NS_ERROR_OUT_OF_MEMORY;
 
   MutexAutoLock lock(mLock);
   mCaches.Put(clientID, weak);
 
   cache.swap(*out);
 
--- a/netwerk/cache/nsDiskCacheDeviceSQL.h
+++ b/netwerk/cache/nsDiskCacheDeviceSQL.h
@@ -13,17 +13,17 @@
 #include "mozIStorageConnection.h"
 #include "mozIStorageFunction.h"
 #include "nsIFile.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsInterfaceHashtable.h"
 #include "nsClassHashtable.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReference.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Mutex.h"
 
 class nsIURI;
 class nsOfflineCacheDevice;
 class mozIStorageService;
 class nsILoadContextInfo;
 namespace mozilla { class OriginAttributesPattern; }
--- a/netwerk/cache2/CacheIndex.h
+++ b/netwerk/cache2/CacheIndex.h
@@ -7,19 +7,19 @@
 
 #include "CacheLog.h"
 #include "CacheFileIOManager.h"
 #include "nsIRunnable.h"
 #include "CacheHashUtils.h"
 #include "nsICacheStorageService.h"
 #include "nsICacheEntry.h"
 #include "nsILoadContextInfo.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsTHashtable.h"
 #include "nsThreadUtils.h"
-#include "nsWeakReference.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/SHA1.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/EndianUtils.h"
 #include "mozilla/TimeStamp.h"
 
 class nsIFile;
--- a/netwerk/cache2/CacheStorageService.cpp
+++ b/netwerk/cache2/CacheStorageService.cpp
@@ -24,17 +24,16 @@
 #include "nsIFile.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsAutoPtr.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
-#include "nsWeakReference.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Services.h"
 #include "mozilla/IntegerPrintfMacros.h"
 
 namespace mozilla {
 namespace net {
--- a/python/mach/mach/registrar.py
+++ b/python/mach/mach/registrar.py
@@ -1,15 +1,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, unicode_literals
 
 from .base import MachError
+import time
 
 INVALID_COMMAND_CONTEXT = r'''
 It looks like you tried to run a mach command from an invalid context. The %s
 command failed to meet the following conditions: %s
 
 Run |mach help| to show a list of all commands available to the current context.
 '''.lstrip()
 
@@ -78,29 +79,34 @@ class MachRegistrar(object):
                     fail_conditions.append(c)
 
             if fail_conditions:
                 print(self._condition_failed_message(handler.name, fail_conditions))
                 return 1
 
         fn = getattr(instance, handler.method)
 
+        start_time = time.time()
+
         if debug_command:
             import pdb
             result = pdb.runcall(fn, **kwargs)
         else:
             result = fn(**kwargs)
 
+        end_time = time.time()
+
         result = result or 0
         assert isinstance(result, (int, long))
 
         if context and not debug_command:
             postrun = getattr(context, 'post_dispatch_handler', None)
             if postrun:
-                postrun(context, handler, args=kwargs)
+                postrun(context, handler, instance, result,
+                        start_time, end_time, args=kwargs)
 
         return result
 
     def dispatch(self, name, context=None, argv=None, subcommand=None, **kwargs):
         """Dispatch/run a command.
 
         Commands can use this to call other commands.
         """
--- a/python/moz.build
+++ b/python/moz.build
@@ -50,16 +50,17 @@ SPHINX_TREES['mach'] = 'mach/docs'
 
 SPHINX_TREES['python'] = 'docs'
 
 with Files('mach/docs/**'):
     SCHEDULES.exclusive = ['docs']
 
 PYTHON_UNITTEST_MANIFESTS += [
     'mach/mach/test/python.ini',
+    'mozboot/mozboot/test/python.ini',
     'mozbuild/dumbmake/test/python.ini',
     'mozlint/test/python.ini',
     'mozrelease/test/python.ini',
     'mozterm/test/python.ini',
     'mozversioncontrol/test/python.ini',
 ]
 
 if CONFIG['MOZ_BUILD_APP']:
--- a/python/mozboot/mozboot/base.py
+++ b/python/mozboot/mozboot/base.py
@@ -426,16 +426,30 @@ class BaseBootstrapper(object):
                 print("ERROR! Please enter a valid option!")
                 limit -= 1
 
         if limit > 0:
             return choice
         else:
             raise Exception("Error! Reached max attempts of entering option.")
 
+    def prompt_yesno(self, prompt):
+        ''' Prompts the user with prompt and requires a yes/no answer.'''
+        valid = False
+        while not valid:
+            choice = raw_input(prompt + ' [Y/n]: ').strip().lower()[:1]
+            if choice == '':
+                choice = 'y'
+            if choice not in ('y', 'n'):
+                print('ERROR! Please enter y or n!')
+            else:
+                valid = True
+
+        return choice == 'y'
+
     def _ensure_package_manager_updated(self):
         if self.package_manager_updated:
             return
 
         self._update_package_manager()
         self.package_manager_updated = True
 
     def _update_package_manager(self):
--- a/python/mozboot/mozboot/bootstrap.py
+++ b/python/mozboot/mozboot/bootstrap.py
@@ -4,16 +4,20 @@
 
 # If we add unicode_literals, Python 2.6.1 (required for OS X 10.6) breaks.
 from __future__ import absolute_import, print_function
 
 import platform
 import sys
 import os
 import subprocess
+from six.moves.configparser import (
+    Error as ConfigParserError,
+    RawConfigParser,
+)
 
 # Don't forgot to add new mozboot modules to the bootstrap download
 # list in bin/bootstrap.py!
 from mozboot.base import MODERN_RUST_VERSION
 from mozboot.centosfedora import CentOSFedoraBootstrapper
 from mozboot.debian import DebianBootstrapper
 from mozboot.freebsd import FreeBSDBootstrapper
 from mozboot.gentoo import GentooBootstrapper
@@ -180,27 +184,64 @@ To add git-cinnabar to the PATH, edit yo
 may be called ~/.bashrc or ~/.bash_profile or ~/.profile, and add the following
 lines:
 
     export PATH="{}:$PATH"
 
 Then restart your shell.
 '''
 
+TELEMETRY_OPT_IN_PROMPT = '''
+Would you like to enable build system telemetry?
+
+Mozilla collects data about local builds in order to make builds faster and
+improve developer tooling. To learn more about the data we intend to collect
+read here:
+https://firefox-source-docs.mozilla.org/build/buildsystem/telemetry.html.
+
+If you have questions, please ask in #build in irc.mozilla.org. If you would
+like to opt out of data collection, select (N) at the prompt.
+
+Your choice'''
+
+
+def update_or_create_build_telemetry_config(path):
+    """Write a mach config file enabling build telemetry to `path`. If the file does not exist,
+    create it. If it exists, add the new setting to the existing data.
+
+    This is standalone from mach's `ConfigSettings` so we can use it during bootstrap
+    without a source checkout.
+    """
+    config = RawConfigParser()
+    if os.path.exists(path):
+        try:
+            config.read([path])
+        except ConfigParserError as e:
+            print('Your mach configuration file at `{path}` is not parseable:\n{error}'.format(
+                path=path, error=e))
+            return False
+    if not config.has_section('build'):
+        config.add_section('build')
+    config.set('build', 'telemetry', 'true')
+    with open(path, 'wb') as f:
+        config.write(f)
+    return True
+
 
 class Bootstrapper(object):
     """Main class that performs system bootstrap."""
 
     def __init__(self, finished=FINISHED, choice=None, no_interactive=False,
-                 hg_configure=False, no_system_changes=False):
+                 hg_configure=False, no_system_changes=False, mach_context=None):
         self.instance = None
         self.finished = finished
         self.choice = choice
         self.hg_configure = hg_configure
         self.no_system_changes = no_system_changes
+        self.mach_context = mach_context
         cls = None
         args = {'no_interactive': no_interactive,
                 'no_system_changes': no_system_changes}
 
         if sys.platform.startswith('linux'):
             distro, version, dist_id = platform.linux_distribution()
 
             if distro in ('CentOS', 'CentOS Linux', 'Fedora'):
@@ -331,16 +372,30 @@ class Bootstrapper(object):
         if not have_clone:
             print(STYLE_NODEJS_REQUIRES_CLONE)
             sys.exit(1)
 
         self.instance.state_dir = state_dir
         self.instance.ensure_stylo_packages(state_dir, checkout_root)
         self.instance.ensure_node_packages(state_dir, checkout_root)
 
+    def check_telemetry_opt_in(self, state_dir):
+        # We can't prompt the user.
+        if self.instance.no_interactive:
+            return
+        # Don't prompt if the user already has a setting for this value.
+        if self.mach_context is not None and 'telemetry' in self.mach_context.settings.build:
+            return
+        choice = self.instance.prompt_yesno(prompt=TELEMETRY_OPT_IN_PROMPT)
+        if choice:
+            cfg_file = os.path.join(state_dir, 'machrc')
+            if update_or_create_build_telemetry_config(cfg_file):
+                print('\nThanks for enabling build telemetry! You can change this setting at ' +
+                      'any time by editing the config file `{}`\n'.format(cfg_file))
+
     def bootstrap(self):
         if self.choice is None:
             # Like ['1. Firefox for Desktop', '2. Firefox for Android Artifact Mode', ...].
             labels = ['%s. %s' % (i + 1, name) for (i, (name, _)) in enumerate(APPLICATIONS_LIST)]
             prompt = APPLICATION_CHOICE % '\n'.join(labels)
             prompt_choice = self.instance.prompt_int(prompt=prompt, low=1, high=len(APPLICATIONS))
             name, application = APPLICATIONS_LIST[prompt_choice-1]
         elif self.choice not in APPLICATIONS.keys():
@@ -355,16 +410,18 @@ class Bootstrapper(object):
             # required to open the repo.
             r = current_firefox_checkout(
                 check_output=self.instance.check_output,
                 env=self.instance._hg_cleanenv(load_hgrc=True),
                 hg=self.instance.which('hg'))
             (checkout_type, checkout_root) = r
             have_clone = bool(checkout_type)
 
+            if state_dir_available:
+                self.check_telemetry_opt_in(state_dir)
             self.maybe_install_private_packages_or_exit(state_dir,
                                                         state_dir_available,
                                                         have_clone,
                                                         checkout_root)
             sys.exit(0)
 
         self.instance.install_system_packages()
 
@@ -429,16 +486,18 @@ class Bootstrapper(object):
                 git = self.instance.which('git')
                 watchman = self.instance.which('watchman')
                 have_clone = git_clone_firefox(git, dest, watchman)
                 checkout_root = dest
 
         if not have_clone:
             print(SOURCE_ADVERTISE)
 
+        if state_dir_available:
+            self.check_telemetry_opt_in(state_dir)
         self.maybe_install_private_packages_or_exit(state_dir,
                                                     state_dir_available,
                                                     have_clone,
                                                     checkout_root)
 
         print(self.finished % name)
         if not (self.instance.which('rustc') and self.instance._parse_version('rustc')
                 >= MODERN_RUST_VERSION):
--- a/python/mozboot/mozboot/mach_commands.py
+++ b/python/mozboot/mozboot/mach_commands.py
@@ -11,35 +11,40 @@ from mach.decorators import (
     CommandProvider,
     Command,
 )
 
 
 @CommandProvider
 class Bootstrap(object):
     """Bootstrap system and mach for optimal development experience."""
+    def __init__(self, context):
+        self._context = context
 
     @Command('bootstrap', category='devenv',
              description='Install required system packages for building.')
     @CommandArgument('--application-choice',
                      default=None,
                      help='Pass in an application choice (see mozboot.bootstrap.APPLICATIONS) '
                      'instead of using the default interactive prompt.')
     @CommandArgument('--no-interactive', dest='no_interactive', action='store_true',
                      help='Answer yes to any (Y/n) interactive prompts.')
     @CommandArgument('--no-system-changes', dest='no_system_changes',
                      action='store_true',
                      help='Only execute actions that leave the system '
                           'configuration alone.')
     def bootstrap(self, application_choice=None, no_interactive=False, no_system_changes=False):
         from mozboot.bootstrap import Bootstrapper
 
-        bootstrapper = Bootstrapper(choice=application_choice,
-                                    no_interactive=no_interactive,
-                                    no_system_changes=no_system_changes)
+        bootstrapper = Bootstrapper(
+            choice=application_choice,
+            no_interactive=no_interactive,
+            no_system_changes=no_system_changes,
+            mach_context=self._context,
+        )
         bootstrapper.bootstrap()
 
 
 @CommandProvider
 class VersionControlCommands(object):
     def __init__(self, context):
         self._context = context
 
new file mode 100644
--- /dev/null
+++ b/python/mozboot/mozboot/test/python.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+skip-if = python == 3
+
+[test_write_config.py]
new file mode 100644
--- /dev/null
+++ b/python/mozboot/mozboot/test/test_write_config.py
@@ -0,0 +1,95 @@
+# 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
+
+import mozunit
+import pytest
+
+from mach.config import ConfigSettings
+from mach.decorators import SettingsProvider
+from mozboot.bootstrap import update_or_create_build_telemetry_config
+
+
+# Duplicated from python/mozbuild/mozbuild/mach_commands.py because we can't
+# actually import that module here.
+@SettingsProvider
+class TelemetrySettings():
+    config_settings = [
+        ('build.telemetry', 'boolean', """
+Enable submission of build system telemetry.
+        """.strip(), False),
+    ]
+
+
+@SettingsProvider
+class OtherSettings():
+    config_settings = [
+        ('foo.bar', 'int', '', 1),
+        ('build.abc', 'string', '', ''),
+    ]
+
+
+def read(path):
+    s = ConfigSettings()
+    s.register_provider(TelemetrySettings)
+    s.register_provider(OtherSettings)
+    s.load_file(path)
+    return s
+
+
+@pytest.fixture
+def config_path(tmpdir):
+    return unicode(tmpdir.join('machrc'))
+
+
+@pytest.fixture
+def write_config(config_path):
+    def _config(contents):
+        with open(config_path, 'wb') as f:
+            f.write(contents)
+    return _config
+
+
+def test_nonexistent(config_path):
+    update_or_create_build_telemetry_config(config_path)
+    s = read(config_path)
+    assert(s.build.telemetry)
+
+
+def test_file_exists_no_build_section(config_path, write_config):
+    write_config('''[foo]
+bar = 2
+''')
+    update_or_create_build_telemetry_config(config_path)
+    s = read(config_path)
+    assert(s.build.telemetry)
+    assert(s.foo.bar == 2)
+
+
+def test_existing_build_section(config_path, write_config):
+    write_config('''[foo]
+bar = 2
+
+[build]
+abc = xyz
+''')
+    update_or_create_build_telemetry_config(config_path)
+    s = read(config_path)
+    assert(s.build.telemetry)
+    assert(s.build.abc == 'xyz')
+    assert(s.foo.bar == 2)
+
+
+def test_malformed_file(config_path, write_config):
+    """Ensure that a malformed config file doesn't cause breakage."""
+    write_config('''[foo
+bar = 1
+''')
+    assert(not update_or_create_build_telemetry_config(config_path))
+    # Can't read config, it will not have been written!
+
+
+if __name__ == '__main__':
+    mozunit.main()
--- a/python/mozbuild/mozbuild/controller/building.py
+++ b/python/mozbuild/mozbuild/controller/building.py
@@ -51,19 +51,16 @@ from ..testing import (
 )
 from ..compilation.warnings import (
     WarningsCollector,
     WarningsDatabase,
 )
 from ..shellutil import (
     quote as shell_quote,
 )
-from ..telemetry import (
-    gather_telemetry,
-)
 from ..util import (
     FileAvoidWrite,
     mkdir,
     resolve_target_to_make,
 )
 
 
 FINDER_SLOW_MESSAGE = '''
@@ -1280,20 +1277,16 @@ class BuildDriver(MozbuildObject):
         except ValueError:
             # Just stick with the default
             pass
 
         if monitor.elapsed > notify_minimum_time:
             # Display a notification when the build completes.
             self.notify('Build complete' if not status else 'Build failed')
 
-        gather_telemetry(command='build', success=(status == 0), monitor=monitor,
-                         mach_context=mach_context, substs=self.substs,
-                         paths=[self.topsrcdir, self.topobjdir])
-
         if status:
             return status
 
         if monitor.have_resource_usage:
             excessive, swap_in, swap_out = monitor.have_excessive_swapping()
             # if excessive:
             #    print(EXCESSIVE_SWAP_MESSAGE)
 
--- a/python/mozbuild/mozbuild/telemetry.py
+++ b/python/mozbuild/mozbuild/telemetry.py
@@ -234,34 +234,34 @@ def filter_args(command, argv, paths):
         base = mozpath.basedir(p, paths)
         if base:
             return mozpath.relpath(p, base)
         # Best-effort.
         return '<path omitted>'
     return [filter_path(arg) for arg in args]
 
 
-def gather_telemetry(command='', success=False, monitor=None, mach_context=None, substs={},
-                     paths=[]):
+def gather_telemetry(command='', success=False, start_time=None, end_time=None,
+                     mach_context=None, substs={}, paths=[]):
     '''
     Gather telemetry about the build and the user's system and pass it to the telemetry
     handler to be stored for later submission.
 
     Any absolute paths on the command line will be made relative to `paths` or replaced
     with a placeholder to avoid including paths from developer's machines.
     '''
     data = {
         'client_id': get_client_id(mach_context.state_dir),
         # Simplest way to get an rfc3339 datetime string, AFAICT.
-        'time': datetime.utcfromtimestamp(monitor.start_time).isoformat(b'T') + 'Z',
+        'time': datetime.utcfromtimestamp(start_time).isoformat(b'T') + 'Z',
         'command': command,
         'argv': filter_args(command, sys.argv, paths),
         'success': success,
         # TODO: use a monotonic clock: https://bugzilla.mozilla.org/show_bug.cgi?id=1481624
-        'duration_ms': int(monitor.elapsed * 1000),
+        'duration_ms': int((end_time - start_time) * 1000),
         'build_opts': get_build_opts(substs),
         'system': get_system_info(),
         # TODO: exception: https://bugzilla.mozilla.org/show_bug.cgi?id=1481617
         # TODO: file_types_changed: https://bugzilla.mozilla.org/show_bug.cgi?id=1481774
     }
     try:
         # Validate against the schema.
         schema(data)
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/mozrelease/buglist_creator.py
@@ -0,0 +1,254 @@
+# -*- coding: utf-8 -*-
+# 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
+
+import logging
+import os
+import re
+import requests
+from taskcluster.notify import Notify
+from operator import itemgetter
+
+from mozilla_version.gecko import GeckoVersion
+
+BUGLIST_PREFIX = 'Bugs since previous changeset: '
+BACKOUT_REGEX = re.compile(r'back(\s?)out|backed out|backing out', re.IGNORECASE)
+BACKOUT_PREFIX = 'Backouts since previous changeset: '
+BUGZILLA_BUGLIST_TEMPLATE = 'https://bugzilla.mozilla.org/buglist.cgi?bug_id={bugs}'
+BUG_NUMBER_REGEX = re.compile(r'bug \d+', re.IGNORECASE)
+CHANGELOG_TO_FROM_STRING = '{product}_{version}_RELEASE'
+CHANGESET_URL_TEMPLATE = (
+    '{repo}/{logtype}'
+    '?fromchange={from_version}&tochange={to_version}&full=1'
+)
+FULL_CHANGESET_PREFIX = 'Full Mercurial changelog: '
+LIST_DESCRIPTION_TEMPLATE = 'Comparing Mercurial tag {from_version} to {to_version}:'
+MAX_BUGS_IN_BUGLIST = 250
+MERCURIAL_TAGS_URL_TEMPLATE = '{repo}/json-tags'
+NO_BUGS = ''  # Return this when bug list can't be created
+URL_SHORTENER_TEMPLATE = 'https://bugzilla.mozilla.org/rest/bitly/shorten?url={url}'
+
+log = logging.getLogger(__name__)
+
+
+def create_bugs_url(product, current_version, current_revision, repo=None):
+    """
+    Creates list of bugs and backout bugs for release-drivers email
+
+    :param release: dict -> containing information about release, from Ship-It
+    :return: str -> description of compared releases, with Bugzilla links
+        containing all bugs in changeset
+    """
+    try:
+        # Extract the important data, ignore if beta1 release
+        if current_version.beta_number == 1:
+            # If the version is beta 1, don't make any links
+            return NO_BUGS
+
+        if repo is None:
+            repo = get_repo_by_version(current_version)
+        # Get the tag version, for display purposes
+        current_version_tag = tag_version(product, current_version)
+
+        # Get all Hg tags for this branch, determine the previous version
+        tag_url = MERCURIAL_TAGS_URL_TEMPLATE.format(repo=repo)
+        mercurial_tags_json = requests.get(tag_url).json()
+        previous_version_tag = get_previous_tag_version(
+            product, current_version, current_version_tag, mercurial_tags_json)
+
+        # Get the changeset between these versions, parse for all unique bugs and backout bugs
+        resp = requests.get(CHANGESET_URL_TEMPLATE.format(repo=repo,
+                                                          from_version=previous_version_tag,
+                                                          to_version=current_revision,
+                                                          logtype='json-pushes'))
+        changeset_data = resp.json()
+        unique_bugs, unique_backout_bugs = get_bugs_in_changeset(changeset_data)
+
+        # Return a descriptive string with links if any relevant bugs are found
+        if unique_bugs or unique_backout_bugs:
+            description_string = LIST_DESCRIPTION_TEMPLATE.format(
+                from_version=previous_version_tag,
+                to_version=current_version_tag)
+
+            changeset_html = CHANGESET_URL_TEMPLATE.format(repo=repo,
+                                                           from_version=previous_version_tag,
+                                                           to_version=current_revision,
+                                                           logtype='pushloghtml')
+
+            return format_return_value(
+                description_string, unique_bugs, unique_backout_bugs, changeset_html)
+        else:
+            return NO_BUGS
+
+    except Exception as err:
+        log.info(err)
+        return NO_BUGS
+
+
+def get_bugs_in_changeset(changeset_data):
+    unique_bugs, unique_backout_bugs = set(), set()
+    for data in changeset_data.values():
+        for changeset in data['changesets']:
+            if is_excluded_change(changeset):
+                continue
+
+            changeset_desc = changeset['desc']
+            bug_re = BUG_NUMBER_REGEX.search(changeset_desc)
+
+            if bug_re:
+                bug_number = bug_re.group().split(' ')[1]
+
+                if is_backout_bug(changeset_desc):
+                    unique_backout_bugs.add(bug_number)
+                else:
+                    unique_bugs.add(bug_number)
+
+    return unique_bugs, unique_backout_bugs
+
+
+def is_excluded_change(changeset):
+    excluded_change_keywords = [
+        'a=test-only',
+        'a=release',
+    ]
+    return any(keyword in changeset['desc'] for keyword in excluded_change_keywords)
+
+
+def is_backout_bug(changeset_description):
+    return bool(BACKOUT_REGEX.search(changeset_description))
+
+
+def create_short_url_with_prefix(buglist, backout_buglist):
+    # Create link if there are bugs, else empty string
+    urls = []
+    for set_of_bugs, prefix in [(buglist, BUGLIST_PREFIX), (backout_buglist, BACKOUT_PREFIX)]:
+        if set_of_bugs and len(set_of_bugs) < MAX_BUGS_IN_BUGLIST:
+            try:
+                long_bugzilla_link = BUGZILLA_BUGLIST_TEMPLATE.format(bugs='%2C'.join(set_of_bugs))
+                response = requests.get(URL_SHORTENER_TEMPLATE.format(url=long_bugzilla_link))
+                url = response.json()['url']
+                url = prefix + url + '\n'
+
+            except (KeyError, ValueError):
+                # If the Bugzilla link fails despite limiting the number of
+                # bugs, don't make the url and continue
+                url = ''
+        else:
+            url = ''
+
+        urls.append(url)
+
+    return urls[0], urls[1]
+
+
+def tag_version(product, version):
+    underscore_version = str(version).replace('.', '_')
+    return CHANGELOG_TO_FROM_STRING.format(product=product.upper(), version=underscore_version)
+
+
+def parse_tag_version(tag):
+    dot_version = '.'.join(tag.split('_')[1:-1])
+    return GeckoVersion.parse(dot_version)
+
+
+def get_previous_tag_version(
+    product, current_version, current_version_tag, mercurial_tags_json,
+):
+    """
+    Gets the previous hg version tag for the product and branch, given the current version tag
+    """
+
+    def _invalid_tag_filter(tag):
+        """Filters by product and removes incorrect major version + base, end releases"""
+        prod_major_version_re = r'^{product}_{major_version}'.format(
+            product=product.upper(), major_version=current_version.major_number)
+
+        return 'BASE' not in tag and \
+               'END' not in tag and \
+               'RELEASE' in tag and \
+               re.match(prod_major_version_re, tag)
+
+    # Get rid of irrelevant tags, sort by date and extract the tag string
+    tags = {
+        (parse_tag_version(item['tag']), item['tag'])
+        for item in mercurial_tags_json['tags']
+        if _invalid_tag_filter(item['tag'])
+    }
+    # Add the current version to the list
+    tags.add((current_version, current_version_tag))
+    tags = sorted(tags, key=lambda tag: tag[0])
+
+    # Find where the current version is and go back one to get the previous version
+    next_version_index = (map(itemgetter(0), tags).index(current_version) - 1)
+
+    return tags[next_version_index][1]
+
+
+def format_return_value(description, unique_bugs, unique_backout_bugs, changeset_html):
+    reg_bugs_link, backout_bugs_link = create_short_url_with_prefix(
+        unique_bugs, unique_backout_bugs)
+    changeset_full = FULL_CHANGESET_PREFIX + changeset_html
+    return_str = '{description}\n{regular_bz_url}{backout_bz_url}{changeset_full}'\
+        .format(description=description, regular_bz_url=reg_bugs_link,
+                backout_bz_url=backout_bugs_link, changeset_full=changeset_full)
+
+    return return_str
+
+
+def get_repo_by_version(version):
+    """
+    Get the repo a given version is found on.
+    """
+    if version.is_beta:
+        return 'https://hg.mozilla.org/releases/mozilla-beta'
+    elif version.is_release:
+        return 'https://hg.mozilla.org/releases/mozilla-release'
+    elif version.is_esr:
+        return 'https://hg.mozilla.org/releases/mozilla-esr{}'.format(version.major_number)
+    else:
+        raise Exception(
+            'Unsupported version type {}: {}'.format(
+                version.version_type.name, version))
+
+
+def email_release_drivers(
+    addresses, product, version, build_number,
+    repo, revision, task_group_id,
+):
+    # Send an email to the mailing after the build
+    email_buglist_string = create_bugs_url(product, version, revision, repo=repo)
+
+    content = """\
+A new build has been started:
+
+Commit: {repo}/rev/{revision}
+Task group: https://tools.taskcluster.net/push-inspector/#/{task_group_id}
+
+{email_buglist_string}
+""".format(repo=repo, revision=revision,
+           task_group_id=task_group_id,
+           email_buglist_string=email_buglist_string)
+
+    # On r-d, we prefix the subject of the email in order to simplify filtering
+    subject_prefix = ""
+    if product in {"fennec"}:
+        subject_prefix = "[mobile] "
+    if product in {"firefox", "devedition"}:
+        subject_prefix = "[desktop] "
+
+    subject = '{} Build of {} {} build {}'.format(subject_prefix, product, version, build_number)
+
+    notify_options = {}
+    if 'TASKCLUSTER_BASE_URL' in os.environ:
+        base_url = os.environ['TASKCLUSTER_PROXY_URL'].rstrip('/')
+        notify_options['baseUrl'] = '{}/notify/v1'.format(base_url)
+    notify = Notify(notify_options)
+    for address in addresses:
+        notify.email({
+            'address': address,
+            'subject': subject,
+            'content': content,
+        })
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/mozrelease/mach_commands.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+
+# 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
+
+import sys
+import logging
+
+from mach.decorators import (
+    CommandArgument,
+    CommandProvider,
+    Command,
+    SubCommand,
+)
+
+from mozbuild.base import MachCommandBase
+from mozilla_version.gecko import GeckoVersion
+
+
+@CommandProvider
+class MachCommands(MachCommandBase):
+
+    @Command('release', category="release",
+             description="Task that are part of the release process.")
+    def release(self):
+        """
+        The release subcommands all relate to the release process.
+        """
+
+    @SubCommand('release', 'buglist',
+                description="Generate list of bugs since the last release.")
+    @CommandArgument('--version',
+                     required=True,
+                     type=GeckoVersion.parse,
+                     help="The version being built.")
+    @CommandArgument('--product',
+                     required=True,
+                     help="The product being built.")
+    @CommandArgument('--repo',
+                     help="The repo being built.")
+    @CommandArgument('--revision',
+                     required=True,
+                     help="The revision being built.")
+    def buglist(self, version, product, revision, repo):
+        self.setup_logging()
+        from mozrelease.buglist_creator import create_bugs_url
+        print(create_bugs_url(
+            product=product,
+            current_version=version,
+            current_revision=revision,
+            repo=repo,
+        ))
+
+    @SubCommand('release', 'send-buglist-email',
+                description="Send an email with the bugs since the last release.")
+    @CommandArgument('--address',
+                     required=True,
+                     action='append',
+                     dest='addresses',
+                     help="The email address to send the bug list to "
+                          "(may be specified more than once.")
+    @CommandArgument('--version',
+                     type=GeckoVersion.parse,
+                     required=True,
+                     help="The version being built.")
+    @CommandArgument('--product',
+                     required=True,
+                     help="The product being built.")
+    @CommandArgument('--repo',
+                     required=True,
+                     help="The repo being built.")
+    @CommandArgument('--revision',
+                     required=True,
+                     help="The revision being built.")
+    @CommandArgument('--build-number',
+                     required=True,
+                     help="The build number")
+    @CommandArgument('--task-group-id',
+                     help="The task group of the build.")
+    def buglist_email(self, **options):
+        self.setup_logging()
+        from mozrelease.buglist_creator import email_release_drivers
+        email_release_drivers(**options)
+
+    def setup_logging(self, quiet=False, verbose=True):
+        """
+        Set up Python logging for all loggers, sending results to stderr (so
+        that command output can be redirected easily) and adding the typical
+        mach timestamp.
+        """
+        # remove the old terminal handler
+        old = self.log_manager.replace_terminal_handler(None)
+
+        # re-add it, with level and fh set appropriately
+        if not quiet:
+            level = logging.DEBUG if verbose else logging.INFO
+            self.log_manager.add_terminal_logging(
+                fh=sys.stderr, level=level,
+                write_interval=old.formatter.write_interval,
+                write_times=old.formatter.write_times)
+
+        # all of the taskgraph logging is unstructured logging
+        self.log_manager.enable_unstructured()
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/test/data/buglist_changesets.json
@@ -0,0 +1,176 @@
+{
+    "0": {
+        "changesets": [
+            {
+                "desc": "Bug 1354038 - [push-apk] taskgraph: Use rollout and deactivate dry-run on release p=jlorenzo r=aki a=release DONTBUILD"
+            }
+        ]
+    },
+    "1": {
+        "changesets": [
+            {
+                "desc": "Bug 1356563 - Only set global ready state on native widget loading; r=snorp a=sylvestre\n\nOur \"chrome-document-loaded\" observer may detect several different types\nof widgets that can exist in the parent process, including the Android\nnsWindow, PuppetWidget, etc. We should only set the global state to\nready when the first top-level nsWindow has loaded, and not just any\nwindow."
+            }
+        ]
+    },
+    "2": {
+        "changesets": [
+            {
+                "desc": "No bug, Automated blocklist update from host bld-linux64-spot-305 - a=blocklist-update"
+            }
+        ]
+    },
+    "3": {
+        "changesets": [
+            {
+                "desc": "Automatic version bump. CLOSED TREE NO BUG a=release"
+            },
+            {
+                "desc": "No bug - Tagging d345b657d381ade5195f1521313ac651618f54a2 with FIREFOX_53_0_BUILD6, FIREFOX_53_0_RELEASE a=release CLOSED TREE"
+            }
+        ]
+    },
+    "4": {
+        "changesets": [
+            {
+                "desc": "No bug, Automated blocklist update from host bld-linux64-spot-305 - a=blocklist-update"
+            }
+        ]
+    },
+    "5": {
+        "changesets": [
+            {
+                "desc": "Bug 1344529 - Remove unused variable in widget/gtk/gtk2drawing.c. r=frg a=release DONOTBUILD in a CLOSED TREE"
+            },
+            {
+                "desc": "Bug 1306543 - Avoid using g_unicode_script_from_iso15924 directly. r=jfkthame a=release in a CLOSED TREE DONTBUILD"
+            }
+        ]
+    },
+    "6": {
+        "changesets": [
+            {
+                "desc": "Bug 1320072 - Backout intent change - broke partner Google test. r=snorp, a=lizzard"
+            }
+        ]
+    },
+    "7": {
+        "changesets": [
+            {
+                "desc": "Bug 1328762 - Cherry-pick ANGLE a4aaa2de57dc51243da35ea147d289a21a9f0c49. a=lizzard\n\nMozReview-Commit-ID: WVK0smAfAW"
+            },
+            {
+                "desc": "Bug 1341190 - Remove .popup-anchor visibility rule. r=mconley, a=lizzard\n\nMozReview-Commit-ID: DFMIKMMnLx5"
+            },
+            {
+                "desc": "Bug 1348409 - Stop supporting the showDialog argument for window.find. r=mrbkap, a=lizzard\n\nThe dialog functionality of the non-standard window.find API has been broken\nwith e10s since it shipped, and bug 1182569 or bug 1232432 (or both) have\nbroken it for non-e10s.\n\nThis patch remove showDialog support entirely, for both e10s and non-e10s,\nin a more deliberate way. We now ignore the argument.\n\nMozReview-Commit-ID: 1CTzgEkDhHW"
+            },
+            {
+                "desc": "Bug 1358089 - [RTL] Separate xml drawable into v17 folder. r=ahunt, a=lizzard\n\nMozReview-Commit-ID: LaOwxXwhsHA"
+            },
+            {
+                "desc": "Bug 1360626 - Create a blacklist for adaptive playback support. r=jolin, a=lizzard\n\nOn some devices / os combinations, enabling adaptive playback causes decoded frame unusable.\nIt may cause the decode frame to be black and white or return tiled frames.\nSo we should do the blacklist according to the report.\n\nMozReview-Commit-ID: j3PZXTtkXG"
+            }
+        ]
+    },
+    "8": {
+        "changesets": [
+            {
+                "desc": "Bug 1354038 - part2: [push-apk] taskgraph: Use rollout and deactivate dry-run on release r=aki a=bustage DONTBUILD\n\nMozReview-Commit-ID: 1f22BcAZkvp"
+            }
+        ]
+    },
+    "9": {
+        "changesets": [
+            {
+                "desc": "bug 1354038 - empty commit to force builds. a=release"
+            }
+        ]
+    },
+    "10": {
+        "changesets": [
+            {
+                "desc": "Bug 1337861 - [Fennec-Relpro] Enforce the presence of $MOZ_BUILD_DATE r=jlund a=release\n\nMozReview-Commit-ID: DzEeeYQjwLW"
+            }
+        ]
+    },
+    "11": {
+        "changesets": [
+            {
+                "desc": "Bug 1332731 - Follow-up to fix accessibility breakage. r=sebastian, a=lizzard\n\nFollow-up to fix breakage in accessibility caused by the bundle\nconversion. In particular, optString(foo) should have been converted to\ngetString(foo, \"\") because optString returns \"\" by default.\n\nAlso fix a small bug in Presentation.jsm where an array or null should\nbe used instead of a string."
+            }
+        ]
+    },
+    "12": {
+        "changesets": [
+            {
+                "desc": "Bug 1355870 - Allow a system preference to determine distribution dir. r=nalexander, a=lizzard"
+            }
+        ]
+    },
+    "13": {
+        "changesets": [
+            {
+                "desc": "Bug 1354911 - Guard against null menu item names. r=sebastian, a=lizzard\n\nAddons may give us invalid menu item names; bail instead of crashing in\nsuch cases."
+            },
+            {
+                "desc": "Bug 1356563 - Remove chrome-document-loaded observer only after handling it. r=me, a=gchang\n\nOnly remove the \"chrome-document-loaded\" observer after handling it in\nnsAppShell. Otherwise we may never end up handling it."
+            }
+        ]
+    },
+    "14": {
+        "changesets": [
+            {
+                "desc": "Bug 1352333 - remove autophone webrtc test manifests, r=dminor, a=test-only."
+            }
+        ]
+    },
+    "15": {
+        "changesets": [
+            {
+                "desc": "Bug 1352333 - sync autophone webrtc test manifests with normal webrtc manifests, r=jmaher,dminor, a=test-only."
+            }
+        ]
+    },
+    "16": {
+        "changesets": [
+            {
+                "desc": "No bug - Tagging f239279b709072490993b099832fa8c18f07713a with FENNEC_53_0_BUILD1, FENNEC_53_0_RELEASE a=release CLOSED TREE"
+            }
+        ]
+    },
+    "17": {
+        "changesets": [
+            {
+                "desc": "Automated checkin: version bump for fennec 53.0.1 release. DONTBUILD CLOSED TREE a=release"
+            },
+            {
+                "desc": "Added FENNEC_53_0_1_RELEASE FENNEC_53_0_1_BUILD1 tag(s) for changeset f029d1a1324b. DONTBUILD CLOSED TREE a=release"
+            }
+        ]
+    },
+    "18": {
+        "changesets": [
+            {
+                "desc": "Backout Bug 1337861 (Enforce MOZ_BUILD_DATE) due to Bug 1360550. r=catlee a=catlee\n\nBug 1360550 resulted in the buildid the Linux builds had being different than the directory they were uploaded to. This had fallout affects for QA's firefox-ui tests and presumably anything using mozdownload.\n\nMozReview-Commit-ID: 8lMvLU0vGiS"
+            }
+        ]
+    },
+    "19": {
+        "changesets": [
+            {
+                "desc": "No bug, Automated blocklist update from host bld-linux64-spot-303 - a=blocklist-update"
+            }
+        ]
+    },
+    "20": {
+        "changesets": [
+            {
+                "desc": "Automatic version bump. CLOSED TREE NO BUG a=release"
+            },
+            {
+                "desc": "No bug - Tagging 5cbf464688a47129c0ea36fe38f42f59926e4b2c with FENNEC_53_0_1_BUILD2, FENNEC_53_0_1_RELEASE a=release CLOSED TREE"
+            }
+        ]
+    }
+}
\ No newline at end of file
--- a/python/mozrelease/test/python.ini
+++ b/python/mozrelease/test/python.ini
@@ -1,5 +1,6 @@
 [DEFAULT]
 subsuite=mozrelease
 skip-if = python == 3
 
 [test_versions.py]
+[test_buglist_creator.py]
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/test/test_buglist_creator.py
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+# 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
+
+import json
+from pathlib2 import Path
+
+import mozunit
+import pytest
+
+from mozilla_version.gecko import GeckoVersion
+from mozrelease.buglist_creator import (
+    is_excluded_change, create_bugs_url, is_backout_bug, get_previous_tag_version,
+    get_bugs_in_changeset, tag_version, parse_tag_version,
+)
+
+
+DATA_PATH = Path(__file__).with_name("data")
+
+
+def test_beta_1_release():
+    buglist_str_54_0b1 = create_bugs_url(
+        product='firefox',
+        current_version=GeckoVersion.parse('54.0b1'),
+        current_revision='cf76e00dcd6f',
+    )
+    assert buglist_str_54_0b1 == '', 'There should be no bugs to compare for beta 1.'
+
+
+@pytest.mark.parametrize('description,is_excluded', (
+    ('something something something a=test-only something something something', True),
+    ('this is a a=release change!', True),
+))
+def test_is_excluded_change(description, is_excluded):
+    assert is_excluded_change({'desc': description}) == is_excluded
+
+
+@pytest.mark.parametrize('description,is_backout', (
+    ('I backed out this bug because', True),
+    ('Backing out this bug due to', True),
+    ('Backout bug xyz', True),
+    ('Back out bug xyz', True),
+    ('this is a regular bug description', False),
+))
+def test_is_backout_bug(description, is_backout):
+    assert is_backout_bug(description) == is_backout
+
+
+@pytest.mark.parametrize('product,version,tag', (
+    ('firefox', GeckoVersion.parse('53.0b10'), 'FIREFOX_53_0b10_RELEASE'),
+    ('firefox', GeckoVersion.parse('52.0'), 'FIREFOX_52_0_RELEASE'),
+    ('fennec', GeckoVersion.parse('52.0.2'), 'FENNEC_52_0_2_RELEASE'),
+))
+def test_tag_version(product, version, tag):
+    assert tag_version(product, version) == tag
+
+
+@pytest.mark.parametrize('tag,version', (
+    ('FIREFOX_53_0b10_RELEASE', GeckoVersion.parse('53.0b10')),
+    ('FIREFOX_52_0_RELEASE', GeckoVersion.parse('52.0')),
+    ('FENNEC_52_0_2_RELEASE', GeckoVersion.parse('52.0.2')),
+))
+def test_parse_tag_version(tag, version):
+    assert parse_tag_version(tag) == version
+
+
+@pytest.mark.parametrize('version,tag,previous_tag', (
+    (GeckoVersion.parse('48.0b4'), 'FIREFOX_48_0b4_RELEASE', 'FIREFOX_48_0b3_RELEASE'),
+    (GeckoVersion.parse('48.0b9'), 'FIREFOX_48_0b9_RELEASE', 'FIREFOX_48_0b7_RELEASE'),
+    (GeckoVersion.parse('48.0.2'), 'FIREFOX_48_0_2_RELEASE', 'FIREFOX_48_0_1_RELEASE'),
+    (GeckoVersion.parse('48.0.1'), 'FIREFOX_48_0_1_RELEASE', 'FIREFOX_48_0_RELEASE'),
+))
+def test_get_previous_tag_version(version, tag, previous_tag):
+    product = 'firefox'
+    ff_48_tags = [
+        u'FIREFOX_BETA_48_END',
+        u'FIREFOX_RELEASE_48_END',
+        u'FIREFOX_48_0_2_RELEASE',
+        u'FIREFOX_48_0_2_BUILD1',
+        u'FIREFOX_48_0_1_RELEASE',
+        u'FIREFOX_48_0_1_BUILD3',
+        u'FIREFOX_48_0_RELEASE',
+        u'FIREFOX_48_0_BUILD2',
+        u'FIREFOX_RELEASE_48_BASE',
+        u'FIREFOX_48_0b10_RELEASE',
+        u'FIREFOX_48_0b10_BUILD1',
+        u'FIREFOX_48_0b9_RELEASE',
+        u'FIREFOX_48_0b9_BUILD1',
+        u'FIREFOX_48_0b7_RELEASE',
+        u'FIREFOX_48_0b7_BUILD1',
+        u'FIREFOX_48_0b6_RELEASE',
+        u'FIREFOX_48_0b6_BUILD1',
+        u'FIREFOX_48_0b5_RELEASE',
+        u'FIREFOX_48_0b5_BUILD1',
+        u'FIREFOX_48_0b4_RELEASE',
+        u'FIREFOX_48_0b4_BUILD1',
+        u'FIREFOX_48_0b3_RELEASE',
+        u'FIREFOX_48_0b3_BUILD1',
+        u'FIREFOX_48_0b2_RELEASE',
+        u'FIREFOX_48_0b2_BUILD2',
+        u'FIREFOX_48_0b1_RELEASE',
+        u'FIREFOX_48_0b1_BUILD2',
+        u'FIREFOX_AURORA_48_END',
+        u'FIREFOX_BETA_48_BASE',
+        u'FIREFOX_AURORA_48_BASE',
+    ]
+
+    mock_hg_json = {
+        'tags': [
+            {'tag': tag} for tag in ff_48_tags
+        ],
+    }
+
+    assert get_previous_tag_version(product, version, tag, mock_hg_json) == previous_tag
+
+
+def test_get_bugs_in_changeset():
+    with DATA_PATH.joinpath("buglist_changesets.json").open("r") as fp:
+        changeset_data = json.load(fp)
+    bugs, backouts = get_bugs_in_changeset(changeset_data)
+
+    assert bugs == {u'1356563', u'1348409', u'1341190', u'1360626', u'1332731', u'1328762',
+                    u'1355870', u'1358089', u'1354911', u'1354038'}
+    assert backouts == {u'1337861', u'1320072'}
+
+
+if __name__ == '__main__':
+    mozunit.main()
--- a/servo/components/style/font_face.rs
+++ b/servo/components/style/font_face.rs
@@ -146,20 +146,30 @@ impl_range!(FontWeightRange, AbsoluteFon
 /// The computed representation of the above so Gecko can read them easily.
 ///
 /// This one is needed because cbindgen doesn't know how to generate
 /// specified::Number.
 #[repr(C)]
 #[allow(missing_docs)]
 pub struct ComputedFontWeightRange(f32, f32);
 
+#[inline]
+fn sort_range<T: PartialOrd>(a: T, b: T) -> (T, T) {
+    if a > b {
+        (b, a)
+    } else {
+        (a, b)
+    }
+}
+
 impl FontWeightRange {
     /// Returns a computed font-stretch range.
     pub fn compute(&self) -> ComputedFontWeightRange {
-        ComputedFontWeightRange(self.0.compute().0, self.1.compute().0)
+        let (min, max) = sort_range(self.0.compute().0, self.1.compute().0);
+        ComputedFontWeightRange(min, max)
     }
 }
 
 /// The font-stretch descriptor:
 ///
 /// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-stretch
 #[derive(Clone, Debug, PartialEq)]
 pub struct FontStretchRange(pub FontStretch, pub FontStretch);
@@ -177,17 +187,21 @@ impl FontStretchRange {
         fn compute_stretch(s: &FontStretch) -> f32 {
             match *s {
                 FontStretch::Keyword(ref kw) => kw.compute().0,
                 FontStretch::Stretch(ref p) => p.get(),
                 FontStretch::System(..) => unreachable!(),
             }
         }
 
-        ComputedFontStretchRange(compute_stretch(&self.0), compute_stretch(&self.1))
+        let (min, max) = sort_range(
+            compute_stretch(&self.0),
+            compute_stretch(&self.1),
+        );
+        ComputedFontStretchRange(min, max)
     }
 }
 
 /// The font-style descriptor:
 ///
 /// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-style
 #[derive(Clone, Debug, PartialEq)]
 #[allow(missing_docs)]
@@ -253,20 +267,21 @@ impl ToCss for FontStyle {
 
 impl FontStyle {
     /// Returns a computed font-style descriptor.
     pub fn compute(&self) -> ComputedFontStyleDescriptor {
         match *self {
             FontStyle::Normal => ComputedFontStyleDescriptor::Normal,
             FontStyle::Italic => ComputedFontStyleDescriptor::Italic,
             FontStyle::Oblique(ref first, ref second) => {
-                ComputedFontStyleDescriptor::Oblique(
+                let (min, max) = sort_range(
                     SpecifiedFontStyle::compute_angle_degrees(first),
                     SpecifiedFontStyle::compute_angle_degrees(second),
-                )
+                );
+                ComputedFontStyleDescriptor::Oblique(min, max)
             }
         }
     }
 }
 
 /// Parse the block inside a `@font-face` rule.
 ///
 /// Note that the prelude parsing code lives in the `stylesheets` module.
--- a/servo/components/style/properties/longhands/inherited_box.mako.rs
+++ b/servo/components/style/properties/longhands/inherited_box.mako.rs
@@ -54,26 +54,24 @@
 ${helpers.single_keyword(
     "color-adjust",
     "economy exact", products="gecko",
     gecko_pref="layout.css.color-adjust.enabled",
     animation_value_type="discrete",
     spec="https://drafts.csswg.org/css-color/#propdef-color-adjust",
 )}
 
-<% image_rendering_custom_consts = { "crisp-edges": "CRISPEDGES",
-                                     "-moz-crisp-edges": "CRISPEDGES" } %>
 // According to to CSS-IMAGES-3, `optimizespeed` and `optimizequality` are synonyms for `auto`
 // And, firefox doesn't support `pixelated` yet (https://bugzilla.mozilla.org/show_bug.cgi?id=856337)
 ${helpers.single_keyword(
     "image-rendering",
-    "auto",
-    extra_gecko_values="optimizespeed optimizequality -moz-crisp-edges",
-    extra_servo_values="pixelated crisp-edges",
-    custom_consts=image_rendering_custom_consts,
+    "auto crisp-edges",
+    extra_gecko_values="optimizespeed optimizequality",
+    extra_servo_values="pixelated",
+    extra_gecko_aliases="-moz-crisp-edges=crisp-edges",
     animation_value_type="discrete",
     spec="https://drafts.csswg.org/css-images/#propdef-image-rendering",
 )}
 
 ${helpers.single_keyword(
     "image-orientation",
     "none from-image",
     products="gecko",
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -21,17 +21,16 @@
 #include "nsIOutputStream.h"
 #include "nsIStorageStream.h"
 #include "nsIStreamBufferAccess.h"
 #include "nsIStringStream.h"
 #include "nsISupports.h"
 #include "nsITimer.h"
 #include "nsIZipWriter.h"
 #include "nsIZipReader.h"
-#include "nsWeakReference.h"
 #include "nsZipArchive.h"
 #include "mozilla/Omnijar.h"
 #include "prenv.h"
 #include "mozilla/Telemetry.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 #include "nsIProtocolHandler.h"
 #include "GeckoProfiler.h"
new file mode 100644
--- /dev/null
+++ b/taskcluster/ci/release-notify-started/kind.yml
@@ -0,0 +1,36 @@
+# 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/.
+
+loader: taskgraph.loader.transform:loader
+
+transforms:
+    - taskgraph.transforms.release_deps:transforms
+    - taskgraph.transforms.release_started:transforms
+    - taskgraph.transforms.job:transforms
+    - taskgraph.transforms.task:transforms
+
+job-defaults:
+    name: notify-release-drivers-started
+    description: Sends email to release-drivers telling release was started.
+    run-on-projects: []
+    shipping-phase: promote
+    worker-type: aws-provisioner-v1/gecko-{level}-b-linux
+    worker:
+        docker-image: {in-tree: "debian9-base"}
+        max-run-time: 600
+    emails:
+        by-project:
+            mozilla-beta: ["release-signoff@mozilla.org"]
+            mozilla-release: ["release-signoff@mozilla.org"]
+            mozilla-esr60: ["release-signoff@mozilla.org"]
+            try: ["{config[params][owner]}"]
+            default: []
+
+jobs:
+    fennec:
+        shipping-product: fennec
+    firefox:
+        shipping-product: firefox
+    devedition:
+        shipping-product: devedition
--- a/taskcluster/ci/release-sign-and-push-langpacks/kind.yml
+++ b/taskcluster/ci/release-sign-and-push-langpacks/kind.yml
@@ -25,20 +25,27 @@ job-template:
    worker-type:
       by-release-level:
          production: scriptworker-prov-v1/addon-v1
          staging: scriptworker-prov-v1/addon-dev
    worker:
       implementation: sign-and-push-addons
       channel:
          by-project:
-            # Only release langpacks are listed publicly
             mozilla-release:
                by-platform:
-                  macosx64.*: unlisted  # ja-JP-mac is only langpack on mac, and is unlisted always
+                  # ja-JP-mac is only langpack on mac, and is unlisted always
+                  macosx64.*: unlisted
+                  default: listed
+            mozilla-beta:
+               by-platform:
+                  # ja-JP-mac is only langpack on mac, and is unlisted always
+                  macosx64-nightly.*: unlisted
+                  macosx64-devedition.*: unlisted
+                  linux.*-devedition.*: unlisted
                   default: listed
             default: unlisted
       upstream-artifacts:   # See transforms
    run-on-projects: []
    scopes:
       by-release-level:
          production:
             - project:releng:addons.mozilla.org:server:production
--- a/taskcluster/ci/searchfox/kind.yml
+++ b/taskcluster/ci/searchfox/kind.yml
@@ -82,31 +82,31 @@ jobs:
             - linux64-clang
             - linux64-hfsplus
             - linux64-libdmg
             - linux64-llvm-dsymutil
             - linux64-node
             - linux64-rust-macos
             - linux64-cbindgen
 
-    # NOTE: Windows Searchfox jobs aren't working quite yet (bug 1418415).
-
     win64-searchfox/debug:
         description: "Win64 Searchfox Debug (clang-cl)"
         index:
             product: firefox
             job-name: win64-searchfox-debug
         treeherder:
             platform: windows2012-64/debug
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
-            max-run-time: 7200
+            max-run-time: 36000
             env:
                 TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
                 PERFHERDER_EXTRA_OPTIONS: searchfox
+                RUSTC_BOOTSTRAP: "1"
+                MOZSEARCH_PLATFORM: "windows"
         run:
             using: mozharness
             options: [append-env-variables-from-configs]
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/releng_base_firefox.py
                 - builds/taskcluster_base_windows.py
                 - builds/taskcluster_base_win64.py
--- a/taskcluster/docker/debian-base/Dockerfile
+++ b/taskcluster/docker/debian-base/Dockerfile
@@ -8,16 +8,20 @@ RUN mkdir /builds && \
     groupadd -g 1000 worker && \
     useradd -u 1000 -g 1000 -d /builds/worker -s /bin/bash -m worker && \
     mkdir -p /builds/worker/workspace && \
     chown -R worker:worker /builds
 
 # Declare default working folder
 WORKDIR /builds/worker
 
+VOLUME /builds/worker/checkouts
+VOLUME /builds/worker/workspace
+VOLUME /builds/worker/tooltool-cache
+
 # Set variable normally configured at login, by the shells parent process, these
 # are taken from GNU su manual
 ENV HOME=/builds/worker \
     SHELL=/bin/bash \
     USER=worker \
     LOGNAME=worker \
     HOSTNAME=taskcluster-worker \
     DEBIAN_FRONTEND=noninteractive
--- a/taskcluster/docs/kinds.rst
+++ b/taskcluster/docs/kinds.rst
@@ -282,16 +282,20 @@ Notify when a release has been shipped.
 release-secondary-notify-ship
 -----------------------------
 Notify when an RC release has been shipped to the beta channel.
 
 release-notify-promote
 ----------------------
 Notify when a release has been promoted.
 
+release-notify-started
+-------------------
+Notify when a release has been started.
+
 release-bouncer-sub
 -------------------
 Submits bouncer updates for releases.
 
 release-mark-as-shipped
 -----------------------
 Marks releases as shipped in Ship-It v1
 
--- a/taskcluster/taskgraph/target_tasks.py
+++ b/taskcluster/taskgraph/target_tasks.py
@@ -535,20 +535,19 @@ def target_tasks_nightly_desktop(full_ta
         | set(target_tasks_nightly_asan(full_task_graph, parameters, graph_config))
     )
 
 
 # Run Searchfox analysis once daily.
 @_target_task('searchfox_index')
 def target_tasks_searchfox(full_task_graph, parameters, graph_config):
     """Select tasks required for indexing Firefox for Searchfox web site each day"""
-    # For now we only do Linux and Mac debug builds. Windows builds
-    # are currently broken (bug 1418415).
     return ['searchfox-linux64-searchfox/debug',
-            'searchfox-macosx64-searchfox/debug']
+            'searchfox-macosx64-searchfox/debug',
+            'searchfox-win64-searchfox/debug']
 
 
 @_target_task('pipfile_update')
 def target_tasks_pipfile_update(full_task_graph, parameters, graph_config):
     """Select the set of tasks required to perform nightly in-tree pipfile updates
     """
     def filter(task):
         # For now any task in the repo-update kind is ok
--- a/taskcluster/taskgraph/transforms/job/mach.py
+++ b/taskcluster/taskgraph/transforms/job/mach.py
@@ -4,24 +4,28 @@
 """
 Support for running mach tasks (via run-task)
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.transforms.job import run_job_using, configure_taskdesc_for_run
 from taskgraph.util.schema import Schema
-from voluptuous import Required
+from voluptuous import Required, Optional, Any
 
 mach_schema = Schema({
     Required('using'): 'mach',
 
     # The mach command (omitting `./mach`) to run
     Required('mach'): basestring,
 
+    # The sparse checkout profile to use. Value is the filename relative to the
+    # directory where sparse profiles are defined (build/sparse-profiles/).
+    Optional('sparse-profile'): Any(basestring, None),
+
     # if true, perform a checkout of a comm-central based branch inside the
     # gecko checkout
     Required('comm-checkout'): bool,
 
     # Base work directory used to set up the task.
     Required('workdir'): basestring,
 })
 
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/transforms/release_started.py
@@ -0,0 +1,51 @@
+# 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/.
+"""
+Add notifications via taskcluster-notify for release tasks
+"""
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+import os
+from pipes import quote as shell_quote
+
+from taskgraph.transforms.base import TransformSequence
+from taskgraph.util.schema import resolve_keyed_by
+
+
+transforms = TransformSequence()
+
+
+@transforms.add
+def add_notifications(config, jobs):
+    for job in jobs:
+        label = '{}-{}'.format(config.kind, job['name'])
+
+        resolve_keyed_by(job, 'emails', label, project=config.params['project'])
+        emails = [email.format(config=config.__dict__) for email in job.pop('emails')]
+
+        command = [
+            'release',
+            'send-buglist-email',
+            '--version', config.params['version'],
+            '--product', job['shipping-product'],
+            '--revision', config.params['head_rev'],
+            '--build-number', str(config.params['build_number']),
+            '--repo', config.params['head_repository'],
+        ]
+        for address in emails:
+            command += ['--address', address]
+        if 'TASK_ID' in os.environ:
+            command += [
+                '--task-group-id', os.environ['TASK_ID'],
+            ]
+
+        job['scopes'] = ['notify:email:{}'.format(address) for address in emails]
+        job['run'] = {
+            'using': 'mach',
+            'sparse-profile': 'mach',
+            'mach': ' '.join(map(shell_quote, command)),
+        }
+
+        yield job
--- a/taskcluster/taskgraph/transforms/task.py
+++ b/taskcluster/taskgraph/transforms/task.py
@@ -501,16 +501,17 @@ def build_docker_worker_payload(config, 
 
     features = {}
 
     if worker.get('relengapi-proxy'):
         features['relengAPIProxy'] = True
 
     if worker.get('taskcluster-proxy'):
         features['taskclusterProxy'] = True
+        worker['env']['TASKCLUSTER_PROXY_URL'] = 'http://taskcluster/'
 
     if worker.get('allow-ptrace'):
         features['allowPtrace'] = True
         task_def['scopes'].append('docker-worker:feature:allowPtrace')
 
     if worker.get('chain-of-trust'):
         features['chainOfTrust'] = True
 
@@ -811,16 +812,17 @@ def build_generic_worker_payload(config,
 
     features = {}
 
     if worker.get('chain-of-trust'):
         features['chainOfTrust'] = True
 
     if worker.get('taskcluster-proxy'):
         features['taskclusterProxy'] = True
+        worker['env']['TASKCLUSTER_PROXY_URL'] = 'http://taskcluster/'
 
     if worker.get('run-as-administrator', False):
         features['runAsAdministrator'] = True
 
     if features:
         task_def['payload']['features'] = features
 
     # coalesce / superseding
--- a/testing/raptor/raptor/tests/raptor-gdocs.ini
+++ b/testing/raptor/raptor/tests/raptor-gdocs.ini
@@ -11,17 +11,17 @@ playback_binary_manifest = mitmproxy-rel
 python3_win_manifest = python3{x64}.manifest
 playback_pageset_manifest = mitmproxy-recordings-raptor-gdocs.manifest
 page_cycles = 25
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 page_timeout = 60000
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 14000000
 
 [raptor-google-docs-firefox]
 apps = firefox
 test_url = https://docs.google.com/document/d/1US-07msg12slQtI_xchzYxcKlTs6Fp7WqIc6W5GK5M8/edit?usp=sharing
 playback_recordings = google-docs.mp
 measure = fnbpaint, hero
 hero = hero1
 
--- a/testing/raptor/raptor/tests/raptor-motionmark-animometer.ini
+++ b/testing/raptor/raptor/tests/raptor-motionmark-animometer.ini
@@ -8,15 +8,15 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/MotionMark/developer.html?test-interval=15&display=minimal&tiles=big&controller=fixed&frame-rate=30&kalman-process-error=1&kalman-measurement-error=4&time-measurement=performance&suite-name=Animometer&raptor=true&oskey={platform}
 page_cycles = 5
 page_timeout = 600000
 unit = score
 lower_is_better = false
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 8000000
 
 [raptor-motionmark-animometer-firefox]
 apps = firefox
 
 [raptor-motionmark-animometer-chrome]
 apps = chrome
--- a/testing/raptor/raptor/tests/raptor-motionmark-htmlsuite.ini
+++ b/testing/raptor/raptor/tests/raptor-motionmark-htmlsuite.ini
@@ -8,15 +8,15 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/MotionMark/developer.html?test-interval=15&display=minimal&tiles=big&controller=fixed&frame-rate=30&kalman-process-error=1&kalman-measurement-error=4&time-measurement=performance&suite-name=HTMLsuite&raptor=true&oskey={platform}
 page_cycles = 5
 page_timeout = 600000
 unit = score
 lower_is_better = false
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 8000000
 
 [raptor-motionmark-htmlsuite-firefox]
 apps = firefox
 
 [raptor-motionmark-htmlsuite-chrome]
 apps = chrome
--- a/testing/raptor/raptor/tests/raptor-speedometer.ini
+++ b/testing/raptor/raptor/tests/raptor-speedometer.ini
@@ -10,17 +10,17 @@ test_url = http://127.0.0.1:<port>/Speed
 page_cycles = 5
 page_timeout = 180000
 unit = score
 subtest_unit = ms
 lower_is_better = false
 subtest_lower_is_better = true
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 14000000
 
 [raptor-speedometer-firefox]
 apps = firefox
 
 [raptor-speedometer-chrome]
 apps = chrome
 
 [raptor-speedometer-geckoview]
--- a/testing/raptor/raptor/tests/raptor-stylebench.ini
+++ b/testing/raptor/raptor/tests/raptor-stylebench.ini
@@ -8,15 +8,15 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/StyleBench/index.html?raptor
 page_cycles = 5
 page_timeout = 120000
 unit = score
 lower_is_better = false
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 8000000
 
 [raptor-stylebench-firefox]
 apps = firefox
 
 [raptor-stylebench-chrome]
 apps = chrome
--- a/testing/raptor/raptor/tests/raptor-sunspider.ini
+++ b/testing/raptor/raptor/tests/raptor-sunspider.ini
@@ -8,15 +8,15 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/SunSpider/sunspider-1.0.1/sunspider-1.0.1/driver.html?raptor
 page_cycles = 5
 page_timeout = 35000
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 8000000
 
 [raptor-sunspider-firefox]
 apps = firefox
 
 [raptor-sunspider-chrome]
 apps = chrome
--- a/testing/raptor/raptor/tests/raptor-tp6.ini
+++ b/testing/raptor/raptor/tests/raptor-tp6.ini
@@ -13,17 +13,17 @@ playback_pageset_manifest = mitmproxy-re
 page_cycles = 25
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 # TTI/TTFI can take a while on some pages, and requires at least 5 seconds
 # beyond typical pageload time
 page_timeout = 30000
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 14000000
 
 [raptor-tp6-amazon-firefox]
 apps = firefox
 test_url = https://www.amazon.com/s/url=search-alias%3Daps&field-keywords=laptop
 playback_recordings = amazon.mp
 measure = fnbpaint, hero, dcf, ttfi
 hero = hero1
 
--- a/testing/raptor/raptor/tests/raptor-unity-webgl.ini
+++ b/testing/raptor/raptor/tests/raptor-unity-webgl.ini
@@ -2,17 +2,17 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/unity-webgl/index.html?raptor
 page_cycles = 5
 page_timeout = 900000
 unit = score
 lower_is_better = false
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 8000000
 
 [raptor-unity-webgl-firefox]
 apps = firefox
 
 [raptor-unity-webgl-chrome]
 apps = chrome
 
 [raptor-unity-webgl-geckoview]
--- a/testing/raptor/raptor/tests/raptor-wasm-godot-baseline.ini
+++ b/testing/raptor/raptor/tests/raptor-wasm-godot-baseline.ini
@@ -8,13 +8,15 @@
 type =  benchmark
 test_url = http://localhost:<port>/wasm-godot/index.html
 page_cycles = 5
 page_timeout = 120000
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 newtab_per_cycle = true
+gecko_profile_interval = 1
+gecko_profile_entries = 8000000
 
 [raptor-wasm-godot-baseline-firefox]
 apps = firefox
 preferences = {"javascript.options.wasm_baselinejit": true,
                "javascript.options.wasm_ionjit": false}
--- a/testing/raptor/raptor/tests/raptor-wasm-godot-ion.ini
+++ b/testing/raptor/raptor/tests/raptor-wasm-godot-ion.ini
@@ -8,13 +8,15 @@
 type =  benchmark
 test_url = http://localhost:<port>/wasm-godot/index.html
 page_cycles = 5
 page_timeout = 120000
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 newtab_per_cycle = true
+gecko_profile_interval = 1
+gecko_profile_entries = 8000000
 
 [raptor-wasm-godot-ion-firefox]
 apps = firefox
 preferences = {"javascript.options.wasm_baselinejit": false,
                "javascript.options.wasm_ionjit": true}
--- a/testing/raptor/raptor/tests/raptor-wasm-godot.ini
+++ b/testing/raptor/raptor/tests/raptor-wasm-godot.ini
@@ -8,14 +8,16 @@
 type =  benchmark
 test_url = http://localhost:<port>/wasm-godot/index.html
 page_cycles = 5
 page_timeout = 120000
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 newtab_per_cycle = true
+gecko_profile_interval = 1
+gecko_profile_entries = 8000000
 
 [raptor-wasm-godot-firefox]
 apps = firefox
 
 [raptor-wasm-godot-chrome]
 apps = chrome
--- a/testing/raptor/raptor/tests/raptor-wasm-misc-baseline.ini
+++ b/testing/raptor/raptor/tests/raptor-wasm-misc-baseline.ini
@@ -8,14 +8,14 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/wasm-misc/index.html?raptor
 page_cycles = 5
 page_timeout = 1200000
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 4000000
 
 [raptor-wasm-misc-baseline-firefox]
 apps = firefox
 preferences = {"javascript.options.wasm_baselinejit": true,
                "javascript.options.wasm_ionjit": false}
--- a/testing/raptor/raptor/tests/raptor-wasm-misc-ion.ini
+++ b/testing/raptor/raptor/tests/raptor-wasm-misc-ion.ini
@@ -8,14 +8,14 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/wasm-misc/index.html?raptor
 page_cycles = 5
 page_timeout = 1200000
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 4000000
 
 [raptor-wasm-misc-ion-firefox]
 apps = firefox
 preferences = {"javascript.options.wasm_baselinejit": false,
                "javascript.options.wasm_ionjit": true}
--- a/testing/raptor/raptor/tests/raptor-wasm-misc.ini
+++ b/testing/raptor/raptor/tests/raptor-wasm-misc.ini
@@ -8,15 +8,15 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/wasm-misc/index.html?raptor
 page_cycles = 5
 page_timeout = 1200000
 unit = ms
 lower_is_better = true
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 4000000
 
 [raptor-wasm-misc-firefox]
 apps = firefox
 
 [raptor-wasm-misc-chrome]
 apps = chrome
--- a/testing/raptor/raptor/tests/raptor-webaudio.ini
+++ b/testing/raptor/raptor/tests/raptor-webaudio.ini
@@ -8,15 +8,15 @@
 type =  benchmark
 test_url = http://127.0.0.1:<port>/webaudio/index.html?raptor
 page_cycles = 5
 page_timeout = 180000
 unit = score
 lower_is_better = true
 alert_threshold = 2.0
 gecko_profile_interval = 1
-gecko_profile_entries = 2000000
+gecko_profile_entries = 4000000
 
 [raptor-webaudio-firefox]
 apps = firefox
 
 [raptor-webaudio-chrome]
 apps = chrome
--- a/testing/raptor/webext/raptor/runner.js
+++ b/testing/raptor/webext/raptor/runner.js
@@ -256,50 +256,40 @@ async function startGeckoProfiling() {
   });
 }
 
 async function stopGeckoProfiling() {
   postToControlServer("status", "stopping gecko profiling");
   await browser.geckoProfiler.stop();
 }
 
-async function pauseGeckoProfiling() {
-  postToControlServer("status", "pausing gecko profiling");
-  await browser.geckoProfiler.pause();
-}
-
-async function resumeGeckoProfiling() {
-  postToControlServer("status", "resuming gecko profiling");
-  await browser.geckoProfiler.resume();
-}
-
 async function getGeckoProfile() {
-  // pause the profiler
-  await pauseGeckoProfiling();
   // get the profile and send to control server
   postToControlServer("status", "retrieving gecko profile");
   let arrayBuffer = await browser.geckoProfiler.getProfileAsArrayBuffer();
   let textDecoder = new TextDecoder();
   let profile = JSON.parse(textDecoder.decode(arrayBuffer));
   console.log(profile);
   postToControlServer("gecko_profile", [testName, pageCycle, profile]);
+  // stop the profiler; must stop so it clears before next cycle
+  await stopGeckoProfiling();
   // resume if we have more pagecycles left
   if (pageCycle + 1 <= pageCycles) {
-    await resumeGeckoProfiling();
+    await startGeckoProfiling();
   }
 }
 
-function nextCycle() {
+async function nextCycle() {
   pageCycle++;
   if (pageCycle == 1) {
     let text = "running " + pageCycles + " pagecycles of " + testURL;
     postToControlServer("status", text);
     // start the profiler if enabled
     if (geckoProfiling) {
-      startGeckoProfiling();
+      await startGeckoProfiling();
     }
   }
   if (pageCycle <= pageCycles) {
     setTimeout(function() {
 
       let text = "begin pagecycle " + pageCycle;
       postToControlServer("status", text);
 
@@ -477,17 +467,18 @@ function cleanUp() {
     // remove listeners
     ext.runtime.onMessage.removeListener(resultListener);
     ext.tabs.onCreated.removeListener(testTabCreated);
     ext.alarms.onAlarm.removeListener(timeoutAlarmListener);
     console.log("pageloader test finished");
   } else if (testType == "benchmark") {
     console.log("benchmark complete");
   }
-  // if profiling was enabled, stop the profiler
+  // if profiling was enabled, stop the profiler - may have already
+  // been stopped but stop again here in cleanup in case of timeout
   if (geckoProfiling) {
     stopGeckoProfiling();
   }
 
   window.onload = null;
   // tell the control server we are done and the browser can be shutdown
   postToControlServer("status", "__raptor_shutdownBrowser");
 }
--- a/testing/web-platform/meta/css/css-images/parsing/image-rendering-valid.html.ini
+++ b/testing/web-platform/meta/css/css-images/parsing/image-rendering-valid.html.ini
@@ -1,13 +1,10 @@
 [image-rendering-valid.html]
   [e.style['image-rendering'\] = "smooth" should set the property value]
     expected: FAIL
 
   [e.style['image-rendering'\] = "high-quality" should set the property value]
     expected: FAIL
 
-  [e.style['image-rendering'\] = "crisp-edges" should set the property value]
-    expected: FAIL
-
   [e.style['image-rendering'\] = "pixelated" should set the property value]
     expected: FAIL
 
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-height.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-height.html.ini
@@ -1,3 +1,39 @@
 [open-features-non-integer-height.html]
   disabled:
     if webrender and not debug: bug 1425588
+  [features "height=405*3" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "height=405.32" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "height=405e1" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "height=405/5" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "height=405^4" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "height=405.5" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "height=405e-1" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "height=405  " should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "height=405LLl" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerheight.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerheight.html.ini
@@ -1,3 +1,39 @@
 [open-features-non-integer-innerheight.html]
   disabled:
     if webrender and not debug: bug 1425588
+  [features "innerheight=405e-1" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerheight=405LLl" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerheight=405^4" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerheight=405e1" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerheight=405  " should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerheight=405/5" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerheight=405.32" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerheight=405.5" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerheight=405*3" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerwidth.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerwidth.html.ini
@@ -1,3 +1,39 @@
 [open-features-non-integer-innerwidth.html]
   disabled:
     if webrender and not debug: bug 1425588
+  [features "innerwidth=405e-1" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerwidth=405*3" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerwidth=405.5" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerwidth=405e1" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerwidth=405.32" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerwidth=405  " should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerwidth=405LLl" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerwidth=405/5" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "innerwidth=405^4" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-left.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-left.html.ini
@@ -1,3 +1,39 @@
 [open-features-non-integer-left.html]
   disabled:
     if webrender and not debug: bug 1425588
+  [features "left=105e1" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "left=105  " should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "left=105/5" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "left=105e-1" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "left=105^4" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "left=105LLl" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "left=105.32" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "left=105*3" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "left=105.5" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screenx.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screenx.html.ini
@@ -1,3 +1,39 @@
 [open-features-non-integer-screenx.html]
   disabled:
     if webrender and not debug: bug 1425588
+  [features "screenx=105.5" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screenx=105e1" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screenx=105  " should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screenx=105*3" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screenx=105e-1" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screenx=105^4" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screenx=105LLl" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screenx=105/5" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screenx=105.32" should set "left=105"]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screeny.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screeny.html.ini
@@ -1,3 +1,39 @@
 [open-features-non-integer-screeny.html]
   disabled:
     if webrender and not debug: bug 1425588
+  [features "screeny=405^4" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screeny=405e-1" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screeny=405LLl" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screeny=405e1" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screeny=405  " should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screeny=405/5" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screeny=405*3" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screeny=405.32" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "screeny=405.5" should set "height=405"]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-top.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-top.html.ini
@@ -1,3 +1,39 @@
 [open-features-non-integer-top.html]
   disabled:
     if webrender and not debug: bug 1425588
+  [features "top=105/5" should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "top=105*3" should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "top=105LLl" should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "top=105e-1" should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "top=105.32" should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "top=105e1" should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "top=105  " should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "top=105^4" should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
+  [features "top=105.5" should set "top=105"]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-width.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-width.html.ini
@@ -1,3 +1,39 @@
 [open-features-non-integer-width.html]
   disabled:
     if webrender and not debug: bug 1425588
+  [features "width=405^4" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "width=405.5" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "width=405e1" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "width=405  " should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "width=405.32" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "width=405LLl" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "width=405*3" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "width=405e-1" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
+  [features "width=405/5" should set "width=405"]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-innerheight-innerwidth.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-innerheight-innerwidth.html.ini
@@ -2,8 +2,56 @@
   disabled:
     if webrender and not debug: bug 1425588
   ["innerwidth==401" should set width of opened window]
     expected: FAIL
 
   ["innerheight==402" should set height of opened window]
     expected: FAIL
 
+  ["INNERHEIGHT=402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["innerHeight=402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" innerwidth = 401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [",innerheight=402,," should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [",innerwidth=401,," should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["innerheight=402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["innerWidth=401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["INNERWIDTH=401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["innerwidth=401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["\\ninnerwidth= 401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" innerheight = 402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["\\ninnerheight= 402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-screenx-screeny.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-screenx-screeny.html.ini
@@ -3,8 +3,56 @@
     if webrender and not debug: bug 1425588
     if verify and (os == "linux") and not debug: fails in verify mode
   ["screenx==141" should set left position of opened window]
     expected: FAIL
 
   ["screeny==142" should set top position of opened window]
     expected: FAIL
 
+  ["screenx=141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["screeny=142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["\\nscreenx= 141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" screeny = 142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["screenX=141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [",screenx=141,," should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [",screeny=142,," should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["screenY=142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" screenx = 141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["SCREENX=141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["SCREENY=142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["\\nscreeny= 142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-top-left.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-top-left.html.ini
@@ -6,8 +6,60 @@
     expected: FAIL
 
   ["top==142" should set top position of opened window]
     expected: FAIL
 
   ["top=152==left=152" should set top and left position of opened window]
     expected: FAIL
 
+  [",left=141,," should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" left = 141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [",,top= 152, left=152" should set top and left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["left=141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["top=142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["top=152,,left=152," should set top and left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["TOP=142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["\\ttop= 142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["top=152,left=152" should set top and left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["LEFT=141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" top = 142" should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["\nleft= 141" should set left position of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [",top=142,," should set top position of opened window]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-width-height.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-width-height.html.ini
@@ -8,8 +8,64 @@
     expected: FAIL
 
   ["height==402 width = 401" should set height and width of opened window]
     expected: FAIL
 
   [",height=402,,width==401" should set height and width of opened window]
     expected: FAIL
 
+  ["\\nheight= 402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["height=402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["width=401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["WIDTH=401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" height = 402 , width = 401 ," should set height and width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["\\nheight= 402,,width=\\n401" should set height and width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [",width=401,," should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" width = 401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["\\nwidth= 401" should set width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["height=402,width=401" should set height and width of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [",height=402,," should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["HEIGHT=402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  [" height = 402" should set height of opened window]
+    expected:
+      if os == "android": FAIL
+
+  ["HEIGHT=402, WIDTH=401" should set height and width of opened window]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/security-window/window-security.https.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/security-window/window-security.https.html.ini
@@ -3,8 +3,12 @@
     expected: FAIL
 
   [A SecurityError exception must be thrown when window.oncuechange is accessed from a different origin.]
     expected: FAIL
 
   [A SecurityError exception must be thrown when window.onmousewheel is accessed from a different origin.]
     expected: FAIL
 
+  [A SecurityError exception must be thrown when window.print is accessed from a different origin.]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/window-properties.https.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/window-properties.https.html.ini
@@ -3,8 +3,12 @@
     expected: FAIL
 
   [Window attribute: oncuechange]
     expected: FAIL
 
   [Window attribute: onmousewheel]
     expected: FAIL
 
+  [Window method: print]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html.ini
+++ b/testing/web-platform/meta/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html.ini
@@ -7,8 +7,12 @@
     expected: FAIL
 
   [opening dialog with multiple focusable children]
     expected: FAIL
 
   [opening dialog with multiple focusable children, one having the autofocus attribute]
     expected: FAIL
 
+  [when opening multiple dialogs, the most recently opened is rendered on top]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/presentation-api/controlling-ua/PresentationRequest_sandboxing_success.https.html.ini
+++ b/testing/web-platform/meta/presentation-api/controlling-ua/PresentationRequest_sandboxing_success.https.html.ini
@@ -1,4 +1,6 @@
 [PresentationRequest_sandboxing_success.https.html]
   [Sandboxing: Creating a PresentationRequest from a nested context succeeds when allow-presentation is set]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
--- a/testing/web-platform/meta/presentation-api/controlling-ua/PresentationRequest_success.https.html.ini
+++ b/testing/web-platform/meta/presentation-api/controlling-ua/PresentationRequest_success.https.html.ini
@@ -4,10 +4,12 @@
 
   [Call PresentationRequest constructor with a valid absolute presentation URL. No Exception expected.]
     expected: FAIL
 
   [Call PresentationRequest constructor with a set of valid presentation URLs. No Exception expected.]
     expected: FAIL
 
   [Constructing a PresentationRequest]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
--- a/testing/web-platform/meta/presentation-api/controlling-ua/defaultRequest.https.html.ini
+++ b/testing/web-platform/meta/presentation-api/controlling-ua/defaultRequest.https.html.ini
@@ -1,4 +1,6 @@
 [defaultRequest.https.html]
   [Setting a default presentation request]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
--- a/testing/web-platform/meta/presentation-api/controlling-ua/getAvailability_sandboxing_success.https.html.ini
+++ b/testing/web-platform/meta/presentation-api/controlling-ua/getAvailability_sandboxing_success.https.html.ini
@@ -1,4 +1,6 @@
 [getAvailability_sandboxing_success.https.html]
   [Sandboxing: Retrieving display availability from a nested context succeeds when allow-presentation is set]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
--- a/testing/web-platform/meta/presentation-api/controlling-ua/idlharness.https.html.ini
+++ b/testing/web-platform/meta/presentation-api/controlling-ua/idlharness.https.html.ini
@@ -1,265 +1,439 @@
 [idlharness.https.html]
   [Presentation API IDL tests for Controlling User Agent]
     expected: FAIL
 
   [PresentationConnectionCloseEvent interface: attribute message]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: navigator.presentation.defaultRequest must inherit property "start()" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: presentation_request_urls must inherit property "onconnectionavailable" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: operation reconnect(USVString)]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: operation terminate()]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationAvailability interface object length]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: presentation_request_urls must inherit property "start()" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionCloseEvent interface: attribute reason]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface object length]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: operation start()]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: navigator.presentation.defaultRequest must inherit property "getAvailability()" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface: navigator.presentation must inherit property "receiver" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: operation send(DOMString)]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationAvailability interface: attribute onchange]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface object length]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Stringification of navigator.presentation.defaultRequest]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface object length]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: operation getAvailability()]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: attribute binaryType]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest must be primary interface of navigator.presentation.defaultRequest]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionAvailableEvent interface: attribute connection]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionAvailableEvent interface object length]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface: attribute defaultRequest]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: presentation_request_urls must inherit property "reconnect(USVString)" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation must be primary interface of navigator.presentation]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: calling reconnect(USVString) on navigator.presentation.defaultRequest with too few arguments must throw TypeError]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface object name]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionAvailableEvent interface object name]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: navigator.presentation.defaultRequest must inherit property "reconnect(USVString)" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface object name]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface: navigator.presentation must inherit property "defaultRequest" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface object name]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface: attribute receiver]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: navigator.presentation.defaultRequest must inherit property "onconnectionavailable" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionAvailableEvent interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest must be primary interface of presentation_request_urls]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Stringification of presentation_request]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationAvailability interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationAvailability interface object name]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: presentation_request_urls must inherit property "getAvailability()" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: presentation_request must inherit property "start()" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: attribute onclose]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: operation close()]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Stringification of presentation_request_urls]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest must be primary interface of presentation_request]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: calling reconnect(USVString) on presentation_request with too few arguments must throw TypeError]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: presentation_request must inherit property "getAvailability()" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionAvailableEvent interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationAvailability interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: attribute state]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: calling reconnect(USVString) on presentation_request_urls with too few arguments must throw TypeError]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: operation send(Blob)]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationAvailability interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: attribute url]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Navigator interface: attribute presentation]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionCloseEvent interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionCloseEvent interface object name]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationAvailability interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: operation send(ArrayBufferView)]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Stringification of navigator.presentation]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionCloseEvent interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionCloseEvent interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: presentation_request must inherit property "reconnect(USVString)" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationAvailability interface: attribute value]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [Presentation interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: operation send(ArrayBuffer)]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: attribute onconnectionavailable]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationRequest interface: presentation_request must inherit property "onconnectionavailable" with the proper type]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: attribute onconnect]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionAvailableEvent interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: attribute onterminate]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionCloseEvent interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionAvailableEvent interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: attribute onmessage]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: attribute id]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnectionCloseEvent interface object length]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
   [PresentationConnection interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
--- a/testing/web-platform/meta/presentation-api/controlling-ua/reconnectToPresentation_sandboxing_success.https.html.ini
+++ b/testing/web-platform/meta/presentation-api/controlling-ua/reconnectToPresentation_sandboxing_success.https.html.ini
@@ -1,4 +1,6 @@
 [reconnectToPresentation_sandboxing_success.https.html]
   [Sandboxing: Reconnecting a presentation from a nested context succeeds when allow-presentation is set]
-    expected: FAIL
+    expected:
+      if os == "android": PASS
+      FAIL
 
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed-ref.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<title>CSS Reference</title>
+
+<style>
+@font-face {
+  font-family: TestWeight;
+  src: url(resources/csstest-weights-100-kerned.ttf);
+  font-weight: 200 300;
+}
+@font-face {
+  font-family: TestWeight;
+  src: url(resources/csstest-weights-900-kerned.ttf);
+  font-weight: 300 400;
+}
+@font-face {
+  font-family: TestStyle;
+  src: url(resources/csstest-weights-100-kerned.ttf);
+  font-style: oblique 20deg 30deg;
+}
+@font-face {
+  font-family: TestStyle;
+  src: url(resources/csstest-weights-900-kerned.ttf);
+  font-style: oblique 30deg 40deg;
+}
+@font-face {
+  font-family: TestStretch;
+  src: url(resources/csstest-weights-100-kerned.ttf);
+  font-stretch: 110% 120%;
+}
+@font-face {
+  font-family: TestStretch;
+  src: url(resources/csstest-weights-900-kerned.ttf);
+  font-stretch: 120% 130%;
+}
+</style>
+
+<p style="font-family: TestWeight; font-weight: 250;">A</p>
+<p style="font-family: TestStyle; font-style: oblique 25deg;">A</p>
+<p style="font-family: TestStretch; font-stretch: 115%;">A</p>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>CSS Test: Matching @font-face font-weight, font-style, and font-stretch descriptors with reversed ranges</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop-desc">
+<link rel="match" href="font-descriptor-range-reversed-ref.html">
+
+<!-- Using csstest-weights-{100,900}-kerned.ttf just as two convenient
+     different fonts here with different "A" glyphs -->
+
+<style>
+@font-face {
+  font-family: TestWeight;
+  src: url(resources/csstest-weights-100-kerned.ttf);
+  font-weight: 300 200;
+}
+@font-face {
+  font-family: TestWeight;
+  src: url(resources/csstest-weights-900-kerned.ttf);
+  font-weight: 300 400;
+}
+@font-face {
+  font-family: TestStyle;
+  src: url(resources/csstest-weights-100-kerned.ttf);
+  font-style: oblique 30deg 20deg;
+}
+@font-face {
+  font-family: TestStyle;
+  src: url(resources/csstest-weights-900-kerned.ttf);
+  font-style: oblique 30deg 40deg;
+}
+@font-face {
+  font-family: TestStretch;
+  src: url(resources/csstest-weights-100-kerned.ttf);
+  font-stretch: 120% 110%;
+}
+@font-face {
+  font-family: TestStretch;
+  src: url(resources/csstest-weights-900-kerned.ttf);
+  font-stretch: 120% 130%;
+}
+</style>
+
+<!-- Matches `font-weight: 300 200;` -->
+<p style="font-family: TestWeight; font-weight: 250;">A</p>
+
+<!-- Matches `font-style: oblique 30deg 20deg;` -->
+<p style="font-family: TestStyle; font-style: oblique 25deg;">A</p>
+
+<!-- Matches `font-style: oblique 120% 110%;` -->
+<p style="font-family: TestStretch; font-stretch: 115%;">A</p>
+
+<script>
+document.fonts.ready.then(function() {
+  document.documentElement.className = "";
+});
+</script>
--- a/testing/web-platform/tests/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/resources/message-opener.html
+++ b/testing/web-platform/tests/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/resources/message-opener.html
@@ -1,17 +1,17 @@
 <script src="/common/PrefixedPostMessage.js"></script>
 <script>
 var prefixedMessage = new PrefixedMessageResource();
-var max = 50, attempts = 0;
+var max = 150, attempts = 0;
 function sendCoordinates() {
   // Certain windowing systems position windows asynchronously.
   // As a result, the window may not be positioned yet when the
   // load event fires. To accommodate this, allow waiting up to
-  // 5 seconds for positioning to take place.
+  // 15 seconds for positioning to take place.
   if (!window.screenX && !window.screenY && ++attempts < max) {
     setTimeout(sendCoordinates, 100);
     return;
   }
   prefixedMessage.postToOpener({
     left: window.screenX,
     top: window.screenY,
     width: window.innerWidth,
--- a/toolkit/components/antitracking/test/browser/browser_subResources.js
+++ b/toolkit/components/antitracking/test/browser/browser_subResources.js
@@ -151,16 +151,35 @@ add_task(async function() {
     });
 
   await fetch("https://tracking.example.org/browser/toolkit/components/antitracking/test/browser/subResources.sjs?result&what=script")
     .then(r => r.text())
     .then(text => {
       is(text, 1, "One cookie received received for scripts.");
     });
 
+  let log = JSON.parse(await browser.getContentBlockingLog());
+  for (let trackerOrigin in log) {
+    is(trackerOrigin, TEST_3RD_PARTY_DOMAIN, "Correct tracker origin must be reported");
+    let originLog = log[trackerOrigin];
+    is(originLog.length, 2, "We should have two entries in the compressed log");
+    is(originLog[0][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
+       "Correct blocking type reported");
+    is(originLog[0][1], true,
+       "Correct blocking status reported");
+    is(originLog[0][2], 6, // 1 for each HTTP request which attempts to set a cookie
+       "Correct repeat count reported");
+    is(originLog[1][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
+       "Correct blocking type reported");
+    is(originLog[1][1], false,
+       "Correct blocking status reported");
+    is(originLog[1][2], 1, // Only got unblocked once
+       "Correct repeat count reported");
+  }
+
   info("Removing the tab");
   BrowserTestUtils.removeTab(tab);
 });
 
 add_task(async function() {
   info("Cleaning up.");
   await new Promise(resolve => {
     Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
--- a/toolkit/components/browser/nsWebBrowser.h
+++ b/toolkit/components/browser/nsWebBrowser.h
@@ -30,17 +30,17 @@
 #include "nsIWebNavigation.h"
 #include "nsIWebBrowserPersist.h"
 #include "nsIWindowWatcher.h"
 #include "nsIPrintSettings.h"
 #include "nsIWidgetListener.h"
 
 #include "mozilla/BasePrincipal.h"
 #include "nsTArray.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 
 class nsWebBrowserInitInfo
 {
 public:
   // nsIBaseWindow Stuff
   int32_t x;
   int32_t y;
   int32_t cx;
--- a/toolkit/components/extensions/webrequest/ChannelWrapper.h
+++ b/toolkit/components/extensions/webrequest/ChannelWrapper.h
@@ -25,17 +25,17 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsIStreamListener.h"
 #include "nsITabParent.h"
 #include "nsIThreadRetargetableStreamListener.h"
 #include "nsPointerHashKeys.h"
 #include "nsInterfaceHashtable.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsWrapperCache.h"
 
 #define NS_CHANNELWRAPPER_IID \
 { 0xc06162d2, 0xb803, 0x43b4, \
   { 0xaa, 0x31, 0xcf, 0x69, 0x7f, 0x93, 0x68, 0x1c } }
 
 class nsILoadContext;
 class nsITraceableChannel;
--- a/toolkit/components/find/nsWebBrowserFind.h
+++ b/toolkit/components/find/nsWebBrowserFind.h
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsWebBrowserFindImpl_h__
 #define nsWebBrowserFindImpl_h__
 
 #include "nsIWebBrowserFind.h"
 
 #include "nsCOMPtr.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 
 #include "nsIFind.h"
 
 #include "nsString.h"
 
 class nsIDOMWindow;
 
 class nsIDocShell;
--- a/toolkit/components/places/nsMaybeWeakPtr.h
+++ b/toolkit/components/places/nsMaybeWeakPtr.h
@@ -3,17 +3,17 @@
  * 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 nsMaybeWeakPtr_h_
 #define nsMaybeWeakPtr_h_
 
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsTArray.h"
 #include "nsCycleCollectionNoteChild.h"
 
 // nsMaybeWeakPtr is a helper object to hold a strong-or-weak reference
 // to the template class.  It's pretty minimal, but sufficient.
 
 template<class T>
 class nsMaybeWeakPtr
--- a/toolkit/components/remote/nsDBusRemoteService.cpp
+++ b/toolkit/components/remote/nsDBusRemoteService.cpp
@@ -9,17 +9,16 @@
 #include "nsRemoteService.h"
 
 #include "nsIBaseWindow.h"
 #include "nsIDocShell.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/Base64.h"
 #include "nsIServiceManager.h"
-#include "nsIWeakReference.h"
 #include "nsIWidget.h"
 #include "nsIAppShellService.h"
 #include "nsAppShellCID.h"
 #include "nsPrintfCString.h"
 
 #include "nsCOMPtr.h"
 
 #include "nsGTKToolkit.h"
--- a/toolkit/components/remote/nsGTKRemoteService.cpp
+++ b/toolkit/components/remote/nsGTKRemoteService.cpp
@@ -11,17 +11,17 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 
 #include "nsIBaseWindow.h"
 #include "nsIDocShell.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsIServiceManager.h"
-#include "nsIWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsIWidget.h"
 #include "nsIAppShellService.h"
 #include "nsAppShellCID.h"
 
 #include "nsCOMPtr.h"
 
 #include "nsGTKToolkit.h"
 
@@ -65,17 +65,17 @@ nsGTKRemoteService::RegisterWindow(mozID
 {
   nsIWidget* mainWidget = GetMainWidget(nsPIDOMWindowInner::From(aWindow));
   NS_ENSURE_TRUE(mainWidget, NS_ERROR_FAILURE);
 
   GtkWidget* widget =
     (GtkWidget*) mainWidget->GetNativeData(NS_NATIVE_SHELLWIDGET);
   NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(aWindow);
+  nsWeakPtr weak = do_GetWeakReference(aWindow);
   NS_ENSURE_TRUE(weak, NS_ERROR_FAILURE);
 
   mWindows.Put(widget, weak);
 
   // If Startup() has already been called, immediately register this window.
   if (mServerWindow) {
     HandleCommandsFor(widget, weak);
   }
--- a/toolkit/components/remote/nsGTKRemoteService.h
+++ b/toolkit/components/remote/nsGTKRemoteService.h
@@ -8,16 +8,17 @@
 #ifndef __nsGTKRemoteService_h__
 #define __nsGTKRemoteService_h__
 
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 
 #include "nsIRemoteService.h"
+#include "nsIWeakReference.h"
 #include "nsInterfaceHashtable.h"
 #include "nsXRemoteService.h"
 #include "mozilla/Attributes.h"
 
 class nsGTKRemoteService final : public nsIRemoteService,
                                  public nsXRemoteService
 {
 public:
--- a/toolkit/components/remote/nsRemoteService.cpp
+++ b/toolkit/components/remote/nsRemoteService.cpp
@@ -15,17 +15,16 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 
 #include "nsIServiceManager.h"
 #include "nsIAppShellService.h"
 #include "nsAppShellCID.h"
 #include "nsInterfaceHashtable.h"
 #include "mozilla/ModuleUtils.h"
-#include "nsIWeakReference.h"
 #include "nsGTKToolkit.h"
 #include "nsICommandLineRunner.h"
 #include "nsCommandLine.h"
 #include "nsString.h"
 #include "nsIFile.h"
 
 NS_IMPL_ISUPPORTS(nsRemoteService,
                   nsIRemoteService,
--- a/toolkit/components/remote/nsXRemoteService.cpp
+++ b/toolkit/components/remote/nsXRemoteService.cpp
@@ -14,17 +14,17 @@
 #include "nsIServiceManager.h"
 #include "nsICommandLineRunner.h"
 #include "nsICommandLine.h"
 
 #include "nsIBaseWindow.h"
 #include "nsIDocShell.h"
 #include "nsIFile.h"
 #include "nsIServiceManager.h"
-#include "nsIWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsIWidget.h"
 #include "nsIAppShellService.h"
 #include "nsAppShellCID.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/X11Util.h"
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -1937,16 +1937,27 @@
               name: aLinks[i + 1],
               type: aLinks[i + 2],
             });
           }
           this.droppedLinkHandler(null, links, aTriggeringPrincipal);
           return true;
         ]]></body>
       </method>
+
+      <method name="getContentBlockingLog">
+        <body><![CDATA[
+          if (this.isRemoteBrowser) {
+            return this.frameLoader.tabParent.getContentBlockingLog();
+          }
+          return this.docShell ?
+                   this.docShell.getContentBlockingLog() :
+                   Promise.reject("docshell isn't available");
+        ]]></body>
+      </method>
     </implementation>
 
     <handlers>
       <handler event="keypress" keycode="VK_F7" group="system">
         <![CDATA[
           if (event.defaultPrevented || !event.isTrusted)
             return;
 
--- a/uriloader/base/nsDocLoader.cpp
+++ b/uriloader/base/nsDocLoader.cpp
@@ -14,17 +14,17 @@
 #include "nsIWebProgressListener2.h"
 
 #include "nsIServiceManager.h"
 #include "nsString.h"
 
 #include "nsIURL.h"
 #include "nsCOMPtr.h"
 #include "nscore.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsAutoPtr.h"
 #include "nsQueryObject.h"
 
 #include "nsIDOMWindow.h"
 
 #include "nsIStringBundle.h"
 #include "nsIScriptSecurityManager.h"
 
--- a/uriloader/base/nsURILoader.cpp
+++ b/uriloader/base/nsURILoader.cpp
@@ -17,17 +17,17 @@
 #include "nsIStreamListener.h"
 #include "nsIURI.h"
 #include "nsIChannel.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIProgressEventSink.h"
 #include "nsIInputStream.h"
 #include "nsIStreamConverterService.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsIHttpChannel.h"
 #include "nsIMultiPartChannel.h"
 #include "netCore.h"
 #include "nsCRT.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIThreadRetargetableStreamListener.h"
--- a/uriloader/prefetch/OfflineCacheUpdateChild.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.cpp
@@ -322,17 +322,17 @@ NS_IMETHODIMP
 OfflineCacheUpdateChild::AddObserver(nsIOfflineCacheUpdateObserver *aObserver,
                                   bool aHoldWeak)
 {
     LOG(("OfflineCacheUpdateChild::AddObserver [%p]", this));
 
     NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
 
     if (aHoldWeak) {
-        nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(aObserver);
+        nsWeakPtr weakRef = do_GetWeakReference(aObserver);
         mWeakObservers.AppendObject(weakRef);
     } else {
         mObservers.AppendObject(aObserver);
     }
 
     return NS_OK;
 }
 
--- a/uriloader/prefetch/OfflineCacheUpdateChild.h
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.h
@@ -10,18 +10,18 @@
 #include "nsIOfflineCacheUpdate.h"
 
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIURI.h"
+#include "nsIWeakReference.h"
 #include "nsString.h"
-#include "nsWeakReference.h"
 
 class nsPIDOMWindowInner;
 
 namespace mozilla {
 namespace docshell {
 
 class OfflineCacheUpdateChild : public nsIOfflineCacheUpdate
                               , public POfflineCacheUpdateChild
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -2429,17 +2429,17 @@ NS_IMETHODIMP
 nsOfflineCacheUpdate::AddObserver(nsIOfflineCacheUpdateObserver *aObserver,
                                   bool aHoldWeak)
 {
     LOG(("nsOfflineCacheUpdate::AddObserver [%p] to update [%p]", aObserver, this));
 
     NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
 
     if (aHoldWeak) {
-        nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(aObserver);
+        nsWeakPtr weakRef = do_GetWeakReference(aObserver);
         mWeakObservers.AppendObject(weakRef);
     } else {
         mObservers.AppendObject(aObserver);
     }
 
     return NS_OK;
 }
 
--- a/uriloader/prefetch/nsOfflineCacheUpdateService.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdateService.cpp
@@ -111,17 +111,17 @@ public:
 
 private:
     ~nsOfflineCachePendingUpdate() {}
 
     RefPtr<nsOfflineCacheUpdateService> mService;
     nsCOMPtr<nsIURI> mManifestURI;
     nsCOMPtr<nsIURI> mDocumentURI;
     nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
-    nsCOMPtr<nsIWeakReference> mDocument;
+    nsWeakPtr mDocument;
     bool mDidReleaseThis;
 };
 
 NS_IMPL_ISUPPORTS(nsOfflineCachePendingUpdate,
                   nsIWebProgressListener,
                   nsISupportsWeakReference)
 
 //-----------------------------------------------------------------------------
--- a/uriloader/prefetch/nsPrefetchService.cpp
+++ b/uriloader/prefetch/nsPrefetchService.cpp
@@ -90,17 +90,17 @@ nsPrefetchNode::nsPrefetchNode(nsPrefetc
     , mReferrerURI(aReferrerURI)
     , mPolicyType(aPolicyType)
     , mPreload(aPreload)
     , mService(aService)
     , mChannel(nullptr)
     , mBytesRead(0)
     , mShouldFireLoadEvent(false)
 {
-    nsCOMPtr<nsIWeakReference> source = do_GetWeakReference(aSource);
+    nsWeakPtr source = do_GetWeakReference(aSource);
     mSources.AppendElement(source);
 }
 
 nsresult
 nsPrefetchNode::OpenChannel()
 {
     if (mSources.IsEmpty()) {
         // Don't attempt to prefetch if we don't have a source node
@@ -742,17 +742,17 @@ nsPrefetchService::Preload(nsIURI *aURI,
     //
     // Check whether it is being preloaded.
     //
     for (uint32_t i = 0; i < mCurrentNodes.Length(); ++i) {
         bool equals;
         if ((mCurrentNodes[i]->mPolicyType == aPolicyType) &&
             NS_SUCCEEDED(mCurrentNodes[i]->mURI->Equals(aURI, &equals)) &&
             equals) {
-            nsCOMPtr<nsIWeakReference> source = do_GetWeakReference(aSource);
+            nsWeakPtr source = do_GetWeakReference(aSource);
             if (mCurrentNodes[i]->mSources.IndexOf(source) ==
                 mCurrentNodes[i]->mSources.NoIndex) {
                 LOG(("URL is already being preloaded, add a new reference "
                      "document\n"));
                 mCurrentNodes[i]->mSources.AppendElement(source);
                 return NS_OK;
             } else {
                 LOG(("URL is already being preloaded by this document"));
@@ -826,17 +826,17 @@ nsPrefetchService::Prefetch(nsIURI *aURI
 
     //
     // Check whether it is being prefetched.
     //
     for (uint32_t i = 0; i < mCurrentNodes.Length(); ++i) {
         bool equals;
         if (NS_SUCCEEDED(mCurrentNodes[i]->mURI->Equals(aURI, &equals)) &&
             equals) {
-            nsCOMPtr<nsIWeakReference> source = do_GetWeakReference(aSource);
+            nsWeakPtr source = do_GetWeakReference(aSource);
             if (mCurrentNodes[i]->mSources.IndexOf(source) ==
                 mCurrentNodes[i]->mSources.NoIndex) {
                 LOG(("URL is already being prefetched, add a new reference "
                      "document\n"));
                 mCurrentNodes[i]->mSources.AppendElement(source);
                 return NS_OK;
             } else {
                 LOG(("URL is already being prefetched by this document"));
@@ -848,17 +848,17 @@ nsPrefetchService::Prefetch(nsIURI *aURI
     //
     // Check whether it is on the prefetch queue.
     //
     for (std::deque<RefPtr<nsPrefetchNode>>::iterator nodeIt = mPrefetchQueue.begin();
          nodeIt != mPrefetchQueue.end(); nodeIt++) {
         bool equals;
         RefPtr<nsPrefetchNode> node = nodeIt->get();
         if (NS_SUCCEEDED(node->mURI->Equals(aURI, &equals)) && equals) {
-            nsCOMPtr<nsIWeakReference> source = do_GetWeakReference(aSource);
+            nsWeakPtr source = do_GetWeakReference(aSource);
             if (node->mSources.IndexOf(source) ==
                 node->mSources.NoIndex) {
                 LOG(("URL is already being prefetched, add a new reference "
                      "document\n"));
                 node->mSources.AppendElement(do_GetWeakReference(aSource));
                 return NS_OK;
             } else {
                 LOG(("URL is already being prefetched by this document"));
@@ -895,17 +895,17 @@ nsPrefetchService::CancelPrefetchPreload
 
     //
     // look in current prefetches
     //
     for (uint32_t i = 0; i < mCurrentNodes.Length(); ++i) {
         bool equals;
         if (NS_SUCCEEDED(mCurrentNodes[i]->mURI->Equals(aURI, &equals)) &&
             equals) {
-            nsCOMPtr<nsIWeakReference> source = do_GetWeakReference(aSource);
+            nsWeakPtr source = do_GetWeakReference(aSource);
             if (mCurrentNodes[i]->mSources.IndexOf(source) !=
                 mCurrentNodes[i]->mSources.NoIndex) {
                 mCurrentNodes[i]->mSources.RemoveElement(source);
                 if (mCurrentNodes[i]->mSources.IsEmpty()) {
                     mCurrentNodes[i]->CancelChannel(NS_BINDING_ABORTED);
                     mCurrentNodes.RemoveElementAt(i);
                 }
                 return NS_OK;
@@ -917,17 +917,17 @@ nsPrefetchService::CancelPrefetchPreload
     //
     // look into the prefetch queue
     //
     for (std::deque<RefPtr<nsPrefetchNode>>::iterator nodeIt = mPrefetchQueue.begin();
          nodeIt != mPrefetchQueue.end(); nodeIt++) {
         bool equals;
         RefPtr<nsPrefetchNode> node = nodeIt->get();
         if (NS_SUCCEEDED(node->mURI->Equals(aURI, &equals)) && equals) {
-            nsCOMPtr<nsIWeakReference> source = do_GetWeakReference(aSource);
+            nsWeakPtr source = do_GetWeakReference(aSource);
             if (node->mSources.IndexOf(source) !=
                 node->mSources.NoIndex) {
 
 #ifdef DEBUG
                 int32_t inx = node->mSources.IndexOf(source);
                 nsCOMPtr<nsINode> domNode =
                     do_QueryReferent(node->mSources.ElementAt(inx));
                 MOZ_ASSERT(domNode);
--- a/uriloader/prefetch/nsPrefetchService.h
+++ b/uriloader/prefetch/nsPrefetchService.h
@@ -112,17 +112,17 @@ public:
                    nsContentPolicyType aPolicyType,
                    bool aPreload);
 
     nsresult OpenChannel();
     nsresult CancelChannel(nsresult error);
 
     nsCOMPtr<nsIURI>                      mURI;
     nsCOMPtr<nsIURI>                      mReferrerURI;
-    nsTArray<nsCOMPtr<nsIWeakReference>>  mSources;
+    nsTArray<nsWeakPtr>                   mSources;
 
     // The policy type to be used for fetching the resource.
     nsContentPolicyType                   mPolicyType;
     // nsPrefetchNode is used for prefetching and preloading resource.
     // mPreload is true if a resource is preloaded. Preloads and
     // prefetches are fetched in different phases (during load and
     // after a page load), therefore we need to distinguish them.
     bool                                  mPreload;
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -10,17 +10,17 @@
 #include "mozView.h"
 #ifdef ACCESSIBILITY
 #include "mozilla/a11y/Accessible.h"
 #include "mozAccessibleProtocol.h"
 #endif
 
 #include "nsISupports.h"
 #include "nsBaseWidget.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "TextInputHandler.h"
 #include "nsCocoaUtils.h"
 #include "gfxQuartzSurface.h"
 #include "GLContextTypes.h"
 #include "mozilla/Mutex.h"
 #include "nsRegion.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/UniquePtr.h"
--- a/widget/nsPrintSettingsImpl.h
+++ b/widget/nsPrintSettingsImpl.h
@@ -3,19 +3,19 @@
  * 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 nsPrintSettingsImpl_h__
 #define nsPrintSettingsImpl_h__
 
 #include "nsIPrintSettings.h"  
+#include "nsIWeakReferenceUtils.h"
 #include "nsMargin.h"  
 #include "nsString.h"
-#include "nsWeakReference.h"  
 
 #define NUM_HEAD_FOOT 3
 
 //*****************************************************************************
 //***    nsPrintSettings
 //*****************************************************************************
 
 class nsPrintSettings : public nsIPrintSettings
--- a/widget/nsTransferable.cpp
+++ b/widget/nsTransferable.cpp
@@ -28,17 +28,16 @@ Notes to self:
 #include "nsMemory.h"
 #include "nsPrimitiveHelpers.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryService.h"
 #include "nsCRT.h"
 #include "nsNetUtil.h"
 #include "nsIOutputStream.h"
 #include "nsIInputStream.h"
-#include "nsIWeakReferenceUtils.h"
 #include "nsILoadContext.h"
 #include "mozilla/UniquePtr.h"
 
 using namespace mozilla;
 
 NS_IMPL_ISUPPORTS(nsTransferable, nsITransferable)
 
 DataStruct::DataStruct(DataStruct&& aRHS)
--- a/widget/windows/TaskbarPreview.h
+++ b/widget/windows/TaskbarPreview.h
@@ -11,17 +11,17 @@
 #include <windows.h>
 #include <shobjidl.h>
 #undef LogSeverity // SetupAPI.h #defines this as DWORD
 
 #include "mozilla/RefPtr.h"
 #include <nsITaskbarPreview.h>
 #include <nsITaskbarPreviewController.h>
 #include <nsString.h>
-#include <nsWeakPtr.h>
+#include <nsIWeakReferenceUtils.h>
 #include <nsIDocShell.h>
 #include "WindowHook.h"
 
 namespace mozilla {
 namespace widget {
 
 class TaskbarPreviewCallback;
 
--- a/widget/windows/TaskbarPreviewButton.h
+++ b/widget/windows/TaskbarPreviewButton.h
@@ -10,17 +10,17 @@
 
 #include <windows.h>
 #include <shobjidl.h>
 #undef LogSeverity // SetupAPI.h #defines this as DWORD
 
 #include "mozilla/RefPtr.h"
 #include <nsITaskbarPreviewButton.h>
 #include <nsString.h>
-#include <nsWeakReference.h>
+#include "nsWeakReference.h"
 
 namespace mozilla {
 namespace widget {
 
 class TaskbarWindowPreview;
 class TaskbarPreviewButton : public nsITaskbarPreviewButton, public nsSupportsWeakReference
 {
   virtual ~TaskbarPreviewButton();
--- a/widget/windows/TaskbarWindowPreview.h
+++ b/widget/windows/TaskbarWindowPreview.h
@@ -7,17 +7,17 @@
 
 #ifndef __mozilla_widget_TaskbarWindowPreview_h__
 #define __mozilla_widget_TaskbarWindowPreview_h__
 
 #include "nsITaskbarWindowPreview.h"
 #include "nsITaskbarProgress.h"
 #include "nsITaskbarOverlayIconController.h"
 #include "TaskbarPreview.h"
-#include <nsWeakReference.h>
+#include "nsWeakReference.h"
 
 namespace mozilla {
 namespace widget {
 
 class TaskbarPreviewButton;
 class TaskbarWindowPreview : public TaskbarPreview,
                              public nsITaskbarWindowPreview,
                              public nsITaskbarProgress,
--- a/xpcom/base/moz.build
+++ b/xpcom/base/moz.build
@@ -81,17 +81,16 @@ EXPORTS += [
     'nsIWeakReferenceUtils.h',
     'nsMemory.h',
     'nsObjCExceptions.h',
     'nsQueryObject.h',
     'nsSystemInfo.h',
     'nsTraceRefcnt.h',
     'nsTWeakRef.h',
     'nsVersionComparator.h',
-    'nsWeakPtr.h',
     'nsWeakReference.h',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS += [
         'nsWindowsHelpers.h',
     ]
     if CONFIG['CC_TYPE'] not in ('gcc', 'clang'):
--- a/xpcom/base/nsIWeakReference.idl
+++ b/xpcom/base/nsIWeakReference.idl
@@ -106,16 +106,8 @@ interface nsISupportsWeakReference : nsI
      * manage it with an |nsCOMPtr|.
      *
      * @see nsIWeakReference
      * @see nsWeakPtr
      * @see nsCOMPtr
      */
     nsIWeakReference GetWeakReference();
   };
-
-
-%{C++
-#ifdef MOZILLA_INTERNAL_API
-#include "nsIWeakReferenceUtils.h"
-#endif
-%}
-
deleted file mode 100644
--- a/xpcom/base/nsWeakPtr.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#ifndef nsWeakPtr_h__
-#define nsWeakPtr_h__
-
-#include "nsIWeakReference.h"
-#include "nsCOMPtr.h"
-
-// typedef nsCOMPtr<nsIWeakReference> nsWeakPtr;
-
-#endif
--- a/xpcom/build/XPCOM.h
+++ b/xpcom/build/XPCOM.h
@@ -136,17 +136,16 @@
 #include "nsIMacUtils.h"
 #endif
 
 // xpcom/glue utility headers
 
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 
-#include "nsIWeakReferenceUtils.h"
 #include "nsWeakReference.h"
 
 #include "nsArrayEnumerator.h"
 #include "nsArrayUtils.h"
 #include "nsCRTGlue.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDeque.h"
 #include "nsEnumeratorUtils.h"
--- a/xpcom/ds/nsObserverList.cpp
+++ b/xpcom/ds/nsObserverList.cpp
@@ -19,17 +19,17 @@ nsObserverList::AddObserver(nsIObserver*
     ObserverRef* o = mObservers.AppendElement(anObserver);
     if (!o) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     return NS_OK;
   }
 
-  nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(anObserver);
+  nsWeakPtr weak = do_GetWeakReference(anObserver);
   if (!weak) {
     return NS_NOINTERFACE;
   }
 
   ObserverRef* o = mObservers.AppendElement(weak);
   if (!o) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
@@ -41,17 +41,17 @@ nsresult
 nsObserverList::RemoveObserver(nsIObserver* anObserver)
 {
   NS_ASSERTION(anObserver, "Null input");
 
   if (mObservers.RemoveElement(static_cast<nsISupports*>(anObserver))) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsIWeakReference> observerRef = do_GetWeakReference(anObserver);
+  nsWeakPtr observerRef = do_GetWeakReference(anObserver);
   if (!observerRef) {
     return NS_ERROR_FAILURE;
   }
 
   if (!mObservers.RemoveElement(observerRef)) {
     return NS_ERROR_FAILURE;
   }
 
--- a/xpfe/appshell/nsXULWindow.h
+++ b/xpfe/appshell/nsXULWindow.h
@@ -26,17 +26,16 @@
 #include "nsIDocShellTreeItem.h"
 #include "nsIDOMWindow.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIXULWindow.h"
 #include "nsIPrompt.h"
 #include "nsIAuthPrompt.h"
 #include "nsIXULBrowserWindow.h"
-#include "nsIWeakReference.h"
 #include "nsIWidgetListener.h"
 #include "nsITabParent.h"
 #include "nsIXULStore.h"
 
 namespace mozilla {
 namespace dom {
 class Element;
 } // namespace dom
@@ -157,17 +156,17 @@ protected:
                                  const nsAString& aValue);
 
    nsChromeTreeOwner*      mChromeTreeOwner;
    nsContentTreeOwner*     mContentTreeOwner;
    nsContentTreeOwner*     mPrimaryContentTreeOwner;
    nsCOMPtr<nsIWidget>     mWindow;
    nsCOMPtr<nsIDocShell>   mDocShell;
    nsCOMPtr<nsPIDOMWindowOuter>  mDOMWindow;
-   nsCOMPtr<nsIWeakReference> mParentWindow;
+   nsWeakPtr               mParentWindow;
    nsCOMPtr<nsIPrompt>     mPrompter;
    nsCOMPtr<nsIAuthPrompt> mAuthPrompter;
    nsCOMPtr<nsIXULBrowserWindow> mXULBrowserWindow;
    nsCOMPtr<nsIDocShellTreeItem> mPrimaryContentShell;
    nsresult                mModalStatus;
    bool                    mContinueModalLoop;
    bool                    mDebuting;       // being made visible right now
    bool                    mChromeLoaded; // True when chrome has loaded