Bug 1382172 - Name nsITimerCallback instances in native implementation. r=billm
authorBevis Tseng <btseng@mozilla.com>
Thu, 27 Jul 2017 02:18:20 +0800
changeset 371127 4b879e41eae3aa845e77f6ce7336fb9eb4ed35fa
parent 371126 0acc77eb92c6372cb73f441d2753c77068d87c2f
child 371128 6efdde2f7dd51a98cfbfdf084e680fbf9cc7cee4
push id93028
push userbtseng@mozilla.com
push dateWed, 26 Jul 2017 19:24:12 +0000
treeherdermozilla-inbound@4b879e41eae3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1382172
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 1382172 - Name nsITimerCallback instances in native implementation. r=billm
accessible/base/nsAccessibilityService.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
dom/base/Selection.cpp
dom/base/TimeoutManager.cpp
dom/canvas/WebGLContextLossHandler.cpp
dom/file/FileReader.cpp
dom/file/FileReader.h
dom/flyweb/FlyWebService.cpp
dom/geolocation/MLSFallback.cpp
dom/geolocation/MLSFallback.h
dom/geolocation/nsGeolocation.cpp
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/IndexedDatabaseManager.h
dom/ipc/ProcessPriorityManager.cpp
dom/media/MediaDevices.cpp
dom/media/MediaStreamGraph.cpp
dom/media/MediaStreamGraphImpl.h
dom/media/VideoUtils.cpp
dom/media/VideoUtils.h
dom/media/webrtc/MediaEngineDefault.cpp
dom/media/webrtc/MediaEngineDefault.h
dom/plugins/base/nsNPAPIPluginStreamListener.cpp
dom/plugins/base/nsNPAPIPluginStreamListener.h
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginHost.h
dom/presentation/PresentationSessionInfo.cpp
dom/presentation/PresentationSessionInfo.h
dom/workers/ServiceWorkerManager.cpp
dom/workers/ServiceWorkerPrivate.cpp
dom/workers/WorkerPrivate.cpp
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/XMLHttpRequestMainThread.h
editor/composer/nsComposerCommandsUpdater.cpp
editor/composer/nsComposerCommandsUpdater.h
editor/libeditor/TextEditRules.cpp
editor/libeditor/TextEditRules.h
extensions/pref/autoconfig/src/nsAutoConfig.cpp
extensions/pref/autoconfig/src/nsAutoConfig.h
gfx/layers/apz/util/APZEventState.cpp
media/mtransport/nr_timer.cpp
media/mtransport/transportlayerloopback.cpp
media/mtransport/transportlayerloopback.h
mobile/android/components/build/nsAndroidHistory.cpp
mobile/android/components/build/nsAndroidHistory.h
netwerk/base/CaptivePortalService.cpp
netwerk/base/CaptivePortalService.h
netwerk/base/Dashboard.cpp
netwerk/base/EventTokenBucket.cpp
netwerk/base/EventTokenBucket.h
netwerk/base/ProxyAutoConfig.cpp
netwerk/base/ThrottleQueue.cpp
netwerk/base/ThrottleQueue.h
netwerk/base/Tickler.cpp
netwerk/cache/nsCacheService.cpp
netwerk/cache2/CacheFileIOManager.cpp
netwerk/cache2/CacheFileIOManager.h
netwerk/cache2/CacheStorageService.cpp
netwerk/cache2/CacheStorageService.h
netwerk/protocol/http/HSTSPrimerListener.cpp
netwerk/protocol/http/HSTSPrimerListener.h
netwerk/protocol/http/TunnelUtils.cpp
netwerk/protocol/http/TunnelUtils.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
netwerk/protocol/websocket/WebSocketChannel.cpp
netwerk/protocol/websocket/WebSocketChannel.h
toolkit/components/alerts/AlertNotification.cpp
toolkit/components/alerts/AlertNotification.h
toolkit/components/autocomplete/nsAutoCompleteController.cpp
toolkit/components/autocomplete/nsAutoCompleteController.h
toolkit/components/places/nsFaviconService.cpp
toolkit/components/places/nsFaviconService.h
toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.h
uriloader/exthandler/nsExternalHelperAppService.cpp
uriloader/exthandler/nsExternalHelperAppService.h
widget/nsNativeTheme.cpp
widget/nsNativeTheme.h
widget/windows/nsAppShell.cpp
xpcom/base/nsMessageLoop.cpp
xpcom/threads/LazyIdleThread.cpp
xpcom/threads/LazyIdleThread.h
xpfe/appshell/nsWebShellWindow.cpp
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -53,16 +53,17 @@
 #include "Logging.h"
 #endif
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 
 #include "nsImageFrame.h"
+#include "nsINamed.h"
 #include "nsIObserverService.h"
 #include "nsLayoutUtils.h"
 #include "nsPluginFrame.h"
 #include "SVGGeometryFrame.h"
 #include "nsTreeBodyFrame.h"
 #include "nsTreeColumns.h"
 #include "nsTreeUtils.h"
 #include "nsXBLPrototypeBinding.h"
@@ -407,16 +408,17 @@ nsAccessibilityService::GetRootDocumentA
   return nullptr;
 }
 
 #ifdef XP_WIN
 static StaticAutoPtr<nsTArray<nsCOMPtr<nsIContent> > > sPendingPlugins;
 static StaticAutoPtr<nsTArray<nsCOMPtr<nsITimer> > > sPluginTimers;
 
 class PluginTimerCallBack final : public nsITimerCallback
+                                , public nsINamed
 {
   ~PluginTimerCallBack() {}
 
 public:
   explicit PluginTimerCallBack(nsIContent* aContent) : mContent(aContent) {}
 
   NS_DECL_ISUPPORTS
 
@@ -439,21 +441,27 @@ public:
 
     // We couldn't get a doc accessible so presumably the document went away.
     // In this case don't leak our ref to the content or timer.
     sPendingPlugins->RemoveElement(mContent);
     sPluginTimers->RemoveElement(aTimer);
     return NS_OK;
   }
 
+  NS_IMETHOD GetName(nsACString& aName) final
+  {
+    aName.AssignLiteral("PluginTimerCallBack");
+    return NS_OK;
+  }
+
 private:
   nsCOMPtr<nsIContent> mContent;
 };
 
-NS_IMPL_ISUPPORTS(PluginTimerCallBack, nsITimerCallback)
+NS_IMPL_ISUPPORTS(PluginTimerCallBack, nsITimerCallback, nsINamed)
 #endif
 
 already_AddRefed<Accessible>
 nsAccessibilityService::CreatePluginAccessible(nsPluginFrame* aFrame,
                                                nsIContent* aContent,
                                                Accessible* aContext)
 {
   // nsPluginFrame means a plugin, so we need to use the accessibility support
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -6785,28 +6785,22 @@ nsDocShell::RefreshURI(nsIURI* aURI, int
   nsresult rv = aURI->Equals(mCurrentURI, &sameURI);
   if (NS_FAILED(rv)) {
     sameURI = false;
   }
   if (!RefreshAttempted(this, aURI, aDelay, sameURI)) {
     return NS_OK;
   }
 
-  nsRefreshTimer* refreshTimer = new nsRefreshTimer();
+  nsCOMPtr<nsITimerCallback> refreshTimer =
+    new nsRefreshTimer(this, aURI, aDelay, aRepeat, aMetaRefresh);
+
   uint32_t busyFlags = 0;
   GetBusyFlags(&busyFlags);
 
-  nsCOMPtr<nsISupports> dataRef = refreshTimer;  // Get the ref count to 1
-
-  refreshTimer->mDocShell = this;
-  refreshTimer->mURI = aURI;
-  refreshTimer->mDelay = aDelay;
-  refreshTimer->mRepeat = aRepeat;
-  refreshTimer->mMetaRefresh = aMetaRefresh;
-
   if (!mRefreshURIList) {
     mRefreshURIList = nsArray::Create();
   }
 
   if (busyFlags & BUSY_FLAGS_BUSY || (!mIsActive && mDisableMetaRefreshWhenInactive)) {
     // We don't  want to create the timer right now. Instead queue up the request
     // and trigger the timer in EndPageLoad() or whenever we become active.
     mRefreshURIList->AppendElement(refreshTimer, /*weak =*/ false);
@@ -13627,47 +13621,57 @@ NS_IMETHODIMP
 nsDocShell::SetLayoutHistoryState(nsILayoutHistoryState* aLayoutHistoryState)
 {
   if (mOSHE) {
     mOSHE->SetLayoutHistoryState(aLayoutHistoryState);
   }
   return NS_OK;
 }
 
-nsRefreshTimer::nsRefreshTimer()
-  : mDelay(0), mRepeat(false), mMetaRefresh(false)
+nsRefreshTimer::nsRefreshTimer(nsDocShell* aDocShell, nsIURI* aURI,
+                               int32_t aDelay, bool aRepeat, bool aMetaRefresh)
+  : mDocShell(aDocShell), mURI(aURI), mDelay(aDelay), mRepeat(aRepeat),
+    mMetaRefresh(aMetaRefresh)
 {
 }
 
 nsRefreshTimer::~nsRefreshTimer()
 {
 }
 
 NS_IMPL_ADDREF(nsRefreshTimer)
 NS_IMPL_RELEASE(nsRefreshTimer)
 
 NS_INTERFACE_MAP_BEGIN(nsRefreshTimer)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITimerCallback)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
+  NS_INTERFACE_MAP_ENTRY(nsINamed)
 NS_INTERFACE_MAP_END_THREADSAFE
 
 NS_IMETHODIMP
 nsRefreshTimer::Notify(nsITimer* aTimer)
 {
   NS_ASSERTION(mDocShell, "DocShell is somehow null");
 
   if (mDocShell && aTimer) {
     // Get the delay count to determine load type
     uint32_t delay = 0;
     aTimer->GetDelay(&delay);
     mDocShell->ForceRefreshURIFromTimer(mURI, delay, mMetaRefresh, aTimer);
   }
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsRefreshTimer::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsRefreshTimer");
+  return NS_OK;
+}
+
 nsDocShell::InterfaceRequestorProxy::InterfaceRequestorProxy(
     nsIInterfaceRequestor* aRequestor)
 {
   if (aRequestor) {
     mWeakPtr = do_GetWeakReference(aRequestor);
   }
 }
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -39,16 +39,17 @@
 #include "timeline/TimelineMarker.h"
 
 // Threshold value in ms for META refresh based redirects
 #define REFRESH_REDIRECT_TIMER 15000
 
 // Interfaces Needed
 #include "nsIDocCharset.h"
 #include "nsIInterfaceRequestor.h"
+#include "nsINamed.h"
 #include "nsIRefreshURI.h"
 #include "nsIWebNavigation.h"
 #include "nsIWebPageDescriptor.h"
 #include "nsIWebProgressListener.h"
 #include "nsIDocShellLoadInfo.h"
 #include "nsIAuthPromptProvider.h"
 #include "nsILoadContext.h"
 #include "nsIWebShellServices.h"
@@ -101,22 +102,25 @@ class FramingChecker;
 /* internally used ViewMode types */
 enum ViewMode
 {
   viewNormal = 0x0,
   viewSource = 0x1
 };
 
 class nsRefreshTimer : public nsITimerCallback
+                     , public nsINamed
 {
 public:
-  nsRefreshTimer();
+  nsRefreshTimer(nsDocShell* aDocShell, nsIURI* aURI, int32_t aDelay,
+                 bool aRepeat, bool aMetaRefresh);
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   int32_t GetDelay() { return mDelay ;}
 
   RefPtr<nsDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURI;
   int32_t mDelay;
   bool mRepeat;
   bool mMetaRefresh;
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -47,16 +47,17 @@
 
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsCaret.h"
 
 #include "nsITimer.h"
 #include "nsIDOMDocument.h"
 #include "nsIDocument.h"
+#include "nsINamed.h"
 
 #include "nsISelectionController.h"//for the enums
 #include "nsAutoCopyListener.h"
 #include "SelectionChangeListener.h"
 #include "nsCopySupport.h"
 #include "nsIClipboard.h"
 #include "nsIFrameInlines.h"
 #include "nsRefreshDriver.h"
@@ -191,16 +192,17 @@ struct CachedOffsetForFrame {
 
   nsPoint      mCachedFrameOffset;      // cached frame offset
   nsIFrame*    mLastCaretFrame;         // store the frame the caret was last drawn in.
   int32_t      mLastContentOffset;      // store last content offset
   bool mCanCacheFrameOffset;    // cached frame offset is valid?
 };
 
 class nsAutoScrollTimer final : public nsITimerCallback
+                              , public nsINamed
 {
 public:
 
   NS_DECL_ISUPPORTS
 
   nsAutoScrollTimer()
   : mFrameSelection(0), mSelection(0), mPresContext(0), mPoint(0,0), mDelay(30)
   {
@@ -275,16 +277,22 @@ public:
       }
 
       NS_ASSERTION(frame->PresContext() == mPresContext, "document mismatch?");
       mSelection->DoAutoScroll(frame, pt);
     }
     return NS_OK;
   }
 
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("nsAutoScrollTimer");
+    return NS_OK;
+  }
+
 protected:
   virtual ~nsAutoScrollTimer()
   {
     if (mTimer) {
       mTimer->Cancel();
     }
   }
 
@@ -294,17 +302,17 @@ private:
   nsPresContext *mPresContext;
   // relative to mPresContext's root frame
   nsPoint mPoint;
   nsCOMPtr<nsITimer> mTimer;
   nsCOMPtr<nsIContent> mContent;
   uint32_t mDelay;
 };
 
-NS_IMPL_ISUPPORTS(nsAutoScrollTimer, nsITimerCallback)
+NS_IMPL_ISUPPORTS(nsAutoScrollTimer, nsITimerCallback, nsINamed)
 
 nsresult NS_NewDomSelection(nsISelection **aDomSelection)
 {
   Selection* rlist = new Selection;
   *aDomSelection = (nsISelection *)rlist;
   NS_ADDREF(rlist);
   return NS_OK;
 }
--- a/dom/base/TimeoutManager.cpp
+++ b/dom/base/TimeoutManager.cpp
@@ -6,16 +6,17 @@
 
 #include "TimeoutManager.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/ThrottledEventQueue.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIDocShell.h"
+#include "nsINamed.h"
 #include "nsITimeoutHandler.h"
 #include "mozilla/dom/TabGroup.h"
 #include "OrderedTimeoutIterator.h"
 #include "TimeoutExecutor.h"
 #include "TimeoutBudgetManager.h"
 #include "mozilla/net/WebSocketEventService.h"
 #include "mozilla/MediaManager.h"
 
@@ -1162,37 +1163,44 @@ TimeoutManager::IsTimeoutTracking(uint32
   return mTrackingTimeouts.ForEachAbortable([&](Timeout* aTimeout) {
       return aTimeout->mTimeoutId == aTimeoutId;
     });
 }
 
 namespace {
 
 class ThrottleTimeoutsCallback final : public nsITimerCallback
+                                     , public nsINamed
 {
 public:
   explicit ThrottleTimeoutsCallback(nsGlobalWindow* aWindow)
     : mWindow(aWindow)
   {
     MOZ_DIAGNOSTIC_ASSERT(aWindow->IsInnerWindow());
   }
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
 
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("ThrottleTimeoutsCallback");
+    return NS_OK;
+  }
+
 private:
   ~ThrottleTimeoutsCallback() {}
 
 private:
   // The strong reference here keeps the Window and hence the TimeoutManager
   // object itself alive.
   RefPtr<nsGlobalWindow> mWindow;
 };
 
-NS_IMPL_ISUPPORTS(ThrottleTimeoutsCallback, nsITimerCallback)
+NS_IMPL_ISUPPORTS(ThrottleTimeoutsCallback, nsITimerCallback, nsINamed)
 
 NS_IMETHODIMP
 ThrottleTimeoutsCallback::Notify(nsITimer* aTimer)
 {
   mWindow->AsInner()->TimeoutManager().StartThrottlingTimeouts();
   mWindow = nullptr;
   return NS_OK;
 }
--- a/dom/canvas/WebGLContextLossHandler.cpp
+++ b/dom/canvas/WebGLContextLossHandler.cpp
@@ -1,46 +1,54 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContextLossHandler.h"
 
 #include "mozilla/DebugOnly.h"
