Bug 1350958 - Finish labeling ProxyReleaseEvent, r=billm
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 14 Jul 2017 08:49:22 +0200
changeset 368821 bfd1975229fddbaf6994373e4a8e9180080677d9
parent 368820 e23b4fd5dce3a7ef94e21943ebba42af3db30f85
child 368822 85a383b0638256b457b42689c8580200ad52e669
push id32173
push userryanvm@gmail.com
push dateFri, 14 Jul 2017 12:35:16 +0000
treeherdermozilla-central@66e27c932aae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1350958
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1350958 - Finish labeling ProxyReleaseEvent, r=billm
dom/base/WebSocket.cpp
dom/base/nsDOMDataChannel.cpp
dom/base/nsDOMDataChannel.h
dom/cache/ManagerId.cpp
dom/console/Console.cpp
dom/filesystem/GetFilesHelper.cpp
dom/media/MediaStreamGraph.cpp
dom/media/webspeech/recognition/SpeechStreamListener.cpp
dom/script/ScriptLoader.cpp
dom/workers/ServiceWorkerJob.cpp
dom/workers/WorkerPrivate.cpp
extensions/spellcheck/src/mozPersonalDictionary.cpp
gfx/thebes/gfxFontSrcPrincipal.cpp
gfx/thebes/gfxFontSrcURI.cpp
image/decoders/icon/mac/nsIconChannelCocoa.mm
image/decoders/icon/win/nsIconChannel.cpp
ipc/mscom/MainThreadHandoff.cpp
ipc/mscom/WeakRef.cpp
js/src/devtools/rootAnalysis/analyzeHeapWrites.js
js/xpconnect/loader/ScriptPreloader.cpp
layout/style/URLExtraData.cpp
layout/style/nsStyleStruct.cpp
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
modules/libjar/nsJARChannel.cpp
netwerk/base/TLSServerSocket.cpp
netwerk/base/nsBaseChannel.cpp
netwerk/base/nsProtocolProxyService.cpp
netwerk/cache2/CacheIndex.h
netwerk/protocol/gio/nsGIOProtocolHandler.cpp
netwerk/protocol/websocket/BaseWebSocketChannel.cpp
netwerk/protocol/websocket/WebSocketChannel.cpp
netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
netwerk/sctp/datachannel/DataChannel.cpp
security/manager/ssl/nsNSSCallbacks.cpp
storage/mozStorageConnection.cpp
storage/mozStorageService.cpp
storage/mozStorageStatementData.h
toolkit/components/osfile/NativeOSFileInternals.cpp
toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
xpcom/base/JSObjectHolder.h
xpcom/base/nsConsoleService.cpp
xpcom/threads/nsProxyRelease.h
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -640,18 +640,20 @@ WebSocketImpl::Disconnect()
       new DisconnectInternalRunnable(this);
     ErrorResult rv;
     runnable->Dispatch(Killing, rv);
     // XXXbz this seems totally broken.  We should be propagating this out, but
     // where to, exactly?
     rv.SuppressException();
   }
 
-  NS_ReleaseOnMainThread("WebSocketImpl::mChannel", mChannel.forget());
-  NS_ReleaseOnMainThread("WebSocketImpl::mService", mService.forget());
+  NS_ReleaseOnMainThreadSystemGroup("WebSocketImpl::mChannel",
+                                    mChannel.forget());
+  NS_ReleaseOnMainThreadSystemGroup("WebSocketImpl::mService",
+                                    mService.forget());
 
   mWebSocket->DontKeepAliveAnyMore();
   mWebSocket->mImpl = nullptr;
 
   if (mWorkerPrivate && mWorkerHolder) {
     UnregisterWorkerHolder();
   }
 
--- a/dom/base/nsDOMDataChannel.cpp
+++ b/dom/base/nsDOMDataChannel.cpp
@@ -572,37 +572,45 @@ nsDOMDataChannel::UpdateMustKeepAlive()
 
     case DataChannel::CLOSED:
     {
       shouldKeepAlive = false;
     }
   }
 
   if (mSelfRef && !shouldKeepAlive) {
-    // release our self-reference (safely) by putting it in an event (always)
-    NS_ReleaseOnMainThread("nsDOMDataChannel::mSelfRef", mSelfRef.forget(), true);
+    ReleaseSelf();
   } else if (!mSelfRef && shouldKeepAlive) {
     mSelfRef = this;
   }
 }
 
 void
 nsDOMDataChannel::DontKeepAliveAnyMore()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mSelfRef) {
-    // Since we're on MainThread, force an eventloop trip to avoid deleting ourselves.
-    NS_ReleaseOnMainThread("nsDOMDataChannel::mSelfRef", mSelfRef.forget(), true);
+    // Since we're on MainThread, force an eventloop trip to avoid deleting
+    // ourselves.
+    ReleaseSelf();
   }
 
   mCheckMustKeepAlive = false;
 }
 
 void
+nsDOMDataChannel::ReleaseSelf()
+{
+  // release our self-reference (safely) by putting it in an event (always)
+  NS_ReleaseOnMainThreadSystemGroup("nsDOMDataChannel::mSelfRef",
+                                    mSelfRef.forget(), true);
+}
+
+void
 nsDOMDataChannel::EventListenerAdded(nsIAtom* aType)
 {
   MOZ_ASSERT(NS_IsMainThread());
   UpdateMustKeepAlive();
 }
 
 void
 nsDOMDataChannel::EventListenerRemoved(nsIAtom* aType)
--- a/dom/base/nsDOMDataChannel.h
+++ b/dom/base/nsDOMDataChannel.h
@@ -125,16 +125,18 @@ public:
 
 protected:
   ~nsDOMDataChannel();
 
 private:
   void Send(nsIInputStream* aMsgStream, const nsACString& aMsgString,
             uint32_t aMsgLength, bool aIsBinary, mozilla::ErrorResult& aRv);
 
