Bug 1415389. Make ChromeUtils a WebIDL namespace. Remove ThreadSafeChromeUtils. r=kmag
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 08 Nov 2017 00:25:33 -0500
changeset 443966 73352624f35c23e6000cd50d095708d69249f35d
parent 443965 ac9d12e5587fe2486a2a8c95ef911768841195e2
child 443967 7e7144bcdcb5b8ea1a7ff362b4ebe9953b8a16a6
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1415389
milestone58.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
Bug 1415389. Make ChromeUtils a WebIDL namespace. Remove ThreadSafeChromeUtils. r=kmag MozReview-Commit-ID: 9ysAeaBMNVt
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-04.js
devtools/client/memory/test/unit/head.js
devtools/docs/tools/memory-panel.md
devtools/server/actors/object.js
devtools/server/performance/memory.js
devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_01.js
devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_02.js
devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_03.js
devtools/shared/builtin-modules.js
devtools/shared/fronts/memory.js
devtools/shared/heapsnapshot/HeapAnalysesWorker.js
devtools/shared/heapsnapshot/HeapSnapshot.cpp
devtools/shared/heapsnapshot/tests/unit/dominator-tree-worker.js
devtools/shared/heapsnapshot/tests/unit/heap-snapshot-worker.js
dom/base/ChromeUtils.cpp
dom/base/ChromeUtils.h
dom/bindings/Bindings.conf
dom/bindings/parser/WebIDL.py
dom/browser-element/BrowserElementParent.js
dom/webidl/ChromeUtils.webidl
dom/webidl/ThreadSafeChromeUtils.webidl
dom/webidl/moz.build
js/xpconnect/tests/chrome/test_getweakmapkeys.xul
js/xpconnect/tests/chrome/test_paris_weakmap_keys.xul
js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xul
js/xpconnect/tests/chrome/test_weakmaps.xul
js/xpconnect/tests/unit/test_weak_keys.js
testing/talos/talos/tests/devtools/addon/content/damp.js
toolkit/components/ctypes/tests/unit/head.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-04.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-04.js
@@ -139,17 +139,17 @@ function test() {
        "Child element should not have a parent.");
     is([...parent].length, 0,
        "Parent should have zero children.");
 
     testScope.remove();
 
     is([...variables].length, 0,
        "VariablesView should have been emptied.");
-    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(variables._itemsByElement).length,
+    is(ChromeUtils.nondeterministicGetWeakMapKeys(variables._itemsByElement).length,
        0, "VariablesView _itemsByElement map has been emptied.");
     is(variables._currHierarchy.size, 0,
        "VariablesView _currHierarchy map has been emptied.");
     is(variables._list.children.length, 0,
        "VariablesView element should have no children.");
 
     closeDebuggerAndFinish(aPanel);
   });