+#include "nsINamed.h"
 #include "nsISupportsImpl.h"
 #include "nsITimer.h"
 #include "nsThreadUtils.h"
 #include "WebGLContext.h"
 
 namespace mozilla {
 
 class WatchdogTimerEvent final : public nsITimerCallback
+                               , public nsINamed
 {
     const WeakPtr<WebGLContextLossHandler> mHandler;
 
 public:
     NS_DECL_ISUPPORTS
 
     explicit WatchdogTimerEvent(WebGLContextLossHandler* handler)
         : mHandler(handler)
     { }
 
+    NS_IMETHOD GetName(nsACString& aName) override
+    {
+      aName.AssignLiteral("WatchdogTimerEvent");
+      return NS_OK;
+    }
+
 private:
     virtual ~WatchdogTimerEvent() { }
 
     NS_IMETHOD Notify(nsITimer*) override {
         if (mHandler) {
             mHandler->TimerCallback();
         }
         return NS_OK;
     }
 };
 
-NS_IMPL_ISUPPORTS(WatchdogTimerEvent, nsITimerCallback, nsISupports)
+NS_IMPL_ISUPPORTS(WatchdogTimerEvent, nsITimerCallback, nsINamed)
 
 ////////////////////////////////////////
 
 WebGLContextLossHandler::WebGLContextLossHandler(WebGLContext* webgl)
     : mWebGL(webgl)
     , mTimer(do_CreateInstance(NS_TIMER_CONTRACTID))
     , mTimerPending(false)
     , mShouldRunTimerAgain(false)
--- a/dom/file/FileReader.cpp
+++ b/dom/file/FileReader.cpp
@@ -66,16 +66,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INH
                                                DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mResultArrayBuffer)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileReader)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+  NS_INTERFACE_MAP_ENTRY(nsINamed)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(FileReader, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(FileReader, DOMEventTargetHelper)
 
 class MOZ_RAII FileReaderDecreaseBusyCounter
 {
   RefPtr<FileReader> mFileReader;
@@ -679,16 +680,24 @@ FileReader::OnInputStreamReady(nsIAsyncI
     NS_ENSURE_SUCCESS(rv, rv);
 
     StartProgressEventTimer();
   }
 
   return NS_OK;
 }
 
+// nsINamed
+NS_IMETHODIMP
+FileReader::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("FileReader");
+  return NS_OK;
+}
+
 nsresult
 FileReader::OnLoadEnd(nsresult aStatus)
 {
   // Cancel the progress event timer
   ClearProgressEventTimer();
 
   // FileReader must be in DONE stage after an operation
   mReadyState = DONE;
--- a/dom/file/FileReader.h
+++ b/dom/file/FileReader.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_dom_FileReader_h
 #define mozilla_dom_FileReader_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 
 #include "nsIAsyncInputStream.h"
 #include "nsIInterfaceRequestor.h"
+#include "nsINamed.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 #include "WorkerHolder.h"
 
 #define NS_PROGRESS_EVENT_INTERVAL 50
 
 class nsITimer;
@@ -36,29 +37,31 @@ extern const uint64_t kUnknownSize;
 
 class FileReaderDecreaseBusyCounter;
 
 class FileReader final : public DOMEventTargetHelper,
                          public nsIInterfaceRequestor,
                          public nsSupportsWeakReference,
                          public nsIInputStreamCallback,
                          public nsITimerCallback,
+                         public nsINamed,
                          public workers::WorkerHolder
 {
   friend class FileReaderDecreaseBusyCounter;
 
 public:
   FileReader(nsIGlobalObject* aGlobal,
              workers::WorkerPrivate* aWorkerPrivate);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIINPUTSTREAMCALLBACK
   NS_DECL_NSIINTERFACEREQUESTOR
+  NS_DECL_NSINAMED
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FileReader,
                                                          DOMEventTargetHelper)
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
   // WebIDL
--- a/dom/flyweb/FlyWebService.cpp
+++ b/dom/flyweb/FlyWebService.cpp
@@ -20,16 +20,17 @@
 #include "mozilla/dom/FlyWebDiscoveryManagerBinding.h"
 #include "prnetdb.h"
 #include "DNS.h"
 #include "nsContentPermissionHelper.h"
 #include "nsSocketTransportService2.h"
 #include "nsSocketTransport2.h"
 #include "nsHashPropertyBag.h"
 #include "nsNetUtil.h"
+#include "nsINamed.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIProperty.h"
 #include "nsICertOverrideService.h"
 
 namespace mozilla {
 namespace dom {
 
 struct FlyWebPublishOptions;
@@ -154,16 +155,17 @@ NS_IMPL_ISUPPORTS(FlyWebPublishServerPer
                   nsIContentPermissionRequest,
                   nsIRunnable)
 
 class FlyWebMDNSService final
   : public nsIDNSServiceDiscoveryListener
   , public nsIDNSServiceResolveListener
   , public nsIDNSRegistrationListener
   , public nsITimerCallback
+  , public nsINamed
 {
   friend class FlyWebService;
 
 private:
   enum DiscoveryState {
     DISCOVERY_IDLE,
     DISCOVERY_STARTING,
     DISCOVERY_RUNNING,
@@ -175,16 +177,22 @@ public:
   NS_DECL_NSIDNSSERVICEDISCOVERYLISTENER
   NS_DECL_NSIDNSSERVICERESOLVELISTENER
   NS_DECL_NSIDNSREGISTRATIONLISTENER
   NS_DECL_NSITIMERCALLBACK
 
   explicit FlyWebMDNSService(FlyWebService* aService,
                              const nsACString& aServiceType);
 
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("FlyWebMDNSService");
+    return NS_OK;
+  }
+
 private:
   virtual ~FlyWebMDNSService() = default;
 
   nsresult Init();
   nsresult StartDiscovery();
   nsresult StopDiscovery();
 
   void ListDiscoveredServices(nsTArray<FlyWebDiscoveredService>& aServices);
@@ -291,17 +299,18 @@ LogDNSInfo(nsIDNSServiceInfo* aServiceIn
     LOG_I("%s: attributes end", aFunc);
   }
 }
 
 NS_IMPL_ISUPPORTS(FlyWebMDNSService,
                   nsIDNSServiceDiscoveryListener,
                   nsIDNSServiceResolveListener,
                   nsIDNSRegistrationListener,
-                  nsITimerCallback)
+                  nsITimerCallback,
+                  nsINamed)
 
 FlyWebMDNSService::FlyWebMDNSService(
         FlyWebService* aService,
         const nsACString& aServiceType)
   : mService(aService)
   , mServiceType(aServiceType)
   , mDiscoveryActive(false)
   , mNumConsecutiveStartDiscoveryFailures(0)
--- a/dom/geolocation/MLSFallback.cpp
+++ b/dom/geolocation/MLSFallback.cpp
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MLSFallback.h"
 #include "nsGeoPosition.h"
 #include "nsIGeolocationProvider.h"
 #include "nsServiceManagerUtils.h"
 
-NS_IMPL_ISUPPORTS(MLSFallback, nsITimerCallback)
+NS_IMPL_ISUPPORTS(MLSFallback, nsITimerCallback, nsINamed)
 
 MLSFallback::MLSFallback(uint32_t delay)
 : mDelayMs(delay)
 {
 }
 
 MLSFallback::~MLSFallback()
 {
@@ -54,16 +54,23 @@ MLSFallback::Shutdown()
 }
 
 NS_IMETHODIMP
 MLSFallback::Notify(nsITimer* aTimer)
 {
   return CreateMLSFallbackProvider();
 }
 
+NS_IMETHODIMP
+MLSFallback::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("MLSFallback");
+  return NS_OK;
+}
+
 nsresult
 MLSFallback::CreateMLSFallbackProvider()
 {
   if (mMLSFallbackProvider || !mUpdateWatcher) {
     return NS_OK;
   }
 
   nsresult rv;
--- a/dom/geolocation/MLSFallback.h
+++ b/dom/geolocation/MLSFallback.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMPtr.h"
 #include "nsITimer.h"
+#include "nsINamed.h"
 
 class nsIGeolocationUpdate;
 class nsIGeolocationProvider;
 
 /*
  This class wraps the NetworkGeolocationProvider in a delayed startup.
  It is for providing a fallback to MLS when:
  1) using another provider as the primary provider, and
@@ -23,20 +24,22 @@ class nsIGeolocationProvider;
 
  MLS has an average response of 3s, so with the 2s default delay, a response can
  be expected in 5s.
 
  Telemetry is recommended to monitor that the primary provider is responding
  first when expected to do so.
 */
 class MLSFallback : public nsITimerCallback
+                  , public nsINamed
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   explicit MLSFallback(uint32_t delayMs = 2000);
   nsresult Startup(nsIGeolocationUpdate* aWatcher);
   nsresult Shutdown();
 
 private:
   nsresult CreateMLSFallbackProvider();
   virtual ~MLSFallback();
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -16,16 +16,17 @@
 #include "mozilla/Unused.h"
 #include "mozilla/WeakPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentPermissionHelper.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsGlobalWindow.h"
 #include "nsIDocument.h"
+#include "nsINamed.h"
 #include "nsIObserverService.h"
 #include "nsIScriptError.h"
 #include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 
 class nsIPrincipal;
@@ -91,25 +92,32 @@ class nsGeolocationRequest final
   nsIPrincipal* GetPrincipal();
 
   bool IsWatch() { return mIsWatchPositionRequest; }
   int32_t WatchId() { return mWatchId; }
  private:
   virtual ~nsGeolocationRequest();
 
   class TimerCallbackHolder final : public nsITimerCallback
+                                  , public nsINamed
   {
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSITIMERCALLBACK
 
     explicit TimerCallbackHolder(nsGeolocationRequest* aRequest)
       : mRequest(aRequest)
     {}
 
+    NS_IMETHOD GetName(nsACString& aName) override
+    {
+      aName.AssignLiteral("nsGeolocationRequest::TimerCallbackHolder");
+      return NS_OK;
+    }
+
   private:
     ~TimerCallbackHolder() = default;
     WeakPtr<nsGeolocationRequest> mRequest;
   };
 
   void Notify();
 
   bool mIsWatchPositionRequest;
@@ -632,17 +640,19 @@ nsGeolocationRequest::Shutdown()
   }
 }
 
 
 ////////////////////////////////////////////////////
 // nsGeolocationRequest::TimerCallbackHolder
 ////////////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS(nsGeolocationRequest::TimerCallbackHolder, nsISupports, nsITimerCallback)
+NS_IMPL_ISUPPORTS(nsGeolocationRequest::TimerCallbackHolder,
+                  nsITimerCallback,
+                  nsINamed)
 
 NS_IMETHODIMP
 nsGeolocationRequest::TimerCallbackHolder::Notify(nsITimer*)
 {
   if (mRequest && mRequest->mLocator) {
     RefPtr<nsGeolocationRequest> request(mRequest);
     request->Notify();
   }
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -1102,17 +1102,18 @@ IndexedDatabaseManager::GetLocale()
   MOZ_ASSERT(idbManager, "IDBManager is not ready!");
 
   return idbManager->mLocale;
 }
 #endif
 
 NS_IMPL_ADDREF(IndexedDatabaseManager)
 NS_IMPL_RELEASE_WITH_DESTROY(IndexedDatabaseManager, Destroy())
-NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsIObserver, nsITimerCallback)
+NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsIObserver, nsITimerCallback,
+                        nsINamed)
 
 NS_IMETHODIMP
 IndexedDatabaseManager::Observe(nsISupports* aSubject, const char* aTopic,
                                 const char16_t* aData)
 {
   NS_ASSERTION(IsMainProcess(), "Wrong process!");
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
@@ -1158,16 +1159,23 @@ IndexedDatabaseManager::Notify(nsITimer*
     runnable->Dispatch();
   }
 
   mPendingDeleteInfos.Clear();
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+IndexedDatabaseManager::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("IndexedDatabaseManager");
+  return NS_OK;
+}
+
 already_AddRefed<FileManager>
 FileManagerInfo::GetFileManager(PersistenceType aPersistenceType,
                                 const nsAString& aName) const
 {
   AssertIsOnIOThread();
 
   const nsTArray<RefPtr<FileManager> >& managers =
     GetImmutableArray(aPersistenceType);
--- a/dom/indexedDB/IndexedDatabaseManager.h
+++ b/dom/indexedDB/IndexedDatabaseManager.h
@@ -11,16 +11,17 @@
 
 #include "js/TypeDecls.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/dom/quota/PersistenceType.h"
 #include "mozilla/Mutex.h"
 #include "nsClassHashtable.h"
 #include "nsCOMPtr.h"
 #include "nsHashKeys.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 
 class nsIEventTarget;
 
 namespace mozilla {
 
 class EventChainPostVisitor;
 
@@ -40,16 +41,17 @@ class BackgroundUtilsChild;
 class FileManager;
 class FileManagerInfo;
 
 } // namespace indexedDB
 
 class IndexedDatabaseManager final
   : public nsIObserver
   , public nsITimerCallback
+  , public nsINamed
 {
   typedef mozilla::dom::quota::PersistenceType PersistenceType;
   typedef mozilla::dom::quota::QuotaManager QuotaManager;
   typedef mozilla::dom::indexedDB::FileManager FileManager;
   typedef mozilla::dom::indexedDB::FileManagerInfo FileManagerInfo;
 
 public:
   enum LoggingMode
@@ -59,16 +61,17 @@ public:
     Logging_Detailed,
     Logging_ConciseProfilerMarks,
     Logging_DetailedProfilerMarks
   };
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   // Returns a non-owning reference.
   static IndexedDatabaseManager*
   GetOrCreate();
 
   // Returns a non-owning reference.
   static IndexedDatabaseManager*
   Get();
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -13,16 +13,17 @@
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Unused.h"
 #include "mozilla/Logging.h"
 #include "nsPrintfCString.h"
 #include "nsXULAppAPI.h"
 #include "nsIFrameLoader.h"
+#include "nsINamed.h"
 #include "nsIObserverService.h"
 #include "StaticPtr.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsIObserver.h"
 #include "nsITimer.h"
 #include "nsIPropertyBag2.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCRT.h"
@@ -221,16 +222,17 @@ private:
 /**
  * This class manages the priority of one particular process.  It is
  * main-process only.
  */
 class ParticularProcessPriorityManager final
   : public WakeLockObserver
   , public nsIObserver
   , public nsITimerCallback
+  , public nsINamed
   , public nsSupportsWeakReference
 {
   ~ParticularProcessPriorityManager();
 public:
   explicit ParticularProcessPriorityManager(ContentParent* aContentParent);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
@@ -269,16 +271,22 @@ public:
   void ResetPriority();
   void ResetPriorityNow();
   void SetPriorityNow(ProcessPriority aPriority);
 
   void TabActivityChanged(TabParent* aTabParent, bool aIsActive);
 
   void ShutDown();
 
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("ParticularProcessPriorityManager");
+    return NS_OK;
+  }
+
 private:
   static uint32_t sBackgroundPerceivableGracePeriodMS;
   static uint32_t sBackgroundGracePeriodMS;
 
   void FireTestOnlyObserverNotification(
     const char* aTopic,
     const nsACString& aData = EmptyCString());
 
@@ -556,17 +564,18 @@ ProcessPriorityManagerImpl::TabActivityC
   }
 
   pppm->TabActivityChanged(aTabParent, aIsActive);
 }
 
 NS_IMPL_ISUPPORTS(ParticularProcessPriorityManager,
                   nsIObserver,
                   nsITimerCallback,
-                  nsISupportsWeakReference);
+                  nsISupportsWeakReference,
+                  nsINamed);
 
 ParticularProcessPriorityManager::ParticularProcessPriorityManager(
   ContentParent* aContentParent)
   : mContentParent(aContentParent)
   , mChildID(aContentParent->ChildID())
   , mPriority(PROCESS_PRIORITY_UNKNOWN)
   , mHoldsCPUWakeLock(false)
   , mHoldsHighPriorityWakeLock(false)
--- a/dom/media/MediaDevices.cpp
+++ b/dom/media/MediaDevices.cpp
@@ -5,46 +5,53 @@
 #include "mozilla/dom/MediaDevices.h"
 #include "mozilla/dom/MediaStreamBinding.h"
 #include "mozilla/dom/MediaDeviceInfo.h"
 #include "mozilla/dom/MediaDevicesBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/MediaManager.h"
 #include "MediaTrackConstraints.h"
 #include "nsIEventTarget.h"