+  void ReleaseSelf();
+
   // to keep us alive while we have listeners
   RefPtr<nsDOMDataChannel> mSelfRef;
   // Owning reference
   RefPtr<mozilla::DataChannel> mDataChannel;
   nsString  mOrigin;
   enum DataChannelBinaryType {
     DC_BINARY_TYPE_ARRAYBUFFER,
     DC_BINARY_TYPE_BLOB,
--- a/dom/cache/ManagerId.cpp
+++ b/dom/cache/ManagerId.cpp
@@ -60,15 +60,15 @@ ManagerId::~ManagerId()
   if (NS_IsMainThread()) {
     return;
   }
 
   // Otherwise we need to proxy to main thread to do the release
 
   // The PBackground worker thread shouldn't be running after the main thread
   // is stopped.  So main thread is guaranteed to exist here.
-  NS_ReleaseOnMainThread(
+  NS_ReleaseOnMainThreadSystemGroup(
     "ManagerId::mPrincipal", mPrincipal.forget());
 }
 
 } // namespace cache
 } // namespace dom
 } // namespace mozilla
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -881,20 +881,18 @@ Console::Shutdown()
   if (NS_IsMainThread()) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->RemoveObserver(this, "inner-window-destroyed");
       obs->RemoveObserver(this, "memory-pressure");
     }
   }
 
-  NS_ReleaseOnMainThread(
-    "Console::mStorage", mStorage.forget());
-  NS_ReleaseOnMainThread(
-    "Console::mSandbox", mSandbox.forget());
+  NS_ReleaseOnMainThreadSystemGroup("Console::mStorage", mStorage.forget());
+  NS_ReleaseOnMainThreadSystemGroup("Console::mSandbox", mSandbox.forget());
 
   mTimerRegistry.Clear();
   mCounterRegistry.Clear();
 
   mCallDataStorage.Clear();
   mCallDataStoragePending.Clear();
 
   mStatus = eShuttingDown;