--- a/devtools/client/memory/test/unit/head.js
+++ b/devtools/client/memory/test/unit/head.js
@@ -57,17 +57,17 @@ StubbedMemoryFront.prototype.attach = Ta
 });
 
 StubbedMemoryFront.prototype.detach = Task.async(function* () {
   this.state = "detached";
 });
 
 StubbedMemoryFront.prototype.saveHeapSnapshot = expectState("attached",
   Task.async(function* () {
-    return ThreadSafeChromeUtils.saveHeapSnapshot({ runtime: true });
+    return ChromeUtils.saveHeapSnapshot({ runtime: true });
   }), "saveHeapSnapshot");
 
 StubbedMemoryFront.prototype.startRecordingAllocations = expectState("attached",
   Task.async(function* () {
     this.recordingAllocations = true;
   }));
 
 StubbedMemoryFront.prototype.stopRecordingAllocations = expectState("attached",
--- a/devtools/docs/tools/memory-panel.md
+++ b/devtools/docs/tools/memory-panel.md
@@ -83,18 +83,18 @@ binary blob in memory, but instead strea
 
 Once all of that is accounted for, saving snapshots becomes pretty straight
 forward. We traverse the live heap graph with `JS::ubi::Node` and
 `JS::ubi::BreadthFirst`, create a protobuf message for each node and each node's
 edges, and write these messages to disk before continuing the traversal to the
 next node.
 
 This functionality is exposed to chrome JavaScript as the
-`[ThreadSafe]ChromeUtils.saveHeapSnapshot` function. See
-`dom/webidl/ThreadSafeChromeUtils.webidl` for API documentation.
+`ChromeUtils.saveHeapSnapshot` function. See `dom/webidl/ChromeUtils.webidl` for
+API documentation.
 
 ### Reading Heap Snapshots
 
 Reading heap snapshots has less restrictions than saving heap snapshots. The
 protobuf messages that make up the core dump are deserialized one by one, stored
 as a set of `DeserializedNode`s and a set of `DeserializedEdge`s, and the result
 is a `HeapSnapshot` instance.
 
--- a/devtools/server/actors/object.js
+++ b/devtools/server/actors/object.js
@@ -7,17 +7,17 @@
 "use strict";
 
 const { Cu, Ci } = require("chrome");
 const { GeneratedLocation } = require("devtools/server/actors/common");
 const { DebuggerServer } = require("devtools/server/main");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 const { assert, dumpn } = DevToolsUtils;
 
-loader.lazyRequireGetter(this, "ThreadSafeChromeUtils");
+loader.lazyRequireGetter(this, "ChromeUtils");
 
 // Number of items to preview in objects, arrays, maps, sets, lists,
 // collections, etc.
 const OBJECT_PREVIEW_MAX_ITEMS = 10;
 
 /**
  * Creates an actor for the specified object.
  *
@@ -1050,17 +1050,17 @@ function enumWeakMapEntries(objectActor)
   // based on whether or not it's Xrayable and/or callable, which breaks
   // the for/of iteration.
   //
   // This code is designed to handle untrusted objects, so we can safely
   // waive Xrays on the iterable, and relying on the Debugger machinery to
   // make sure we handle the resulting objects carefully.
   let raw = objectActor.obj.unsafeDereference();
   let keys = Cu.waiveXrays(
-    ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(raw));
+    ChromeUtils.nondeterministicGetWeakMapKeys(raw));
 
   return {
     [Symbol.iterator]: function* () {
       for (let key of keys) {
         let value = WeakMap.prototype.get.call(raw, key);
         yield [ key, value ].map(val => gripFromEntry(objectActor, val));
       }
     },
@@ -1127,17 +1127,17 @@ function enumWeakSetEntries(objectActor)
   // based on whether or not it's Xrayable and/or callable, which breaks
   // the for/of iteration.
   //
   // This code is designed to handle untrusted objects, so we can safely
   // waive Xrays on the iterable, and relying on the Debugger machinery to
   // make sure we handle the resulting objects carefully.
   let raw = objectActor.obj.unsafeDereference();
   let keys = Cu.waiveXrays(
-    ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys(raw));
+    ChromeUtils.nondeterministicGetWeakSetKeys(raw));
 
   return {
     [Symbol.iterator]: function* () {
       for (let item of keys) {
         yield gripFromEntry(objectActor, item);
       }
     },
     size: keys.length,
--- a/devtools/server/performance/memory.js
+++ b/devtools/server/performance/memory.js
@@ -8,17 +8,17 @@ const { Cc, Ci, Cu } = require("chrome")
 const { reportException } = require("devtools/shared/DevToolsUtils");
 const { expectState } = require("devtools/server/actors/common");
 
 loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
 loader.lazyRequireGetter(this, "DeferredTask",
   "resource://gre/modules/DeferredTask.jsm", true);
 loader.lazyRequireGetter(this, "StackFrameCache",
   "devtools/server/actors/utils/stack", true);
-loader.lazyRequireGetter(this, "ThreadSafeChromeUtils");
+loader.lazyRequireGetter(this, "ChromeUtils");
 loader.lazyRequireGetter(this, "HeapSnapshotFileUtils",
   "devtools/shared/heapsnapshot/HeapSnapshotFileUtils");
 loader.lazyRequireGetter(this, "ChromeActor", "devtools/server/actors/chrome",
                          true);
 loader.lazyRequireGetter(this, "ChildProcessActor",
                          "devtools/server/actors/child-process", true);
 
 /**
@@ -146,17 +146,17 @@ Memory.prototype = {
     if (!boundaries) {
       if (this.parent instanceof ChromeActor ||
           this.parent instanceof ChildProcessActor) {
         boundaries = { runtime: true };
       } else {
         boundaries = { debugger: this.dbg };
       }
     }
-    return ThreadSafeChromeUtils.saveHeapSnapshotGetId(boundaries);
+    return ChromeUtils.saveHeapSnapshotGetId(boundaries);
   }, "saveHeapSnapshot"),
 
   /**
    * Take a census of the heap. See js/src/doc/Debugger/Debugger.Memory.md for
    * more information.
    */
   takeCensus: expectState("attached", function () {
     return this.dbg.memory.takeCensus();
--- a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_01.js
+++ b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_01.js
@@ -7,12 +7,12 @@
 // and then create a HeapSnapshot instance from the resulting file.
 
 const { OS } = require("resource://gre/modules/osfile.jsm");
 
 const run_test = makeMemoryActorTest(function* (client, memoryFront) {
   const snapshotFilePath = yield memoryFront.saveHeapSnapshot();
   ok(!!(yield OS.File.stat(snapshotFilePath)),
      "Should have the heap snapshot file");
-  const snapshot = ThreadSafeChromeUtils.readHeapSnapshot(snapshotFilePath);
+  const snapshot = ChromeUtils.readHeapSnapshot(snapshotFilePath);
   ok(snapshot instanceof HeapSnapshot,
      "And we should be able to read a HeapSnapshot instance from the file");
 });
--- a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_02.js
+++ b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_02.js
@@ -9,12 +9,12 @@
 const { OS } = require("resource://gre/modules/osfile.jsm");
 
 const run_test = makeMemoryActorTest(function* (client, memoryFront) {
   const snapshotFilePath = yield memoryFront.saveHeapSnapshot({
     forceCopy: true
   });
   ok(!!(yield OS.File.stat(snapshotFilePath)),
      "Should have the heap snapshot file");
-  const snapshot = ThreadSafeChromeUtils.readHeapSnapshot(snapshotFilePath);
+  const snapshot = ChromeUtils.readHeapSnapshot(snapshotFilePath);
   ok(snapshot instanceof HeapSnapshot,
      "And we should be able to read a HeapSnapshot instance from the file");
 });
--- a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_03.js
+++ b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_03.js
@@ -7,12 +7,12 @@
 // ChromeActor or a ChildProcessActor.
 
 const { OS } = require("resource://gre/modules/osfile.jsm");
 
 const run_test = makeFullRuntimeMemoryActorTest(function* (client, memoryFront) {
   const snapshotFilePath = yield memoryFront.saveHeapSnapshot();
   ok(!!(yield OS.File.stat(snapshotFilePath)),
      "Should have the heap snapshot file");
-  const snapshot = ThreadSafeChromeUtils.readHeapSnapshot(snapshotFilePath);
+  const snapshot = ChromeUtils.readHeapSnapshot(snapshotFilePath);
   ok(snapshot instanceof HeapSnapshot,
      "And we should be able to read a HeapSnapshot instance from the file");
 });
--- a/devtools/shared/builtin-modules.js
+++ b/devtools/shared/builtin-modules.js
@@ -13,17 +13,17 @@
  * they would also miss them.
  */
 
 const { Cu, CC, Cc, Ci } = require("chrome");
 const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
 const jsmScope = Cu.import("resource://gre/modules/Services.jsm", {});
 const { Services } = jsmScope;
 // Steal various globals only available in JSM scope (and not Sandbox one)
-const { PromiseDebugging, ChromeUtils, ThreadSafeChromeUtils, HeapSnapshot,
+const { PromiseDebugging, ChromeUtils, HeapSnapshot,
         atob, btoa, TextEncoder, TextDecoder } = Cu.getGlobalForObject(jsmScope);
 
 // Create a single Sandbox to access global properties needed in this module.
 // Sandbox are memory expensive, so we should create as little as possible.
 const { CSS, FileReader, indexedDB, URL } =
     Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(), {
       wantGlobalProperties: ["CSS", "FileReader", "indexedDB", "URL"]
     });
@@ -173,17 +173,16 @@ exports.modules = {
   "Services": Object.create(Services),
   promise,
   // Expose "chrome" Promise, which aren't related to any document
   // and so are never frozen, even if the browser loader module which
   // pull it is destroyed. See bug 1402779.
   Promise,
   PromiseDebugging,
   ChromeUtils,
-  ThreadSafeChromeUtils,
   HeapSnapshot,
   FileReader,
 };
 
 defineLazyGetter(exports.modules, "Debugger", () => {
   // addDebuggerToGlobal only allows adding the Debugger object to a global. The
   // this object is not guaranteed to be a global (in particular on B2G, due to
   // compartment sharing), so add the Debugger object to a sandbox instead.
--- a/devtools/shared/fronts/memory.js
+++ b/devtools/shared/fronts/memory.js
@@ -32,17 +32,17 @@ const MemoryFront = protocol.FrontClassW
    * as we jump through the correct IPDL hoops.
    *
    * @params Boolean options.forceCopy
    *         Always force a bulk data copy of the saved heap snapshot, even when
    *         the server and client share a file system.
    *
    * @params {Object|undefined} options.boundaries
    *         The boundaries for the heap snapshot. See
-   *         ThreadSafeChromeUtils.webidl for more details.
+   *         ChromeUtils.webidl for more details.
    *
    * @returns Promise<String>
    */
   saveHeapSnapshot: protocol.custom(Task.async(function* (options = {}) {
     const snapshotId = yield this._saveHeapSnapshotImpl(options.boundaries);
 
     if (!options.forceCopy &&
         (yield HeapSnapshotFileUtils.haveHeapSnapshotTempFile(snapshotId))) {
--- a/devtools/shared/heapsnapshot/HeapAnalysesWorker.js
+++ b/devtools/shared/heapsnapshot/HeapAnalysesWorker.js
@@ -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/. */
-/* global ThreadSafeChromeUtils*/
+/* global ChromeUtils*/
 
 // This is a worker which reads offline heap snapshots into memory and performs
 // heavyweight analyses on them without blocking the main thread. A
 // HeapAnalysesWorker is owned and communicated with by a HeapAnalysesClient
 // instance. See HeapAnalysesClient.js.
 
 /* global importScripts, workerHelper, self */
 
@@ -42,17 +42,17 @@ const dominatorTrees = [];
  */
 const dominatorTreeSnapshots = [];
 
 /**
  * @see HeapAnalysesClient.prototype.readHeapSnapshot
  */
 workerHelper.createTask(self, "readHeapSnapshot", ({ snapshotFilePath }) => {
   snapshots[snapshotFilePath] =
-    ThreadSafeChromeUtils.readHeapSnapshot(snapshotFilePath);
+    ChromeUtils.readHeapSnapshot(snapshotFilePath);
   return true;
 });
 
 /**
  * @see HeapAnalysesClient.prototype.deleteHeapSnapshot
  */
 workerHelper.createTask(self, "deleteHeapSnapshot", ({ snapshotFilePath }) => {
   let snapshot = snapshots[snapshotFilePath];
--- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp
@@ -1563,21 +1563,21 @@ getCoreDumpOutputStream(ErrorResult& rv,
 } // namespace devtools
 
 namespace dom {
 
 using namespace JS;
 using namespace devtools;
 
 /* static */ void
-ThreadSafeChromeUtils::SaveHeapSnapshotShared(GlobalObject& global,
-                                              const HeapSnapshotBoundaries& boundaries,
-                                              nsAString& outFilePath,
-                                              nsAString& outSnapshotId,
-                                              ErrorResult& rv)
+ChromeUtils::SaveHeapSnapshotShared(GlobalObject& global,
+                                    const HeapSnapshotBoundaries& boundaries,
+                                    nsAString& outFilePath,
+                                    nsAString& outSnapshotId,
+                                    ErrorResult& rv)
 {
   auto start = TimeStamp::Now();
 
   bool wantNames = true;
   CompartmentSet compartments;
   uint32_t nodeCount = 0;
   uint32_t edgeCount = 0;
 
@@ -1632,39 +1632,39 @@ ThreadSafeChromeUtils::SaveHeapSnapshotS
                                  start);
   Telemetry::Accumulate(Telemetry::DEVTOOLS_HEAP_SNAPSHOT_NODE_COUNT,
                         nodeCount);
   Telemetry::Accumulate(Telemetry::DEVTOOLS_HEAP_SNAPSHOT_EDGE_COUNT,
                         edgeCount);
 }
 
 /* static */ void
-ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
-                                        const HeapSnapshotBoundaries& boundaries,
-                                        nsAString& outFilePath,
-                                        ErrorResult& rv)
+ChromeUtils::SaveHeapSnapshot(GlobalObject& global,
+                              const HeapSnapshotBoundaries& boundaries,
+                              nsAString& outFilePath,
+                              ErrorResult& rv)
 {
   nsAutoString snapshotId;
   SaveHeapSnapshotShared(global, boundaries, outFilePath, snapshotId, rv);
 }
 
 /* static */ void
-ThreadSafeChromeUtils::SaveHeapSnapshotGetId(GlobalObject& global,
-                                             const HeapSnapshotBoundaries& boundaries,
-                                             nsAString& outSnapshotId,
-                                             ErrorResult& rv)
+ChromeUtils::SaveHeapSnapshotGetId(GlobalObject& global,
+                                   const HeapSnapshotBoundaries& boundaries,
+                                   nsAString& outSnapshotId,
+                                   ErrorResult& rv)
 {
   nsAutoString filePath;
   SaveHeapSnapshotShared(global, boundaries, filePath, outSnapshotId, rv);
 }
 
 /* static */ already_AddRefed<HeapSnapshot>
-ThreadSafeChromeUtils::ReadHeapSnapshot(GlobalObject& global,
-                                        const nsAString& filePath,
-                                        ErrorResult& rv)
+ChromeUtils::ReadHeapSnapshot(GlobalObject& global,
+                              const nsAString& filePath,
+                              ErrorResult& rv)
 {
   auto start = TimeStamp::Now();
 
   UniquePtr<char[]> path(ToNewCString(filePath));
   if (!path) {
     rv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
--- a/devtools/shared/heapsnapshot/tests/unit/dominator-tree-worker.js
+++ b/devtools/shared/heapsnapshot/tests/unit/dominator-tree-worker.js
@@ -3,18 +3,18 @@
 
 "use strict";
 
 console.log("Initializing worker.");
 
 self.onmessage = e => {
   console.log("Starting test.");
   try {
-    const path = ThreadSafeChromeUtils.saveHeapSnapshot({ runtime: true });
-    const snapshot = ThreadSafeChromeUtils.readHeapSnapshot(path);
+    const path = ChromeUtils.saveHeapSnapshot({ runtime: true });
+    const snapshot = ChromeUtils.readHeapSnapshot(path);
 
     const dominatorTree = snapshot.computeDominatorTree();
     ok(dominatorTree);
     ok(dominatorTree instanceof DominatorTree);
 
     let threw = false;
     try {
       new DominatorTree();
--- a/devtools/shared/heapsnapshot/tests/unit/heap-snapshot-worker.js
+++ b/devtools/shared/heapsnapshot/tests/unit/heap-snapshot-worker.js
@@ -3,27 +3,25 @@
 
 "use strict";
 
 console.log("Initializing worker.");
 
 self.onmessage = ex => {
   console.log("Starting test.");
   try {
-    ok(typeof ChromeUtils === "undefined",
-       "Should not have access to ChromeUtils in a worker.");
-    ok(ThreadSafeChromeUtils,
-       "Should have access to ThreadSafeChromeUtils in a worker.");
+    ok(ChromeUtils,
+       "Should have access to ChromeUtils in a worker.");
     ok(HeapSnapshot,
        "Should have access to HeapSnapshot in a worker.");
 
-    const filePath = ThreadSafeChromeUtils.saveHeapSnapshot({ globals: [this] });
+    const filePath = ChromeUtils.saveHeapSnapshot({ globals: [this] });
     ok(true, "Should be able to save a snapshot.");
 
-    const snapshot = ThreadSafeChromeUtils.readHeapSnapshot(filePath);
+    const snapshot = ChromeUtils.readHeapSnapshot(filePath);
     ok(snapshot, "Should be able to read a heap snapshot");
     ok(snapshot instanceof HeapSnapshot, "Should be an instanceof HeapSnapshot");
   } catch (e) {
     ok(false, "Unexpected error inside worker:\n" + e.toString() + "\n" + e.stack);
   } finally {
     done();
   }
 };
--- a/dom/base/ChromeUtils.cpp
+++ b/dom/base/ChromeUtils.cpp
@@ -15,61 +15,61 @@
 #include "mozilla/dom/IdleDeadline.h"
 #include "mozilla/dom/WindowBinding.h" // For IdleRequestCallback/Options
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 /* static */ void
-ThreadSafeChromeUtils::NondeterministicGetWeakMapKeys(GlobalObject& aGlobal,
-                                                      JS::Handle<JS::Value> aMap,
-                                                      JS::MutableHandle<JS::Value> aRetval,
-                                                      ErrorResult& aRv)
+ChromeUtils::NondeterministicGetWeakMapKeys(GlobalObject& aGlobal,
+                                            JS::Handle<JS::Value> aMap,
+                                            JS::MutableHandle<JS::Value> aRetval,
+                                            ErrorResult& aRv)
 {
   if (!aMap.isObject()) {
     aRetval.setUndefined();
   } else {
     JSContext* cx = aGlobal.Context();
     JS::Rooted<JSObject*> objRet(cx);
     JS::Rooted<JSObject*> mapObj(cx, &aMap.toObject());
     if (!JS_NondeterministicGetWeakMapKeys(cx, mapObj, &objRet)) {
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     } else {
       aRetval.set(objRet ? JS::ObjectValue(*objRet) : JS::UndefinedValue());
     }
   }
 }
 
 /* static */ void
-ThreadSafeChromeUtils::NondeterministicGetWeakSetKeys(GlobalObject& aGlobal,
-                                                      JS::Handle<JS::Value> aSet,
-                                                      JS::MutableHandle<JS::Value> aRetval,
-                                                      ErrorResult& aRv)
+ChromeUtils::NondeterministicGetWeakSetKeys(GlobalObject& aGlobal,
+                                            JS::Handle<JS::Value> aSet,
+                                            JS::MutableHandle<JS::Value> aRetval,
+                                            ErrorResult& aRv)
 {
   if (!aSet.isObject()) {
     aRetval.setUndefined();
   } else {
     JSContext* cx = aGlobal.Context();
     JS::Rooted<JSObject*> objRet(cx);
     JS::Rooted<JSObject*> setObj(cx, &aSet.toObject());
     if (!JS_NondeterministicGetWeakSetKeys(cx, setObj, &objRet)) {
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     } else {
       aRetval.set(objRet ? JS::ObjectValue(*objRet) : JS::UndefinedValue());
     }
   }
 }
 
 /* static */ void
-ThreadSafeChromeUtils::Base64URLEncode(GlobalObject& aGlobal,
-                                       const ArrayBufferViewOrArrayBuffer& aSource,
-                                       const Base64URLEncodeOptions& aOptions,
-                                       nsACString& aResult,
-                                       ErrorResult& aRv)
+ChromeUtils::Base64URLEncode(GlobalObject& aGlobal,
+                             const ArrayBufferViewOrArrayBuffer& aSource,
+                             const Base64URLEncodeOptions& aOptions,
+                             nsACString& aResult,
+                             ErrorResult& aRv)
 {
   size_t length = 0;
   uint8_t* data = nullptr;
   if (aSource.IsArrayBuffer()) {
     const ArrayBuffer& buffer = aSource.GetAsArrayBuffer();
     buffer.ComputeLengthAndData();
     length = buffer.Length();
     data = buffer.Data();
@@ -87,21 +87,21 @@ ThreadSafeChromeUtils::Base64URLEncode(G
   nsresult rv = mozilla::Base64URLEncode(length, data, paddingPolicy, aResult);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aResult.Truncate();
     aRv.Throw(rv);
   }
 }
 
 /* static */ void
-ThreadSafeChromeUtils::Base64URLDecode(GlobalObject& aGlobal,
-                                       const nsACString& aString,
-                                       const Base64URLDecodeOptions& aOptions,
-                                       JS::MutableHandle<JSObject*> aRetval,
-                                       ErrorResult& aRv)
+ChromeUtils::Base64URLDecode(GlobalObject& aGlobal,
+                             const nsACString& aString,
+                             const Base64URLDecodeOptions& aOptions,
+                             JS::MutableHandle<JSObject*> aRetval,
+                             ErrorResult& aRv)
 {
   Base64URLDecodePaddingPolicy paddingPolicy;
   switch (aOptions.mPadding) {
     case Base64URLDecodePadding::Require:
       paddingPolicy = Base64URLDecodePaddingPolicy::Require;
       break;
 
     case Base64URLDecodePadding::Ignore:
--- a/dom/base/ChromeUtils.h
+++ b/dom/base/ChromeUtils.h
@@ -5,34 +5,33 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_ChromeUtils__
 #define mozilla_dom_ChromeUtils__
 
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/ChromeUtilsBinding.h"
-#include "mozilla/dom/ThreadSafeChromeUtilsBinding.h"
 #include "mozilla/ErrorResult.h"
 
 namespace mozilla {
 
 namespace devtools {
 class HeapSnapshot;
 } // namespace devtools
 
 namespace dom {
 
 class ArrayBufferViewOrArrayBuffer;
 class IdleRequestCallback;
 struct IdleRequestOptions;
 class PrecompiledScript;
 class Promise;
 
-class ThreadSafeChromeUtils
+class ChromeUtils
 {
 private:
   // Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
   static void SaveHeapSnapshotShared(GlobalObject& global,
                                      const HeapSnapshotBoundaries& boundaries,
                                      nsAString& filePath,
                                      nsAString& snapshotId,
                                      ErrorResult& rv);
@@ -71,21 +70,17 @@ public:
                               nsACString& aResult,
                               ErrorResult& aRv);
 
   static void Base64URLDecode(GlobalObject& aGlobal,
                               const nsACString& aString,
                               const Base64URLDecodeOptions& aOptions,
                               JS::MutableHandle<JSObject*> aRetval,
                               ErrorResult& aRv);
-};
 
-class ChromeUtils : public ThreadSafeChromeUtils
-{
-public:
   static void
   OriginAttributesToSuffix(GlobalObject& aGlobal,
                            const dom::OriginAttributesDictionary& aAttrs,
                            nsCString& aSuffix);
 
   static bool
   OriginAttributesMatchPattern(dom::GlobalObject& aGlobal,
                                const dom::OriginAttributesDictionary& aAttrs,
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -139,22 +139,16 @@ DOMInterfaces = {
     'nativeType': 'mozilla::extensions::ChannelWrapper',
 },
 
 'CharacterData': {
     'nativeType': 'nsGenericDOMDataNode',
     'concrete': False
 },
 
-'ChromeUtils': {
-    # The codegen is dumb, and doesn't understand that this interface is only a
-    # collection of static methods, so we have this `concrete: False` hack.
-    'concrete': False,
-},
-
 'ChromeWorker': {
     'headerFile': 'mozilla/dom/WorkerPrivate.h',
     'nativeType': 'mozilla::dom::workers::ChromeWorkerPrivate',
 },
 
 'Client': {
     'nativeType': 'mozilla::dom::workers::ServiceWorkerClient',
     'headerFile': 'mozilla/dom/workers/bindings/ServiceWorkerClient.h',
@@ -1077,23 +1071,16 @@ DOMInterfaces = {
 'TextMetrics': {
     'wrapperCache': False
 },
 
 'TCPSocket': {
     'implicitJSContext': ['send']
 },
 
-'ThreadSafeChromeUtils': {
-    # The codegen is dumb, and doesn't understand that this interface is only a
-    # collection of static methods, so we have this `concrete: False` hack.
-    'concrete': False,
-    'headerFile': 'mozilla/dom/ChromeUtils.h',
-},
-
 'TouchList': {
     'headerFile': 'mozilla/dom/TouchEvent.h',
 },
 
 'TreeColumn': {
     'nativeType': 'nsTreeColumn',
     'headerFile': 'nsTreeColumns.h',
 },
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1777,17 +1777,18 @@ class IDLNamespace(IDLInterfaceOrNamespa
                 convertExposedAttrToGlobalNameSet(attr,
                                                   self._exposureGlobalNames)
             elif identifier == "ClassString":
                 # Takes a string value to override the default "Object" if
                 # desired.
                 if not attr.hasValue():
                     raise WebIDLError("[%s] must have a value" % identifier,
                                       [attr.location])
-            elif identifier == "ProtoObjectHack":
+            elif (identifier == "ProtoObjectHack" or
+                  identifier == "ChromeOnly"):
                 if not attr.noArguments():
                     raise WebIDLError("[%s] must not have arguments" % identifier,
                                       [attr.location])
             else:
                 raise WebIDLError("Unknown extended attribute %s on namespace" %
                                   identifier,
                                   [attr.location])
 
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -29,17 +29,17 @@ function getIntPref(prefName, def) {
   }
   catch(err) {
     return def;
   }
 }
 
 function handleWindowEvent(e) {
   if (this._browserElementParents) {
-    let beps = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(this._browserElementParents);
+    let beps = ChromeUtils.nondeterministicGetWeakMapKeys(this._browserElementParents);
     beps.forEach(bep => bep._handleOwnerEvent(e));
   }
 }
 
 function defineNoReturnMethod(fn) {
   return function method() {
     if (!this._domRequestReady) {
       // Remote browser haven't been created, we just queue the API call.
--- a/dom/webidl/ChromeUtils.webidl
+++ b/dom/webidl/ChromeUtils.webidl
@@ -1,120 +1,210 @@
 /* -*- Mode: IDL; 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/.
  */
 
 /**
- * A collection of static utility methods that are only exposed to Chrome. This
- * interface is not exposed in workers, while ThreadSafeChromeUtils is.
+ * A collection of static utility methods that are only exposed to system code.
+ * This is exposed in all the system globals where we can expose stuff by
+ * default, so should only include methods that are **thread-safe**.
  */
-[ChromeOnly, Exposed=(Window,System)]
-interface ChromeUtils : ThreadSafeChromeUtils {
+[ChromeOnly, Exposed=(Window,System,Worker)]
+namespace ChromeUtils {
+  /**
+   * Serialize a snapshot of the heap graph, as seen by |JS::ubi::Node| and
+   * restricted by |boundaries|, and write it to the provided file path.
+   *
+   * @param boundaries        The portion of the heap graph to write.
+   *
+   * @returns                 The path to the file the heap snapshot was written
+   *                          to. This is guaranteed to be within the temp
+   *                          directory and its file name will match the regexp
+   *                          `\d+(\-\d+)?\.fxsnapshot`.
+   */
+  [Throws]
+  DOMString saveHeapSnapshot(optional HeapSnapshotBoundaries boundaries);
+
+  /**
+   * This is the same as saveHeapSnapshot, but with a different return value.
+   *
+   * @returns                 The snapshot ID of the file. This is the file name
+   *                          without the temp directory or the trailing
+   *                          `.fxsnapshot`.
+   */
+  [Throws]
+  DOMString saveHeapSnapshotGetId(optional HeapSnapshotBoundaries boundaries);
+
+  /**
+   * Deserialize a core dump into a HeapSnapshot.
+   *
+   * @param filePath          The file path to read the heap snapshot from.
+   */
+  [Throws, NewObject]
+  HeapSnapshot readHeapSnapshot(DOMString filePath);
+
+  /**
+   * Return the keys in a weak map.  This operation is
+   * non-deterministic because it is affected by the scheduling of the
+   * garbage collector and the cycle collector.
+   *
+   * @param aMap weak map or other JavaScript value
+   * @returns If aMap is a weak map object, return the keys of the weak
+   *          map as an array.  Otherwise, return undefined.
+   */
+  [Throws, NewObject]
+  any nondeterministicGetWeakMapKeys(any map);
+
+  /**
+   * Return the keys in a weak set.  This operation is
+   * non-deterministic because it is affected by the scheduling of the
+   * garbage collector and the cycle collector.
+   *
+   * @param aSet weak set or other JavaScript value
+   * @returns If aSet is a weak set object, return the keys of the weak
+   *          set as an array.  Otherwise, return undefined.
+   */
+  [Throws, NewObject]
+  any nondeterministicGetWeakSetKeys(any aSet);
+
+  /**
+   * Converts a buffer to a Base64 URL-encoded string per RFC 4648.
+   *
+   * @param source The buffer to encode.
+   * @param options Additional encoding options.
+   * @returns The encoded string.
+   */
+  [Throws]
+  ByteString base64URLEncode(BufferSource source,
+                             Base64URLEncodeOptions options);
+
+  /**
+   * Decodes a Base64 URL-encoded string per RFC 4648.
+   *
+   * @param string The string to decode.
+   * @param options Additional decoding options.
+   * @returns The decoded buffer.
+   */
+  [Throws, NewObject]
+  ArrayBuffer base64URLDecode(ByteString string,
+                              Base64URLDecodeOptions options);
+
+  /**
+   * IF YOU ADD NEW METHODS HERE, MAKE SURE THEY ARE THREAD-SAFE.
+   */
+};
+
+/**
+ * Additional ChromeUtils methods that are _not_ thread-safe, and hence not
+ * exposed in workers.
+ */
+[Exposed=(Window,System)]
+partial namespace ChromeUtils {
   /**
    * A helper that converts OriginAttributesDictionary to a opaque suffix string.
    *
    * @param originAttrs       The originAttributes from the caller.
    */
-  static ByteString
+  ByteString
   originAttributesToSuffix(optional OriginAttributesDictionary originAttrs);
 
   /**
    * Returns true if the members of |originAttrs| match the provided members
    * of |pattern|.
    *
    * @param originAttrs       The originAttributes under consideration.
    * @param pattern           The pattern to use for matching.
    */
-  static boolean
+  boolean
   originAttributesMatchPattern(optional OriginAttributesDictionary originAttrs,
                                optional OriginAttributesPatternDictionary pattern);
 
   /**
    * Returns an OriginAttributesDictionary with values from the |origin| suffix
    * and unspecified attributes added and assigned default values.
    *
    * @param origin            The origin URI to create from.
    * @returns                 An OriginAttributesDictionary with values from
    *                          the origin suffix and unspecified attributes
    *                          added and assigned default values.
    */
   [Throws]
-  static OriginAttributesDictionary
+  OriginAttributesDictionary
   createOriginAttributesFromOrigin(DOMString origin);
 
   /**
    * Returns an OriginAttributesDictionary that is a copy of |originAttrs| with
    * unspecified attributes added and assigned default values.
    *
    * @param originAttrs       The origin attributes to copy.
    * @returns                 An OriginAttributesDictionary copy of |originAttrs|
    *                          with unspecified attributes added and assigned
    *                          default values.
    */
-  static OriginAttributesDictionary
+  OriginAttributesDictionary
   fillNonDefaultOriginAttributes(optional OriginAttributesDictionary originAttrs);
 
   /**
    * Returns true if the 2 OriginAttributes are equal.
    */
-  static boolean
+  boolean
   isOriginAttributesEqual(optional OriginAttributesDictionary aA,
                           optional OriginAttributesDictionary aB);
 
   /**
    * Loads and compiles the script at the given URL and returns an object
    * which may be used to execute it repeatedly, in different globals, without
    * re-parsing.
    */
-  [NewObject, Throws]
-  static Promise<PrecompiledScript>
+  [NewObject]
+  Promise<PrecompiledScript>
   compileScript(DOMString url, optional CompileScriptOptionsDictionary options);
 
   /**
    * Waive Xray on a given value. Identity op for primitives.
    */
   [Throws]
-  static any waiveXrays(any val);
+  any waiveXrays(any val);
 
   /**
    * Strip off Xray waivers on a given value. Identity op for primitives.
    */
   [Throws]
-  static any unwaiveXrays(any val);
+  any unwaiveXrays(any val);
 
   /**
    * Gets the name of the JSClass of the object.
    *
    * if |unwrap| is true, all wrappers are unwrapped first. Unless you're
    * specifically trying to detect whether the object is a proxy, this is
    * probably what you want.
    */
-  static DOMString getClassName(object obj, optional boolean unwrap = true);
+  DOMString getClassName(object obj, optional boolean unwrap = true);
 
   /**
    * Clones the properties of the given object into a new object in the given
    * target compartment (or the caller compartment if no target is provided).
    * Property values themeselves are not cloned.
    *
    * Ignores non-enumerable properties, properties on prototypes, and properties
    * with getters or setters.
    */
   [Throws]
-  static object shallowClone(object obj, optional object? target = null);
+  object shallowClone(object obj, optional object? target = null);
 
   /**
    * Dispatches the given callback to the main thread when it would be
    * otherwise idle. Similar to Window.requestIdleCallback, but not bound to a
    * particular DOM windw.
    */
   [Throws]
-  static void idleDispatch(IdleRequestCallback callback,
-                           optional IdleRequestOptions options);
+  void idleDispatch(IdleRequestCallback callback,
+                    optional IdleRequestOptions options);
 };
 
 /**
  * Used by principals and the script security manager to represent origin
  * attributes. The first dictionary is designed to contain the full set of
  * OriginAttributes, the second is used for pattern-matching (i.e. does this
  * OriginAttributesDictionary match the non-empty attributes in this pattern).
  *
@@ -154,8 +244,68 @@ dictionary CompileScriptOptionsDictionar
   /**
    * If true, the script will be compiled so that its last expression will be
    * returned as the value of its execution. This makes certain types of
    * optimization impossible, and disables the JIT in many circumstances, so
    * should not be used when not absolutely necessary.
    */
   boolean hasReturnValue = false;
 };
+
+/**
+ * A JS object whose properties specify what portion of the heap graph to
+ * write. The recognized properties are:
+ *
+ * * globals: [ global, ... ]
+ *   Dump only nodes that either:
+ *   - belong in the compartment of one of the given globals;
+ *   - belong to no compartment, but do belong to a Zone that contains one of
+ *     the given globals;
+ *   - are referred to directly by one of the last two kinds of nodes; or
+ *   - is the fictional root node, described below.
+ *
+ * * debugger: Debugger object
+ *   Like "globals", but use the Debugger's debuggees as the globals.
+ *
+ * * runtime: true
+ *   Dump the entire heap graph, starting with the JSRuntime's roots.
+ *
+ * One, and only one, of these properties must exist on the boundaries object.
+ *
+ * The root of the dumped graph is a fictional node whose ubi::Node type name is
+ * "CoreDumpRoot". If we are dumping the entire ubi::Node graph, this root node
+ * has an edge for each of the JSRuntime's roots. If we are dumping a selected
+ * set of globals, the root has an edge to each global, and an edge for each
+ * incoming JS reference to the selected Zones.
+ */
+dictionary HeapSnapshotBoundaries {
+  sequence<object> globals;
+  object           debugger;
+  boolean          runtime;
+};
+
+dictionary Base64URLEncodeOptions {
+  /** Specifies whether the output should be padded with "=" characters. */
+  required boolean pad;
+};
+
+enum Base64URLDecodePadding {
+  /**
+   * Fails decoding if the input is unpadded. RFC 4648, section 3.2 requires
+   * padding, unless the referring specification prohibits it.
+   */
+  "require",
+
+  /** Tolerates padded and unpadded input. */
+  "ignore",
+
+  /**
+   * Fails decoding if the input is padded. This follows the strict base64url
+   * variant used in JWS (RFC 7515, Appendix C) and HTTP Encrypted
+   * Content-Encoding (draft-ietf-httpbis-encryption-encoding-01).
+   */
+  "reject"
+};
+
+dictionary Base64URLDecodeOptions {
+  /** Specifies the padding mode for decoding the input. */
+  required Base64URLDecodePadding padding;
+};
deleted file mode 100644
--- a/dom/webidl/ThreadSafeChromeUtils.webidl
+++ /dev/null
@@ -1,150 +0,0 @@
-/* -*- Mode: IDL; 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/.
- */
-
-/**
- * A collection of **thread-safe** static utility methods that are only exposed
- * to Chrome. This interface is exposed in workers, while ChromeUtils is not.
- */
-[ChromeOnly, Exposed=(Window,System,Worker)]
-interface ThreadSafeChromeUtils {
-  /**
-   * Serialize a snapshot of the heap graph, as seen by |JS::ubi::Node| and
-   * restricted by |boundaries|, and write it to the provided file path.
-   *
-   * @param boundaries        The portion of the heap graph to write.
-   *
-   * @returns                 The path to the file the heap snapshot was written
-   *                          to. This is guaranteed to be within the temp
-   *                          directory and its file name will match the regexp
-   *                          `\d+(\-\d+)?\.fxsnapshot`.
-   */
-  [Throws]
-  static DOMString saveHeapSnapshot(optional HeapSnapshotBoundaries boundaries);
-
-  /**
-   * This is the same as saveHeapSnapshot, but with a different return value.
-   *
-   * @returns                 The snapshot ID of the file. This is the file name
-   *                          without the temp directory or the trailing
-   *                          `.fxsnapshot`.
-   */
-  [Throws]
-  static DOMString saveHeapSnapshotGetId(optional HeapSnapshotBoundaries boundaries);
-
-  /**
-   * Deserialize a core dump into a HeapSnapshot.
-   *
-   * @param filePath          The file path to read the heap snapshot from.
-   */
-  [Throws, NewObject]
-  static HeapSnapshot readHeapSnapshot(DOMString filePath);
-
-  /**
-   * Return the keys in a weak map.  This operation is
-   * non-deterministic because it is affected by the scheduling of the
-   * garbage collector and the cycle collector.
-   *
-   * @param aMap weak map or other JavaScript value
-   * @returns If aMap is a weak map object, return the keys of the weak
-   *          map as an array.  Otherwise, return undefined.
-   */
-  [Throws, NewObject]
-  static any nondeterministicGetWeakMapKeys(any map);
-
-  /**
-   * Return the keys in a weak set.  This operation is
-   * non-deterministic because it is affected by the scheduling of the
-   * garbage collector and the cycle collector.
-   *
-   * @param aSet weak set or other JavaScript value
-   * @returns If aSet is a weak set object, return the keys of the weak
-   *          set as an array.  Otherwise, return undefined.
-   */
-  [Throws, NewObject]
-  static any nondeterministicGetWeakSetKeys(any aSet);
-
-  /**
-   * Converts a buffer to a Base64 URL-encoded string per RFC 4648.
-   *
-   * @param source The buffer to encode.
-   * @param options Additional encoding options.
-   * @returns The encoded string.
-   */
-  [Throws]
-  static ByteString base64URLEncode(BufferSource source,
-                                    Base64URLEncodeOptions options);
-
-  /**
-   * Decodes a Base64 URL-encoded string per RFC 4648.
-   *
-   * @param string The string to decode.
-   * @param options Additional decoding options.
-   * @returns The decoded buffer.
-   */
-  [Throws, NewObject]
-  static ArrayBuffer base64URLDecode(ByteString string,
-                                     Base64URLDecodeOptions options);
-};
-
-/**
- * A JS object whose properties specify what portion of the heap graph to
- * write. The recognized properties are:
- *
- * * globals: [ global, ... ]
- *   Dump only nodes that either:
- *   - belong in the compartment of one of the given globals;
- *   - belong to no compartment, but do belong to a Zone that contains one of
- *     the given globals;
- *   - are referred to directly by one of the last two kinds of nodes; or
- *   - is the fictional root node, described below.
- *
- * * debugger: Debugger object
- *   Like "globals", but use the Debugger's debuggees as the globals.
- *
- * * runtime: true
- *   Dump the entire heap graph, starting with the JSRuntime's roots.
- *
- * One, and only one, of these properties must exist on the boundaries object.
- *
- * The root of the dumped graph is a fictional node whose ubi::Node type name is
- * "CoreDumpRoot". If we are dumping the entire ubi::Node graph, this root node
- * has an edge for each of the JSRuntime's roots. If we are dumping a selected
- * set of globals, the root has an edge to each global, and an edge for each
- * incoming JS reference to the selected Zones.
- */
-dictionary HeapSnapshotBoundaries {
-  sequence<object> globals;
-  object           debugger;
-  boolean          runtime;
-};
-
-dictionary Base64URLEncodeOptions {
-  /** Specifies whether the output should be padded with "=" characters. */
-  required boolean pad;
-};
-
-enum Base64URLDecodePadding {
-  /**
-   * Fails decoding if the input is unpadded. RFC 4648, section 3.2 requires
-   * padding, unless the referring specification prohibits it.
-   */
-  "require",
-
-  /** Tolerates padded and unpadded input. */
-  "ignore",
-
-  /**
-   * Fails decoding if the input is padded. This follows the strict base64url
-   * variant used in JWS (RFC 7515, Appendix C) and HTTP Encrypted
-   * Content-Encoding (draft-ietf-httpbis-encryption-encoding-01).
-   */
-  "reject"
-};
-
-dictionary Base64URLDecodeOptions {
-  /** Specifies the padding mode for decoding the input. */
-  required Base64URLDecodePadding padding;
-};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -308,19 +308,16 @@ with Files("SubtleCrypto.webidl"):
     BUG_COMPONENT = ("Core", "DOM: Security")
 
 with Files("TCP*"):
     BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
 
 with Files("TextTrack*"):
     BUG_COMPONENT = ("Core", "Audio/Video")
 
-with Files("ThreadSafeChromeUtils.webidl"):
-    BUG_COMPONENT = ("Firefox", "Developer Tools: Memory")
-
 with Files("TrackEvent.webidl"):
     BUG_COMPONENT = ("Core", "Audio/Video")
 
 with Files("U2F.webidl"):
     BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
 
 with Files("UDP*"):
     BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
@@ -923,17 +920,16 @@ WEBIDL_FILES = [
     'Text.webidl',
     'TextClause.webidl',
     'TextDecoder.webidl',
     'TextEncoder.webidl',
     'TextTrack.webidl',
     'TextTrackCue.webidl',
     'TextTrackCueList.webidl',
     'TextTrackList.webidl',
-    'ThreadSafeChromeUtils.webidl',
     'TimeEvent.webidl',
     'TimeRanges.webidl',
     'Touch.webidl',
     'TouchEvent.webidl',
     'TouchList.webidl',
     'TransitionEvent.webidl',
     'TreeBoxObject.webidl',
     'TreeColumn.webidl',
--- a/js/xpconnect/tests/chrome/test_getweakmapkeys.xul
+++ b/js/xpconnect/tests/chrome/test_getweakmapkeys.xul
@@ -17,26 +17,26 @@ https://bugzilla.mozilla.org/show_bug.cg
   <!-- test code goes here -->
   <script type="application/javascript">
   <![CDATA[
   /** Test for Bug 688277 **/
 
   let Cu = Components.utils;
 
   /* Fail gracefully if junk is passed in. */
-  is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(11), undefined,
+  is(ChromeUtils.nondeterministicGetWeakMapKeys(11), undefined,
     "nondeterministicGetWeakMapKeys should return undefined for non-objects");
-  is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys({}), undefined,
+  is(ChromeUtils.nondeterministicGetWeakMapKeys({}), undefined,
     "nondeterministicGetWeakMapKeys should return undefined for non-weakmap objects");
-  is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(null), undefined,
+  is(ChromeUtils.nondeterministicGetWeakMapKeys(null), undefined,
     "nondeterministicGetWeakMapKeys should return undefined for null");
 
   /* return an empty array for an empty WeakMap */
   let mempty = new WeakMap();
-  is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(mempty).length, 0,
+  is(ChromeUtils.nondeterministicGetWeakMapKeys(mempty).length, 0,
     "nondeterministicGetWeakMapKeys should return empty array for empty weakmap");
 
   /* Test freeing/nonfreeing. */
   let m = new WeakMap();
   let liveKeys = new Array();
 
   let add_elements = function () {
     let k1 = {};
@@ -48,17 +48,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     let k = {};
     m.set(k, k); /* simple cycle */
   };
 
   add_elements();
 
   Cu.schedulePreciseGC(function () {
-    let keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(m);
+    let keys = ChromeUtils.nondeterministicGetWeakMapKeys(m);
     is(liveKeys.length, 1, "Wrong number of live keys.");
     is(keys.length, 1, "Should have one weak map key.");
     is(m.get(keys[0]), "live1", "live1 should be live");
     SimpleTest.finish();
   });
 
   SimpleTest.waitForExplicitFinish();
 
--- a/js/xpconnect/tests/chrome/test_paris_weakmap_keys.xul
+++ b/js/xpconnect/tests/chrome/test_paris_weakmap_keys.xul
@@ -62,17 +62,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   SimpleTest.waitForExplicitFinish();
 
   Cu.schedulePreciseGC(function () {
     SpecialPowers.DOMWindowUtils.cycleCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
 
-    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 1,
+    is(ChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 1,
        "Live nsISupports new DOM bindings wrappercached native weak map key should not be removed.");
 
     is(live_map.get(get_div_style()), 12345, "Live map should have live style with right value after GC.");
 
     SimpleTest.finish();
   });
 
   ]]>
--- a/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xul
+++ b/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xul
@@ -49,30 +49,30 @@ https://bugzilla.mozilla.org/show_bug.cg
     sandbox.wrapper = wrappee;
     sandbox.value = dead_dom;
     let map = Cu.evalInSandbox("wm = new WeakMap(); wm.set(wrapper, value); wm", sandbox);
     sandbox.wrapper = null;
     sandbox.value = null;
 
     live_dom.xyzabc = {wrappee: wrappee, m: map, sb: sandbox};
 
-    let key = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(map)[0];
+    let key = ChromeUtils.nondeterministicGetWeakMapKeys(map)[0];
     let value = map.get(key);
     is(value.children.length, 1, "children have wrong length");
   }
 
   wrappers_as_keys_test();
 
   let check_wrappers_as_keys = function () {
     let live_dom = window.eeeevent.data.dummy;
     let live_map = live_dom.xyzabc.m;
     let sandbox = live_dom.xyzabc.sb;
-    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 1,
+    is(ChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 1,
       "Map should not be empty.");
-    let key = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(live_map)[0];
+    let key = ChromeUtils.nondeterministicGetWeakMapKeys(live_map)[0];
     let value = live_map.get(key);
     is(value.children.length, 1, "children have wrong length");
   }
 
   Cu.schedulePreciseGC(function () {
     SpecialPowers.DOMWindowUtils.cycleCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
 
--- a/js/xpconnect/tests/chrome/test_weakmaps.xul
+++ b/js/xpconnect/tests/chrome/test_weakmaps.xul
@@ -26,17 +26,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   let make_weak_ref = function (obj) {
     let m = new WeakMap;
     m.set(obj, {});
     return m;
   };
 
   /* Check to see if a weak reference is dead. */
   let weak_ref_dead = function (r) {
-    return ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(r).length == 0;
+    return ChromeUtils.nondeterministicGetWeakMapKeys(r).length == 0;
   }
 
   /* Deterministically grab an arbitrary DOM element. */
   let get_live_dom = function () {
     let elems = document.getElementsByTagName("a");
     return elems[0];
   };
 
@@ -113,25 +113,25 @@ https://bugzilla.mozilla.org/show_bug.cg
     ok(weak_ref_dead(basic_weak_ref), "Dead value was kept alive.");
     ok(weak_ref_dead(basic_map_weak_ref), "Dead map was kept alive.");
 
     // check the live gray map
     is(live_map.get(live_key).my_key, 'live_live',
       "Live key should have the same value in live map.");
     is(live_map.get(black_key).my_key, 'live_black',
       "Black key should have the same value in live map.");
-    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 2,
+    is(ChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 2,
       "Live map should have two entries.");
 
     // check the live black map
     is(black_map.get(live_key).my_key, 'black_live',
       "Live key should have the same value in black map.");
     is(black_map.get(black_key).my_key, 'black_black',
       "Black key should have the same value in black map.");
-    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(black_map).length, 2,
+    is(ChromeUtils.nondeterministicGetWeakMapKeys(black_map).length, 2,
       "Black map should have two entries.");    
 
   };
 
 
   /* live gray chained weak map entries, involving the cycle collector. */
   let chainm = new WeakMap;
   let num_chains = 5;
@@ -225,26 +225,26 @@ https://bugzilla.mozilla.org/show_bug.cg
     SpecialPowers.DOMWindowUtils.cycleCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
 
     ok(weak_ref_dead(weakref), "Garbage gray cycle should be collected.");
 
     check_nested_cc_maps();
 
-    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(garbage_map).length, 0, "Chained garbage weak map entries should not leak.");
+    is(ChromeUtils.nondeterministicGetWeakMapKeys(garbage_map).length, 0, "Chained garbage weak map entries should not leak.");
 
     check_basic_unit();
 
     // fixed by Bug 680937
-    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(wn_garbage_map).length, 0,
+    is(ChromeUtils.nondeterministicGetWeakMapKeys(wn_garbage_map).length, 0,
        "Chained garbage WN weak map entries should not leak.");
 
     // fixed by Bug 680937
-    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(wn_live_map).length, 1,
+    is(ChromeUtils.nondeterministicGetWeakMapKeys(wn_live_map).length, 1,
        "Live weak map wrapped native key should not be removed.");
 
     ok(wn_live_map.has(get_live_dom()), "Live map should have live dom.");
 
     SimpleTest.finish();
   });
 
   ]]>
--- a/js/xpconnect/tests/unit/test_weak_keys.js
+++ b/js/xpconnect/tests/unit/test_weak_keys.js
@@ -9,37 +9,37 @@ function run_test()
   var bunnies = new String("bunnies");
   var lizards = new String("lizards");
 
   var weakset = new WeakSet([bunnies, lizards]);
   var weakmap = new WeakMap();
   weakmap.set(bunnies, 23);
   weakmap.set(lizards, "oh no");
 
-  var keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(bunnies);
+  var keys = ChromeUtils.nondeterministicGetWeakMapKeys(bunnies);
   equal(keys, undefined, "test nondeterministicGetWeakMapKeys on non-WeakMap");
 
-  keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(weakmap);
+  keys = ChromeUtils.nondeterministicGetWeakMapKeys(weakmap);
   equal(keys.length, 2, "length of nondeterministicGetWeakMapKeys");
   equal(weakmap.get(bunnies), 23, "check bunnies in weakmap");
   equal(weakmap.get(lizards), "oh no", "check lizards in weakmap");
 
-  keys = ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys(bunnies);
+  keys = ChromeUtils.nondeterministicGetWeakSetKeys(bunnies);
   equal(keys, undefined, "test nondeterministicGetWeakSetKeys on non-WeakMap");
 
-  keys = ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys(weakset);
+  keys = ChromeUtils.nondeterministicGetWeakSetKeys(weakset);
   equal(keys.length, 2, "length of nondeterministicGetWeakSetKeys");
   ok(weakset.has(bunnies), "check bunnies in weakset");
   ok(weakset.has(lizards), "check lizards in weakset");
 
   bunnies = null;
   keys = null;
 
   Components.utils.forceGC();
 
-  keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(weakmap);
+  keys = ChromeUtils.nondeterministicGetWeakMapKeys(weakmap);
   equal(keys.length, 1, "length of nondeterministicGetWeakMapKeys after GC");
   equal(weakmap.get(lizards), "oh no", "check lizards still in weakmap");
 
-  keys = ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys(weakset);
+  keys = ChromeUtils.nondeterministicGetWeakSetKeys(weakset);
   equal(keys.length, 1, "length of nondeterministicGetWeakSetKeys after GC");
   ok(weakset.has(lizards), "check lizards still in weakset");
 }
--- a/testing/talos/talos/tests/devtools/addon/content/damp.js
+++ b/testing/talos/talos/tests/devtools/addon/content/damp.js
@@ -14,18 +14,18 @@ XPCOMUtils.defineLazyGetter(this, "gDevT
 XPCOMUtils.defineLazyGetter(this, "EVENTS", function() {
   let { EVENTS } = require("devtools/client/netmonitor/src/constants");
   return EVENTS;
 });
 XPCOMUtils.defineLazyGetter(this, "TargetFactory", function() {
   let { TargetFactory } = require("devtools/client/framework/target");
   return TargetFactory;
 });
-XPCOMUtils.defineLazyGetter(this, "ThreadSafeChromeUtils", function() {
-  return require("ThreadSafeChromeUtils");
+XPCOMUtils.defineLazyGetter(this, "ChromeUtils", function() {
+  return require("ChromeUtils");
 });
 
 const webserver = Services.prefs.getCharPref("addon.test.damp.webserver");
 
 const SIMPLE_URL = webserver + "/tests/devtools/addon/content/pages/simple.html";
 const COMPLICATED_URL = webserver + "/tests/tp5n/bild.de/www.bild.de/index.html";
 
 function getMostRecentBrowserWindow() {
@@ -137,17 +137,17 @@ Damp.prototype = {
         name: label + ".saveHeapSnapshot",
         value: end - start
       });
     });
   },
 
   readHeapSnapshot(label) {
     let start = performance.now();
-    this._snapshot = ThreadSafeChromeUtils.readHeapSnapshot(this._heapSnapshotFilePath);
+    this._snapshot = ChromeUtils.readHeapSnapshot(this._heapSnapshotFilePath);
     let end = performance.now();
     this._results.push({
       name: label + ".readHeapSnapshot",
       value: end - start
     });
     return Promise.resolve();
   },
 
--- a/toolkit/components/ctypes/tests/unit/head.js
+++ b/toolkit/components/ctypes/tests/unit/head.js
@@ -1,9 +1,9 @@
-/* global ThreadSafeChromeUtils */
+/* global ChromeUtils */
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 try {
   // We might be running without privileges, in which case it's up to the
   // harness to give us the 'ctypes' object.
   Components.utils.import("resource://gre/modules/ctypes.jsm");
 } catch (e) {
@@ -21,17 +21,17 @@ function ResourceCleaner() {
   this._map = new WeakMap();
 }
 ResourceCleaner.prototype = {
   add: function ResourceCleaner_add(v) {
     this._map.set(v);
     return v;
   },
   cleanup: function ResourceCleaner_cleanup() {
-    let keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(this._map);
+    let keys = ChromeUtils.nondeterministicGetWeakMapKeys(this._map);
     keys.forEach(k => {
       try {
         k.dispose();
       } catch (x) {
         // This can fail if |forget|/|dispose| has been called manually
         // during the test. This is normal.
       }
       this._map.delete(k);