+#include "nsINamed.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIPermissionManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsQueryObject.h"
 
 #define DEVICECHANGE_HOLD_TIME_IN_MS 1000
 
 namespace mozilla {
 namespace dom {
 
-class FuzzTimerCallBack final : public nsITimerCallback
+class FuzzTimerCallBack final : public nsITimerCallback, public nsINamed
 {
   ~FuzzTimerCallBack() {}
 
 public:
   explicit FuzzTimerCallBack(MediaDevices* aMediaDevices) : mMediaDevices(aMediaDevices) {}
 
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD Notify(nsITimer* aTimer) final
   {
     mMediaDevices->DispatchTrustedEvent(NS_LITERAL_STRING("devicechange"));
     return NS_OK;
   }
 
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("FuzzTimerCallBack");
+    return NS_OK;
+  }
+
 private:
   nsCOMPtr<MediaDevices> mMediaDevices;
 };
 
-NS_IMPL_ISUPPORTS(FuzzTimerCallBack, nsITimerCallback)
+NS_IMPL_ISUPPORTS(FuzzTimerCallBack, nsITimerCallback, nsINamed)
 
 class MediaDevices::GumResolver : public nsIDOMGetUserMediaSuccessCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   explicit GumResolver(Promise* aPromise) : mPromise(aPromise) {}
 
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -1527,16 +1527,22 @@ MediaStreamGraphImpl::Notify(nsITimer* a
   MonitorAutoLock lock(mMonitor);
   NS_ASSERTION(!mForceShutdownTicket, "MediaStreamGraph took too long to shut down!");
   // Sigh, graph took too long to shut down.  Stop blocking system
   // shutdown and hope all is well.
   mForceShutdownTicket = nullptr;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+MediaStreamGraphImpl::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("MediaStreamGraphImpl");
+  return NS_OK;
+}
 
 /* static */ StaticRefPtr<nsIAsyncShutdownBlocker> gMediaStreamGraphShutdownBlocker;
 
 namespace {
 
 class MediaStreamGraphShutDownRunnable : public Runnable {
 public:
   explicit MediaStreamGraphShutDownRunnable(MediaStreamGraphImpl* aGraph)
@@ -3619,17 +3625,18 @@ MediaStreamGraph::DestroyNonRealtimeInst
 
   if (!graph->mNonRealtimeProcessing) {
     // Start the graph, but don't produce anything
     graph->StartNonRealtimeProcessing(0);
   }
   graph->ForceShutDown(nullptr);
 }
 
-NS_IMPL_ISUPPORTS(MediaStreamGraphImpl, nsIMemoryReporter, nsITimerCallback)
+NS_IMPL_ISUPPORTS(MediaStreamGraphImpl, nsIMemoryReporter, nsITimerCallback,
+                  nsINamed)
 
 NS_IMETHODIMP
 MediaStreamGraphImpl::CollectReports(nsIHandleReportCallback* aHandleReport,
                                      nsISupports* aData, bool aAnonymize)
 {
   if (mLifecycleState >= LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN) {
     // Shutting down, nothing to report.
     FinishCollectReports(aHandleReport, aData, nsTArray<AudioNodeSizes>());
--- a/dom/media/MediaStreamGraphImpl.h
+++ b/dom/media/MediaStreamGraphImpl.h
@@ -9,16 +9,17 @@
 #include "MediaStreamGraph.h"
 
 #include "nsDataHashtable.h"
 
 #include "nsITimer.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIMemoryReporter.h"
+#include "nsINamed.h"
 #include "nsIThread.h"
 #include "nsIRunnable.h"
 #include "nsIAsyncShutdown.h"
 #include "Latency.h"
 #include "mozilla/Services.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WeakPtr.h"
 #include "GraphDriver.h"
@@ -94,22 +95,24 @@ public:
  * be able to friend it.
  *
  * There can be multiple MediaStreamGraph per process: one per AudioChannel.
  * Additionaly, each OfflineAudioContext object creates its own MediaStreamGraph
  * object too.
  */
 class MediaStreamGraphImpl : public MediaStreamGraph,
                              public nsIMemoryReporter,
-                             public nsITimerCallback
+                             public nsITimerCallback,
+                             public nsINamed
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIMEMORYREPORTER
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   /**
    * Use aGraphDriverRequested with SYSTEM_THREAD_DRIVER or AUDIO_THREAD_DRIVER
    * to create a MediaStreamGraph which provides support for real-time audio
    * and/or video.  Set it to OFFLINE_THREAD_DRIVER in order to create a
    * non-realtime instance which just churns through its inputs and produces
    * output.  Those objects currently only support audio, and are used to
    * implement OfflineAudioContext.  They do not support MediaStream inputs.
--- a/dom/media/VideoUtils.cpp
+++ b/dom/media/VideoUtils.cpp
@@ -336,16 +336,23 @@ SimpleTimer::Notify(nsITimer *timer) {
   RefPtr<SimpleTimer> deathGrip(this);
   if (mTask) {
     mTask->Run();
     mTask = nullptr;
   }
   return NS_OK;
 }
 
+NS_IMETHODIMP
+SimpleTimer::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("SimpleTimer");
+  return NS_OK;
+}
+
 nsresult
 SimpleTimer::Init(nsIRunnable* aTask, uint32_t aTimeoutMs, nsIEventTarget* aTarget)
 {
   nsresult rv;
 
   // Get target thread first, so we don't have to cancel the timer if it fails.
   nsCOMPtr<nsIEventTarget> target;
   if (aTarget) {
@@ -373,17 +380,17 @@ SimpleTimer::Init(nsIRunnable* aTask, ui
     return rv;
   }
 
   mTimer = timer.forget();
   mTask = aTask;
   return NS_OK;
 }
 
-NS_IMPL_ISUPPORTS(SimpleTimer, nsITimerCallback)
+NS_IMPL_ISUPPORTS(SimpleTimer, nsITimerCallback, nsINamed)
 
 already_AddRefed<SimpleTimer>
 SimpleTimer::Create(nsIRunnable* aTask, uint32_t aTimeoutMs, nsIEventTarget* aTarget)
 {
   RefPtr<SimpleTimer> t(new SimpleTimer());
   if (NS_FAILED(t->Init(aTask, aTimeoutMs, aTarget))) {
     return nullptr;
   }
--- a/dom/media/VideoUtils.h
+++ b/dom/media/VideoUtils.h
@@ -15,16 +15,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/MozPromise.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
+#include "nsINamed.h"
 #include "nsIThread.h"
 #include "nsITimer.h"
 #include "nsRect.h"
 #include "nsSize.h"
 #include "nsThreadUtils.h"
 #include "prtime.h"
 
 using mozilla::CheckedInt64;
@@ -279,20 +280,21 @@ RefPtr<GenericPromise> InvokeUntil(Work 
     }
   };
 
   Helper::Iteration(p, aWork, aCondition);
   return p.forget();
 }
 
 // Simple timer to run a runnable after a timeout.
-class SimpleTimer : public nsITimerCallback
+class SimpleTimer : public nsITimerCallback, public nsINamed
 {
 public:
   NS_DECL_ISUPPORTS
+  NS_DECL_NSINAMED
 
   // Create a new timer to run aTask after aTimeoutMs milliseconds
   // on thread aTarget. If aTarget is null, task is run on the main thread.
   static already_AddRefed<SimpleTimer> Create(nsIRunnable* aTask,
                                               uint32_t aTimeoutMs,
                                               nsIEventTarget* aTarget = nullptr);
   void Cancel();
 
--- a/dom/media/webrtc/MediaEngineDefault.cpp
+++ b/dom/media/webrtc/MediaEngineDefault.cpp
@@ -27,17 +27,17 @@
 #endif
 
 #define AUDIO_RATE mozilla::MediaEngine::DEFAULT_SAMPLE_RATE
 #define DEFAULT_AUDIO_TIMER_MS 10
 namespace mozilla {
 
 using namespace mozilla::gfx;
 
-NS_IMPL_ISUPPORTS(MediaEngineDefaultVideoSource, nsITimerCallback)
+NS_IMPL_ISUPPORTS(MediaEngineDefaultVideoSource, nsITimerCallback, nsINamed)
 /**
  * Default video source.
  */
 
 MediaEngineDefaultVideoSource::MediaEngineDefaultVideoSource()
 #ifdef MOZ_WEBRTC
   : MediaEngineCameraVideoSource("FakeVideo.Monitor")
 #else
@@ -281,16 +281,23 @@ MediaEngineDefaultVideoSource::Notify(ns
   MonitorAutoLock lock(mMonitor);
 
   // implicitly releases last image
   mImage = ycbcr_image.forget();
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+MediaEngineDefaultVideoSource::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("MediaEngineDefaultVideoSource");
+  return NS_OK;
+}
+
 void
 MediaEngineDefaultVideoSource::NotifyPull(MediaStreamGraph* aGraph,
                                           SourceMediaStream *aSource,
                                           TrackID aID,
                                           StreamTime aDesiredTime,
                                           const PrincipalHandle& aPrincipalHandle)
 {
   // AddTrack takes ownership of segment
--- a/dom/media/webrtc/MediaEngineDefault.h
+++ b/dom/media/webrtc/MediaEngineDefault.h
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MEDIAENGINEDEFAULT_H_
 #define MEDIAENGINEDEFAULT_H_
 
+#include "nsINamed.h"
 #include "nsITimer.h"
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "DOMMediaStream.h"
 #include "nsComponentManagerUtils.h"
 #include "mozilla/Monitor.h"
 
@@ -31,16 +32,17 @@ class ImageContainer;
 } // namespace layers
 
 class MediaEngineDefault;
 
 /**
  * The default implementation of the MediaEngine interface.
  */
 class MediaEngineDefaultVideoSource : public nsITimerCallback,
+                                      public nsINamed,
 #ifdef MOZ_WEBRTC
                                       public MediaEngineCameraVideoSource
 #else
                                       public MediaEngineVideoSource
 #endif
 {
 public:
   MediaEngineDefaultVideoSource();
@@ -82,16 +84,17 @@ public:
 
   nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
 protected:
   ~MediaEngineDefaultVideoSource();
 
   friend class MediaEngineDefault;
 
   TrackID mTrackID;
   nsCOMPtr<nsITimer> mTimer;
--- a/dom/plugins/base/nsNPAPIPluginStreamListener.cpp
+++ b/dom/plugins/base/nsNPAPIPluginStreamListener.cpp
@@ -31,17 +31,17 @@ nsNPAPIStreamWrapper::~nsNPAPIStreamWrap
 {
   if (mOutputStream) {
     mOutputStream->Close();
   }
 }
 
 // nsNPAPIPluginStreamListener Methods
 NS_IMPL_ISUPPORTS(nsNPAPIPluginStreamListener,
-                  nsITimerCallback, nsIHTTPHeaderListener)
+                  nsITimerCallback, nsIHTTPHeaderListener, nsINamed)
 
 nsNPAPIPluginStreamListener::nsNPAPIPluginStreamListener(nsNPAPIPluginInstance* inst,
                                                          void* notifyData,
                                                          const char* aURL)
   : mStreamBuffer(nullptr)
   , mNotifyURL(aURL ? PL_strdup(aURL) : nullptr)
   , mInst(inst)
   , mStreamBufferSize(0)
@@ -769,16 +769,23 @@ nsNPAPIPluginStreamListener::Notify(nsIT
         StopDataPump();
       }
 
   MaybeRunStopBinding();
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsNPAPIPluginStreamListener::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsNPAPIPluginStreamListener");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsNPAPIPluginStreamListener::StatusLine(const char* line)
 {
   mResponseHeaders.Append(line);
   mResponseHeaders.Append('\n');
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/plugins/base/nsNPAPIPluginStreamListener.h
+++ b/dom/plugins/base/nsNPAPIPluginStreamListener.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsNPAPIPluginStreamListener_h_
 #define nsNPAPIPluginStreamListener_h_
 
 #include "nscore.h"
 #include "nsIHTTPHeaderListener.h"
+#include "nsINamed.h"
 #include "nsIRequest.h"
 #include "nsITimer.h"
 #include "nsCOMArray.h"
 #include "nsIOutputStream.h"
 #include "nsIPluginInstanceOwner.h"
 #include "nsString.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "mozilla/PluginLibrary.h"
@@ -36,25 +37,27 @@ public:
 
   NPStream                              mNPStream;
 protected:
   nsCOMPtr<nsIOutputStream>             mOutputStream; // only valid if not browser initiated
   nsNPAPIPluginStreamListener*          mStreamListener; // only valid if browser initiated
 };
 
 class nsNPAPIPluginStreamListener : public nsITimerCallback,
-                                    public nsIHTTPHeaderListener
+                                    public nsIHTTPHeaderListener,
+                                    public nsINamed
 {
 private:
   typedef mozilla::PluginLibrary PluginLibrary;
 
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIHTTPHEADERLISTENER
+  NS_DECL_NSINAMED
 
   nsNPAPIPluginStreamListener(nsNPAPIPluginInstance* inst, void* notifyData,
                               const char* aURL);
 
   nsresult OnStartBinding(nsPluginStreamListenerPeer* streamPeer);
   nsresult OnDataAvailable(nsPluginStreamListenerPeer* streamPeer,
                            nsIInputStream* input,
                            uint32_t length);
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -315,17 +315,18 @@ nsPluginHost::~nsPluginHost()
   UnloadPlugins();
   sInst = nullptr;
 }
 
 NS_IMPL_ISUPPORTS(nsPluginHost,
                   nsIPluginHost,
                   nsIObserver,
                   nsITimerCallback,
-                  nsISupportsWeakReference)
+                  nsISupportsWeakReference,
+                  nsINamed)
 
 already_AddRefed<nsPluginHost>
 nsPluginHost::GetInst()
 {
   if (!sInst) {
     sInst = new nsPluginHost();
     if (!sInst)
       return nullptr;
@@ -3729,16 +3730,23 @@ NS_IMETHODIMP nsPluginHost::Notify(nsITi
       return NS_OK;
     }
     pluginTag = pluginTag->mNext;
   }
 
   return NS_ERROR_FAILURE;
 }
 
+NS_IMETHODIMP
+nsPluginHost::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsPluginHost");
+  return NS_OK;
+}
+
 #ifdef XP_WIN
 // Re-enable any top level browser windows that were disabled by modal dialogs
 // displayed by the crashed plugin.
 static void
 CheckForDisabledWindows()
 {
   nsCOMPtr<nsIWindowMediator> wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
   if (!wm)
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -15,16 +15,17 @@
 #include "nsIPluginTag.h"
 #include "nsPluginsDir.h"
 #include "nsPluginDirServiceProvider.h"
 #include "nsWeakPtr.h"
 #include "nsIPrompt.h"
 #include "nsWeakReference.h"
 #include "MainThreadUtils.h"
 #include "nsTArray.h"
+#include "nsINamed.h"
 #include "nsTObserverArray.h"
 #include "nsITimer.h"
 #include "nsPluginTags.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIIDNService.h"
 #include "nsCRT.h"
 
 #ifdef XP_WIN
@@ -70,31 +71,33 @@ public:
 
   RefPtr<nsInvalidPluginTag> mPrev;
   RefPtr<nsInvalidPluginTag> mNext;
 };
 
 class nsPluginHost final : public nsIPluginHost,
                            public nsIObserver,
                            public nsITimerCallback,
-                           public nsSupportsWeakReference
+                           public nsSupportsWeakReference,
+                           public nsINamed
 {
   friend class nsPluginTag;
   friend class nsFakePluginTag;
   virtual ~nsPluginHost();
 
 public:
   nsPluginHost();
 
   static already_AddRefed<nsPluginHost> GetInst();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPLUGINHOST
   NS_DECL_NSIOBSERVER
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   nsresult LoadPlugins();
   nsresult UnloadPlugins();
 
   nsresult SetUpPluginInstance(const nsACString &aMimeType,
                                nsIURI *aURL,
                                nsPluginInstanceOwner *aOwner);
 
--- a/dom/presentation/PresentationSessionInfo.cpp
+++ b/dom/presentation/PresentationSessionInfo.cpp
@@ -1150,17 +1150,18 @@ PresentationControllingInfo::NotifyData(
  *    receives the answer.)
  * 5. |NotifyTransportReady| of |nsIPresentationSessionTransportCallback| is
  *    called. The presentation session is ready to use, so notify the listener
  *    of CONNECTED state.
  */
 
 NS_IMPL_ISUPPORTS_INHERITED(PresentationPresentingInfo,
                             PresentationSessionInfo,
-                            nsITimerCallback)
+                            nsITimerCallback,
+                            nsINamed)
 
 nsresult
 PresentationPresentingInfo::Init(nsIPresentationControlChannel* aControlChannel)
 {
   PresentationSessionInfo::Init(aControlChannel);
 
   // Add a timer to prevent waiting indefinitely in case the receiver page fails
   // to become ready.
@@ -1537,16 +1538,24 @@ PresentationPresentingInfo::Notify(nsITi
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_WARNING("The receiver page fails to become ready before timeout.");
 
   mTimer = nullptr;
   return ReplyError(NS_ERROR_DOM_TIMEOUT_ERR);
 }
 
+// nsITimerCallback
+NS_IMETHODIMP
+PresentationPresentingInfo::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("PresentationPresentingInfo");
+  return NS_OK;
+}
+
 // PromiseNativeHandler
 void
 PresentationPresentingInfo::ResolvedCallback(JSContext* aCx,
                                              JS::Handle<JS::Value> aValue)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (NS_WARN_IF(!aValue.isObject())) {
--- a/dom/presentation/PresentationSessionInfo.h
+++ b/dom/presentation/PresentationSessionInfo.h
@@ -9,16 +9,17 @@
 
 #include "base/process.h"
 #include "mozilla/dom/nsIContentParent.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
+#include "nsINamed.h"
 #include "nsINetworkInfoService.h"
 #include "nsIPresentationControlChannel.h"
 #include "nsIPresentationDevice.h"
 #include "nsIPresentationListener.h"
 #include "nsIPresentationService.h"
 #include "nsIPresentationSessionTransport.h"
 #include "nsIPresentationSessionTransportBuilder.h"
 #include "nsIServerSocket.h"
@@ -228,21 +229,23 @@ private:
   bool mIsReconnecting = false;
   bool mDoReconnectAfterClose = false;
 };
 
 // Session info with presenting browsing context (receiver side) behaviors.
 class PresentationPresentingInfo final : public PresentationSessionInfo
                                        , public PromiseNativeHandler
                                        , public nsITimerCallback
+                                       , public nsINamed
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIPRESENTATIONCONTROLCHANNELLISTENER
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   PresentationPresentingInfo(const nsAString& aUrl,
                              const nsAString& aSessionId,
                              nsIPresentationDevice* aDevice)
     : PresentationSessionInfo(aUrl,
                               aSessionId,
                               nsIPresentationService::ROLE_RECEIVER)
   {
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -10,16 +10,17 @@
 #include "nsIConsoleService.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDocument.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIStreamLoader.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIHttpHeaderVisitor.h"
+#include "nsINamed.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIMutableArray.h"
 #include "nsIScriptError.h"
 #include "nsISimpleEnumerator.h"
 #include "nsITimer.h"
 #include "nsIUploadChannel2.h"
 #include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
@@ -4169,16 +4170,17 @@ ServiceWorkerManager::RemoveNavigationIn
     if (list->IsEmpty()) {
       list = nullptr;
       mNavigationInterceptions.Remove(aScope);
     }
   }
 }
 
 class UpdateTimerCallback final : public nsITimerCallback
+                                , public nsINamed
 {
   nsCOMPtr<nsIPrincipal> mPrincipal;
   const nsCString mScope;
 
   ~UpdateTimerCallback()
   {
   }
 
@@ -4202,20 +4204,27 @@ public:
       // shutting down, do nothing
       return NS_OK;
     }
 
     swm->UpdateTimerFired(mPrincipal, mScope);
     return NS_OK;
   }
 
+  NS_IMETHOD
+  GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("UpdateTimerCallback");
+    return NS_OK;
+  }
+
   NS_DECL_ISUPPORTS
 };
 
-NS_IMPL_ISUPPORTS(UpdateTimerCallback, nsITimerCallback)
+NS_IMPL_ISUPPORTS(UpdateTimerCallback, nsITimerCallback, nsINamed)
 
 bool
 ServiceWorkerManager::MayHaveActiveServiceWorkerInstance(ContentParent* aContent,
                                                          nsIPrincipal* aPrincipal)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aPrincipal);
 
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -6,16 +6,17 @@
 
 #include "ServiceWorkerPrivate.h"
 
 #include "ServiceWorkerManager.h"
 #include "ServiceWorkerWindowClient.h"
 #include "nsContentUtils.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIHttpHeaderVisitor.h"