--- a/dom/filesystem/GetFilesHelper.cpp
+++ b/dom/filesystem/GetFilesHelper.cpp
@@ -613,17 +613,17 @@ GetFilesHelperParent::GetFilesHelperPare
                                            bool aRecursiveFlag)
   : GetFilesHelper(nullptr, aRecursiveFlag)
   , mContentParent(aContentParent)
   , mUUID(aUUID)
 {}
 
 GetFilesHelperParent::~GetFilesHelperParent()
 {
-  NS_ReleaseOnMainThread(
+  NS_ReleaseOnMainThreadSystemGroup(
     "GetFilesHelperParent::mContentParent", mContentParent.forget());
 }
 
 /* static */ already_AddRefed<GetFilesHelperParent>
 GetFilesHelperParent::Create(const nsID& aUUID, const nsAString& aDirectoryPath,
                              bool aRecursiveFlag, ContentParent* aContentParent,
                              ErrorResult& aRv)
 {
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -1767,17 +1767,17 @@ MediaStreamGraphImpl::RunInStableState(b
              CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver"
                                                       : "SystemDriver"));
         RefPtr<GraphDriver> driver = CurrentDriver();
         MonitorAutoUnlock unlock(mMonitor);
         driver->Start();
         // It's not safe to Shutdown() a thread from StableState, and
         // releasing this may shutdown a SystemClockDriver thread.
         // Proxy the release to outside of StableState.
-        NS_ReleaseOnMainThread(
+        NS_ReleaseOnMainThreadSystemGroup(
           "MediaStreamGraphImpl::CurrentDriver", driver.forget(),
           true); // always proxy
       }
     }
 
     if ((mForceShutDown || !mRealtime) &&
         mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP) {
       // Defer calls to RunDuringShutdown() to happen while mMonitor is not held.
--- a/dom/media/webspeech/recognition/SpeechStreamListener.cpp
+++ b/dom/media/webspeech/recognition/SpeechStreamListener.cpp
@@ -14,17 +14,17 @@ namespace dom {
 
 SpeechStreamListener::SpeechStreamListener(SpeechRecognition* aRecognition)
   : mRecognition(aRecognition)
 {
 }
 
 SpeechStreamListener::~SpeechStreamListener()
 {
-  NS_ReleaseOnMainThread(
+  NS_ReleaseOnMainThreadSystemGroup(
     "SpeechStreamListener::mRecognition", mRecognition.forget());
 }
 
 void
 SpeechStreamListener::NotifyQueuedAudioData(MediaStreamGraph* aGraph, TrackID aID,
                                             StreamTime aTrackOffset,
                                             const AudioSegment& aQueuedMedia,
                                             MediaStream* aInputStream,
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -1552,20 +1552,20 @@ ScriptLoader::ProcessOffThreadRequest(Sc
   nsresult rv = ProcessRequest(aRequest);
   mDocument->UnblockOnload(false);
   return rv;
 }
 
 NotifyOffThreadScriptLoadCompletedRunnable::~NotifyOffThreadScriptLoadCompletedRunnable()
 {
   if (MOZ_UNLIKELY(mRequest || mLoader) && !NS_IsMainThread()) {
-    NS_ReleaseOnMainThread(
-      "NotifyOffThreadScriptLoadCompletedRunnable::mRequest", mRequest.forget());
-    NS_ReleaseOnMainThread(
-      "NotifyOffThreadScriptLoadCompletedRunnable::mLoader", mLoader.forget());
+    NS_ReleaseOnMainThreadSystemGroup("NotifyOffThreadScriptLoadCompletedRunnable::mRequest",
+                                      mRequest.forget());
+    NS_ReleaseOnMainThreadSystemGroup("NotifyOffThreadScriptLoadCompletedRunnable::mLoader",
+                                      mLoader.forget());
   }
 }
 
 NS_IMETHODIMP
 NotifyOffThreadScriptLoadCompletedRunnable::Run()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
--- a/dom/workers/ServiceWorkerJob.cpp
+++ b/dom/workers/ServiceWorkerJob.cpp
@@ -227,17 +227,17 @@ ServiceWorkerJob::Finish(ErrorResult& aR
     mFinalCallback = nullptr;
   }
 
   // The callback might not consume the error.
   aRv.SuppressException();
 
   // Async release this object to ensure that our caller methods complete
   // as well.
-  NS_ReleaseOnMainThread("ServiceWorkerJob",
+  NS_ReleaseOnMainThreadSystemGroup("ServiceWorkerJob",
     kungFuDeathGrip.forget(), true /* always proxy */);
 }
 
 void
 ServiceWorkerJob::Finish(nsresult aRv)
 {
   ErrorResult converted(aRv);
   Finish(converted);
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -4130,17 +4130,17 @@ WorkerDebugger::WorkerDebugger(WorkerPri
 }
 
 WorkerDebugger::~WorkerDebugger()
 {
   MOZ_ASSERT(!mWorkerPrivate);
 
   if (!NS_IsMainThread()) {
     for (size_t index = 0; index < mListeners.Length(); ++index) {
-      NS_ReleaseOnMainThread(
+      NS_ReleaseOnMainThreadSystemGroup(
         "WorkerDebugger::mListeners", mListeners[index].forget());
     }
   }
 }
 
 NS_IMPL_ISUPPORTS(WorkerDebugger, nsIWorkerDebugger)
 
 NS_IMETHODIMP
--- a/extensions/spellcheck/src/mozPersonalDictionary.cpp
+++ b/extensions/spellcheck/src/mozPersonalDictionary.cpp
@@ -59,17 +59,17 @@ public:
   {
   }
 
   NS_IMETHOD Run() override
   {
     mDict->SyncLoad();
 
     // Release the dictionary on the main thread
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "mozPersonalDictionaryLoader::mDict",
       mDict.forget().downcast<mozIPersonalDictionary>());
 
     return NS_OK;
   }
 
 private:
   RefPtr<mozPersonalDictionary> mDict;
@@ -133,17 +133,17 @@ public:
       mDict->mSavePending = false;
       mon.Notify();
 
       // Leaving the block where 'mon' was declared will call the destructor
       // and unlock.
     }
 
     // Release the dictionary on the main thread.
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "mozPersonalDictionarySave::mDict",
       mDict.forget().downcast<mozIPersonalDictionary>());
 
     return NS_OK;
   }
 
 private:
   nsTArray<nsString> mDictWords;
--- a/gfx/thebes/gfxFontSrcPrincipal.cpp
+++ b/gfx/thebes/gfxFontSrcPrincipal.cpp
@@ -17,18 +17,18 @@ gfxFontSrcPrincipal::gfxFontSrcPrincipal
 
   uint32_t hash = 0;
   mPrincipal->GetHashValue(&hash);
   mHash = hash;
 }
 
 gfxFontSrcPrincipal::~gfxFontSrcPrincipal()
 {
-  NS_ReleaseOnMainThread("gfxFontSrcPrincipal::mPrincipal",
-                         mPrincipal.forget());
+  NS_ReleaseOnMainThreadSystemGroup("gfxFontSrcPrincipal::mPrincipal",
+                                    mPrincipal.forget());
 }
 
 bool
 gfxFontSrcPrincipal::Equals(gfxFontSrcPrincipal* aOther)
 {
   return BasePrincipal::Cast(mPrincipal)->
            FastEquals(BasePrincipal::Cast(aOther->mPrincipal));
 }
--- a/gfx/thebes/gfxFontSrcURI.cpp
+++ b/gfx/thebes/gfxFontSrcURI.cpp
@@ -30,18 +30,18 @@ gfxFontSrcURI::gfxFontSrcURI(nsIURI* aUR
   // If we have a data: URI, we know that it is backed by an nsSimpleURI,
   // and that we don't need to serialize it ahead of time.
   nsCString scheme;
   mURI->GetScheme(scheme);
 
   if (scheme.EqualsLiteral("data")) {
     // We know that nsSimpleURI::From returns us a pointer to the same object,
     // and we hold a strong reference to the object in mURI, so no need to
-    // hold it strongly here as well.  (And we'd have to NS_ReleaseOnMainThread
-    // it in our destructor anyway.)
+    // hold it strongly here as well.  (And we'd have to
+    // NS_ReleaseOnMainThreadSystemGroup it in our destructor anyway.)
     RefPtr<mozilla::net::nsSimpleURI> simpleURI =
       mozilla::net::nsSimpleURI::From(aURI);
     mSimpleURI = simpleURI;
 
     NS_ASSERTION(mSimpleURI, "Why aren't our data: URLs backed by nsSimpleURI?");
   } else {
     mSimpleURI = nullptr;
   }
@@ -55,17 +55,17 @@ gfxFontSrcURI::gfxFontSrcURI(nsIURI* aUR
   mInheritsSecurityContext =
     HasFlag(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT);
   mSyncLoadIsOK =
     HasFlag(aURI, nsIProtocolHandler::URI_SYNC_LOAD_IS_OK);
 }
 
 gfxFontSrcURI::~gfxFontSrcURI()
 {
-  NS_ReleaseOnMainThread("gfxFontSrcURI::mURI", mURI.forget());
+  NS_ReleaseOnMainThreadSystemGroup("gfxFontSrcURI::mURI", mURI.forget());
 }
 
 bool
 gfxFontSrcURI::Equals(gfxFontSrcURI* aOther)
 {
   if (mSimpleURI) {
     if (aOther->mSimpleURI) {
       return mSimpleURI->Equals(aOther->mSimpleURI);
--- a/image/decoders/icon/mac/nsIconChannelCocoa.mm
+++ b/image/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -34,17 +34,17 @@
 // nsIconChannel methods
 nsIconChannel::nsIconChannel()
 {
 }
 
 nsIconChannel::~nsIconChannel()
 {
   if (mLoadInfo) {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsIconChannel::mLoadInfo", mLoadInfo.forget());
   }
 }
 
 NS_IMPL_ISUPPORTS(nsIconChannel,
                   nsIChannel,
                   nsIRequest,
                   nsIRequestObserver,
--- a/image/decoders/icon/win/nsIconChannel.cpp
+++ b/image/decoders/icon/win/nsIconChannel.cpp
@@ -67,17 +67,17 @@ GetStockIconIDForName(const nsACString& 
 // nsIconChannel methods
 nsIconChannel::nsIconChannel()
 {
 }
 
 nsIconChannel::~nsIconChannel()
 {
   if (mLoadInfo) {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsIconChannel::mLoadInfo", mLoadInfo.forget());
   }
 }
 
 NS_IMPL_ISUPPORTS(nsIconChannel,
                   nsIChannel,
                   nsIRequest,
                   nsIRequestObserver,
--- a/ipc/mscom/MainThreadHandoff.cpp
+++ b/ipc/mscom/MainThreadHandoff.cpp
@@ -217,17 +217,17 @@ MainThreadHandoff::Release()
     // If so, we need to dispatch an event to delete ourselves.
     if (NS_IsMainThread()) {
       delete this;
     } else {
       // We need to delete this object on the main thread, but we aren't on the
       // main thread right now, so we send a reference to ourselves to the main
       // thread to be re-released there.
       RefPtr<MainThreadHandoff> self = this;
-      NS_ReleaseOnMainThread(
+      NS_ReleaseOnMainThreadSystemGroup(
         "MainThreadHandoff", self.forget());
     }
   }
   return newRefCnt;
 }
 
 HRESULT
 MainThreadHandoff::FixIServiceProvider(ICallFrame* aFrame)
--- a/ipc/mscom/WeakRef.cpp
+++ b/ipc/mscom/WeakRef.cpp
@@ -163,17 +163,17 @@ WeakReferenceSupport::Release()
   if (newRefCnt == 0) {
     if (mFlags != Flags::eDestroyOnMainThread || NS_IsMainThread()) {
       delete this;
     } else {
       // We need to delete this object on the main thread, but we aren't on the
       // main thread right now, so we send a reference to ourselves to the main
       // thread to be re-released there.
       RefPtr<WeakReferenceSupport> self = this;
-      NS_ReleaseOnMainThread(
+      NS_ReleaseOnMainThreadSystemGroup(
         "WeakReferenceSupport", self.forget());
     }
   }
   return newRefCnt;
 }
 
 HRESULT
 WeakReferenceSupport::GetWeakReference(IWeakReference** aOutWeakRef)
--- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
+++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
@@ -366,17 +366,17 @@ function ignoreContents(entry)
         /InvalidArrayIndex_CRASH/,
         /NS_ABORT_OOM/,
 
         // These ought to be threadsafe.
         "NS_DebugBreak",
         /mozalloc_handle_oom/,
         /^NS_Log/, /log_print/, /LazyLogModule::operator/,
         /SprintfLiteral/, "PR_smprintf", "PR_smprintf_free",
-        /NS_DispatchToMainThread/, /NS_ReleaseOnMainThread/,
+        /NS_DispatchToMainThread/, /NS_ReleaseOnMainThreadSystemGroup/,
         /NS_NewRunnableFunction/, /NS_Atomize/,
         /nsCSSValue::BufferFromString/,
         /NS_strdup/,
         /Assert_NoQueryNeeded/,
         /imgRequestProxy::GetProgressTracker/, // Uses an AutoLock
         /Smprintf/,
         "malloc",
         "free",
--- a/js/xpconnect/loader/ScriptPreloader.cpp
+++ b/js/xpconnect/loader/ScriptPreloader.cpp
@@ -678,17 +678,18 @@ ScriptPreloader::Run()
 
     auto result = WriteCache();
     Unused << NS_WARN_IF(result.isErr());
 
     result = mChildCache->WriteCache();
     Unused << NS_WARN_IF(result.isErr());
 
     mSaveComplete = true;
-    NS_ReleaseOnMainThread("ScriptPreloader::mSaveThread", mSaveThread.forget());
+    NS_ReleaseOnMainThreadSystemGroup("ScriptPreloader::mSaveThread",
+                                      mSaveThread.forget());
 
     mal.NotifyAll();
     return NS_OK;
 }
 
 void
 ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
                             JS::HandleScript jsscript)
--- a/layout/style/URLExtraData.cpp
+++ b/layout/style/URLExtraData.cpp
@@ -27,15 +27,18 @@ URLExtraData::InitDummy()
 URLExtraData::ReleaseDummy()
 {
   sDummy = nullptr;
 }
 
 URLExtraData::~URLExtraData()
 {
   if (!NS_IsMainThread()) {
-    NS_ReleaseOnMainThread("URLExtraData::mBaseURI", mBaseURI.forget());
-    NS_ReleaseOnMainThread("URLExtraData::mReferrer", mReferrer.forget());
-    NS_ReleaseOnMainThread("URLExtraData::mPrincipal", mPrincipal.forget());
+    NS_ReleaseOnMainThreadSystemGroup("URLExtraData::mBaseURI",
+                                      mBaseURI.forget());
+    NS_ReleaseOnMainThreadSystemGroup("URLExtraData::mReferrer",
+                                      mReferrer.forget());
+    NS_ReleaseOnMainThreadSystemGroup("URLExtraData::mPrincipal",
+                                      mPrincipal.forget());
   }
 }
 
 } // namespace mozilla
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -3450,29 +3450,29 @@ nsStyleDisplay::nsStyleDisplay(const nsS
 
 nsStyleDisplay::~nsStyleDisplay()
 {
   // We don't allow releasing nsCSSValues with refcounted data in the Servo
   // traversal, since the refcounts aren't threadsafe. Since Servo may trigger
   // the deallocation of style structs during styling, we need to handle it
   // here.
   if (mSpecifiedTransform && ServoStyleSet::IsInServoTraversal()) {
-    // The default behavior of NS_ReleaseOnMainThread is to only proxy the
-    // release if we're not already on the main thread. This is a nice
+    // The default behavior of NS_ReleaseOnMainThreadSystemGroup is to only
+    // proxy the release if we're not already on the main thread. This is a nice
     // optimization for the cases we happen to be doing a sequential traversal
     // (i.e. a single-core machine), but it trips our assertions which check
     // whether we're in a Servo traversal, parallel or not. So we
     // unconditionally proxy in debug builds.
     bool alwaysProxy =
 #ifdef DEBUG
       true;
 #else
       false;
 #endif
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsStyleDisplay::mSpecifiedTransform",
       mSpecifiedTransform.forget(), alwaysProxy);
   }
 
   MOZ_COUNT_DTOR(nsStyleDisplay);
 }
 
 nsChangeHint
@@ -3768,17 +3768,17 @@ nsStyleVisibility::CalcDifference(const 
   return hint;
 }
 
 nsStyleContentData::~nsStyleContentData()
 {
   MOZ_COUNT_DTOR(nsStyleContentData);
 
   if (mType == eStyleContentType_Image) {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsStyleContentData::mContent.mImage", dont_AddRef(mContent.mImage));
     mContent.mImage = nullptr;
   } else if (mType == eStyleContentType_Counter ||
              mType == eStyleContentType_Counters) {
     mContent.mCounters->Release();
   } else if (mContent.mString) {
     free(mContent.mString);
   }
@@ -4360,17 +4360,17 @@ nsStyleUIReset::~nsStyleUIReset()
   // See the nsStyleDisplay destructor for why we're doing this.
   if (mSpecifiedWindowTransform && ServoStyleSet::IsInServoTraversal()) {
     bool alwaysProxy =
 #ifdef DEBUG
       true;
 #else
       false;
 #endif
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsStyleUIReset::mSpecifiedWindowTransform",
       mSpecifiedWindowTransform.forget(), alwaysProxy);
   }
 }
 
 nsChangeHint
 nsStyleUIReset::CalcDifference(const nsStyleUIReset& aNewData) const
 {
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -541,17 +541,17 @@ public:
   }
 
 protected:
   virtual ~AudioProxyThread()
   {
     // Conduits must be released on MainThread, and we might have the last reference
     // We don't need to worry about runnables still trying to access the conduit, since
     // the runnables hold a ref to AudioProxyThread.
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "AudioProxyThread::mConduit", mConduit.forget());
     MOZ_COUNT_DTOR(AudioProxyThread);
   }
 
   RefPtr<AudioSessionConduit> mConduit;
   nsCOMPtr<nsIEventTarget> mThread;
   // Only accessed on mThread
   nsAutoPtr<AudioPacketizer<int16_t, int16_t>> packetizer_;
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -204,17 +204,18 @@ nsJARChannel::nsJARChannel()
     mBlockRemoteFiles = Preferences::GetBool("network.jar.block-remote-files", false);
 
     // hold an owning reference to the jar handler
     NS_ADDREF(gJarHandler);
 }
 
 nsJARChannel::~nsJARChannel()
 {
-    NS_ReleaseOnMainThread("nsJARChannel::mLoadInfo", mLoadInfo.forget());
+    NS_ReleaseOnMainThreadSystemGroup("nsJARChannel::mLoadInfo",
+                                      mLoadInfo.forget());
 
     // release owning reference to the jar handler
     nsJARProtocolHandler *handler = gJarHandler;
     NS_RELEASE(handler); // nullptr parameter
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(nsJARChannel,
                             nsHashPropertyBag,
--- a/netwerk/base/TLSServerSocket.cpp
+++ b/netwerk/base/TLSServerSocket.cpp
@@ -353,17 +353,17 @@ TLSServerConnectionInfo::~TLSServerConne
 
   RefPtr<nsITLSServerSecurityObserver> observer;
   {
     MutexAutoLock lock(mLock);
     observer = mSecurityObserver.forget();
   }
 
   if (observer) {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "TLSServerConnectionInfo::mSecurityObserver", observer.forget());
   }
 }
 
 NS_IMETHODIMP
 TLSServerConnectionInfo::SetSecurityObserver(nsITLSServerSecurityObserver* aObserver)
 {
   {
--- a/netwerk/base/nsBaseChannel.cpp
+++ b/netwerk/base/nsBaseChannel.cpp
@@ -65,17 +65,17 @@ nsBaseChannel::nsBaseChannel()
   , mContentLength(-1)
   , mWasOpened(false)
 {
   mContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE);
 }
 
 nsBaseChannel::~nsBaseChannel()
 {
-  NS_ReleaseOnMainThread(
+  NS_ReleaseOnMainThreadSystemGroup(
     "nsBaseChannel::mLoadInfo", mLoadInfo.forget());
 }
 
 nsresult
 nsBaseChannel::Redirect(nsIChannel *newChannel, uint32_t redirectFlags,
                         bool openNewChannel)
 {
   SUSPEND_PUMP_FOR_SCOPE();
--- a/netwerk/base/nsProtocolProxyService.cpp
+++ b/netwerk/base/nsProtocolProxyService.cpp
@@ -124,32 +124,32 @@ private:
     ~nsAsyncResolveRequest()
     {
         if (!NS_IsMainThread()) {
             // these xpcom pointers might need to be proxied back to the
             // main thread to delete safely, but if this request had its
             // callbacks called normally they will all be null and this is a nop
 
             if (mChannel) {
-                NS_ReleaseOnMainThread(
+                NS_ReleaseOnMainThreadSystemGroup(
                   "nsAsyncResolveRequest::mChannel", mChannel.forget());
             }
 
             if (mCallback) {
-                NS_ReleaseOnMainThread(
+                NS_ReleaseOnMainThreadSystemGroup(
                   "nsAsyncResolveRequest::mCallback", mCallback.forget());
             }
 
             if (mProxyInfo) {
-                NS_ReleaseOnMainThread(
+                NS_ReleaseOnMainThreadSystemGroup(
                   "nsAsyncResolveRequest::mProxyInfo", mProxyInfo.forget());
             }
 
             if (mXPComPPS) {
-                NS_ReleaseOnMainThread(
+                NS_ReleaseOnMainThreadSystemGroup(
                   "nsAsyncResolveRequest::mXPComPPS", mXPComPPS.forget());
             }
         }
     }
 
 public:
     void SetResult(nsresult status, nsIProxyInfo *pi)
     {
@@ -361,17 +361,17 @@ public:
 
         return NS_DispatchToMainThread(event);
     }
 
 private:
     ~AsyncGetPACURIRequest()
     {
         MOZ_ASSERT(NS_IsMainThread() == mIsMainThreadOnly);
-        NS_ReleaseOnMainThread(
+        NS_ReleaseOnMainThreadSystemGroup(
           "AsyncGetPACURIRequest::mServiceHolder", mServiceHolder.forget());
     }
 
     bool mIsMainThreadOnly;
 
     nsProtocolProxyService* mService; // ref-count is hold by mServiceHolder
     nsCOMPtr<nsIProtocolProxyService2> mServiceHolder;
     CallbackFunc mCallback;
--- a/netwerk/cache2/CacheIndex.h
+++ b/netwerk/cache2/CacheIndex.h
@@ -1207,17 +1207,17 @@ private:
   private:
     explicit DiskConsumptionObserver(nsWeakPtr const& aWeakObserver)
       : Runnable("net::CacheIndex::DiskConsumptionObserver")
       , mObserver(aWeakObserver)
     {
     }
     virtual ~DiskConsumptionObserver() {
       if (mObserver && !NS_IsMainThread()) {
-        NS_ReleaseOnMainThread(
+        NS_ReleaseOnMainThreadSystemGroup(
           "DiskConsumptionObserver::mObserver", mObserver.forget());
       }
     }
 
     NS_IMETHOD Run() override
     {
       MOZ_ASSERT(NS_IsMainThread());
 
--- a/netwerk/protocol/gio/nsGIOProtocolHandler.cpp
+++ b/netwerk/protocol/gio/nsGIOProtocolHandler.cpp
@@ -611,17 +611,17 @@ nsGIOInputStream::Close()
     // Destroy the list of GIOFileInfo objects...
     g_list_foreach(mDirList, (GFunc) g_object_unref, nullptr);
     g_list_free(mDirList);
     mDirList = nullptr;
     mDirListPtr = nullptr;
   }
 
   if (mChannel) {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsGIOInputStream::mChannel", dont_AddRef(mChannel));
 
     mChannel = nullptr;
   }
 
   mSpec.Truncate(); // free memory
 
   // Prevent future reads from re-opening the handle.
--- a/netwerk/protocol/websocket/BaseWebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/BaseWebSocketChannel.cpp
@@ -368,18 +368,18 @@ BaseWebSocketChannel::ListenerAndContext
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mListener);
 }
 
 BaseWebSocketChannel::ListenerAndContextContainer::~ListenerAndContextContainer()
 {
   MOZ_ASSERT(mListener);
 
-  NS_ReleaseOnMainThread(
+  NS_ReleaseOnMainThreadSystemGroup(
     "BaseWebSocketChannel::ListenerAndContextContainer::mListener",
     mListener.forget());
-  NS_ReleaseOnMainThread(
+  NS_ReleaseOnMainThreadSystemGroup(
     "BaseWebSocketChannel::ListenerAndContextContainer::mContext",
     mContext.forget());
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -1228,24 +1228,28 @@ WebSocketChannel::~WebSocketChannel()
 
   while ((mCurrentOut = (OutboundMessage *) mOutgoingPingMessages.PopFront()))
     delete mCurrentOut;
   while ((mCurrentOut = (OutboundMessage *) mOutgoingPongMessages.PopFront()))
     delete mCurrentOut;
   while ((mCurrentOut = (OutboundMessage *) mOutgoingMessages.PopFront()))
     delete mCurrentOut;
 
-  NS_ReleaseOnMainThread("WebSocketChannel::mURI", mURI.forget());
-  NS_ReleaseOnMainThread("WebSocketChannel::mOriginalURI", mOriginalURI.forget());
+  NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mURI", mURI.forget());
+  NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mOriginalURI",
+                                    mOriginalURI.forget());
 
   mListenerMT = nullptr;
 
-  NS_ReleaseOnMainThread("WebSocketChannel::mLoadGroup", mLoadGroup.forget());
-  NS_ReleaseOnMainThread("WebSocketChannel::mLoadInfo", mLoadInfo.forget());
-  NS_ReleaseOnMainThread("WebSocketChannel::mService", mService.forget());
+  NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mLoadGroup",
+                                    mLoadGroup.forget());
+  NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mLoadInfo",
+                                    mLoadInfo.forget());
+  NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mService",
+                                    mService.forget());
 }
 
 NS_IMETHODIMP
 WebSocketChannel::Observe(nsISupports *subject,
                           const char *topic,
                           const char16_t *data)
 {
   LOG(("WebSocketChannel::Observe [topic=\"%s\"]\n", topic));
@@ -2370,20 +2374,24 @@ WebSocketChannel::StopSession(nsresult r
 
   // normally this should be called on socket thread, but it is ok to call it
   // from OnStartRequest before the socket thread machine has gotten underway
 
   mStopped = 1;
 
   if (!mOpenedHttpChannel) {
     // The HTTP channel information will never be used in this case
-    NS_ReleaseOnMainThread("WebSocketChannel::mChannel", mChannel.forget());
-    NS_ReleaseOnMainThread("WebSocketChannel::mHttpChannel", mHttpChannel.forget());
-    NS_ReleaseOnMainThread("WebSocketChannel::mLoadGroup", mLoadGroup.forget());
-    NS_ReleaseOnMainThread("WebSocketChannel::mCallbacks", mCallbacks.forget());
+    NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mChannel",
+                                      mChannel.forget());
+    NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mHttpChannel",
+                                      mHttpChannel.forget());
+    NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mLoadGroup",
+                                      mLoadGroup.forget());
+    NS_ReleaseOnMainThreadSystemGroup("WebSocketChannel::mCallbacks",
+                                      mCallbacks.forget());
   }
 
   if (mCloseTimer) {
     mCloseTimer->Cancel();
     mCloseTimer = nullptr;
   }
 
   if (mOpenTimer) {
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
@@ -61,17 +61,17 @@ WyciwygChannelChild::WyciwygChannelChild
   // IPDL holds a reference until IPDL channel gets destroyed
   AddIPDLReference();
 }
 
 WyciwygChannelChild::~WyciwygChannelChild()
 {
   LOG(("Destroying WyciwygChannelChild @%p\n", this));
   if (mLoadInfo) {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "WyciwygChannelChild::mLoadInfo", mLoadInfo.forget());
   }
 }
 
 void
 WyciwygChannelChild::AddIPDLReference()
 {
   MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
--- a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
+++ b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
@@ -42,17 +42,17 @@ nsWyciwygChannel::nsWyciwygChannel()
     mLoadFlags(LOAD_NORMAL),
     mNeedToSetSecurityInfo(false)
 {
 }
 
 nsWyciwygChannel::~nsWyciwygChannel()
 {
   if (mLoadInfo) {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsWyciwygChannel::mLoadInfo", mLoadInfo.forget(), false);
   }
 }
 
 NS_IMPL_ISUPPORTS(nsWyciwygChannel,
                   nsIChannel,
                   nsIRequest,
                   nsIStreamListener,
--- a/netwerk/sctp/datachannel/DataChannel.cpp
+++ b/netwerk/sctp/datachannel/DataChannel.cpp
@@ -2414,17 +2414,17 @@ DataChannelConnection::ReadBlob(already_
   RefPtr<DataChannelBlobSendRunnable> runnable = new DataChannelBlobSendRunnable(aThis,
                                                                                    aStream);
   // avoid copying the blob data by passing the mData from the runnable
   if (NS_FAILED(aBlob->Available(&len)) ||
       NS_FAILED(NS_ReadInputStreamToString(aBlob, runnable->mData, len))) {
     // Bug 966602:  Doesn't return an error to the caller via onerror.
     // We must release DataChannelConnection on MainThread to avoid issues (bug 876167)
     // aThis is now owned by the runnable; release it there
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "DataChannelBlobSendRunnable", runnable.forget());
     return;
   }
   aBlob->Close();
   Dispatch(runnable.forget());
 }
 
 void
--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -562,17 +562,18 @@ nsHTTPListener::~nsHTTPListener()
   if (mResponsibleForDoneSignal)
     send_done_signal();
 
   if (mResultData) {
     free(const_cast<uint8_t *>(mResultData));
   }
 
   if (mLoader) {
-    NS_ReleaseOnMainThread("nsHTTPListener::mLoader", mLoader.forget());
+    NS_ReleaseOnMainThreadSystemGroup("nsHTTPListener::mLoader",
+                                      mLoader.forget());
   }
 }
 
 NS_IMPL_ISUPPORTS(nsHTTPListener, nsIStreamLoaderObserver)
 
 void
 nsHTTPListener::FreeLoadGroup(bool aCancelLoad)
 {
--- a/storage/mozStorageConnection.cpp
+++ b/storage/mozStorageConnection.cpp
@@ -404,19 +404,19 @@ public:
       (void)NS_GetMainThread(getter_AddRefs(thread));
       (void)thread->Dispatch(mCallbackEvent, NS_DISPATCH_NORMAL);
     }
 
     return NS_OK;
   }
 
   ~AsyncCloseConnection() override {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "AsyncCloseConnection::mConnection", mConnection.forget());
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "AsyncCloseConnection::mCallbackEvent", mCallbackEvent.forget());
   }
 private:
   RefPtr<Connection> mConnection;
   sqlite3 *mNativeConnection;
   nsCOMPtr<nsIRunnable> mCallbackEvent;
 };
 