+#include "nsINamed.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIPushErrorReporter.h"
 #include "nsISupportsImpl.h"
 #include "nsITimedChannel.h"
 #include "nsIUploadChannel2.h"
 #include "nsNetUtil.h"
 #include "nsProxyRelease.h"
 #include "nsQueryObject.h"
@@ -1048,16 +1049,17 @@ ServiceWorkerPrivate::SendPushSubscripti
 
   return NS_OK;
 }
 
 namespace {
 
 class AllowWindowInteractionHandler final : public ExtendableEventCallback
                                           , public nsITimerCallback
+                                          , public nsINamed
                                           , public WorkerHolder
 {
   nsCOMPtr<nsITimer> mTimer;
 
   ~AllowWindowInteractionHandler()
   {
     // We must either fail to initialize or call ClearWindowAllowed.
     MOZ_DIAGNOSTIC_ASSERT(!mTimer);
@@ -1132,16 +1134,24 @@ class AllowWindowInteractionHandler fina
   NS_IMETHOD
   Notify(nsITimer* aTimer) override
   {
     MOZ_DIAGNOSTIC_ASSERT(mTimer == aTimer);
     ClearWindowAllowed(mWorkerPrivate);
     return NS_OK;
   }
 
+  // nsINamed virtual methods
+  NS_IMETHOD
+  GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("AllowWindowInteractionHandler");
+    return NS_OK;
+  }
+
   // WorkerHolder virtual methods
   bool
   Notify(Status aStatus) override
   {
     // We could try to hold the worker alive until the timer fires, but other
     // APIs are not likely to work in this partially shutdown state.  We might
     // as well let the worker thread exit.
     ClearWindowAllowed(mWorkerPrivate);
@@ -1159,17 +1169,17 @@ public:
   void
   FinishedWithResult(ExtendableEventResult /* aResult */) override
   {
     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     ClearWindowAllowed(workerPrivate);
   }
 };
 
-NS_IMPL_ISUPPORTS(AllowWindowInteractionHandler, nsITimerCallback)
+NS_IMPL_ISUPPORTS(AllowWindowInteractionHandler, nsITimerCallback, nsINamed)
 
 class SendNotificationEventRunnable final : public ExtendableEventWorkerRunnable
 {
   const nsString mEventName;
   const nsString mID;
   const nsString mTitle;
   const nsString mDir;
   const nsString mLang;
@@ -2014,16 +2024,17 @@ ServiceWorkerPrivate::IsIdle() const
 {
   AssertIsOnMainThread();
   return mTokenCount == 0 || (mTokenCount == 1 && mIdleKeepAliveToken);
 }
 
 namespace {
 
 class ServiceWorkerPrivateTimerCallback final : public nsITimerCallback
+                                              , public nsINamed
 {
 public:
   typedef void (ServiceWorkerPrivate::*Method)(nsITimer*);
 
   ServiceWorkerPrivateTimerCallback(ServiceWorkerPrivate* aServiceWorkerPrivate,
                                     Method aMethod)
     : mServiceWorkerPrivate(aServiceWorkerPrivate)
     , mMethod(aMethod)
@@ -2033,26 +2044,33 @@ public:
   NS_IMETHOD
   Notify(nsITimer* aTimer) override
   {
     (mServiceWorkerPrivate->*mMethod)(aTimer);
     mServiceWorkerPrivate = nullptr;
     return NS_OK;
   }
 
+  NS_IMETHOD
+  GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("ServiceWorkerPrivateTimerCallback");
+    return NS_OK;
+  }
+
 private:
   ~ServiceWorkerPrivateTimerCallback() = default;
 
   RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
   Method mMethod;
 
   NS_DECL_THREADSAFE_ISUPPORTS
 };
 
-NS_IMPL_ISUPPORTS(ServiceWorkerPrivateTimerCallback, nsITimerCallback);
+NS_IMPL_ISUPPORTS(ServiceWorkerPrivateTimerCallback, nsITimerCallback, nsINamed);
 
 } // anonymous namespace
 
 void
 ServiceWorkerPrivate::NoteIdleWorkerCallback(nsITimer* aTimer)
 {
   AssertIsOnMainThread();
 
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -11,16 +11,17 @@
 #include "nsIContentSecurityPolicy.h"
 #include "nsIConsoleService.h"
 #include "nsIDOMDOMException.h"
 #include "nsIDOMEvent.h"
 #include "nsIDocument.h"
 #include "nsIDocShell.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIMemoryReporter.h"
+#include "nsINamed.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIPermissionManager.h"
 #include "nsIScriptError.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScriptTimeoutHandler.h"
 #include "nsITabChild.h"
 #include "nsITextToSubURI.h"
@@ -1207,17 +1208,18 @@ private:
 
     ReportError(aCx, parent, fireAtScope, aWorkerPrivate, mReport,
                 innerWindowId);
     return true;
   }
 };
 
 class TimerRunnable final : public WorkerRunnable,
-                            public nsITimerCallback
+                            public nsITimerCallback,
+                            public nsINamed
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   explicit TimerRunnable(WorkerPrivate* aWorkerPrivate)
   : WorkerRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
   { }
 
@@ -1243,19 +1245,27 @@ private:
     return aWorkerPrivate->RunExpiredTimeouts(aCx);
   }
 
   NS_IMETHOD
   Notify(nsITimer* aTimer) override
   {
     return Run();
   }
+
+  NS_IMETHOD
+  GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("TimerRunnable");
+    return NS_OK;
+  }
 };
 
-NS_IMPL_ISUPPORTS_INHERITED(TimerRunnable, WorkerRunnable, nsITimerCallback)
+NS_IMPL_ISUPPORTS_INHERITED(TimerRunnable, WorkerRunnable, nsITimerCallback,
+                            nsINamed)
 
 class DebuggerImmediateRunnable : public WorkerRunnable
 {
   RefPtr<dom::Function> mHandler;
 
 public:
   explicit DebuggerImmediateRunnable(WorkerPrivate* aWorkerPrivate,
                                      dom::Function& aHandler)
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -3958,16 +3958,17 @@ XMLHttpRequestMainThread::GetName(nsACSt
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXMLHttpRequestXPCOMifier)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
   NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
   NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)
   NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
+  NS_INTERFACE_MAP_ENTRY(nsINamed)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXMLHttpRequestXPCOMifier)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXMLHttpRequestXPCOMifier)
 
 // Can't NS_IMPL_CYCLE_COLLECTION( because mXHR has ambiguous
 // inheritance from nsISupports.
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -873,17 +873,18 @@ private:
 
 // A shim class designed to expose the non-DOM interfaces of
 // XMLHttpRequest via XPCOM stuff.
 class nsXMLHttpRequestXPCOMifier final : public nsIStreamListener,
                                          public nsIChannelEventSink,
                                          public nsIAsyncVerifyRedirectCallback,
                                          public nsIProgressEventSink,
                                          public nsIInterfaceRequestor,
-                                         public nsITimerCallback
+                                         public nsITimerCallback,
+                                         public nsINamed
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXMLHttpRequestXPCOMifier,
                                            nsIStreamListener)
 
   explicit nsXMLHttpRequestXPCOMifier(XMLHttpRequestMainThread* aXHR) :
     mXHR(aXHR)
   {
@@ -898,16 +899,17 @@ private:
 
 public:
   NS_FORWARD_NSISTREAMLISTENER(mXHR->)
   NS_FORWARD_NSIREQUESTOBSERVER(mXHR->)
   NS_FORWARD_NSICHANNELEVENTSINK(mXHR->)
   NS_FORWARD_NSIASYNCVERIFYREDIRECTCALLBACK(mXHR->)
   NS_FORWARD_NSIPROGRESSEVENTSINK(mXHR->)
   NS_FORWARD_NSITIMERCALLBACK(mXHR->)
+  NS_FORWARD_NSINAMED(mXHR->)
 
   NS_DECL_NSIINTERFACEREQUESTOR
 
 private:
   RefPtr<XMLHttpRequestMainThread> mXHR;
 };
 
 class nsXHRParseEndListener : public nsIDOMEventListener
--- a/editor/composer/nsComposerCommandsUpdater.cpp
+++ b/editor/composer/nsComposerCommandsUpdater.cpp
@@ -35,17 +35,18 @@ nsComposerCommandsUpdater::~nsComposerCo
 {
   // cancel any outstanding update timer
   if (mUpdateTimer) {
     mUpdateTimer->Cancel();
   }
 }
 
 NS_IMPL_ISUPPORTS(nsComposerCommandsUpdater, nsISelectionListener,
-                  nsIDocumentStateListener, nsITransactionListener, nsITimerCallback)
+                  nsIDocumentStateListener, nsITransactionListener,
+                  nsITimerCallback, nsINamed)
 
 #if 0
 #pragma mark -
 #endif
 
 NS_IMETHODIMP
 nsComposerCommandsUpdater::NotifyDocumentCreated()
 {
@@ -350,16 +351,23 @@ nsComposerCommandsUpdater::GetCommandUpd
 {
   nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShell);
   NS_ENSURE_TRUE(docShell, nullptr);
   nsCOMPtr<nsICommandManager> manager = docShell->GetCommandManager();
   nsCOMPtr<nsPICommandUpdater> updater = do_QueryInterface(manager);
   return updater.forget();
 }
 
+NS_IMETHODIMP
+nsComposerCommandsUpdater::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsComposerCommandsUpdater");
+  return NS_OK;
+}
+
 #if 0
 #pragma mark -
 #endif
 
 nsresult
 nsComposerCommandsUpdater::Notify(nsITimer *timer)
 {
   NS_ASSERTION(timer == mUpdateTimer.get(), "Hey, this ain't my timer!");
--- a/editor/composer/nsComposerCommandsUpdater.h
+++ b/editor/composer/nsComposerCommandsUpdater.h
@@ -7,32 +7,34 @@
 
 
 
 #ifndef nsComposerCommandsUpdater_h__
 #define nsComposerCommandsUpdater_h__
 
 #include "nsCOMPtr.h"                   // for already_AddRefed, nsCOMPtr
 #include "nsIDocumentStateListener.h"
+#include "nsINamed.h"
 #include "nsISelectionListener.h"
 #include "nsISupportsImpl.h"            // for NS_DECL_ISUPPORTS
 #include "nsITimer.h"                   // for NS_DECL_NSITIMERCALLBACK, etc
 #include "nsITransactionListener.h"     // for nsITransactionListener
 #include "nsIWeakReferenceUtils.h"      // for nsWeakPtr
 #include "nscore.h"                     // for NS_IMETHOD, nsresult, etc
 
 class nsPIDOMWindowOuter;
 class nsITransaction;
 class nsITransactionManager;
 class nsPICommandUpdater;
 
 class nsComposerCommandsUpdater : public nsISelectionListener,
                                   public nsIDocumentStateListener,
                                   public nsITransactionListener,
-                                  public nsITimerCallback
+                                  public nsITimerCallback,
+                                  public nsINamed
 {
 public:
 
                                   nsComposerCommandsUpdater();
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
@@ -40,16 +42,19 @@ public:
   NS_DECL_NSISELECTIONLISTENER
 
   // nsIDocumentStateListener
   NS_DECL_NSIDOCUMENTSTATELISTENER
 
   // nsITimerCallback interfaces
   NS_DECL_NSITIMERCALLBACK
 
+  // nsINamed
+  NS_DECL_NSINAMED
+
   /** nsITransactionListener interfaces
     */
   NS_IMETHOD WillDo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt) override;
   NS_IMETHOD DidDo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aDoResult) override;
   NS_IMETHOD WillUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt) override;
   NS_IMETHOD DidUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aUndoResult) override;
   NS_IMETHOD WillRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt) override;
   NS_IMETHOD DidRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aRedoResult) override;
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -99,16 +99,17 @@ TextEditRules::~TextEditRules()
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION(TextEditRules, mBogusNode, mCachedSelectionNode)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextEditRules)
   NS_INTERFACE_MAP_ENTRY(nsIEditRules)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
+  NS_INTERFACE_MAP_ENTRY(nsINamed)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditRules)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(TextEditRules)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(TextEditRules)
 
 NS_IMETHODIMP
 TextEditRules::Init(TextEditor* aTextEditor)
@@ -1584,16 +1585,23 @@ TextEditRules::Notify(nsITimer* aTimer)
   // Check whether our text editor's password flag was changed before this
   // "hide password character" timer actually fires.
   nsresult rv = IsPasswordEditor() ? HideLastPWInput() : NS_OK;
   ASSERT_PASSWORD_LENGTHS_EQUAL();
   mLastLength = 0;
   return rv;
 }
 
+NS_IMETHODIMP
+TextEditRules::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("TextEditRules");
+  return NS_OK;
+}
+
 nsresult
 TextEditRules::HideLastPWInput()
 {
   if (!mLastLength) {
     // Special case, we're trying to replace a range that no longer exists
     return NS_OK;
   }
 
--- a/editor/libeditor/TextEditRules.h
+++ b/editor/libeditor/TextEditRules.h
@@ -6,16 +6,17 @@
 #ifndef mozilla_TextEditRules_h
 #define mozilla_TextEditRules_h
 
 #include "mozilla/EditorBase.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIEditRules.h"
 #include "nsIEditor.h"
+#include "nsINamed.h"
 #include "nsISupportsImpl.h"
 #include "nsITimer.h"
 #include "nsString.h"
 #include "nscore.h"
 
 class nsIDOMNode;
 
 namespace mozilla {
@@ -35,16 +36,17 @@ class Selection;
  *    directly.  Content nodes in document fragments that are not part of the
  *    document itself may be manipulated at will.  Operations on document
  *    fragments must <B>not</B> go through the editor.
  * 2. Selection must not be explicitly set by the rule method.
  *    Any manipulation of Selection must be done by the editor.
  */
 class TextEditRules : public nsIEditRules
                     , public nsITimerCallback
+                    , public nsINamed
 {
 public:
   typedef dom::Element Element;
   typedef dom::Selection Selection;
   typedef dom::Text Text;
   template<typename T> using OwningNonNull = OwningNonNull<T>;
 
   NS_DECL_NSITIMERCALLBACK
@@ -63,16 +65,19 @@ public:
                        nsIEditor::EDirection aDirection) override;
   NS_IMETHOD WillDoAction(Selection* aSelection, RulesInfo* aInfo,
                           bool* aCancel, bool* aHandled) override;
   NS_IMETHOD DidDoAction(Selection* aSelection, RulesInfo* aInfo,
                          nsresult aResult) override;
   NS_IMETHOD_(bool) DocumentIsEmpty() override;
   NS_IMETHOD DocumentModified() override;
 
+  // nsINamed methods
+  NS_DECL_NSINAMED
+
 protected:
   virtual ~TextEditRules();
 
 public:
   void ResetIMETextPWBuf();
 
   /**
    * Handles the newline characters either according to aNewLineHandling
--- a/extensions/pref/autoconfig/src/nsAutoConfig.cpp
+++ b/extensions/pref/autoconfig/src/nsAutoConfig.cpp
@@ -31,17 +31,19 @@ mozilla::LazyLogModule MCD("MCD");
 extern nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
                                           const char *filename,
                                           bool bGlobalContext,
                                           bool bCallbacks,
                                           bool skipFirstLine);
 
 // nsISupports Implementation
 
-NS_IMPL_ISUPPORTS(nsAutoConfig, nsIAutoConfig, nsITimerCallback, nsIStreamListener, nsIObserver, nsIRequestObserver, nsISupportsWeakReference)
+NS_IMPL_ISUPPORTS(nsAutoConfig, nsIAutoConfig, nsITimerCallback, nsIStreamListener,
+                  nsIObserver, nsIRequestObserver, nsISupportsWeakReference,
+                  nsINamed)
 
 nsAutoConfig::nsAutoConfig()
 {
 }
 
 nsresult nsAutoConfig::Init()
 {
     // member initializers and constructor code
@@ -167,16 +169,23 @@ nsAutoConfig::OnStopRequest(nsIRequest *
 
 // Notify method as a TimerCallBack function
 NS_IMETHODIMP nsAutoConfig::Notify(nsITimer *timer)
 {
     downloadAutoConfig();
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsAutoConfig::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsAutoConfig");
+  return NS_OK;
+}
+
 /* Observe() is called twice: once at the instantiation time and other
    after the profile is set. It doesn't do anything but return NS_OK during the
    creation time. Second time it calls  downloadAutoConfig().
 */
 
 NS_IMETHODIMP nsAutoConfig::Observe(nsISupports *aSubject,
                                     const char *aTopic,
                                     const char16_t *someData)
--- a/extensions/pref/autoconfig/src/nsAutoConfig.h
+++ b/extensions/pref/autoconfig/src/nsAutoConfig.h
@@ -4,38 +4,41 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAutoConfig_h
 #define nsAutoConfig_h
 
 #include "nsIAutoConfig.h"
 #include "nsITimer.h"
 #include "nsIFile.h"
+#include "nsINamed.h"
 #include "nsIObserver.h"
 #include "nsIStreamListener.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsWeakReference.h"
 #include "nsString.h"
 
 class nsAutoConfig : public nsIAutoConfig,
                      public nsITimerCallback,
                      public nsIStreamListener,
                      public nsIObserver,
-                     public nsSupportsWeakReference
+                     public nsSupportsWeakReference,
+                     public nsINamed
 
 {
     public:
 
         NS_DECL_THREADSAFE_ISUPPORTS
         NS_DECL_NSIAUTOCONFIG
         NS_DECL_NSIREQUESTOBSERVER
         NS_DECL_NSISTREAMLISTENER
         NS_DECL_NSIOBSERVER
         NS_DECL_NSITIMERCALLBACK
+        NS_DECL_NSINAMED
 
         nsAutoConfig();
         nsresult Init();
 
     protected:
 
         virtual ~nsAutoConfig();
         nsresult downloadAutoConfig();
--- a/gfx/layers/apz/util/APZEventState.cpp
+++ b/gfx/layers/apz/util/APZEventState.cpp
@@ -16,16 +16,17 @@
 #include "mozilla/Move.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/TouchEvents.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "nsCOMPtr.h"
 #include "nsDocShell.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMWindowUtils.h"
+#include "nsINamed.h"
 #include "nsIScrollableFrame.h"
 #include "nsIScrollbarMediator.h"
 #include "nsITimer.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsIWidget.h"
 #include "nsLayoutUtils.h"
 #include "nsQueryFrame.h"
 #include "TouchManager.h"
@@ -119,16 +120,17 @@ APZEventState::APZEventState(nsIWidget* 
     sActiveDurationMsSet = true;
   }
 }
 
 APZEventState::~APZEventState()
 {}
 
 class DelayedFireSingleTapEvent final : public nsITimerCallback
+                                      , public nsINamed
 {
 public:
   NS_DECL_ISUPPORTS
 
   DelayedFireSingleTapEvent(nsWeakPtr aWidget,
                             LayoutDevicePoint& aPoint,
                             Modifiers aModifiers,
                             int32_t aClickCount,
@@ -149,16 +151,23 @@ public:
     if (nsCOMPtr<nsIWidget> widget = do_QueryReferent(mWidget)) {
       widget::nsAutoRollup rollup(mTouchRollup.get());
       APZCCallbackHelper::FireSingleTapEvent(mPoint, mModifiers, mClickCount, widget);
     }
     mTimer = nullptr;
     return NS_OK;
   }
 
+  NS_IMETHOD
+  GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("DelayedFireSingleTapEvent");
+    return NS_OK;
+  }
+
   void ClearTimer() {
     mTimer = nullptr;
   }
 
 private:
   ~DelayedFireSingleTapEvent()
   {
   }
@@ -166,17 +175,17 @@ private:
   nsWeakPtr mWidget;
   LayoutDevicePoint mPoint;
   Modifiers mModifiers;
   int32_t mClickCount;
   nsCOMPtr<nsITimer> mTimer;
   RefPtr<nsIContent> mTouchRollup;
 };
 
-NS_IMPL_ISUPPORTS(DelayedFireSingleTapEvent, nsITimerCallback)
+NS_IMPL_ISUPPORTS(DelayedFireSingleTapEvent, nsITimerCallback, nsINamed)
 
 void
 APZEventState::ProcessSingleTap(const CSSPoint& aPoint,
                                 const CSSToLayoutDeviceScale& aScale,
                                 Modifiers aModifiers,
                                 const ScrollableLayerGuid& aGuid,
                                 int32_t aClickCount)
 {
--- a/media/mtransport/nr_timer.cpp
+++ b/media/mtransport/nr_timer.cpp
@@ -50,16 +50,17 @@
  */
 
 #include <string>
 
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIEventTarget.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 #include "nsNetCID.h"
 #include "runnable_utils.h"
 #include "mozilla/DebugOnly.h"
 
 extern "C" {
 #include "nr_api.h"
 #include "async_timer.h"
@@ -82,17 +83,18 @@ protected:
   /* additional members */
   NR_async_cb cb_;
   void *cb_arg_;
   std::string function_;
   int line_;
 };
 
 class nrappkitTimerCallback : public nrappkitCallback,
-                              public nsITimerCallback {
+                              public nsITimerCallback,
+                              public nsINamed {
  public:
   // We're going to release ourself in the callback, so we need to be threadsafe
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
 
   nrappkitTimerCallback(NR_async_cb cb, void *cb_arg,
                         const char *function, int line)
       : nrappkitCallback(cb, cb_arg, function, line),
@@ -105,22 +107,28 @@ class nrappkitTimerCallback : public nra
   virtual void Cancel() override {
     AddRef();  // Cancelling the timer causes the callback it holds to
                // be released. AddRef() keeps us alive.
     timer_->Cancel();
     timer_ = nullptr;
     Release(); // Will cause deletion of this object.
   }
 
+  NS_IMETHOD
+  GetName(nsACString& aName) override {
+    aName.AssignLiteral("nrappkitTimerCallback");
+    return NS_OK;
+  }
+
  private:
   nsCOMPtr<nsITimer> timer_;
   virtual ~nrappkitTimerCallback() {}
 };
 
-NS_IMPL_ISUPPORTS(nrappkitTimerCallback, nsITimerCallback)
+NS_IMPL_ISUPPORTS(nrappkitTimerCallback, nsITimerCallback, nsINamed)
 
 NS_IMETHODIMP nrappkitTimerCallback::Notify(nsITimer *timer) {
   r_log(LOG_GENERIC, LOG_DEBUG, "Timer callback fired (set in %s:%d)",
         function_.c_str(), line_);
   MOZ_RELEASE_ASSERT(timer == timer_);
   cb_(nullptr, 0, cb_arg_);
 
   // Allow the timer to go away.
--- a/media/mtransport/transportlayerloopback.cpp
+++ b/media/mtransport/transportlayerloopback.cpp
@@ -14,16 +14,17 @@
 #include "nsIComponentManager.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIEventTarget.h"
 #include "nsIIOService.h"
 #include "nsIServiceManager.h"
 #include "nsISocketTransportService.h"
 #include "nsServiceManagerUtils.h"
+#include "nsString.h"
 
 #include "transportflow.h"
 #include "transportlayerloopback.h"
 
 namespace mozilla {
 
 MOZ_MTLOG_MODULE("mtransport")
 
@@ -113,19 +114,25 @@ void TransportLayerLoopback::DeliverPack
     MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " Delivering packet of length " <<
          packet->len());
     SignalPacketReceived(this, packet->data(), packet->len());
 
     delete packet;
   }
 }
 
-NS_IMPL_ISUPPORTS(TransportLayerLoopback::Deliverer, nsITimerCallback)
+NS_IMPL_ISUPPORTS(TransportLayerLoopback::Deliverer, nsITimerCallback, nsINamed)
 
 NS_IMETHODIMP TransportLayerLoopback::Deliverer::Notify(nsITimer *timer) {
   if (!layer_)
     return NS_OK;
 
   layer_->DeliverPackets();
 
   return NS_OK;
 }
+
+NS_IMETHODIMP TransportLayerLoopback::Deliverer::GetName(nsACString& aName) {
+  aName.AssignLiteral("TransportLayerLoopback::Deliverer");
+  return NS_OK;
+}
+
 }  // close namespace
--- a/media/mtransport/transportlayerloopback.h
+++ b/media/mtransport/transportlayerloopback.h
@@ -14,16 +14,17 @@
 #include "prlock.h"
 
 #include <memory>
 #include <queue>
 
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 
 
 #include "m_cpp_utils.h"
 #include "transportflow.h"
 #include "transportlayer.h"
 
 // A simple loopback transport layer that is used for testing.
@@ -113,26 +114,28 @@ class TransportLayerLoopback : public Tr
     DISALLOW_COPY_ASSIGN(QueuedPacket);
 
     unsigned char *data_;
     size_t len_;
   };
 
   // A timer to deliver packets if some are available
   // Fires every 100 ms