--- a/storage/mozStorageService.cpp
+++ b/storage/mozStorageService.cpp
@@ -709,25 +709,25 @@ private:
       new CallbackComplete(aStatus,
                            aValue,
                            mCallback.forget());
     return NS_DispatchToMainThread(event);
   }
 
   ~AsyncInitDatabase()
   {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "AsyncInitDatabase::mStorageFile", mStorageFile.forget());
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "AsyncInitDatabase::mConnection", mConnection.forget());
 
     // Generally, the callback will be released by CallbackComplete.
     // However, if for some reason Run() is not executed, we still
     // need to ensure that it is released here.
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "AsyncInitDatabase::mCallback", mCallback.forget());
   }
 
   RefPtr<Connection> mConnection;
   nsCOMPtr<nsIFile> mStorageFile;
   int32_t mGrowthIncrement;
   RefPtr<mozIStorageCompletionCallback> mCallback;
 };
--- a/storage/mozStorageStatementData.h
+++ b/storage/mozStorageStatementData.h
@@ -47,17 +47,18 @@ public:
   : mStatement(nullptr)
   {
   }
   ~StatementData()
   {
     // We need to ensure that mParamsArray is released on the main thread,
     // as the binding arguments may be XPConnect values, which are safe
     // to release only on the main thread.
-    NS_ReleaseOnMainThread("StatementData::mParamsArray", mParamsArray.forget());
+    NS_ReleaseOnMainThreadSystemGroup("StatementData::mParamsArray",
+                                      mParamsArray.forget());
   }
 
   /**
    * Return the sqlite statement, fetching it from the storage statement.  In
    * the case of AsyncStatements this may actually create the statement
    */
   inline int getSqliteStatement(sqlite3_stmt **_stmt)
   {
--- a/toolkit/components/osfile/NativeOSFileInternals.cpp
+++ b/toolkit/components/osfile/NativeOSFileInternals.cpp
@@ -525,34 +525,36 @@ public:
                                                 aDiscardedResult,
                                                 aOperation,
                                                 aOSError);
     nsresult rv = NS_DispatchToMainThread(event);
     if (NS_FAILED(rv)) {
       // Last ditch attempt to release on the main thread - some of
       // the members of event are not thread-safe, so letting the
       // pointer go out of scope would cause a crash.
-      NS_ReleaseOnMainThread("AbstractDoEvent::ErrorEvent", event.forget());
+      NS_ReleaseOnMainThreadSystemGroup("AbstractDoEvent::ErrorEvent",
+                                        event.forget());
     }
   }
 
   /**
    * Succeed, asynchronously.
    */
   void Succeed(already_AddRefed<nsINativeOSFileResult>&& aResult) {
     Resolve();
     RefPtr<SuccessEvent> event = new SuccessEvent(mOnSuccess,
                                                     mOnError,
                                                     aResult);
     nsresult rv = NS_DispatchToMainThread(event);
     if (NS_FAILED(rv)) {
       // Last ditch attempt to release on the main thread - some of
       // the members of event are not thread-safe, so letting the
       // pointer go out of scope would cause a crash.
-      NS_ReleaseOnMainThread("AbstractDoEvent::SuccessEvent", event.forget());
+      NS_ReleaseOnMainThreadSystemGroup("AbstractDoEvent::SuccessEvent",
+                                        event.forget());
     }
 
   }
 
 private:
 
   /**
    * Mark the event as complete, for debugging purposes.
@@ -743,17 +745,18 @@ public:
   { }
 
   ~DoReadToTypedArrayEvent() override {
     // If AbstractReadEvent::Run() has bailed out, we may need to cleanup
     // mResult, which is main-thread only data
     if (!mResult) {
       return;
     }
-    NS_ReleaseOnMainThread("DoReadToTypedArrayEvent::mResult", mResult.forget());
+    NS_ReleaseOnMainThreadSystemGroup("DoReadToTypedArrayEvent::mResult",
+                                      mResult.forget());
   }
 
 protected:
   void AfterRead(TimeStamp aDispatchDate,
                  ScopedArrayBufferContents& aBuffer) override {
     MOZ_ASSERT(!NS_IsMainThread());
     mResult->Init(aDispatchDate, TimeStamp::Now() - aDispatchDate, aBuffer.forget());
     Succeed(mResult.forget());
@@ -780,17 +783,18 @@ public:
   { }
 
   ~DoReadToStringEvent() override {
     // If AbstraactReadEvent::Run() has bailed out, we may need to cleanup
     // mResult, which is main-thread only data
     if (!mResult) {
       return;
     }
-    NS_ReleaseOnMainThread("DoReadToStringEvent::mResult", mResult.forget());
+    NS_ReleaseOnMainThreadSystemGroup("DoReadToStringEvent::mResult",
+                                      mResult.forget());
   }
 
 protected:
   nsresult BeforeRead() override {
     // Obtain the decoder. We do this before reading to avoid doing
     // any unnecessary I/O in case the name of the encoding is incorrect.
     MOZ_ASSERT(!NS_IsMainThread());
     const Encoding* encoding = Encoding::ForLabel(mEncoding);
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
@@ -1047,17 +1047,17 @@ private:
 
 NS_IMPL_ISUPPORTS(nsUrlClassifierLookupCallback,
                   nsIUrlClassifierLookupCallback,
                   nsIUrlClassifierHashCompleterCallback)
 
 nsUrlClassifierLookupCallback::~nsUrlClassifierLookupCallback()
 {
   if (mCallback) {
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsUrlClassifierLookupCallback::mCallback", mCallback.forget());
   }
 }
 
 NS_IMETHODIMP
 nsUrlClassifierLookupCallback::LookupComplete(nsTArray<LookupResult>* results)
 {
   NS_ASSERTION(mResults == nullptr,
--- a/xpcom/base/JSObjectHolder.h
+++ b/xpcom/base/JSObjectHolder.h
@@ -16,17 +16,18 @@ namespace mozilla {
 // a JS Object from another thread. If they are both on the same thread, the
 // owning class should instead be made a cycle collected SCRIPT_HOLDER class.
 // This object should only be AddRefed and Released on the same thread as
 // mJSObject.
 //
 // Note that this keeps alive the JS object until it goes away, so be sure not to
 // create cycles that keep alive the holder.
 //
-// JSObjectHolder is ISupports to make it usable with NS_ReleaseOnMainThread.
+// JSObjectHolder is ISupports to make it usable with
+// NS_ReleaseOnMainThreadSystemGroup.
 class JSObjectHolder final : public nsISupports
 {
 public:
   JSObjectHolder(JSContext* aCx, JSObject* aObject) : mJSObject(aCx, aObject) {}
 
   NS_DECL_ISUPPORTS
 
   JSObject* GetJSObject() { return mJSObject; }
--- a/xpcom/base/nsConsoleService.cpp
+++ b/xpcom/base/nsConsoleService.cpp
@@ -318,17 +318,17 @@ nsConsoleService::LogMessageWithMode(nsI
       r = new LogMessageRunnable(aMessage, this);
     }
   }
 
   if (retiredMessage) {
     // Release |retiredMessage| on the main thread in case it is an instance of
     // a mainthread-only class like nsScriptErrorWithStack and we're off the
     // main thread.
-    NS_ReleaseOnMainThread(
+    NS_ReleaseOnMainThreadSystemGroup(
       "nsConsoleService::retiredMessage", retiredMessage.forget());
   }
 
   if (r) {
     // avoid failing in XPCShell tests
     nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
     if (mainThread) {
       SystemGroup::Dispatch("LogMessageRunnable", TaskCategory::Other, r.forget());
--- a/xpcom/threads/nsProxyRelease.h
+++ b/xpcom/threads/nsProxyRelease.h
@@ -121,16 +121,18 @@ struct ProxyReleaseChooser<true>
                                     bool aAlwaysProxy);
 };
 
 } // namespace detail
 
 /**
  * Ensures that the delete of a smart pointer occurs on the target thread.
  *
+ * @param aName
+ *        the labelling name of the runnable involved in the releasing
  * @param aTarget
  *        the target thread where the doomed object should be released.
  * @param aDoomed
  *        the doomed object; the object to be released on the target thread.
  * @param aAlwaysProxy
  *        normally, if NS_ProxyRelease is called on the target thread, then the
  *        doomed object will be released directly. However, if this parameter is
  *        true, then an event will always be posted to the target thread for
@@ -143,72 +145,57 @@ NS_ProxyRelease(const char* aName, nsIEv
 {
   ::detail::ProxyReleaseChooser<mozilla::IsBaseOf<nsISupports, T>::value>
     ::ProxyRelease(aName, aTarget, mozilla::Move(aDoomed), aAlwaysProxy);
 }
 
 /**
  * Ensures that the delete of a smart pointer occurs on the main thread.
  *
+ * @param aName
+ *        the labelling name of the runnable involved in the releasing
  * @param aDoomed
  *        the doomed object; the object to be released on the main thread.
  * @param aAlwaysProxy
- *        normally, if NS_ReleaseOnMainThread is called on the main thread,
- *        then the doomed object will be released directly. However, if this
- *        parameter is true, then an event will always be posted to the main
- *        thread for asynchronous release.
+ *        normally, if NS_ReleaseOnMainThreadSystemGroup is called on the main
+ *        thread, then the doomed object will be released directly. However, if
+ *        this parameter is true, then an event will always be posted to the
+ *        main thread for asynchronous release.
  */
 template<class T>
 inline NS_HIDDEN_(void)
-NS_ReleaseOnMainThread(const char* aName,
-                       already_AddRefed<T> aDoomed,
-                       bool aAlwaysProxy = false)
-{
-  // NS_ProxyRelease treats a null event target as "the current thread".  So a
-  // handle on the main thread is only necessary when we're not already on the
-  // main thread or the release must happen asynchronously.
-  nsCOMPtr<nsIThread> mainThread;
-  if (!NS_IsMainThread() || aAlwaysProxy) {
-    nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
-
-    if (NS_FAILED(rv)) {
-      MOZ_ASSERT_UNREACHABLE("Could not get main thread; leaking an object!");
-      mozilla::Unused << aDoomed.take();
-      return;
-    }
-  }
-
-  NS_ProxyRelease(aName, mainThread, mozilla::Move(aDoomed), aAlwaysProxy);
-}
-
-/**
- * This is the same as NS_ReleaseOnMainThread, except that the
- * runnable for the deletion will be dispatched to the system group.
- */
-template<class T>
-inline NS_HIDDEN_(void)
-NS_ReleaseOnMainThreadSystemGroup(already_AddRefed<T> aDoomed,
+NS_ReleaseOnMainThreadSystemGroup(const char* aName,
+                                  already_AddRefed<T> aDoomed,
                                   bool aAlwaysProxy = false)
 {
   // NS_ProxyRelease treats a null event target as "the current thread".  So a
   // handle on the main thread is only necessary when we're not already on the
   // main thread or the release must happen asynchronously.
   nsCOMPtr<nsIEventTarget> systemGroupEventTarget;
   if (!NS_IsMainThread() || aAlwaysProxy) {
     systemGroupEventTarget = mozilla::SystemGroup::EventTargetFor(mozilla::TaskCategory::Other);
 
     if (!systemGroupEventTarget) {
       MOZ_ASSERT_UNREACHABLE("Could not get main thread; leaking an object!");
       mozilla::Unused << aDoomed.take();
       return;
     }
   }
 
-  NS_ProxyRelease("NS_ReleaseOnMainThreadSystemGroup", systemGroupEventTarget,
-                  mozilla::Move(aDoomed), aAlwaysProxy);
+  NS_ProxyRelease(aName, systemGroupEventTarget, mozilla::Move(aDoomed),
+                  aAlwaysProxy);
+}
+
+template<class T>
+inline NS_HIDDEN_(void)
+NS_ReleaseOnMainThreadSystemGroup(already_AddRefed<T> aDoomed,
+                                  bool aAlwaysProxy = false)
+{
+  NS_ReleaseOnMainThreadSystemGroup("NS_ReleaseOnMainThreadSystemGroup",
+                                    mozilla::Move(aDoomed), aAlwaysProxy);
 }
 
 /**
  * Class to safely handle main-thread-only pointers off the main thread.
  *
  * Classes like XPCWrappedJS are main-thread-only, which means that it is
  * forbidden to call methods on instances of these classes off the main thread.
  * For various reasons (see bug 771074), this restriction recently began to