-  class Deliverer : public nsITimerCallback {
+  class Deliverer : public nsITimerCallback
+                  , public nsINamed {
    public:
     explicit Deliverer(TransportLayerLoopback *layer) :
         layer_(layer) {}
     void Detach() {
       layer_ = nullptr;
     }
 
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSITIMERCALLBACK
+    NS_DECL_NSINAMED
 
  private:
     virtual ~Deliverer() {
     }
 
     DISALLOW_COPY_ASSIGN(Deliverer);
 
     TransportLayerLoopback *layer_;
--- a/mobile/android/components/build/nsAndroidHistory.cpp
+++ b/mobile/android/components/build/nsAndroidHistory.cpp
@@ -20,17 +20,17 @@
 #define PREF_HISTORY_ENABLED "places.history.enabled"
 
 // Time we wait to see if a pending visit is really a redirect
 #define PENDING_REDIRECT_TIMEOUT 3000
 
 using namespace mozilla;
 using mozilla::dom::Link;
 
-NS_IMPL_ISUPPORTS(nsAndroidHistory, IHistory, nsIRunnable, nsITimerCallback)
+NS_IMPL_ISUPPORTS(nsAndroidHistory, IHistory, nsIRunnable, nsITimerCallback, nsINamed)
 
 nsAndroidHistory* nsAndroidHistory::sHistory = nullptr;
 
 /*static*/
 nsAndroidHistory*
 nsAndroidHistory::GetSingleton()
 {
   if (!sHistory) {
@@ -189,16 +189,23 @@ nsAndroidHistory::Notify(nsITimer *timer
   for (i = 0; i < mPendingVisitURIs.Length(); ++i) {
     SaveVisitURI(mPendingVisitURIs.ElementAt(i));
   }
   mPendingVisitURIs.Clear();
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsAndroidHistory::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsAndroidHistory");
+  return NS_OK;
+}
+
 void
 nsAndroidHistory::SaveVisitURI(nsIURI* aURI) {
   // Add the URI to our cache so we can take a fast path later
   AppendToRecentlyVisitedURIs(aURI);
 
   if (jni::IsFennec()) {
     // Save this URI in our history
     nsAutoCString spec;
--- a/mobile/android/components/build/nsAndroidHistory.h
+++ b/mobile/android/components/build/nsAndroidHistory.h
@@ -4,39 +4,42 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NS_ANDROIDHISTORY_H
 #define NS_ANDROIDHISTORY_H
 
 #include "IHistory.h"
 #include "nsDataHashtable.h"
 #include "nsTPriorityQueue.h"
+#include "nsINamed.h"
 #include "nsIRunnable.h"
 #include "nsIURI.h"
 #include "nsITimer.h"
 
 
 #define NS_ANDROIDHISTORY_CID \
     {0xCCAA4880, 0x44DD, 0x40A7, {0xA1, 0x3F, 0x61, 0x56, 0xFC, 0x88, 0x2C, 0x0B}}
 
 // Max size of History::mRecentlyVisitedURIs
 #define RECENTLY_VISITED_URI_SIZE 8
 
 // Max size of History::mEmbedURIs
 #define EMBED_URI_SIZE 128
 
 class nsAndroidHistory final : public mozilla::IHistory,
                                public nsIRunnable,
-                               public nsITimerCallback
+                               public nsITimerCallback,
+                               public nsINamed
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IHISTORY
   NS_DECL_NSIRUNNABLE
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   /**
    * Obtains a pointer that has had AddRef called on it.  Used by the service
    * manager only.
    */
   static nsAndroidHistory* GetSingleton();
 
   nsAndroidHistory();
--- a/netwerk/base/CaptivePortalService.cpp
+++ b/netwerk/base/CaptivePortalService.cpp
@@ -21,17 +21,17 @@ namespace mozilla {
 namespace net {
 
 static LazyLogModule gCaptivePortalLog("CaptivePortalService");
 #undef LOG
 #define LOG(args) MOZ_LOG(gCaptivePortalLog, mozilla::LogLevel::Debug, args)
 
 NS_IMPL_ISUPPORTS(CaptivePortalService, nsICaptivePortalService, nsIObserver,
                   nsISupportsWeakReference, nsITimerCallback,
-                  nsICaptivePortalCallback)
+                  nsICaptivePortalCallback, nsINamed)
 
 CaptivePortalService::CaptivePortalService()
   : mState(UNKNOWN)
   , mStarted(false)
   , mInitialized(false)
   , mRequestInProgress(false)
   , mEverBeenCaptive(false)
   , mDelay(kDefaultInterval)
@@ -274,16 +274,27 @@ CaptivePortalService::Notify(nsITimer *a
 
   // Note - if mDelay is 0, the timer will not be rearmed.
   RearmTimer();
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
+// CaptivePortalService::nsINamed
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+CaptivePortalService::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("CaptivePortalService");
+  return NS_OK;
+}
+
+//-----------------------------------------------------------------------------
 // CaptivePortalService::nsIObserver
 //-----------------------------------------------------------------------------
 NS_IMETHODIMP
 CaptivePortalService::Observe(nsISupports *aSubject,
                               const char * aTopic,
                               const char16_t * aData)
 {
   if (XRE_GetProcessType() != GeckoProcessType_Default) {
--- a/netwerk/base/CaptivePortalService.h
+++ b/netwerk/base/CaptivePortalService.h
@@ -2,38 +2,41 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef CaptivePortalService_h_
 #define CaptivePortalService_h_
 
 #include "nsICaptivePortalService.h"
 #include "nsICaptivePortalDetector.h"
+#include "nsINamed.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsITimer.h"
 #include "nsCOMArray.h"
 #include "mozilla/TimeStamp.h"
 
 namespace mozilla {
 namespace net {
 
 class CaptivePortalService
   : public nsICaptivePortalService
   , public nsIObserver
   , public nsSupportsWeakReference
   , public nsITimerCallback
   , public nsICaptivePortalCallback
+  , public nsINamed
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSICAPTIVEPORTALSERVICE
   NS_DECL_NSIOBSERVER
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSICAPTIVEPORTALCALLBACK
+  NS_DECL_NSINAMED
 
   CaptivePortalService();
   nsresult Initialize();
   nsresult Start();
   nsresult Stop();
 
   // This method is only called in the content process, in order to mirror
   // the captive portal state in the parent process.
--- a/netwerk/base/Dashboard.cpp
+++ b/netwerk/base/Dashboard.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/ErrorNames.h"
 #include "mozilla/net/Dashboard.h"
 #include "mozilla/net/HttpInfo.h"
 #include "nsHttp.h"
 #include "nsICancelable.h"
 #include "nsIDNSService.h"
 #include "nsIDNSRecord.h"
 #include "nsIInputStream.h"
+#include "nsINamed.h"
 #include "nsISocketTransport.h"
 #include "nsIThread.h"
 #include "nsProxyRelease.h"
 #include "nsSocketTransportService2.h"
 #include "nsThreadUtils.h"
 #include "nsURLHelper.h"
 #include "mozilla/Logging.h"
 #include "nsIOService.h"
@@ -125,29 +126,37 @@ public:
 };
 
 NS_IMPL_ISUPPORTS0(DnsData)
 
 
 class ConnectionData
     : public nsITransportEventSink
     , public nsITimerCallback
+    , public nsINamed
 {
     virtual ~ConnectionData()
     {
         if (mTimer) {
             mTimer->Cancel();
         }
     }
 
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSITRANSPORTEVENTSINK
     NS_DECL_NSITIMERCALLBACK
 
+    NS_IMETHOD GetName(nsACString& aName) override
+    {
+      aName.AssignLiteral("net::ConnectionData");
+      return NS_OK;
+    }
+
+
     void StartTimer(uint32_t aTimeout);
     void StopTimer();
 
     explicit ConnectionData(Dashboard *target)
     {
         mEventTarget = nullptr;
         mDashboard = target;
     }
@@ -162,17 +171,17 @@ public:
     nsCString mHost;
     uint32_t mPort;
     const char *mProtocol;
     uint32_t mTimeout;
 
     nsString mStatus;
 };
 
-NS_IMPL_ISUPPORTS(ConnectionData, nsITransportEventSink, nsITimerCallback)
+NS_IMPL_ISUPPORTS(ConnectionData, nsITransportEventSink, nsITimerCallback, nsINamed)
 
 
 class RcwnData
     : public nsISupports
 {
     virtual ~RcwnData()
     {
     }
--- a/netwerk/base/EventTokenBucket.cpp
+++ b/netwerk/base/EventTokenBucket.cpp
@@ -70,17 +70,17 @@ TokenBucketCancelable::Fire()
   mEvent = nullptr;
   event->OnTokenBucketAdmitted();
 }
 
 ////////////////////////////////////////////
 // EventTokenBucket
 ////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS(EventTokenBucket, nsITimerCallback)
+NS_IMPL_ISUPPORTS(EventTokenBucket, nsITimerCallback, nsINamed)
 
 // by default 1hz with no burst
 EventTokenBucket::EventTokenBucket(uint32_t eventsPerSecond,
                                    uint32_t burstSize)
   : mUnitCost(kUsecPerSec)
   , mMaxCredit(kUsecPerSec)
   , mCredit(kUsecPerSec)
   , mPaused(false)
@@ -353,16 +353,23 @@ EventTokenBucket::Notify(nsITimer *timer
 
   UpdateCredits();
   DispatchEvents();
   UpdateTimer();
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+EventTokenBucket::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("EventTokenBucket");
+  return NS_OK;
+}
+
 void
 EventTokenBucket::UpdateCredits()
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
   TimeStamp now = TimeStamp::Now();
   TimeDuration elapsed = now - mLastUpdate;
   mLastUpdate = now;
--- a/netwerk/base/EventTokenBucket.h
+++ b/netwerk/base/EventTokenBucket.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NetEventTokenBucket_h__
 #define NetEventTokenBucket_h__
 
 #include "ARefBase.h"
 #include "nsCOMPtr.h"
 #include "nsDeque.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 
 #include "mozilla/TimeStamp.h"
 
 class nsICancelable;
 
 namespace mozilla {
 namespace net {
@@ -63,21 +64,24 @@ class EventTokenBucket;
 class ATokenBucketEvent
 {
 public:
   virtual void OnTokenBucketAdmitted() = 0;
 };
 
 class TokenBucketCancelable;
 
-class EventTokenBucket : public nsITimerCallback, public ARefBase
+class EventTokenBucket : public nsITimerCallback
+                       , public nsINamed
+                       , public ARefBase
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   // This should be constructed on the main thread
   EventTokenBucket(uint32_t eventsPerSecond, uint32_t burstSize);
 
   // These public methods are all meant to be called from the socket thread
   void ClearCredits();
   uint32_t BurstEventsAvailable();
   uint32_t QueuedEvents();
--- a/netwerk/base/ProxyAutoConfig.cpp
+++ b/netwerk/base/ProxyAutoConfig.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ProxyAutoConfig.h"
 #include "nsICancelable.h"
 #include "nsIDNSListener.h"
 #include "nsIDNSRecord.h"
 #include "nsIDNSService.h"
+#include "nsINamed.h"
 #include "nsThreadUtils.h"
 #include "nsIConsoleService.h"
 #include "nsIURLParser.h"
 #include "nsJSUtils.h"
 #include "jsfriendapi.h"
 #include "prnetdb.h"
 #include "nsITimer.h"
 #include "mozilla/net/DNS.h"
@@ -271,16 +272,17 @@ static void SetRunning(ProxyAutoConfig *
 {
   MOZ_ASSERT(sRunningIndex != 0xdeadbeef);
   PR_SetThreadPrivate(sRunningIndex, arg);
 }
 
 // The PACResolver is used for dnsResolve()
 class PACResolver final : public nsIDNSListener
                         , public nsITimerCallback
+                        , public nsINamed
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   explicit PACResolver(nsIEventTarget *aTarget)
     : mStatus(NS_ERROR_FAILURE)
     , mMainThreadEventTarget(aTarget)
   {
@@ -306,26 +308,33 @@ public:
   NS_IMETHOD Notify(nsITimer *timer) override
   {
     if (mRequest)
       mRequest->Cancel(NS_ERROR_NET_TIMEOUT);
     mTimer = nullptr;
     return NS_OK;
   }
 
+  // nsINamed
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("PACResolver");
+    return NS_OK;
+  }
+
   nsresult                 mStatus;
   nsCOMPtr<nsICancelable>  mRequest;
   nsCOMPtr<nsIDNSRecord>   mResponse;
   nsCOMPtr<nsITimer>       mTimer;
   nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
 
 private:
   ~PACResolver() {}
 };
-NS_IMPL_ISUPPORTS(PACResolver, nsIDNSListener, nsITimerCallback)
+NS_IMPL_ISUPPORTS(PACResolver, nsIDNSListener, nsITimerCallback, nsINamed)
 
 static
 void PACLogToConsole(nsString &aMessage)
 {
   nsCOMPtr<nsIConsoleService> consoleService =
     do_GetService(NS_CONSOLESERVICE_CONTRACTID);
   if (!consoleService)
     return;
--- a/netwerk/base/ThrottleQueue.cpp
+++ b/netwerk/base/ThrottleQueue.cpp
@@ -230,17 +230,17 @@ ThrottleInputStream::AllowInput()
                                 mCallback, mEventTarget);
   mCallback = nullptr;
   mEventTarget = nullptr;
   callbackEvent->OnInputStreamReady(this);
 }
 
 //-----------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS(ThrottleQueue, nsIInputChannelThrottleQueue, nsITimerCallback)
+NS_IMPL_ISUPPORTS(ThrottleQueue, nsIInputChannelThrottleQueue, nsITimerCallback, nsINamed)
 
 ThrottleQueue::ThrottleQueue()
   : mMeanBytesPerSecond(0)
   , mMaxBytesPerSecond(0)
   , mBytesProcessed(0)
   , mTimerArmed(false)
 {
   nsresult rv;
@@ -350,16 +350,23 @@ ThrottleQueue::Notify(nsITimer* aTimer)
   for (size_t i = 0; i < events.Length(); ++i) {
     events[i]->AllowInput();
   }
 
   mTimerArmed = false;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+ThrottleQueue::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("net::ThrottleQueue");
+  return NS_OK;
+}
+
 void
 ThrottleQueue::QueueStream(ThrottleInputStream* aStream)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
   if (mAsyncEvents.IndexOf(aStream) == mAsyncEvents.NoIndex) {
     mAsyncEvents.AppendElement(aStream);
 
     if (!mTimerArmed) {
--- a/netwerk/base/ThrottleQueue.h
+++ b/netwerk/base/ThrottleQueue.h
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_net_ThrottleQueue_h
 #define mozilla_net_ThrottleQueue_h
 
 #include "mozilla/TimeStamp.h"
+#include "nsINamed.h"
 #include "nsIThrottledInputChannel.h"
 #include "nsITimer.h"
 
 namespace mozilla {
 namespace net {
 
 class ThrottleInputStream;
 
@@ -23,24 +24,26 @@ class ThrottleInputStream;
  * but otherwise, after creation, it can only be used on the socket
  * thread.  It currently throttles with a one second granularity, so
  * may be a bit choppy.
  */
 
 class ThrottleQueue final
   : public nsIInputChannelThrottleQueue
   , public nsITimerCallback
+  , public nsINamed
 {
 public:
 
   ThrottleQueue();
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIINPUTCHANNELTHROTTLEQUEUE
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   void QueueStream(ThrottleInputStream* aStream);
   void DequeueStream(ThrottleInputStream* aStream);
 
 private:
 
   ~ThrottleQueue();
 
--- a/netwerk/base/Tickler.cpp
+++ b/netwerk/base/Tickler.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Tickler.h"
 
 #ifdef MOZ_USE_WIFI_TICKLER
 #include "nsComponentManagerUtils.h"
+#include "nsINamed.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "prnetdb.h"
 
 #include "mozilla/jni/Utils.h"
 #include "GeneratedJNIWrappers.h"
@@ -191,26 +192,33 @@ void Tickler::StopTickler()
   MOZ_ASSERT(mThread == NS_GetCurrentThread());
   MOZ_ASSERT(mTimer);
   MOZ_ASSERT(mActive);
 
   mTimer->Cancel();
   mActive = false;
 }
 
-class TicklerTimer final : public nsITimerCallback
+class TicklerTimer final : public nsITimerCallback, public nsINamed
 {
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
 
   TicklerTimer(Tickler *aTickler)
   {
     mTickler = do_GetWeakReference(aTickler);
   }
 
+  // nsINamed
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("TicklerTimer");
+    return NS_OK;
+  }
+
 private:
   ~TicklerTimer() {}
 
   nsWeakPtr mTickler;
 };
 
 void Tickler::StartTickler()
 {
@@ -232,17 +240,17 @@ void Tickler::SetIPV4Address(uint32_t ad
 }
 
 // argument should be in network byte order
 void Tickler::SetIPV4Port(uint16_t port)
 {
   mAddr.inet.port = port;
 }
 
-NS_IMPL_ISUPPORTS(TicklerTimer, nsITimerCallback)
+NS_IMPL_ISUPPORTS(TicklerTimer, nsITimerCallback, nsINamed)
 
 NS_IMETHODIMP TicklerTimer::Notify(nsITimer *timer)
 {
   RefPtr<Tickler> tickler = do_QueryReferent(mTickler);
   if (!tickler)
     return NS_ERROR_FAILURE;
   MutexAutoLock lock(tickler->mLock);
 
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
@@ -18,17 +18,17 @@
 #include "nsCacheEntryDescriptor.h"
 #include "nsCacheDevice.h"
 #include "nsMemoryCacheDevice.h"
 #include "nsICacheVisitor.h"
 #include "nsDiskCacheDevice.h"
 #include "nsDiskCacheDeviceSQL.h"
 #include "nsCacheUtils.h"
 #include "../cache2/CacheObserver.h"
-
+#include "nsINamed.h"
 #include "nsIObserverService.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIFile.h"
 #include "nsIOService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsThreadUtils.h"
@@ -198,33 +198,39 @@ private:
 
     bool                    mSanitizeOnShutdown;
     bool                    mClearCacheOnShutdown;
 };
 
 NS_IMPL_ISUPPORTS(nsCacheProfilePrefObserver, nsIObserver)
 
 class nsSetDiskSmartSizeCallback final : public nsITimerCallback
+                                       , public nsINamed
 {
     ~nsSetDiskSmartSizeCallback() {}
 
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
 
     NS_IMETHOD Notify(nsITimer* aTimer) override {
         if (nsCacheService::gService) {
             nsCacheServiceAutoLock autoLock(LOCK_TELEM(NSSETDISKSMARTSIZECALLBACK_NOTIFY));
             nsCacheService::gService->SetDiskSmartSize_Locked();
             nsCacheService::gService->mSmartSizeTimer = nullptr;
         }
         return NS_OK;
     }
+
+    NS_IMETHOD GetName(nsACString& aName) override {
+      aName.AssignLiteral("nsSetDiskSmartSizeCallback");
+      return NS_OK;
+    }
 };
 
-NS_IMPL_ISUPPORTS(nsSetDiskSmartSizeCallback, nsITimerCallback)
+NS_IMPL_ISUPPORTS(nsSetDiskSmartSizeCallback, nsITimerCallback, nsINamed)
 
 // Runnable sent to main thread after the cache IO thread calculates available
 // disk space, so that there is no race in setting mDiskCacheCapacity.
 class nsSetSmartSizeEvent: public Runnable
 {
 public:
   explicit nsSetSmartSizeEvent(int32_t smartSize)
     : mozilla::Runnable("nsSetSmartSizeEvent")
--- a/netwerk/cache2/CacheFileIOManager.cpp
+++ b/netwerk/cache2/CacheFileIOManager.cpp
@@ -1187,17 +1187,17 @@ public:
       break;
     }
     return NS_OK;
   }
 };
 
 StaticRefPtr<CacheFileIOManager> CacheFileIOManager::gInstance;
 
-NS_IMPL_ISUPPORTS(CacheFileIOManager, nsITimerCallback)
+NS_IMPL_ISUPPORTS(CacheFileIOManager, nsITimerCallback, nsINamed)
 
 CacheFileIOManager::CacheFileIOManager()
   : mShuttingDown(false)
   , mTreeCreated(false)
   , mTreeCreationFailed(false)
   , mOverLimitEvicting(false)
   , mCacheSizeOnHardLimit(false)
   , mRemovingTrashDirs(false)
@@ -1621,16 +1621,23 @@ CacheFileIOManager::Notify(nsITimer * aT
   for (uint32_t i = 0; i < files.Length(); ++i) {
     CacheFile * file = files[i];
     file->WriteMetadataIfNeeded();
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+CacheFileIOManager::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("CacheFileIOManager");
+  return NS_OK;
+}
+
 // static
 nsresult
 CacheFileIOManager::OpenFile(const nsACString &aKey,
                              uint32_t aFlags, CacheFileIOListener *aCallback)
 {
   LOG(("CacheFileIOManager::OpenFile() [key=%s, flags=%d, listener=%p]",
        PromiseFlatCString(aKey).get(), aFlags, aCallback));
 
--- a/netwerk/cache2/CacheFileIOManager.h
+++ b/netwerk/cache2/CacheFileIOManager.h
@@ -4,16 +4,17 @@
 
 #ifndef CacheFileIOManager__h__
 #define CacheFileIOManager__h__
 
 #include "CacheIOThread.h"
 #include "CacheStorageService.h"
 #include "CacheHashUtils.h"
 #include "nsIEventTarget.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/SHA1.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "nsTArray.h"
 #include "nsString.h"
@@ -254,20 +255,22 @@ public:
 
   virtual bool IsKilled() { return false; }
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileIOListener, CACHEFILEIOLISTENER_IID)
 
 
 class CacheFileIOManager : public nsITimerCallback
+                         , public nsINamed
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   enum {
     OPEN         =  0U,
     CREATE       =  1U,
     CREATE_NEW   =  2U,
     PRIORITY     =  4U,
     SPECIAL_FILE =  8U,
     PINNED       = 16U
--- a/netwerk/cache2/CacheStorageService.cpp
+++ b/netwerk/cache2/CacheStorageService.cpp
@@ -103,17 +103,18 @@ CacheStorageService::MemoryPool::Limit()
   MOZ_CRASH("Bad pool type");
   return 0;
 }
 
 NS_IMPL_ISUPPORTS(CacheStorageService,
                   nsICacheStorageService,
                   nsIMemoryReporter,
                   nsITimerCallback,
-                  nsICacheTesting)
+                  nsICacheTesting,
+                  nsINamed)
 
 CacheStorageService* CacheStorageService::sSelf = nullptr;
 
 CacheStorageService::CacheStorageService()
 : mLock("CacheStorageService.mLock")
 , mForcedValidEntriesLock("CacheStorageService.mForcedValidEntriesLock")
 , mShutdown(false)
 , mDiskPool(MemoryPool::DISK)
@@ -1332,16 +1333,23 @@ CacheStorageService::Notify(nsITimer* aT
                         this,
                         &CacheStorageService::PurgeOverMemoryLimit);
     Dispatch(event);
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+CacheStorageService::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("CacheStorageService");
+  return NS_OK;
+}
+
 void
 CacheStorageService::PurgeOverMemoryLimit()
 {
   MOZ_ASSERT(IsOnManagementThread());
 
   LOG(("CacheStorageService::PurgeOverMemoryLimit"));
 
   static TimeDuration const kFourSeconds = TimeDuration::FromSeconds(4);
--- a/netwerk/cache2/CacheStorageService.h
+++ b/netwerk/cache2/CacheStorageService.h
@@ -2,16 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef CacheStorageService__h__
 #define CacheStorageService__h__
 
 #include "nsICacheStorageService.h"
 #include "nsIMemoryReporter.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 #include "nsICacheTesting.h"
 
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "nsProxyRelease.h"
@@ -63,23 +64,25 @@ protected:
   ~CacheMemoryConsumer() { DoMemoryReport(0); }
   void DoMemoryReport(uint32_t aCurrentSize);
 };
 
 class CacheStorageService final : public nsICacheStorageService
                                 , public nsIMemoryReporter
                                 , public nsITimerCallback
                                 , public nsICacheTesting
+                                , public nsINamed
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSICACHESTORAGESERVICE
   NS_DECL_NSIMEMORYREPORTER
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSICACHETESTING
+  NS_DECL_NSINAMED
 
   CacheStorageService();
 
   void Shutdown();
   void DropPrivateBrowsingEntries();
 
   // Takes care of deleting any pending trashes for both cache1 and cache2
   // as well as the cache directory of an inactive cache version when requested.
--- a/netwerk/protocol/http/HSTSPrimerListener.cpp
+++ b/netwerk/protocol/http/HSTSPrimerListener.cpp
@@ -24,17 +24,17 @@
 
 namespace mozilla {
 namespace net {
 
 using namespace mozilla;
 
 NS_IMPL_ISUPPORTS(HSTSPrimingListener, nsIStreamListener,
                   nsIRequestObserver, nsIInterfaceRequestor,
-                  nsITimerCallback)
+                  nsITimerCallback, nsINamed)
 
 // default to 2000ms, same as the preference
 // security.mixed_content.hsts_priming_request_timeout
 uint32_t HSTSPrimingListener::sHSTSPrimingTimeout = 2000;
 
 
 HSTSPrimingListener::HSTSPrimingListener(nsIHstsPrimingCallback* aCallback)
   : mCallback(aCallback)
@@ -208,16 +208,24 @@ HSTSPrimingListener::Notify(nsITimer* ti
   rv = callback->OnHSTSPrimingFailed(NS_ERROR_HSTS_PRIMING_TIMEOUT, false);
   if (NS_FAILED(rv)) {
     NS_ERROR("HSTS Priming timed out, and we got an error reporting the failure.");
   }
 
   return NS_OK; // unused
 }
 
+/** nsINamed **/
+NS_IMETHODIMP
+HSTSPrimingListener::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("HSTSPrimingListener");
+  return NS_OK;
+}
+
 // static
 nsresult
 HSTSPrimingListener::StartHSTSPriming(nsIChannel* aRequestChannel,
                                       nsIHstsPrimingCallback* aCallback)
 {
   nsCOMPtr<nsIURI> finalChannelURI;
   nsresult rv = NS_GetFinalChannelURI(aRequestChannel, getter_AddRefs(finalChannelURI));
   NS_ENSURE_SUCCESS(rv, rv);
--- a/netwerk/protocol/http/HSTSPrimerListener.h
+++ b/netwerk/protocol/http/HSTSPrimerListener.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef HSTSPrimingListener_h__
 #define HSTSPrimingListener_h__
 
 #include "nsCOMPtr.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
+#include "nsINamed.h"
 #include "nsIStreamListener.h"
 #include "nsIThreadRetargetableStreamListener.h"
 #include "nsITimer.h"
 
 #include "mozilla/Attributes.h"
 
 class nsIPrincipal;
 class nsINetworkInterceptController;
@@ -85,26 +86,28 @@ enum HSTSPrimingResult {
 };
 
 //////////////////////////////////////////////////////////////////////////
 // Class used as streamlistener and notification callback when
 // doing the HEAD request for an HSTS Priming check. Needs to be an
 // nsIStreamListener in order to receive events from AsyncOpen2
 class HSTSPrimingListener final : public nsIStreamListener,
                                   public nsIInterfaceRequestor,
-                                  public nsITimerCallback
+                                  public nsITimerCallback,
+                                  public nsINamed
 {
 public:
   explicit HSTSPrimingListener(nsIHstsPrimingCallback* aCallback);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
 private:
   ~HSTSPrimingListener() {}
 
   // Only nsHttpChannel can invoke HSTS priming
   friend class mozilla::net::nsHttpChannel;
 
   /**
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -442,16 +442,23 @@ TLSFilterTransaction::Notify(nsITimer *t
   if (timer != mTimer) {
     return NS_ERROR_UNEXPECTED;
   }
   DebugOnly<nsresult> rv = StartTimerCallback();
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   return NS_OK;
 }
 
+NS_IMETHODIMP
+TLSFilterTransaction::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("TLSFilterTransaction");
+  return NS_OK;
+}
+
 nsresult
 TLSFilterTransaction::StartTimerCallback()
 {
   LOG(("TLSFilterTransaction %p NudgeTunnel StartTimerCallback %p\n",
        this, mNudgeCallback.get()));
 
   if (mNudgeCallback) {
     // This class can be called re-entrantly, so cleanup m* before ->on()
@@ -1618,17 +1625,17 @@ SocketTransportShim::SetQoSBits(uint8_t 
 }
 
 NS_IMETHODIMP
 SocketTransportShim::SetFastOpenCallback(TCPFastOpen *aFastOpen)
 {
   return mWrapped->SetFastOpenCallback(aFastOpen);
 }
 
-NS_IMPL_ISUPPORTS(TLSFilterTransaction, nsITimerCallback)
+NS_IMPL_ISUPPORTS(TLSFilterTransaction, nsITimerCallback, nsINamed)
 NS_IMPL_ISUPPORTS(SocketTransportShim, nsISocketTransport, nsITransport)
 NS_IMPL_ISUPPORTS(InputStreamShim, nsIInputStream, nsIAsyncInputStream)
 NS_IMPL_ISUPPORTS(OutputStreamShim, nsIOutputStream, nsIAsyncOutputStream)
 NS_IMPL_ISUPPORTS(SocketInWrapper, nsIAsyncInputStream)
 NS_IMPL_ISUPPORTS(SocketOutWrapper, nsIAsyncOutputStream)
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/TunnelUtils.h
+++ b/netwerk/protocol/http/TunnelUtils.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_net_TLSFilterTransaction_h
 #define mozilla_net_TLSFilterTransaction_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAHttpTransaction.h"
 #include "nsIAsyncInputStream.h"
 #include "nsIAsyncOutputStream.h"
+#include "nsINamed.h"
 #include "nsISocketTransport.h"
 #include "nsITimer.h"
 #include "NullHttpTransaction.h"
 #include "mozilla/TimeStamp.h"
 #include "prio.h"
 
 // a TLSFilterTransaction wraps another nsAHttpTransaction but
 // applies a encode/decode filter of TLS onto the ReadSegments
@@ -98,24 +99,26 @@ public:
 
 #define NS_DECL_NUDGETUNNELCALLBACK void OnTunnelNudged(TLSFilterTransaction *) override;
 
 class TLSFilterTransaction final
   : public nsAHttpTransaction
   , public nsAHttpSegmentReader
   , public nsAHttpSegmentWriter
   , public nsITimerCallback
+  , public nsINamed
 {
   ~TLSFilterTransaction();
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSAHTTPTRANSACTION
   NS_DECL_NSAHTTPSEGMENTREADER
   NS_DECL_NSAHTTPSEGMENTWRITER
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   TLSFilterTransaction(nsAHttpTransaction *aWrappedTransaction,
                        const char *tlsHost, int32_t tlsPort,
                        nsAHttpSegmentReader *reader,
                        nsAHttpSegmentWriter *writer);
 
   const nsAHttpTransaction *Transaction() const { return mTransaction.get(); }
   MOZ_MUST_USE nsresult CommitToSegmentSize(uint32_t size,
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -3652,16 +3652,17 @@ NS_IMPL_ADDREF(nsHttpConnectionMgr::nsHa
 NS_IMPL_RELEASE(nsHttpConnectionMgr::nsHalfOpenSocket)
 
 NS_INTERFACE_MAP_BEGIN(nsHttpConnectionMgr::nsHalfOpenSocket)
     NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     NS_INTERFACE_MAP_ENTRY(nsIOutputStreamCallback)
     NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
     NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
     NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
+    NS_INTERFACE_MAP_ENTRY(nsINamed)
     // we have no macro that covers this case.
     if (aIID.Equals(NS_GET_IID(nsHttpConnectionMgr::nsHalfOpenSocket)) ) {
         AddRef();
         *aInstancePtr = this;
         return NS_OK;
     } else
 NS_INTERFACE_MAP_END
 
@@ -4032,16 +4033,23 @@ nsHttpConnectionMgr::nsHalfOpenSocket::N
 
     DebugOnly<nsresult> rv = SetupBackupStreams();
     MOZ_ASSERT(NS_SUCCEEDED(rv));
 
     mSynTimer = nullptr;
     return NS_OK;
 }
 
+NS_IMETHODIMP // method for nsINamed
+nsHttpConnectionMgr::nsHalfOpenSocket::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsHttpConnectionMgr::nsHalfOpenSocket");
+  return NS_OK;
+}
+
 already_AddRefed<nsHttpConnectionMgr::PendingTransactionInfo>
 nsHttpConnectionMgr::
 nsHalfOpenSocket::FindTransactionHelper(bool removeWhenFound)
 {
     nsTArray<RefPtr<PendingTransactionInfo>> *pendingQ =
         gHttpHandler->ConnMgr()->GetTransactionPendingQHelper(mEnt, mTransaction);
 
     int32_t index = pendingQ
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -16,16 +16,17 @@
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Attributes.h"
 #include "AlternateServices.h"
 #include "ARefBase.h"
 #include "nsWeakReference.h"
 #include "TCPFastOpen.h"
 
+#include "nsINamed.h"
 #include "nsIObserver.h"
 #include "nsITimer.h"
 
 class nsIHttpUpgradeListener;
 
 namespace mozilla {
 namespace net {
 class EventTokenBucket;
@@ -353,28 +354,30 @@ private:
 
     // nsHalfOpenSocket is used to hold the state of an opening TCP socket
     // while we wait for it to establish and bind it to a connection
 
     class nsHalfOpenSocket final : public nsIOutputStreamCallback,
                                    public nsITransportEventSink,
                                    public nsIInterfaceRequestor,
                                    public nsITimerCallback,
+                                   public nsINamed,
                                    public nsSupportsWeakReference,
                                    public TCPFastOpen
     {
         ~nsHalfOpenSocket();
 
     public:
         NS_DECLARE_STATIC_IID_ACCESSOR(NS_HALFOPENSOCKET_IID)
         NS_DECL_THREADSAFE_ISUPPORTS
         NS_DECL_NSIOUTPUTSTREAMCALLBACK
         NS_DECL_NSITRANSPORTEVENTSINK
         NS_DECL_NSIINTERFACEREQUESTOR
         NS_DECL_NSITIMERCALLBACK
+        NS_DECL_NSINAMED
 
         nsHalfOpenSocket(nsConnectionEntry *ent,
                          nsAHttpTransaction *trans,
                          uint32_t caps,
                          bool speculative,
                          bool isFromPredictor);
 
         MOZ_MUST_USE nsresult SetupStreams(nsISocketTransport **,
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -84,17 +84,18 @@ NS_IMPL_ISUPPORTS(WebSocketChannel,
                   nsIInputStreamCallback,
                   nsIOutputStreamCallback,
                   nsITimerCallback,
                   nsIDNSListener,
                   nsIProtocolProxyCallback,
                   nsIInterfaceRequestor,
                   nsIChannelEventSink,
                   nsIThreadRetargetableRequest,
-                  nsIObserver)
+                  nsIObserver,
+                  nsINamed)
 
 // We implement RFC 6455, which uses Sec-WebSocket-Version: 13 on the wire.
 #define SEC_WEBSOCKET_VERSION "13"
 
 /*
  * About SSL unsigned certificates
  *
  * wss will not work to a host using an unsigned certificate unless there
@@ -3315,16 +3316,25 @@ WebSocketChannel::Notify(nsITimer *timer
     CleanupConnection();
   } else {
     MOZ_ASSERT(0, "Unknown Timer");
   }
 
   return NS_OK;
 }
 
+// nsINamed
+
+NS_IMETHODIMP
+WebSocketChannel::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("WebSocketChannel");
+  return NS_OK;
+}
+
 // nsIWebSocketChannel
 
 NS_IMETHODIMP
 WebSocketChannel::GetSecurityInfo(nsISupports **aSecurityInfo)
 {
   LOG(("WebSocketChannel::GetSecurityInfo() %p\n", this));
   MOZ_ASSERT(NS_IsMainThread(), "not main thread");
 
--- a/netwerk/protocol/websocket/WebSocketChannel.h
+++ b/netwerk/protocol/websocket/WebSocketChannel.h
@@ -9,16 +9,17 @@
 
 #include "nsISupports.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIStreamListener.h"
 #include "nsIAsyncInputStream.h"
 #include "nsIAsyncOutputStream.h"
 #include "nsITimer.h"
 #include "nsIDNSListener.h"
+#include "nsINamed.h"
 #include "nsIObserver.h"
 #include "nsIProtocolProxyCallback.h"
 #include "nsIChannelEventSink.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIStringStream.h"
 #include "BaseWebSocketChannel.h"
 
 #include "nsCOMPtr.h"
@@ -66,33 +67,35 @@ class WebSocketChannel : public BaseWebS
                          public nsIStreamListener,
                          public nsIInputStreamCallback,
                          public nsIOutputStreamCallback,
                          public nsITimerCallback,
                          public nsIDNSListener,
                          public nsIObserver,
                          public nsIProtocolProxyCallback,
                          public nsIInterfaceRequestor,
-                         public nsIChannelEventSink
+                         public nsIChannelEventSink,
+                         public nsINamed
 {
   friend class WebSocketFrame;
 
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIHTTPUPGRADELISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIINPUTSTREAMCALLBACK
   NS_DECL_NSIOUTPUTSTREAMCALLBACK
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIDNSLISTENER
   NS_DECL_NSIPROTOCOLPROXYCALLBACK
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIOBSERVER
+  NS_DECL_NSINAMED
 
   // nsIWebSocketChannel methods BaseWebSocketChannel didn't implement for us
   //
   NS_IMETHOD AsyncOpen(nsIURI *aURI,
                        const nsACString &aOrigin,
                        uint64_t aWindowID,
                        nsIWebSocketListener *aListener,
                        nsISupports *aContext) override;
--- a/toolkit/components/alerts/AlertNotification.cpp
+++ b/toolkit/components/alerts/AlertNotification.cpp
@@ -190,16 +190,17 @@ AlertNotification::LoadImage(uint32_t aT
 
 NS_IMPL_CYCLE_COLLECTION(AlertImageRequest, mURI, mPrincipal, mListener,
                          mUserData)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AlertImageRequest)
   NS_INTERFACE_MAP_ENTRY(imgINotificationObserver)
   NS_INTERFACE_MAP_ENTRY(nsICancelable)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
+  NS_INTERFACE_MAP_ENTRY(nsINamed)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, imgINotificationObserver)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(AlertImageRequest)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(AlertImageRequest)
 
 AlertImageRequest::AlertImageRequest(nsIURI* aURI, nsIPrincipal* aPrincipal,
                                      bool aInPrivateBrowsing, uint32_t aTimeout,
@@ -265,16 +266,23 @@ AlertImageRequest::Notify(imgIRequest* a
 NS_IMETHODIMP
 AlertImageRequest::Notify(nsITimer* aTimer)
 {
   MOZ_ASSERT(aTimer == mTimer);
   return NotifyMissing();
 }
 
 NS_IMETHODIMP
+AlertImageRequest::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("AlertImageRequest");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 AlertImageRequest::Cancel(nsresult aReason)
 {
   if (mRequest) {
     mRequest->Cancel(aReason);
   }
   // We call `NotifyMissing` here because we won't receive a `LOAD_COMPLETE`
   // notification if we cancel the request before it loads (bug 1233086,
   // comment 33). Once that's fixed, `nsIAlertNotification::loadImage` could
--- a/toolkit/components/alerts/AlertNotification.h
+++ b/toolkit/components/alerts/AlertNotification.h
@@ -5,33 +5,36 @@
 #ifndef mozilla_AlertNotification_h__
 #define mozilla_AlertNotification_h__
 
 #include "imgINotificationObserver.h"
 #include "nsIAlertsService.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsICancelable.h"
+#include "nsINamed.h"
 #include "nsIPrincipal.h"
 #include "nsString.h"
 #include "nsITimer.h"
 
 namespace mozilla {
 
 class AlertImageRequest final : public imgINotificationObserver,
                                 public nsICancelable,
-                                public nsITimerCallback
+                                public nsITimerCallback,
+                                public nsINamed
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(AlertImageRequest,
                                            imgINotificationObserver)
   NS_DECL_IMGINOTIFICATIONOBSERVER
   NS_DECL_NSICANCELABLE
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   AlertImageRequest(nsIURI* aURI, nsIPrincipal* aPrincipal,
                     bool aInPrivateBrowsing, uint32_t aTimeout,
                     nsIAlertNotificationImageListener* aListener,
                     nsISupports* aUserData);
 
   nsresult Start();
 
--- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp
@@ -50,17 +50,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSearches)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResults)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAutoCompleteController)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAutoCompleteController)
 NS_INTERFACE_TABLE_HEAD(nsAutoCompleteController)
   NS_INTERFACE_TABLE(nsAutoCompleteController, nsIAutoCompleteController,
-                     nsIAutoCompleteObserver, nsITimerCallback, nsITreeView)
+                     nsIAutoCompleteObserver, nsITimerCallback, nsITreeView,
+                     nsINamed)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsAutoCompleteController)
 NS_INTERFACE_MAP_END
 
 nsAutoCompleteController::nsAutoCompleteController() :
   mDefaultIndexCompleted(false),
   mPopupClosedByCompositionStart(false),
   mProhibitAutoFill(false),
   mUserClearedAutoFill(false),
@@ -919,16 +920,26 @@ nsAutoCompleteController::Notify(nsITime
       return rv;
   }
   StartSearch(nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_DELAYED);
   AfterSearches();
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////
+//// nsINamed
+
+NS_IMETHODIMP
+nsAutoCompleteController::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsAutoCompleteController");
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////
 // nsITreeView
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetRowCount(int32_t *aRowCount)
 {
   *aRowCount = mRowCount;
   return NS_OK;
 }
--- a/toolkit/components/autocomplete/nsAutoCompleteController.h
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.h
@@ -7,37 +7,40 @@
 
 #include "nsIAutoCompleteController.h"
 
 #include "nsCOMPtr.h"
 #include "nsIAutoCompleteInput.h"
 #include "nsIAutoCompletePopup.h"
 #include "nsIAutoCompleteResult.h"
 #include "nsIAutoCompleteSearch.h"
+#include "nsINamed.h"
 #include "nsString.h"
 #include "nsITreeView.h"
 #include "nsITreeSelection.h"
 #include "nsITimer.h"
 #include "nsTArray.h"
 #include "nsCOMArray.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsAutoCompleteController final : public nsIAutoCompleteController,
                                        public nsIAutoCompleteObserver,
                                        public nsITimerCallback,
-                                       public nsITreeView
+                                       public nsITreeView,
+                                       public nsINamed
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsAutoCompleteController,
                                            nsIAutoCompleteController)
   NS_DECL_NSIAUTOCOMPLETECONTROLLER
   NS_DECL_NSIAUTOCOMPLETEOBSERVER
   NS_DECL_NSITREEVIEW
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   nsAutoCompleteController();
 
 protected:
   virtual ~nsAutoCompleteController();
 
   nsresult OpenPopup();
   nsresult ClosePopup();
--- a/toolkit/components/places/nsFaviconService.cpp
+++ b/toolkit/components/places/nsFaviconService.cpp
@@ -125,16 +125,17 @@ GetFramesInfoForContainer(imgIContainer*
 PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsFaviconService, gFaviconService)
 
 NS_IMPL_CLASSINFO(nsFaviconService, nullptr, 0, NS_FAVICONSERVICE_CID)
 NS_IMPL_ISUPPORTS_CI(
   nsFaviconService
 , nsIFaviconService
 , mozIAsyncFavicons
 , nsITimerCallback
+, nsINamed
 )
 
 nsFaviconService::nsFaviconService()
   : mFailedFaviconSerial(0)
   , mFailedFavicons(MAX_FAILED_FAVICONS / 2)
   , mUnassociatedIcons(UNASSOCIATED_FAVICONS_LENGTH)
 {
   NS_ASSERTION(!gFaviconService,
@@ -235,16 +236,26 @@ nsFaviconService::Notify(nsITimer* timer
   if (mUnassociatedIcons.Count() > 0) {
     mExpireUnassociatedIconsTimer->InitWithCallback(
       this, UNASSOCIATED_ICON_EXPIRY_INTERVAL, nsITimer::TYPE_ONE_SHOT);
   }
 
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////
+//// nsINamed
+
+NS_IMETHODIMP
+nsFaviconService::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsFaviconService");
+  return NS_OK;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIFaviconService
 
 NS_IMETHODIMP
 nsFaviconService::GetDefaultFavicon(nsIURI** _retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
--- a/toolkit/components/places/nsFaviconService.h
+++ b/toolkit/components/places/nsFaviconService.h
@@ -11,16 +11,17 @@
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsDataHashtable.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTHashtable.h"
 #include "nsToolkitCompsCID.h"
 #include "nsURIHashKey.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 #include "Database.h"
 #include "imgITools.h"
 #include "mozilla/storage.h"
 #include "mozilla/Attributes.h"
 
 #include "FaviconHelpers.h"
 
@@ -46,16 +47,17 @@ public:
   }
   mozilla::places::IconData iconData;
   PRTime created;
 };
 
 class nsFaviconService final : public nsIFaviconService
                              , public mozIAsyncFavicons
                              , public nsITimerCallback
+                             , public nsINamed
 {
 public:
   nsFaviconService();
 
   /**
    * Obtains the service's object.
    */
   static already_AddRefed<nsFaviconService> GetSingleton();
@@ -119,16 +121,17 @@ public:
   static mozilla::Atomic<int64_t> sLastInsertedIconId;
   static void StoreLastInsertedId(const nsACString& aTable,
                                   const int64_t aLastInsertedId);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIFAVICONSERVICE
   NS_DECL_MOZIASYNCFAVICONS
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
 private:
   imgITools* GetImgTools() {
     if (!mImgTools) {
       mImgTools = do_CreateInstance("@mozilla.org/image/tools;1");
     }
     return mImgTools;
   }
--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
@@ -92,17 +92,18 @@ nsUrlClassifierStreamUpdater::nsUrlClass
 
 NS_IMPL_ISUPPORTS(nsUrlClassifierStreamUpdater,
                   nsIUrlClassifierStreamUpdater,
                   nsIUrlClassifierUpdateObserver,
                   nsIRequestObserver,
                   nsIStreamListener,
                   nsIObserver,
                   nsIInterfaceRequestor,
-                  nsITimerCallback)
+                  nsITimerCallback,
+                  nsINamed)
 
 /**
  * Clear out the update.
  */
 void
 nsUrlClassifierStreamUpdater::DownloadDone()
 {
   LOG(("nsUrlClassifierStreamUpdater::DownloadDone [this=%p]", this));
@@ -988,8 +989,18 @@ nsUrlClassifierStreamUpdater::Notify(nsI
 
     return NS_OK;
   }
 
   MOZ_ASSERT_UNREACHABLE("A timer is fired from nowhere.");
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////
+//// nsINamed
+
+NS_IMETHODIMP
+nsUrlClassifierStreamUpdater::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsUrlClassifierStreamUpdater");
+  return NS_OK;
+}
+
--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.h
+++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.h
@@ -4,45 +4,48 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsUrlClassifierStreamUpdater_h_
 #define nsUrlClassifierStreamUpdater_h_
 
 #include <nsISupportsUtils.h>
 
 #include "nsCOMPtr.h"
+#include "nsINamed.h"
 #include "nsIObserver.h"
 #include "nsIUrlClassifierStreamUpdater.h"
 #include "nsIStreamListener.h"
 #include "nsIChannel.h"
 #include "nsTArray.h"
 #include "nsITimer.h"
 #include "mozilla/Attributes.h"
 
 // Forward declare pointers
 class nsIURI;
 
 class nsUrlClassifierStreamUpdater final : public nsIUrlClassifierStreamUpdater,
                                            public nsIUrlClassifierUpdateObserver,
                                            public nsIStreamListener,
                                            public nsIObserver,
                                            public nsIInterfaceRequestor,
-                                           public nsITimerCallback
+                                           public nsITimerCallback,
+                                           public nsINamed
 {
 public:
   nsUrlClassifierStreamUpdater();
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURLCLASSIFIERSTREAMUPDATER
   NS_DECL_NSIURLCLASSIFIERUPDATEOBSERVER
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIOBSERVER
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
 private:
   // No subclassing
   ~nsUrlClassifierStreamUpdater() {}
 
   // When the dbservice sends an UpdateComplete or UpdateFailure, we call this
   // to reset the stream updater.
   void DownloadDone();
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -1192,16 +1192,17 @@ NS_IMPL_RELEASE(nsExternalAppHandler)
 NS_INTERFACE_MAP_BEGIN(nsExternalAppHandler)
    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener)
    NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
    NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
    NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher)
    NS_INTERFACE_MAP_ENTRY(nsICancelable)
    NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
    NS_INTERFACE_MAP_ENTRY(nsIBackgroundFileSaverObserver)
+   NS_INTERFACE_MAP_ENTRY(nsINamed)
 NS_INTERFACE_MAP_END_THREADSAFE
 
 nsExternalAppHandler::nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo,
                                            const nsACString& aTempFileExtension,
                                            nsIInterfaceRequestor* aContentContext,
                                            nsIInterfaceRequestor* aWindowContext,
                                            nsExternalHelperAppService *aExtProtSvc,
                                            const nsAString& aSuggestedFilename,
@@ -2558,16 +2559,24 @@ nsExternalAppHandler::Notify(nsITimer* t
   NS_ASSERTION(mWindowToClose, "No window to close after timer fired");
 
   mWindowToClose->Close();
   mWindowToClose = nullptr;
   mTimer = nullptr;
 
   return NS_OK;
 }
+
+NS_IMETHODIMP
+nsExternalAppHandler::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsExternalAppHandler");
+  return NS_OK;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // The following section contains our nsIMIMEService implementation and related methods.
 //
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 // nsIMIMEService methods
 NS_IMETHODIMP nsExternalHelperAppService::GetFromTypeAndExtension(const nsACString& aMIMEType, const nsACString& aFileExt, nsIMIMEInfo **_retval) 
 {
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -11,16 +11,17 @@
 
 #include "nsIExternalHelperAppService.h"
 #include "nsIExternalProtocolService.h"
 #include "nsIWebProgressListener2.h"
 #include "nsIHelperAppLauncherDialog.h"
 
 #include "nsIMIMEInfo.h"
 #include "nsIMIMEService.h"
+#include "nsINamed.h"
 #include "nsIStreamListener.h"
 #include "nsIFile.h"
 #include "nsIFileStreams.h"
 #include "nsIOutputStream.h"
 #include "nsString.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIChannel.h"
@@ -206,26 +207,28 @@ private:
  * is bound to an application when it is created. When it receives an
  * OnStopRequest it launches the application using the temp file it has
  * stored the data into.  We create a handler every time we have to process
  * data using a helper app.
  */
 class nsExternalAppHandler final : public nsIStreamListener,
                                    public nsIHelperAppLauncher,
                                    public nsITimerCallback,
-                                   public nsIBackgroundFileSaverObserver
+                                   public nsIBackgroundFileSaverObserver,
+                                   public nsINamed
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSIHELPERAPPLAUNCHER
   NS_DECL_NSICANCELABLE
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIBACKGROUNDFILESAVEROBSERVER
+  NS_DECL_NSINAMED
 
   /**
    * @param aMIMEInfo       MIMEInfo object, representing the type of the
    *                        content that should be handled
    * @param aFileExtension  The extension we need to append to our temp file,
    *                        INCLUDING the ".". e.g. .mp3
    * @param aContentContext dom Window context, as passed to DoContent.
    * @param aWindowContext  Top level window context used in dialog parenting,
--- a/widget/nsNativeTheme.cpp
+++ b/widget/nsNativeTheme.cpp
@@ -33,17 +33,17 @@
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsNativeTheme::nsNativeTheme()
 : mAnimatedContentTimeout(UINT32_MAX)
 {
 }
 
-NS_IMPL_ISUPPORTS(nsNativeTheme, nsITimerCallback)
+NS_IMPL_ISUPPORTS(nsNativeTheme, nsITimerCallback, nsINamed)
 
 nsIPresShell *
 nsNativeTheme::GetPresShell(nsIFrame* aFrame)
 {
   if (!aFrame)
     return nullptr;
 
   nsPresContext* context = aFrame->PresContext();
@@ -681,16 +681,23 @@ nsNativeTheme::Notify(nsITimer* aTimer)
     }
   }
 
   mAnimatedContentList.Clear();
   mAnimatedContentTimeout = UINT32_MAX;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsNativeTheme::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("nsNativeTheme");
+  return NS_OK;
+}
+
 nsIFrame*
 nsNativeTheme::GetAdjacentSiblingFrameWithSameAppearance(nsIFrame* aFrame,
                                                          bool aNextSibling)
 {
   if (!aFrame)
     return nullptr;
 
   // Find the next visible sibling.
--- a/widget/nsNativeTheme.h
+++ b/widget/nsNativeTheme.h
@@ -8,34 +8,36 @@
 
 #include "nsAlgorithm.h"
 #include "nsIAtom.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsMargin.h"
 #include "nsGkAtoms.h"
 #include "nsTArray.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 #include "nsIContent.h"
 
 class nsIFrame;
 class nsIPresShell;
 class nsPresContext;
 
 namespace mozilla {
 class EventStates;
 } // namespace mozilla
 
-class nsNativeTheme : public nsITimerCallback
+class nsNativeTheme : public nsITimerCallback, public nsINamed
 {
  protected:
   virtual ~nsNativeTheme() {}
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSINAMED
 
   enum ScrollbarButtonType {
     eScrollbarButton_UpTop   = 0,
     eScrollbarButton_Down    = 1 << 0,
     eScrollbarButton_Bottom  = 1 << 1
   };
 
   enum TreeSortDirection {
--- a/widget/windows/nsAppShell.cpp
+++ b/widget/windows/nsAppShell.cpp
@@ -18,16 +18,17 @@
 #include "mozilla/HangMonitor.h"
 #include "nsIDOMWakeLockListener.h"
 #include "nsIPowerManagerService.h"
 #include "mozilla/StaticPtr.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "GeckoProfiler.h"
 #include "nsComponentManagerUtils.h"
+#include "nsINamed.h"
 #include "nsITimer.h"
 #include "ScreenHelperWin.h"
 #include "mozilla/widget/ScreenManager.h"
 
 // These are two messages that the code in winspool.drv on Windows 7 explicitly
 // waits for while it is pumping other Windows messages, during display of the
 // Printer Properties dialog.
 #define MOZ_WM_PRINTER_PROPERTIES_COMPLETION 0x5b7a
@@ -38,25 +39,31 @@ using namespace mozilla::widget;
 
 #define WAKE_LOCK_LOG(...) MOZ_LOG(gWinWakeLockLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
 static mozilla::LazyLogModule gWinWakeLockLog("WinWakeLock");
 
 // A wake lock listener that disables screen saver when requested by
 // Gecko. For example when we're playing video in a foreground tab we
 // don't want the screen saver to turn on.
 class WinWakeLockListener final : public nsIDOMMozWakeLockListener
-                                , public nsITimerCallback {
+                                , public nsITimerCallback
+                                , public nsINamed {
 public:
   NS_DECL_ISUPPORTS;
 
   NS_IMETHOD Notify(nsITimer *timer) override {
     WAKE_LOCK_LOG("WinWakeLock: periodic timer fired");
     ResetScreenSaverTimeout();
     return NS_OK;
   }
+
+  NS_IMETHOD GetName(nsACString& aName) override {
+    aName.AssignLiteral("WinWakeLockListener");
+    return NS_OK;
+  }
 private:
   ~WinWakeLockListener() {}
 
   NS_IMETHOD Callback(const nsAString& aTopic, const nsAString& aState) {
     if (!aTopic.EqualsASCII("screen")) {
       return NS_OK;
     }
     // Note the wake lock code ensures that we're not sent duplicate
@@ -129,17 +136,17 @@ private:
     }
     WAKE_LOCK_LOG("WinWakeLock: ResetScreenSaverTimeout() mScreenSaverTimeout=%d", mScreenSaverTimeout);
   }
 
   UINT mScreenSaverTimeout = 60;
   nsCOMPtr<nsITimer> mTimer;
 };
 
-NS_IMPL_ISUPPORTS(WinWakeLockListener, nsIDOMMozWakeLockListener, nsITimerCallback)
+NS_IMPL_ISUPPORTS(WinWakeLockListener, nsIDOMMozWakeLockListener, nsITimerCallback, nsINamed)
 StaticRefPtr<WinWakeLockListener> sWakeLockListener;
 
 static void
 AddScreenWakeLockListener()
 {
   nsCOMPtr<nsIPowerManagerService> sPowerManagerService = do_GetService(POWERMANAGERSERVICE_CONTRACTID);
   if (sPowerManagerService) {
     sWakeLockListener = new WinWakeLockListener();
--- a/xpcom/base/nsMessageLoop.cpp
+++ b/xpcom/base/nsMessageLoop.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsMessageLoop.h"
 #include "mozilla/WeakPtr.h"
 #include "base/message_loop.h"
 #include "base/task.h"
+#include "nsINamed.h"
 #include "nsIRunnable.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsThreadUtils.h"
 
 using namespace mozilla;
@@ -51,24 +52,30 @@ private:
  * not a refcounted object; it's owned by the MessageLoop.)
  *
  * We keep a weak reference to the MessageLoopIdleTask, although a raw pointer
  * should in theory suffice: When the MessageLoopIdleTask runs (right before
  * the MessageLoop deletes it), it cancels its timer.  But the weak pointer
  * saves us from worrying about an edge case somehow messing us up here.
  */
 class MessageLoopTimerCallback
-  : public nsITimerCallback
+  : public nsITimerCallback, public nsINamed
 {
 public:
   explicit MessageLoopTimerCallback(MessageLoopIdleTask* aTask);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
 
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("MessageLoopTimerCallback");
+    return NS_OK;
+  }
+
 private:
   WeakPtr<MessageLoopIdleTask> mTask;
 
   virtual ~MessageLoopTimerCallback() {}
 };
 
 MessageLoopIdleTask::MessageLoopIdleTask(nsIRunnable* aTask,
                                          uint32_t aEnsureRunsAfterMS)
@@ -137,17 +144,17 @@ MessageLoopTimerCallback::Notify(nsITime
   NS_WARNING_ASSERTION(mTask, "This timer shouldn't have fired.");
 
   if (mTask) {
     mTask->Run();
   }
   return NS_OK;
 }
 
-NS_IMPL_ISUPPORTS(MessageLoopTimerCallback, nsITimerCallback)
+NS_IMPL_ISUPPORTS(MessageLoopTimerCallback, nsITimerCallback, nsINamed)
 
 } // namespace
 
 NS_IMPL_ISUPPORTS(nsMessageLoop, nsIMessageLoop)
 
 NS_IMETHODIMP
 nsMessageLoop::PostIdleTask(nsIRunnable* aTask, uint32_t aEnsureRunsAfterMS)
 {
--- a/xpcom/threads/LazyIdleThread.cpp
+++ b/xpcom/threads/LazyIdleThread.cpp
@@ -373,17 +373,18 @@ LazyIdleThread::Release()
   return count;
 }
 
 NS_IMPL_QUERY_INTERFACE(LazyIdleThread, nsIThread,
                         nsIEventTarget,
                         nsISerialEventTarget,
                         nsITimerCallback,
                         nsIThreadObserver,
-                        nsIObserver)
+                        nsIObserver,
+                        nsINamed)
 
 NS_IMETHODIMP
 LazyIdleThread::DispatchFromScript(nsIRunnable* aEvent, uint32_t aFlags)
 {
   nsCOMPtr<nsIRunnable> event(aEvent);
   return Dispatch(event.forget(), aFlags);
 }
 
@@ -559,16 +560,23 @@ LazyIdleThread::Notify(nsITimer* aTimer)
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+LazyIdleThread::GetName(nsACString& aName)
+{
+  aName.AssignLiteral("LazyIdleThread");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 LazyIdleThread::OnDispatchedEvent(nsIThreadInternal* /*aThread */)
 {
   MOZ_ASSERT(mOwningEventTarget->IsOnCurrentThread());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LazyIdleThread::OnProcessNextEvent(nsIThreadInternal* /* aThread */,
--- a/xpcom/threads/LazyIdleThread.h
+++ b/xpcom/threads/LazyIdleThread.h
@@ -6,16 +6,17 @@
 
 #ifndef mozilla_lazyidlethread_h__
 #define mozilla_lazyidlethread_h__
 
 #ifndef MOZILLA_INTERNAL_API
 #error "This header is only usable from within libxul (MOZILLA_INTERNAL_API)."
 #endif
 
+#include "nsINamed.h"
 #include "nsIObserver.h"
 #include "nsIThreadInternal.h"
 #include "nsITimer.h"
 
 #include "mozilla/Mutex.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
@@ -32,24 +33,26 @@ namespace mozilla {
  * is created on the main thread then it will automatically join its thread on
  * XPCOM shutdown using the Observer Service.
  */
 class LazyIdleThread final
   : public nsIThread
   , public nsITimerCallback
   , public nsIThreadObserver
   , public nsIObserver
+  , public nsINamed
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIEVENTTARGET_FULL
   NS_DECL_NSITHREAD
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSITHREADOBSERVER
   NS_DECL_NSIOBSERVER
+  NS_DECL_NSINAMED
 
   enum ShutdownMethod
   {
     AutomaticShutdown = 0,
     ManualShutdown
   };
 
   /**
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ b/xpfe/appshell/nsWebShellWindow.cpp
@@ -524,16 +524,17 @@ static void LoadNativeMenus(nsIDOMDocume
     nms->CreateNativeMenuBar(aParentWindow, nullptr);
   }
 }
 #endif
 
 namespace mozilla {
 
 class WebShellWindowTimerCallback final : public nsITimerCallback
+                                        , public nsINamed
 {
 public:
   explicit WebShellWindowTimerCallback(nsWebShellWindow* aWindow)
     : mWindow(aWindow)
   {}
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
@@ -542,23 +543,29 @@ public:
     // Although this object participates in a refcount cycle (this -> mWindow
     // -> mSPTimer -> this), mSPTimer is a one-shot timer and releases this
     // after it fires.  So we don't need to release mWindow here.
 
     mWindow->FirePersistenceTimer();
     return NS_OK;
   }
 
+  NS_IMETHOD GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("WebShellWindowTimerCallback");
+    return NS_OK;
+  }
+
 private:
   ~WebShellWindowTimerCallback() {}
 
   RefPtr<nsWebShellWindow> mWindow;
 };
 
-NS_IMPL_ISUPPORTS(WebShellWindowTimerCallback, nsITimerCallback)
+NS_IMPL_ISUPPORTS(WebShellWindowTimerCallback, nsITimerCallback, nsINamed)
 
 } // namespace mozilla
 
 void
 nsWebShellWindow::SetPersistenceTimer(uint32_t aDirtyFlags)
 {
   MutexAutoLock lock(mSPTimerLock);
   if (!mSPTimer) {