Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 22 Jun 2017 17:08:53 +1000
changeset 404825 aa1693a26a15eb5cba24102222687dc81eeddd7b
parent 404824 4cbea3e428e7378f8258c227780e7bc65de01dd1
child 404826 4da7ff4c92bf47c1ceb8383da4cc459e84a95e08
push id58
push userfmarier@mozilla.com
push dateThu, 06 Jul 2017 00:08:44 +0000
reviewersmstange
bugs1375392
milestone56.0a1
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange. This patch makes the following changes to the macros. - Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was mostly misused. - Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is universally available now anyway. - Combines the first two string literal arguments of PROFILER_LABEL and PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for them to be separate, and it forced a '::' in the label, which isn't always appropriate. Also, the meaning of the "name_space" argument was interpreted in an interesting variety of ways. - Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make it clearer they construct RAII objects rather than just being function calls. (I myself have screwed up the scoping because of this in the past.) - Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so the caller doesn't need to. This makes a *lot* more of the uses fit onto a single line. The patch also makes the following changes to the macro uses (beyond those required by the changes described above). - Fixes a bunch of labels that had gotten out of sync with the name of the class and/or function that encloses them. - Removes a useless PROFILER_LABEL use within a trivial scope in EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving any useful purpose. It also serves as extra evidence that the AUTO_ prefix is a good idea. - Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is done within them, instead of at their callsites, because that's a more standard way of doing things.
accessible/base/NotificationController.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsFrameLoader.cpp
dom/base/nsFrameMessageManager.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSUtils.cpp
dom/base/nsObjectLoadingContent.cpp
dom/events/EventDispatcher.cpp
dom/events/EventListenerManager.cpp
dom/events/EventStateManager.cpp
dom/html/HTMLCanvasElement.cpp
dom/html/PluginDocument.cpp
dom/html/nsGenericHTMLFrameElement.cpp
dom/indexedDB/ActorsChild.cpp
dom/indexedDB/ActorsParent.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/TabChild.cpp
dom/ipc/TabParent.cpp
dom/ipc/nsIContentChild.cpp
dom/ipc/nsIContentParent.cpp
dom/media/MediaRecorder.cpp
dom/media/encoder/MediaEncoder.cpp
dom/media/encoder/OpusTrackEncoder.cpp
dom/media/encoder/VP8TrackEncoder.cpp
dom/media/ogg/OggWriter.cpp
dom/media/webm/WebMWriter.cpp
dom/media/webspeech/synth/windows/SapiService.cpp
dom/plugins/base/nsJSNPRuntime.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginStreamListener.cpp
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginStreamListenerPeer.cpp
dom/plugins/ipc/PluginModuleParent.cpp
dom/quota/ActorsParent.cpp
dom/storage/StorageDBThread.cpp
dom/xhr/XMLHttpRequestMainThread.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderCGL.mm
gfx/gl/GLContextProviderEAGL.mm
gfx/gl/GLLibraryEGL.h
gfx/layers/D3D9SurfaceImage.cpp
gfx/layers/RotatedBuffer.cpp
gfx/layers/basic/BasicLayerManager.cpp
gfx/layers/basic/BasicPaintedLayer.cpp
gfx/layers/client/ClientCanvasLayer.cpp
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientPaintedLayer.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TiledContentClient.cpp
gfx/layers/composite/AsyncCompositionManager.cpp
gfx/layers/composite/LayerManagerComposite.cpp
gfx/layers/composite/PaintedLayerComposite.cpp
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/mlgpu/FrameBuilder.cpp
gfx/layers/mlgpu/LayerManagerMLGPU.cpp
gfx/layers/opengl/CompositorOGL.cpp
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxDWriteFontList.cpp
gfx/thebes/gfxGDIFontList.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxWindowsPlatform.cpp
image/DecodePool.cpp
image/DecodePool.h
image/Decoder.cpp
image/FrameAnimator.cpp
image/RasterImage.cpp
image/imgFrame.cpp
ipc/chromium/src/base/message_pump_default.cc
ipc/glue/GeckoChildProcessHost.cpp
ipc/ipdl/ipdl/lower.py
js/ipc/WrapperOwner.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/wrappers/AddonWrapper.cpp
layout/base/GeckoRestyleManager.cpp
layout/base/PresShell.cpp
layout/base/RestyleManager.cpp
layout/base/RestyleTracker.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsRefreshDriver.cpp
layout/generic/ViewportFrame.cpp
layout/generic/nsSubDocumentFrame.cpp
layout/generic/nsTextFrame.cpp
layout/painting/FrameLayerBuilder.cpp
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRenderingBorders.cpp
layout/painting/nsCSSRenderingGradients.cpp
layout/painting/nsDisplayList.cpp
layout/style/nsStyleContext.cpp
layout/style/nsStyleSet.cpp
modules/libpref/Preferences.cpp
netwerk/base/nsIncrementalStreamLoader.cpp
netwerk/base/nsInputStreamPump.cpp
netwerk/base/nsStreamLoader.cpp
netwerk/protocol/http/nsHttpChannel.cpp
parser/html/nsHtml5TreeOpExecutor.cpp
startupcache/StartupCache.cpp
storage/mozStorageConnection.cpp
storage/mozStorageStatement.cpp
toolkit/components/places/nsAnnotationService.cpp
toolkit/components/places/nsNavBookmarks.cpp
toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbedFunctions.cpp
toolkit/xre/nsXREDirProvider.cpp
tools/profiler/public/GeckoProfiler.h
tools/profiler/tests/gtest/GeckoProfiler.cpp
view/nsViewManager.cpp
widget/android/nsAppShell.cpp
widget/android/nsWindow.cpp
widget/cocoa/nsAppShell.mm
widget/cocoa/nsChildView.mm
widget/gtk/nsWindow.cpp
widget/nsBaseDragService.cpp
widget/uikit/nsWindow.mm
widget/windows/nsFilePicker.cpp
xpcom/base/nsCycleCollector.cpp
xpcom/ds/nsObserverService.cpp
xpcom/io/FileUtilsWin.cpp
xpcom/io/nsLocalFileWin.cpp
xpcom/threads/nsTimerImpl.cpp
xpfe/appshell/nsXULWindow.cpp
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -585,17 +585,17 @@ NotificationController::ProcessMutationE
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector: private
 
 void
 NotificationController::WillRefresh(mozilla::TimeStamp aTime)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("NotificationController::WillRefresh", OTHER);
 
   // If the document accessible that notification collector was created for is
   // now shut down, don't process notifications anymore.
   NS_ASSERTION(mDocument,
                "The document was shut down while refresh observer is attached!");
   if (!mDocument)
     return;
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -678,18 +678,17 @@ nsDOMWindowUtils::SendMouseEventToWindow
                                          float aPressure,
                                          unsigned short aInputSourceArg,
                                          bool aIsDOMEventSynthesized,
                                          bool aIsWidgetEventSynthesized,
                                          int32_t aButtons,
                                          uint32_t aIdentifier,
                                          uint8_t aOptionalArgCount)
 {
-  PROFILER_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow",
-    js::ProfileEntry::Category::EVENTS);
+  AUTO_PROFILER_LABEL("nsDOMWindowUtils::SendMouseEventToWindow", EVENTS);
 
   return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
                               aIgnoreRootScrollFrame, aPressure,
                               aInputSourceArg,
                               aOptionalArgCount >= 7 ?
                                 aIdentifier : DEFAULT_MOUSE_POINTER_ID,
                               true, nullptr,
                               aOptionalArgCount >= 4 ?
@@ -830,18 +829,17 @@ nsDOMWindowUtils::SendPointerEvent(const
                                    int32_t aHeight,
                                    int32_t aTiltX,
                                    int32_t aTiltY,
                                    bool aIsPrimary,
                                    bool aIsSynthesized,
                                    uint8_t aOptionalArgCount,
                                    bool* aPreventDefault)
 {
-  PROFILER_LABEL("nsDOMWindowUtils", "SendPointerEvent",
-                 js::ProfileEntry::Category::EVENTS);
+  AUTO_PROFILER_LABEL("nsDOMWindowUtils::SendPointerEvent", EVENTS);
 
   return SendPointerEventCommon(aType, aX, aY, aButton, aClickCount,
                                 aModifiers, aIgnoreRootScrollFrame,
                                 aPressure, aInputSourceArg, aPointerId,
                                 aWidth, aHeight, aTiltX, aTiltY,
                                 aIsPrimary, aIsSynthesized,
                                 aOptionalArgCount, false, aPreventDefault);
 }
@@ -860,18 +858,17 @@ nsDOMWindowUtils::SendPointerEventToWind
                                            int32_t aWidth,
                                            int32_t aHeight,
                                            int32_t aTiltX,
                                            int32_t aTiltY,
                                            bool aIsPrimary,
                                            bool aIsSynthesized,
                                            uint8_t aOptionalArgCount)
 {
-  PROFILER_LABEL("nsDOMWindowUtils", "SendPointerEventToWindow",
-                 js::ProfileEntry::Category::EVENTS);
+  AUTO_PROFILER_LABEL("nsDOMWindowUtils::SendPointerEventToWindow", EVENTS);
 
   return SendPointerEventCommon(aType, aX, aY, aButton, aClickCount,
                                 aModifiers, aIgnoreRootScrollFrame,
                                 aPressure, aInputSourceArg, aPointerId,
                                 aWidth, aHeight, aTiltX, aTiltY,
                                 aIsPrimary, aIsSynthesized,
                                 aOptionalArgCount, true, nullptr);
 }
@@ -1324,18 +1321,17 @@ nsDOMWindowUtils::Focus(nsIDOMElement* a
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
                                  int32_t aExtraForgetSkippableCalls)
 {
-  PROFILER_LABEL("nsDOMWindowUtils", "GarbageCollect",
-    js::ProfileEntry::Category::GC);
+  AUTO_PROFILER_LABEL("nsDOMWindowUtils::GarbageCollect", GC);
 
   nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS);
   nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -775,18 +775,17 @@ nsFrameLoader::ReallyStartLoading()
   return rv;
 }
 
 nsresult
 nsFrameLoader::ReallyStartLoadingInternal()
 {
   NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInComposedDoc());
 
-  PROFILER_LABEL("nsFrameLoader", "ReallyStartLoading",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsFrameLoader::ReallyStartLoadingInternal", OTHER);
 
   if (IsRemoteFrame()) {
     if (!mRemoteBrowser && !TryRemoteBrowser()) {
         NS_WARNING("Couldn't create child process for iframe.");
         return NS_ERROR_FAILURE;
     }
 
     // FIXME get error codes from child
@@ -1249,17 +1248,17 @@ nsFrameLoader::MarginsChanged(uint32_t a
     // a different style
     presContext->RebuildAllStyleData(nsChangeHint(0), eRestyle_Subtree);
 }
 
 bool
 nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
                                nsSubDocumentFrame *aFrame)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsFrameLoader::ShowRemoteFrame", GRAPHICS);
   NS_ASSERTION(IsRemoteFrame(), "ShowRemote only makes sense on remote frames.");
 
   if (!mRemoteBrowser && !TryRemoteBrowser()) {
     NS_ERROR("Couldn't create child process.");
     return false;
   }
 
   // FIXME/bug 589337: Show()/Hide() is pretty expensive for
@@ -2972,18 +2971,17 @@ nsFrameLoader::TryRemoteBrowser()
       !parentOwner) {
     return false;
   }
   nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner));
   if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
     return false;
   }
 
-  PROFILER_LABEL("nsFrameLoader", "CreateRemoteBrowser",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsFrameLoader::TryRemoteBrowser:Create", OTHER);
 
   MutableTabContext context;
   nsresult rv = GetNewTabContext(&context);
   NS_ENSURE_SUCCESS(rv, false);
 
   uint64_t nextTabParentId = 0;
   if (mOwnerContent) {
     nsAutoString nextTabParentIdAttr;
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -599,20 +599,21 @@ nsFrameMessageManager::SendMessage(const
                                    JS::Handle<JS::Value> aJSON,
                                    JS::Handle<JS::Value> aObjects,
                                    nsIPrincipal* aPrincipal,
                                    JSContext* aCx,
                                    uint8_t aArgc,
                                    JS::MutableHandle<JS::Value> aRetval,
                                    bool aIsSync)
 {
-  NS_LossyConvertUTF16toASCII messageNameCStr(aMessageName);
-  PROFILER_LABEL_DYNAMIC("nsFrameMessageManager", "SendMessage",
-                          js::ProfileEntry::Category::EVENTS,
-                          messageNameCStr.get());
+  if (profiler_is_active()) {
+    NS_LossyConvertUTF16toASCII messageNameCStr(aMessageName);
+    AUTO_PROFILER_LABEL_DYNAMIC("nsFrameMessageManager::SendMessage", EVENTS,
+                                messageNameCStr.get());
+  }
 
   NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!IsBroadcaster(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!mParentManager, "Should not have parent manager in content!");
 
   aRetval.setUndefined();
   NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
 
@@ -1518,20 +1519,19 @@ nsMessageManagerScriptExecutor::Shutdown
 }
 
 void
 nsMessageManagerScriptExecutor::LoadScriptInternal(const nsAString& aURL,
                                                    bool aRunInGlobalScope)
 {
   if (profiler_is_active()) {
     NS_LossyConvertUTF16toASCII urlCStr(aURL);
-    PROFILER_LABEL_DYNAMIC("nsMessageManagerScriptExecutor",
-                           "LoadScriptInternal",
-                           js::ProfileEntry::Category::OTHER,
-                           urlCStr.get());
+    AUTO_PROFILER_LABEL_DYNAMIC(
+      "nsMessageManagerScriptExecutor::LoadScriptInternal", OTHER,
+      urlCStr.get());
   }
 
   if (!mGlobal || !sCachedScripts) {
     return;
   }
 
   JS::RootingContext* rcx = RootingCx();
   JS::Rooted<JSScript*> script(rcx);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9652,18 +9652,17 @@ public:
   enum class Phase
   {
     Destroying,
     Nuking
   };
 
   NS_IMETHOD Run() override
   {
-    PROFILER_LABEL("WindowDestroyedEvent", "Run",
-                   js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("WindowDestroyedEvent::Run", OTHER);
 
     nsCOMPtr<nsIObserverService> observerService =
       services::GetObserverService();
     if (!observerService) {
       return NS_OK;
     }
 
     nsCOMPtr<nsISupportsPRUint64> wrapper =
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1358,19 +1358,18 @@ FullGCTimerFired(nsITimer* aTimer, void*
 
 //static
 void
 nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
                                IsIncremental aIncremental,
                                IsShrinking aShrinking,
                                int64_t aSliceMillis)
 {
-  PROFILER_LABEL_DYNAMIC("nsJSContext", "GarbageCollectNow",
-                         js::ProfileEntry::Category::GC,
-                         JS::gcreason::ExplainReason(aReason));
+  AUTO_PROFILER_LABEL_DYNAMIC("nsJSContext::GarbageCollectNow", GC,
+                              JS::gcreason::ExplainReason(aReason));
 
   MOZ_ASSERT_IF(aSliceMillis, aIncremental == IncrementalGC);
 
   KillGCTimer();
 
   // Reset sPendingLoadCount in case the timer that fired was a
   // timer we scheduled due to a normal GC timer firing while
   // documents were loading. If this happens we're waiting for a
@@ -1412,17 +1411,17 @@ nsJSContext::GarbageCollectNow(JS::gcrea
   } else {
     JS::GCForReason(cx, gckind, aReason);
   }
 }
 
 static void
 FinishAnyIncrementalGC()
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GC);
+  AUTO_PROFILER_LABEL("FinishAnyIncrementalGC", GC);
 
   if (sCCLockedOut) {
     AutoJSAPI jsapi;
     jsapi.Init();
 
     // We're in the middle of an incremental GC, so finish it.
     JS::PrepareForIncrementalGC(jsapi.cx());
     JS::FinishIncrementalGC(jsapi.cx(), JS::gcreason::CC_FORCED);
@@ -1675,18 +1674,17 @@ CycleCollectorStats::RunForgetSkippable(
 void
 nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
                              int32_t aExtraForgetSkippableCalls)
 {
   if (!NS_IsMainThread()) {
     return;
   }
 
-  PROFILER_LABEL("nsJSContext", "CycleCollectNow",
-    js::ProfileEntry::Category::CC);
+  AUTO_PROFILER_LABEL("nsJSContext::CycleCollectNow", CC);
 
   gCCStats.PrepareForCycleCollectionSlice(TimeStamp(),
                                           aExtraForgetSkippableCalls);
   nsCycleCollector_collect(aListener);
   gCCStats.FinishCycleCollectionSlice();
 }
 
 //static
@@ -1695,18 +1693,17 @@ nsJSContext::RunCycleCollectorSlice(Time
 {
   if (!NS_IsMainThread()) {
     return;
   }
 
   AutoProfilerTracing
     tracing("CC", aDeadline.IsNull() ? "CCSlice" : "IdleCCSlice");
 
-  PROFILER_LABEL("nsJSContext", "RunCycleCollectorSlice",
-    js::ProfileEntry::Category::CC);
+  AUTO_PROFILER_LABEL("nsJSContext::RunCycleCollectorSlice", CC);
 
   gCCStats.PrepareForCycleCollectionSlice(aDeadline);
 
   // Decide how long we want to budget for this slice. By default,
   // use an unlimited budget.
   js::SliceBudget budget = js::SliceBudget::unlimited();
 
   if (sIncrementalCC) {
@@ -1751,18 +1748,17 @@ nsJSContext::RunCycleCollectorSlice(Time
 //static
 void
 nsJSContext::RunCycleCollectorWorkSlice(int64_t aWorkBudget)
 {
   if (!NS_IsMainThread()) {
     return;
   }
 
-  PROFILER_LABEL("nsJSContext", "RunCycleCollectorWorkSlice",
-    js::ProfileEntry::Category::CC);
+  AUTO_PROFILER_LABEL("nsJSContext::RunCycleCollectorWorkSlice", CC);
 
   gCCStats.PrepareForCycleCollectionSlice();
 
   js::SliceBudget budget = js::SliceBudget(js::WorkBudget(aWorkBudget));
   nsCycleCollector_collectSlice(budget);
 
   gCCStats.FinishCycleCollectionSlice();
 }
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -375,18 +375,17 @@ nsJSUtils::ExecutionContext::ExtractRetu
 
 nsresult
 nsJSUtils::CompileModule(JSContext* aCx,
                        JS::SourceBufferHolder& aSrcBuf,
                        JS::Handle<JSObject*> aEvaluationGlobal,
                        JS::CompileOptions &aCompileOptions,
                        JS::MutableHandle<JSObject*> aModule)
 {
-  PROFILER_LABEL("nsJSUtils", "CompileModule",
-    js::ProfileEntry::Category::JS);
+  AUTO_PROFILER_LABEL("nsJSUtils::CompileModule", JS);
 
   MOZ_ASSERT_IF(aCompileOptions.versionSet,
                 aCompileOptions.version != JSVERSION_UNKNOWN);
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(aSrcBuf.get());
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
              aEvaluationGlobal);
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
@@ -400,36 +399,34 @@ nsJSUtils::CompileModule(JSContext* aCx,
   }
 
   return NS_OK;
 }
 
 nsresult
 nsJSUtils::ModuleDeclarationInstantiation(JSContext* aCx, JS::Handle<JSObject*> aModule)
 {
-  PROFILER_LABEL("nsJSUtils", "ModuleDeclarationInstantiation",
-    js::ProfileEntry::Category::JS);
+  AUTO_PROFILER_LABEL("nsJSUtils::ModuleDeclarationInstantiation", JS);
 
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
 
   if (!JS::ModuleDeclarationInstantiation(aCx, aModule)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsresult
 nsJSUtils::ModuleEvaluation(JSContext* aCx, JS::Handle<JSObject*> aModule)
 {
-  PROFILER_LABEL("nsJSUtils", "ModuleEvaluation",
-    js::ProfileEntry::Category::JS);
+  AUTO_PROFILER_LABEL("nsJSUtils::ModuleEvaluation", JS);
 
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(nsContentUtils::IsInMicroTask());
 
   NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
 
   if (!JS::ModuleEvaluation(aCx, aModule)) {
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -1016,18 +1016,17 @@ nsObjectLoadingContent::NotifyOwnerDocum
   }
 }
 
 // nsIRequestObserver
 NS_IMETHODIMP
 nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
                                        nsISupports *aContext)
 {
-  PROFILER_LABEL("nsObjectLoadingContent", "OnStartRequest",
-    js::ProfileEntry::Category::NETWORK);
+  AUTO_PROFILER_LABEL("nsObjectLoadingContent::OnStartRequest", NETWORK);
 
   LOG(("OBJLC [%p]: Channel OnStartRequest", this));
 
   if (aRequest != mChannel || !aRequest) {
     // happens when a new load starts before the previous one got here
     return NS_BINDING_ABORTED;
   }
 
@@ -1095,18 +1094,17 @@ nsObjectLoadingContent::OnStartRequest(n
   return LoadObject(true, false, aRequest);
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::OnStopRequest(nsIRequest *aRequest,
                                       nsISupports *aContext,
                                       nsresult aStatusCode)
 {
-  PROFILER_LABEL("nsObjectLoadingContent", "OnStopRequest",
-    js::ProfileEntry::Category::NETWORK);
+  AUTO_PROFILER_LABEL("nsObjectLoadingContent::OnStopRequest", NETWORK);
 
   // Handle object not loading error because source was a tracking URL.
   // We make a note of this object node by including it in a dedicated
   // array of blocked tracking nodes under its parent document.
   if (aStatusCode == NS_ERROR_TRACKING_URI) {
     nsCOMPtr<nsIContent> thisNode =
       do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
     if (thisNode && thisNode->IsInComposedDoc()) {
@@ -3190,17 +3188,17 @@ nsObjectLoadingContent::DoStopPlugin(nsP
 
   TeardownProtoChain();
   mIsStopping = false;
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::StopPluginInstance()
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsObjectLoadingContent::StopPluginInstance", OTHER);
   // Clear any pending events
   mPendingInstantiateEvent = nullptr;
   mPendingCheckPluginStopEvent = nullptr;
 
   // If we're currently instantiating, clearing this will cause
   // InstantiatePluginInstance's re-entrance check to destroy the created plugin
   mInstantiating = false;
 
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -585,18 +585,17 @@ MayRetargetToChromeIfCanNotHandleEvent(
 EventDispatcher::Dispatch(nsISupports* aTarget,
                           nsPresContext* aPresContext,
                           WidgetEvent* aEvent,
                           nsIDOMEvent* aDOMEvent,
                           nsEventStatus* aEventStatus,
                           EventDispatchingCallback* aCallback,
                           nsTArray<EventTarget*>* aTargets)
 {
-  PROFILER_LABEL("EventDispatcher", "Dispatch",
-    js::ProfileEntry::Category::EVENTS);
+  AUTO_PROFILER_LABEL("EventDispatcher::Dispatch", EVENTS);
 
   NS_ASSERTION(aEvent, "Trying to dispatch without WidgetEvent!");
   NS_ENSURE_TRUE(!aEvent->mFlags.mIsBeingDispatched,
                  NS_ERROR_DOM_INVALID_STATE_ERR);
   NS_ASSERTION(!aTargets || !aEvent->mMessage, "Wrong parameters!");
 
   // If we're dispatching an already created DOMEvent object, make
   // sure it is initialized!
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -1290,19 +1290,19 @@ EventListenerManager::HandleEventInterna
 #ifdef MOZ_GECKO_PROFILER
               // Add a profiler label and a profiler marker for the actual
               // dispatch of the event.
               // This is a very hot code path, so we need to make sure not to
               // do this extra work when we're not profiling.
               nsAutoString typeStr;
               (*aDOMEvent)->GetType(typeStr);
               NS_LossyConvertUTF16toASCII typeCStr(typeStr);
-              PROFILER_LABEL_DYNAMIC("EventListenerManager", "HandleEventInternal",
-                                     js::ProfileEntry::Category::EVENTS,
-                                     typeCStr.get());
+              AUTO_PROFILER_LABEL_DYNAMIC(
+                "EventListenerManager::HandleEventInternal", EVENTS,
+                typeCStr.get());
               TimeStamp startTime = TimeStamp::Now();
 
               rv = HandleEventSubType(listener, *aDOMEvent, aCurrentTarget);
 
               TimeStamp endTime = TimeStamp::Now();
               uint16_t phase;
               (*aDOMEvent)->GetEventPhase(&phase);
               profiler_add_marker(
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3860,18 +3860,17 @@ EventStateManager::IsHandlingUserInput()
 static void
 CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
                                 EventMessage aMessage,
                                 nsIContent* aRelatedContent,
                                 nsAutoPtr<WidgetMouseEvent>& aNewEvent)
 {
   WidgetPointerEvent* sourcePointer = aMouseEvent->AsPointerEvent();
   if (sourcePointer) {
-    PROFILER_LABEL("Input", "DispatchPointerEvent",
-      js::ProfileEntry::Category::EVENTS);
+    AUTO_PROFILER_LABEL("CreateMouseOrPointerWidgetEvent", EVENTS);
 
     nsAutoPtr<WidgetPointerEvent> newPointerEvent;
     newPointerEvent =
       new WidgetPointerEvent(aMouseEvent->IsTrusted(), aMessage,
                              aMouseEvent->mWidget);
     newPointerEvent->mIsPrimary = sourcePointer->mIsPrimary;
     newPointerEvent->mWidth = sourcePointer->mWidth;
     newPointerEvent->mHeight = sourcePointer->mHeight;
@@ -3929,21 +3928,16 @@ EventStateManager::DispatchMouseOrPointe
   CreateMouseOrPointerWidgetEvent(aMouseEvent, aMessage,
                                   aRelatedContent, dispatchEvent);
 
   AutoWeakFrame previousTarget = mCurrentTarget;
   mCurrentTargetContent = aTargetContent;
 
   nsIFrame* targetFrame = nullptr;
 
-  if (aMouseEvent->AsMouseEvent()) {
-    PROFILER_LABEL("Input", "DispatchMouseEvent",
-      js::ProfileEntry::Category::EVENTS);
-  }
-
   nsEventStatus status = nsEventStatus_eIgnore;
   ESMEventCB callback(aTargetContent);
   EventDispatcher::Dispatch(aTargetContent, mPresContext, dispatchEvent, nullptr,
                             &status, &callback);
 
   if (mPresContext) {
     // Although the primary frame was checked in event callback, it may not be
     // the same object after event dispatch and handling, so refetch it.
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -103,17 +103,17 @@ public:
 
     return copy.forget();
   }
 
   void WillRefresh(TimeStamp aTime) override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
-    PROFILER_LABEL("HTMLCanvasElement", "FrameCapture", js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("RequestedFrameRefreshObserver::WillRefresh", OTHER);
 
     if (!mOwningElement) {
       return;
     }
 
     if (mOwningElement->IsWriteOnly()) {
       return;
     }
@@ -125,34 +125,37 @@ public:
     mOwningElement->ProcessDestroyedFrameListeners();
 
     if (!mOwningElement->IsFrameCaptureRequested()) {
       return;
     }
 
     RefPtr<SourceSurface> snapshot;
     {
-      PROFILER_LABEL("HTMLCanvasElement", "GetSnapshot", js::ProfileEntry::Category::OTHER);
+      AUTO_PROFILER_LABEL(
+        "RequestedFrameRefreshObserver::WillRefresh:GetSnapshot", OTHER);
       snapshot = mOwningElement->GetSurfaceSnapshot(nullptr);
       if (!snapshot) {
         return;
       }
     }
 
     RefPtr<DataSourceSurface> copy;
     {
-      PROFILER_LABEL("HTMLCanvasElement", "CopySnapshot", js::ProfileEntry::Category::OTHER);
+      AUTO_PROFILER_LABEL(
+        "RequestedFrameRefreshObserver::WillRefresh:CopySurface", OTHER);
       copy = CopySurface(snapshot);
       if (!copy) {
         return;
       }
     }
 
     {
-      PROFILER_LABEL("HTMLCanvasElement", "SetFrame", js::ProfileEntry::Category::OTHER);
+      AUTO_PROFILER_LABEL(
+        "RequestedFrameRefreshObserver::WillRefresh:SetFrame", OTHER);
       mOwningElement->SetFrameCapture(copy.forget(), aTime);
       mOwningElement->MarkContextCleanForFrameCapture();
     }
   }
 
   void DetachFromRefreshDriver()
   {
     MOZ_ASSERT(mOwningElement);
--- a/dom/html/PluginDocument.cpp
+++ b/dom/html/PluginDocument.cpp
@@ -70,18 +70,17 @@ public:
 private:
   RefPtr<PluginDocument> mPluginDoc;
 };
 
 
 NS_IMETHODIMP
 PluginStreamListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
 {
-  PROFILER_LABEL("PluginStreamListener", "OnStartRequest",
-    js::ProfileEntry::Category::NETWORK);
+  AUTO_PROFILER_LABEL("PluginStreamListener::OnStartRequest", NETWORK);
 
   nsCOMPtr<nsIContent> embed = mPluginDoc->GetPluginContent();
   nsCOMPtr<nsIObjectLoadingContent> objlc = do_QueryInterface(embed);
   nsCOMPtr<nsIStreamListener> objListener = do_QueryInterface(objlc);
 
   if (!objListener) {
     NS_NOTREACHED("PluginStreamListener without appropriate content node");
     return NS_BINDING_ABORTED;
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -269,18 +269,17 @@ nsGenericHTMLFrameElement::BindToTree(ns
                                                  aBindingParent,
                                                  aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (IsInComposedDoc()) {
     NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
                  "Missing a script blocker!");
 
-    PROFILER_LABEL("nsGenericHTMLFrameElement", "BindToTree",
-      js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("nsGenericHTMLFrameElement::BindToTree", OTHER);
 
     // We're in a document now.  Kick off the frame load.
     LoadSrc();
   }
 
   // We're now in document and scripts may move us, so clear
   // the mNetworkCreated flag.
   mNetworkCreated = false;
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -728,19 +728,17 @@ DispatchErrorEvent(IDBRequest* aRequest,
                    IDBTransaction* aTransaction = nullptr,
                    nsIDOMEvent* aEvent = nullptr)
 {
   MOZ_ASSERT(aRequest);
   aRequest->AssertIsOnOwningThread();
   MOZ_ASSERT(NS_FAILED(aErrorCode));
   MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_INDEXEDDB);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DispatchErrorEvent",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("IndexedDB:DispatchErrorEvent", STORAGE);
 
   RefPtr<IDBRequest> request = aRequest;
   RefPtr<IDBTransaction> transaction = aTransaction;
 
   request->SetError(aErrorCode);
 
   nsCOMPtr<nsIDOMEvent> errorEvent;
   if (!aEvent) {
@@ -803,19 +801,17 @@ DispatchErrorEvent(IDBRequest* aRequest,
 }
 
 void
 DispatchSuccessEvent(ResultHelper* aResultHelper,
                      nsIDOMEvent* aEvent = nullptr)
 {
   MOZ_ASSERT(aResultHelper);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DispatchSuccessEvent",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("IndexedDB:DispatchSuccessEvent", STORAGE);
 
   RefPtr<IDBRequest> request = aResultHelper->Request();
   MOZ_ASSERT(request);
   request->AssertIsOnOwningThread();
 
   RefPtr<IDBTransaction> transaction = aResultHelper->Transaction();
 
   if (transaction && transaction->IsAborted()) {
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -755,19 +755,17 @@ MakeCompressedIndexDataValues(
                              UniqueFreePtr<uint8_t>& aCompressedIndexDataValues,
                              uint32_t* aCompressedIndexDataValuesLength)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(!aCompressedIndexDataValues);
   MOZ_ASSERT(aCompressedIndexDataValuesLength);
 
-  PROFILER_LABEL("IndexedDB",
-                 "MakeCompressedIndexDataValues",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("MakeCompressedIndexDataValues", STORAGE);
 
   const uint32_t arrayLength = aIndexValues.Length();
   if (!arrayLength) {
     *aCompressedIndexDataValuesLength = 0;
     return NS_OK;
   }
 
   // First calculate the size of the final buffer.
@@ -849,19 +847,17 @@ ReadCompressedIndexDataValuesFromBlob(co
                                       nsTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aBlobData);
   MOZ_ASSERT(aBlobDataLength);
   MOZ_ASSERT(aIndexValues.IsEmpty());
 
-  PROFILER_LABEL("IndexedDB",
-                 "ReadCompressedIndexDataValuesFromBlob",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ReadCompressedIndexDataValuesFromBlob", STORAGE);
 
   const uint8_t* blobDataIter = aBlobData;
   const uint8_t* blobDataEnd = aBlobData + aBlobDataLength;
 
   while (blobDataIter < blobDataEnd) {
     int64_t indexId;
     bool unique;
     ReadCompressedIndexId(&blobDataIter, blobDataEnd, &indexId, &unique);
@@ -985,19 +981,17 @@ ReadCompressedIndexDataValues(mozIStorag
 }
 
 nsresult
 CreateFileTables(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "CreateFileTables",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("CreateFileTables", STORAGE);
 
   // Table `file`
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "CREATE TABLE file ("
       "id INTEGER PRIMARY KEY, "
       "refcount INTEGER NOT NULL"
     ");"
   ));
@@ -1059,19 +1053,17 @@ CreateFileTables(mozIStorageConnection* 
 }
 
 nsresult
 CreateTables(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "CreateTables",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("CreateTables", STORAGE);
 
   // Table `database`
 
   // There are two reasons for having the origin column.
   // First, we can ensure that we don't have collisions in the origin hash we
   // use for the path because when we open the db we can make sure that the
   // origins exactly match. Second, chrome code crawling through the idb
   // directory can figure out the origin of every db without having to
@@ -1209,19 +1201,17 @@ CreateTables(mozIStorageConnection* aCon
 }
 
 nsresult
 UpgradeSchemaFrom4To5(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom4To5",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom4To5", STORAGE);
 
   nsresult rv;
 
   // All we changed is the type of the version column, so lets try to
   // convert that to an integer, and if we fail, set it to 0.
   nsCOMPtr<mozIStorageStatement> stmt;
   rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
     "SELECT name, version, dataVersion "
@@ -1328,19 +1318,17 @@ UpgradeSchemaFrom4To5(mozIStorageConnect
 }
 
 nsresult
 UpgradeSchemaFrom5To6(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom5To6",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom5To6", STORAGE);
 
   // First, drop all the indexes we're no longer going to use.
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "DROP INDEX key_index;"
   ));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
@@ -1778,19 +1766,17 @@ UpgradeSchemaFrom5To6(mozIStorageConnect
 }
 
 nsresult
 UpgradeSchemaFrom6To7(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom6To7",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom6To7", STORAGE);
 
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "CREATE TEMPORARY TABLE temp_upgrade ("
       "id, "
       "name, "
       "key_path, "
       "auto_increment"
     ");"
@@ -1853,19 +1839,17 @@ UpgradeSchemaFrom6To7(mozIStorageConnect
 }
 
 nsresult
 UpgradeSchemaFrom7To8(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom7To8",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom7To8", STORAGE);
 
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "CREATE TEMPORARY TABLE temp_upgrade ("
       "id, "
       "object_store_id, "
       "name, "
       "key_path, "
       "unique_index, "
@@ -1948,19 +1932,17 @@ private:
 
   NS_IMETHOD
   OnFunctionCall(mozIStorageValueArray* aArguments,
                  nsIVariant** aResult) override
   {
     MOZ_ASSERT(aArguments);
     MOZ_ASSERT(aResult);
 
-    PROFILER_LABEL("IndexedDB",
-                   "CompressDataBlobsFunction::OnFunctionCall",
-                   js::ProfileEntry::Category::STORAGE);
+    AUTO_PROFILER_LABEL("CompressDataBlobsFunction::OnFunctionCall", STORAGE);
 
     uint32_t argc;
     nsresult rv = aArguments->GetNumEntries(&argc);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     if (argc != 1) {
@@ -2009,19 +1991,17 @@ private:
 };
 
 nsresult
 UpgradeSchemaFrom8To9_0(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom8To9_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom8To9_0", STORAGE);
 
   // We no longer use the dataVersion column.
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "UPDATE database SET dataVersion = 0;"
   ));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
@@ -2064,19 +2044,17 @@ UpgradeSchemaFrom8To9_0(mozIStorageConne
 }
 
 nsresult
 UpgradeSchemaFrom9_0To10_0(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom9_0To10_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom9_0To10_0", STORAGE);
 
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "ALTER TABLE object_data ADD COLUMN file_ids TEXT;"
   ));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
@@ -2101,19 +2079,17 @@ UpgradeSchemaFrom9_0To10_0(mozIStorageCo
 }
 
 nsresult
 UpgradeSchemaFrom10_0To11_0(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom10_0To11_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom10_0To11_0", STORAGE);
 
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "CREATE TEMPORARY TABLE temp_upgrade ("
       "id, "
       "object_store_id, "
       "name, "
       "key_path, "
       "unique_index, "
@@ -2281,19 +2257,17 @@ private:
 
   NS_IMETHOD
   OnFunctionCall(mozIStorageValueArray* aArguments,
                  nsIVariant** aResult) override
   {
     MOZ_ASSERT(aArguments);
     MOZ_ASSERT(aResult);
 
-    PROFILER_LABEL("IndexedDB",
-                   "EncodeKeysFunction::OnFunctionCall",
-                   js::ProfileEntry::Category::STORAGE);
+    AUTO_PROFILER_LABEL("EncodeKeysFunction::OnFunctionCall", STORAGE);
 
     uint32_t argc;
     nsresult rv = aArguments->GetNumEntries(&argc);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     if (argc != 1) {
@@ -2334,19 +2308,17 @@ private:
 };
 
 nsresult
 UpgradeSchemaFrom11_0To12_0(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom11_0To12_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom11_0To12_0", STORAGE);
 
   NS_NAMED_LITERAL_CSTRING(encoderName, "encode");
 
   nsCOMPtr<mozIStorageFunction> encoder = new EncodeKeysFunction();
 
   nsresult rv = aConnection->CreateFunction(encoderName, 1, encoder);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -2605,19 +2577,17 @@ UpgradeSchemaFrom11_0To12_0(mozIStorageC
 
 nsresult
 UpgradeSchemaFrom12_0To13_0(mozIStorageConnection* aConnection,
                             bool* aVacuumNeeded)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom12_0To13_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom12_0To13_0", STORAGE);
 
   nsresult rv;
 
 #ifdef IDB_MOBILE
   int32_t defaultPageSize;
   rv = aConnection->GetDefaultPageSize(&defaultPageSize);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -3593,33 +3563,29 @@ UpgradeSchemaFrom17_0To18_0Helper::DoUpg
 
 nsresult
 UpgradeSchemaFrom17_0To18_0(mozIStorageConnection* aConnection,
                             const nsACString& aOrigin)
 {
   MOZ_ASSERT(aConnection);
   MOZ_ASSERT(!aOrigin.IsEmpty());
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom17_0To18_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom17_0To18_0", STORAGE);
 
   return UpgradeSchemaFrom17_0To18_0Helper::DoUpgrade(aConnection, aOrigin);
 }
 
 nsresult
 UpgradeSchemaFrom18_0To19_0(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
   nsresult rv;
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom18_0To19_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom18_0To19_0", STORAGE);
 
   rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "ALTER TABLE object_store_index "
     "ADD COLUMN locale TEXT;"
   ));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
@@ -3715,19 +3681,17 @@ private:
 
 nsresult
 UpgradeSchemaFrom19_0To20_0(nsIFile* aFMDirectory,
                             mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom19_0To20_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom19_0To20_0", STORAGE);
 
 #if defined(MOZ_B2G)
 
   // We don't have to do the upgrade of file ids on B2G. The old format was
   // only used by the previous single process implementation and B2G was
   // always multi process. This is a nice optimization since the upgrade needs
   // to deserialize all structured clones which reference a stored file or
   // a mutable file.
@@ -3948,19 +3912,18 @@ UpgradeIndexDataValuesFunction::ReadOldC
 
 NS_IMETHODIMP
 UpgradeIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aArguments,
                                                nsIVariant** aResult)
 {
   MOZ_ASSERT(aArguments);
   MOZ_ASSERT(aResult);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeIndexDataValuesFunction::OnFunctionCall",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "UpgradeIndexDataValuesFunction::OnFunctionCall", STORAGE);
 
   uint32_t argc;
   nsresult rv = aArguments->GetNumEntries(&argc);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (argc != 1) {
@@ -4009,19 +3972,17 @@ UpgradeSchemaFrom20_0To21_0(mozIStorageC
 {
   // This should have been part of the 18 to 19 upgrade, where we changed the
   // layout of the index_data_values blobs but didn't upgrade the existing data.
   // See bug 1202788.
 
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom20_0To21_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom20_0To21_0", STORAGE);
 
   RefPtr<UpgradeIndexDataValuesFunction> function =
     new UpgradeIndexDataValuesFunction();
 
   NS_NAMED_LITERAL_CSTRING(functionName, "upgrade_idv");
 
   nsresult rv = aConnection->CreateFunction(functionName, 1, function);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -4066,19 +4027,17 @@ UpgradeSchemaFrom21_0To22_0(mozIStorageC
 nsresult
 UpgradeSchemaFrom22_0To23_0(mozIStorageConnection* aConnection,
                             const nsACString& aOrigin)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
   MOZ_ASSERT(!aOrigin.IsEmpty());
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom22_0To23_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom22_0To23_0", STORAGE);
 
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
     "UPDATE database "
       "SET origin = :origin;"
   ), getter_AddRefs(stmt));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -4141,19 +4100,18 @@ private:
 
   NS_IMETHOD
   OnFunctionCall(mozIStorageValueArray* aArguments,
                  nsIVariant** aResult) override
   {
     MOZ_ASSERT(aArguments);
     MOZ_ASSERT(aResult);
 
-    PROFILER_LABEL("IndexedDB",
-                   "StripObsoleteOriginAttributesFunction::OnFunctionCall",
-                   js::ProfileEntry::Category::STORAGE);
+    AUTO_PROFILER_LABEL(
+      "StripObsoleteOriginAttributesFunction::OnFunctionCall", STORAGE);
 
 #ifdef DEBUG
   {
     uint32_t argCount;
     MOZ_ALWAYS_SUCCEEDS(aArguments->GetNumEntries(&argCount));
     MOZ_ASSERT(argCount == 1);
 
     int32_t type;
@@ -4190,19 +4148,17 @@ private:
 };
 
 nsresult
 UpgradeSchemaFrom25_0To26_0(mozIStorageConnection* aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeSchemaFrom25_0To26_0",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeSchemaFrom25_0To26_0", STORAGE);
 
   NS_NAMED_LITERAL_CSTRING(functionName, "strip_obsolete_attributes");
 
   nsCOMPtr<mozIStorageFunction> stripObsoleteAttributes =
     new StripObsoleteOriginAttributesFunction();
 
   nsresult rv = aConnection->CreateFunction(functionName,
                                             /* aNumArguments */ 1,
@@ -4534,19 +4490,17 @@ CreateStorageConnection(nsIFile* aDBFile
                         uint32_t aTelemetryId,
                         mozIStorageConnection** aConnection)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aDBFile);
   MOZ_ASSERT(aFMDirectory);
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "CreateStorageConnection",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("CreateStorageConnection", STORAGE);
 
   nsresult rv;
   bool exists;
 
   if (IndexedDatabaseManager::InLowDiskSpaceMode()) {
     rv = aDBFile->Exists(&exists);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
@@ -5004,19 +4958,17 @@ GetStorageConnection(nsIFile* aDatabaseF
                      uint32_t aTelemetryId,
                      mozIStorageConnection** aConnection)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aDatabaseFile);
   MOZ_ASSERT(aConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "GetStorageConnection",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("GetStorageConnection", STORAGE);
 
   bool exists;
   nsresult rv = aDatabaseFile->Exists(&exists);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (NS_WARN_IF(!exists)) {
@@ -10653,19 +10605,17 @@ nsresult
 DatabaseConnection::GetCachedStatement(const nsACString& aQuery,
                                        CachedStatement* aCachedStatement)
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(!aQuery.IsEmpty());
   MOZ_ASSERT(aCachedStatement);
   MOZ_ASSERT(mStorageConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::GetCachedStatement",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::GetCachedStatement", STORAGE);
 
   nsCOMPtr<mozIStorageStatement> stmt;
 
   if (!mCachedStatements.Get(aQuery, getter_AddRefs(stmt))) {
     nsresult rv =
       mStorageConnection->CreateStatement(aQuery, getter_AddRefs(stmt));
     if (NS_FAILED(rv)) {
 #ifdef DEBUG
@@ -10692,19 +10642,17 @@ DatabaseConnection::GetCachedStatement(c
 nsresult
 DatabaseConnection::BeginWriteTransaction()
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(mStorageConnection);
   MOZ_ASSERT(mInReadTransaction);
   MOZ_ASSERT(!mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::BeginWriteTransaction",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::BeginWriteTransaction", STORAGE);
 
   // Release our read locks.
   CachedStatement rollbackStmt;
   nsresult rv =
     GetCachedStatement(NS_LITERAL_CSTRING("ROLLBACK;"), &rollbackStmt);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
@@ -10771,19 +10719,17 @@ DatabaseConnection::BeginWriteTransactio
 nsresult
 DatabaseConnection::CommitWriteTransaction()
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(mStorageConnection);
   MOZ_ASSERT(!mInReadTransaction);
   MOZ_ASSERT(mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::CommitWriteTransaction",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::CommitWriteTransaction", STORAGE);
 
   CachedStatement stmt;
   nsresult rv = GetCachedStatement(NS_LITERAL_CSTRING("COMMIT;"), &stmt);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = stmt->Execute();
@@ -10797,19 +10743,17 @@ DatabaseConnection::CommitWriteTransacti
 
 void
 DatabaseConnection::RollbackWriteTransaction()
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(!mInReadTransaction);
   MOZ_ASSERT(mStorageConnection);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::RollbackWriteTransaction",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::RollbackWriteTransaction", STORAGE);
 
   if (!mInWriteTransaction) {
     return;
   }
 
   DatabaseConnection::CachedStatement stmt;
   nsresult rv = GetCachedStatement(NS_LITERAL_CSTRING("ROLLBACK;"), &stmt);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -10826,19 +10770,17 @@ DatabaseConnection::RollbackWriteTransac
 void
 DatabaseConnection::FinishWriteTransaction()
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(mStorageConnection);
   MOZ_ASSERT(!mInReadTransaction);
   MOZ_ASSERT(!mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::FinishWriteTransaction",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::FinishWriteTransaction", STORAGE);
 
   if (mUpdateRefcountFunction) {
     mUpdateRefcountFunction->Reset();
   }
 
   CachedStatement stmt;
   nsresult rv = GetCachedStatement(NS_LITERAL_CSTRING("BEGIN;"), &stmt);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -10856,19 +10798,17 @@ DatabaseConnection::FinishWriteTransacti
 nsresult
 DatabaseConnection::StartSavepoint()
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(mStorageConnection);
   MOZ_ASSERT(mUpdateRefcountFunction);
   MOZ_ASSERT(mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::StartSavepoint",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::StartSavepoint", STORAGE);
 
   CachedStatement stmt;
   nsresult rv = GetCachedStatement(NS_LITERAL_CSTRING(SAVEPOINT_CLAUSE), &stmt);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = stmt->Execute();
@@ -10889,19 +10829,17 @@ DatabaseConnection::StartSavepoint()
 nsresult
 DatabaseConnection::ReleaseSavepoint()
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(mStorageConnection);
   MOZ_ASSERT(mUpdateRefcountFunction);
   MOZ_ASSERT(mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::ReleaseSavepoint",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::ReleaseSavepoint", STORAGE);
 
   CachedStatement stmt;
   nsresult rv = GetCachedStatement(
     NS_LITERAL_CSTRING("RELEASE " SAVEPOINT_CLAUSE),
     &stmt);
   if (NS_SUCCEEDED(rv)) {
     rv = stmt->Execute();
     if (NS_SUCCEEDED(rv)) {
@@ -10920,19 +10858,17 @@ DatabaseConnection::ReleaseSavepoint()
 nsresult
 DatabaseConnection::RollbackSavepoint()
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(mStorageConnection);
   MOZ_ASSERT(mUpdateRefcountFunction);
   MOZ_ASSERT(mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::RollbackSavepoint",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::RollbackSavepoint", STORAGE);
 
 #ifdef DEBUG
   MOZ_ASSERT(mDEBUGSavepointCount);
   mDEBUGSavepointCount--;
 #endif
 
   mUpdateRefcountFunction->RollbackSavepoint();
 
@@ -10953,19 +10889,17 @@ DatabaseConnection::RollbackSavepoint()
 
 nsresult
 DatabaseConnection::CheckpointInternal(CheckpointMode aMode)
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(!mInReadTransaction);
   MOZ_ASSERT(!mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::CheckpointInternal",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::CheckpointInternal", STORAGE);
 
   nsAutoCString stmtString;
   stmtString.AssignLiteral("PRAGMA wal_checkpoint(");
 
   switch (aMode) {
     case CheckpointMode::Full:
       // Ensures that the database is completely checkpointed and flushed to
       // disk.
@@ -11005,19 +10939,17 @@ DatabaseConnection::CheckpointInternal(C
 
 void
 DatabaseConnection::DoIdleProcessing(bool aNeedsCheckpoint)
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(mInReadTransaction);
   MOZ_ASSERT(!mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::DoIdleProcessing",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::DoIdleProcessing", STORAGE);
 
   DatabaseConnection::CachedStatement freelistStmt;
   uint32_t freelistCount;
   nsresult rv = GetFreelistCount(freelistStmt, &freelistCount);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     freelistCount = 0;
   }
 
@@ -11086,19 +11018,17 @@ DatabaseConnection::ReclaimFreePagesWhil
   AssertIsOnConnectionThread();
   MOZ_ASSERT(aFreelistStatement);
   MOZ_ASSERT(aRollbackStatement);
   MOZ_ASSERT(aFreelistCount);
   MOZ_ASSERT(aFreedSomePages);
   MOZ_ASSERT(!mInReadTransaction);
   MOZ_ASSERT(!mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::ReclaimFreePagesWhileIdle",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::ReclaimFreePagesWhileIdle", STORAGE);
 
   // Make sure we don't keep working if anything else needs this thread.
   nsIThread* currentThread = NS_GetCurrentThread();
   MOZ_ASSERT(currentThread);
 
   if (NS_HasPendingEvents(currentThread)) {
     *aFreedSomePages = false;
     return NS_OK;
@@ -11200,19 +11130,17 @@ DatabaseConnection::ReclaimFreePagesWhil
 
 nsresult
 DatabaseConnection::GetFreelistCount(CachedStatement& aCachedStatement,
                                      uint32_t* aFreelistCount)
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(aFreelistCount);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::GetFreelistCount",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::GetFreelistCount", STORAGE);
 
   nsresult rv;
 
   if (!aCachedStatement) {
     rv = GetCachedStatement(NS_LITERAL_CSTRING("PRAGMA freelist_count;"),
                             &aCachedStatement);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
@@ -11246,19 +11174,17 @@ DatabaseConnection::GetFreelistCount(Cac
 void
 DatabaseConnection::Close()
 {
   AssertIsOnConnectionThread();
   MOZ_ASSERT(mStorageConnection);
   MOZ_ASSERT(!mDEBUGSavepointCount);
   MOZ_ASSERT(!mInWriteTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::Close",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::Close", STORAGE);
 
   if (mUpdateRefcountFunction) {
     MOZ_ALWAYS_SUCCEEDS(
       mStorageConnection->RemoveFunction(
         NS_LITERAL_CSTRING("update_refcount")));
     mUpdateRefcountFunction = nullptr;
   }
 
@@ -11538,19 +11464,17 @@ UpdateRefcountFunction::UpdateRefcountFu
 
 nsresult
 DatabaseConnection::
 UpdateRefcountFunction::WillCommit()
 {
   MOZ_ASSERT(mConnection);
   mConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::UpdateRefcountFunction::WillCommit",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseConnection::UpdateRefcountFunction::WillCommit", STORAGE);
 
   DatabaseUpdateFunction function(this);
   for (auto iter = mFileInfoEntries.ConstIter(); !iter.Done(); iter.Next()) {
     auto key = iter.Key();
     FileInfoEntry* value = iter.Data();
     MOZ_ASSERT(value);
 
     if (value->mDelta && !function.Update(key, value->mDelta)) {
@@ -11573,19 +11497,18 @@ UpdateRefcountFunction::WillCommit()
 
 void
 DatabaseConnection::
 UpdateRefcountFunction::DidCommit()
 {
   MOZ_ASSERT(mConnection);
   mConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::UpdateRefcountFunction::DidCommit",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseConnection::UpdateRefcountFunction::DidCommit", STORAGE);
 
   for (auto iter = mFileInfoEntries.ConstIter(); !iter.Done(); iter.Next()) {
     FileInfoEntry* value = iter.Data();
 
     MOZ_ASSERT(value);
 
     if (value->mDelta) {
       value->mFileInfo->UpdateDBRefs(value->mDelta);
@@ -11599,19 +11522,18 @@ UpdateRefcountFunction::DidCommit()
 
 void
 DatabaseConnection::
 UpdateRefcountFunction::DidAbort()
 {
   MOZ_ASSERT(mConnection);
   mConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::UpdateRefcountFunction::DidAbort",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseConnection::UpdateRefcountFunction::DidAbort", STORAGE);
 
   if (NS_FAILED(RemoveJournals(mJournalsToRemoveAfterAbort))) {
     NS_WARNING("RemoveJournals failed!");
   }
 }
 
 void
 DatabaseConnection::
@@ -11761,19 +11683,18 @@ DatabaseConnection::
 UpdateRefcountFunction::ProcessValue(mozIStorageValueArray* aValues,
                                      int32_t aIndex,
                                      UpdateType aUpdateType)
 {
   MOZ_ASSERT(mConnection);
   mConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(aValues);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::UpdateRefcountFunction::ProcessValue",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseConnection::UpdateRefcountFunction::ProcessValue", STORAGE);
 
   int32_t type;
   nsresult rv = aValues->GetTypeOfIndex(aIndex, &type);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (type == mozIStorageValueArray::VALUE_TYPE_NULL) {
@@ -11831,19 +11752,18 @@ UpdateRefcountFunction::ProcessValue(moz
 
 nsresult
 DatabaseConnection::
 UpdateRefcountFunction::CreateJournals()
 {
   MOZ_ASSERT(mConnection);
   mConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::UpdateRefcountFunction::CreateJournals",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseConnection::UpdateRefcountFunction::CreateJournals", STORAGE);
 
   nsCOMPtr<nsIFile> journalDirectory = mFileManager->GetJournalDirectory();
   if (NS_WARN_IF(!journalDirectory)) {
     return NS_ERROR_FAILURE;
   }
 
   for (uint32_t i = 0; i < mJournalsToCreateBeforeCommit.Length(); i++) {
     int64_t id = mJournalsToCreateBeforeCommit[i];
@@ -11867,19 +11787,18 @@ UpdateRefcountFunction::CreateJournals()
 
 nsresult
 DatabaseConnection::
 UpdateRefcountFunction::RemoveJournals(const nsTArray<int64_t>& aJournals)
 {
   MOZ_ASSERT(mConnection);
   mConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::UpdateRefcountFunction::RemoveJournals",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseConnection::UpdateRefcountFunction::RemoveJournals", STORAGE);
 
   nsCOMPtr<nsIFile> journalDirectory = mFileManager->GetJournalDirectory();
   if (NS_WARN_IF(!journalDirectory)) {
     return NS_ERROR_FAILURE;
   }
 
   for (uint32_t index = 0; index < aJournals.Length(); index++) {
     nsCOMPtr<nsIFile> file =
@@ -11902,19 +11821,18 @@ NS_IMPL_ISUPPORTS(DatabaseConnection::Up
 NS_IMETHODIMP
 DatabaseConnection::
 UpdateRefcountFunction::OnFunctionCall(mozIStorageValueArray* aValues,
                                        nsIVariant** _retval)
 {
   MOZ_ASSERT(aValues);
   MOZ_ASSERT(_retval);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::UpdateRefcountFunction::OnFunctionCall",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseConnection::UpdateRefcountFunction::OnFunctionCall", STORAGE);
 
   uint32_t numEntries;
   nsresult rv = aValues->GetNumEntries(&numEntries);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   MOZ_ASSERT(numEntries == 2);
@@ -11961,20 +11879,20 @@ DatabaseUpdateFunction::Update(int64_t a
 
 nsresult
 DatabaseConnection::UpdateRefcountFunction::
 DatabaseUpdateFunction::UpdateInternal(int64_t aId,
                                        int32_t aDelta)
 {
   MOZ_ASSERT(mFunction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseConnection::UpdateRefcountFunction::"
-                 "DatabaseUpdateFunction::UpdateInternal",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseConnection::UpdateRefcountFunction::"
+    "DatabaseUpdateFunction::UpdateInternal",
+    STORAGE);
 
   DatabaseConnection* connection = mFunction->mConnection;
   MOZ_ASSERT(connection);
   connection->AssertIsOnConnectionThread();
 
   MOZ_ASSERT(connection->GetStorageConnection());
 
   nsresult rv;
@@ -12111,19 +12029,17 @@ ConnectionPool::~ConnectionPool()
 }
 
 // static
 void
 ConnectionPool::IdleTimerCallback(nsITimer* aTimer, void* aClosure)
 {
   MOZ_ASSERT(aTimer);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::IdleTimerCallback",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::IdleTimerCallback", STORAGE);
 
   auto* self = static_cast<ConnectionPool*>(aClosure);
   MOZ_ASSERT(self);
   MOZ_ASSERT(self->mIdleTimer);
   MOZ_ASSERT(SameCOMIdentity(self->mIdleTimer, aTimer));
   MOZ_ASSERT(!self->mTargetIdleTime.IsNull());
   MOZ_ASSERT_IF(self->mIdleDatabases.IsEmpty(), !self->mIdleThreads.IsEmpty());
   MOZ_ASSERT_IF(self->mIdleThreads.IsEmpty(), !self->mIdleDatabases.IsEmpty());
@@ -12177,19 +12093,17 @@ ConnectionPool::IdleTimerCallback(nsITim
 nsresult
 ConnectionPool::GetOrCreateConnection(const Database* aDatabase,
                                       DatabaseConnection** aConnection)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aDatabase);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::GetOrCreateConnection",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::GetOrCreateConnection", STORAGE);
 
   DatabaseInfo* dbInfo;
   {
     MutexAutoLock lock(mDatabasesMutex);
 
     dbInfo = mDatabases.Get(aDatabase->Id());
   }
 
@@ -12244,19 +12158,17 @@ ConnectionPool::Start(const nsID& aBackg
                       bool aIsWriteTransaction,
                       TransactionDatabaseOperationBase* aTransactionOp)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!aDatabaseId.IsEmpty());
   MOZ_ASSERT(mNextTransactionId < UINT64_MAX);
   MOZ_ASSERT(!mShutdownRequested);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::Start",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::Start", STORAGE);
 
   const uint64_t transactionId = ++mNextTransactionId;
 
   DatabaseInfo* dbInfo = mDatabases.Get(aDatabaseId);
 
   const bool databaseInfoIsNew = !dbInfo;
 
   if (databaseInfoIsNew) {
@@ -12341,19 +12253,17 @@ ConnectionPool::Start(const nsID& aBackg
 }
 
 void
 ConnectionPool::Dispatch(uint64_t aTransactionId, nsIRunnable* aRunnable)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aRunnable);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::Dispatch",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::Dispatch", STORAGE);
 
   TransactionInfo* transactionInfo = mTransactions.Get(aTransactionId);
   MOZ_ASSERT(transactionInfo);
   MOZ_ASSERT(!transactionInfo->mFinished);
 
   if (transactionInfo->mRunning) {
     DatabaseInfo* dbInfo = transactionInfo->mDatabaseInfo;
     MOZ_ASSERT(dbInfo);
@@ -12376,19 +12286,17 @@ ConnectionPool::Finish(uint64_t aTransac
   AssertIsOnOwningThread();
 
 #ifdef DEBUG
   TransactionInfo* transactionInfo = mTransactions.Get(aTransactionId);
   MOZ_ASSERT(transactionInfo);
   MOZ_ASSERT(!transactionInfo->mFinished);
 #endif
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::Finish",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::Finish", STORAGE);
 
   RefPtr<FinishCallbackWrapper> wrapper =
     new FinishCallbackWrapper(this, aTransactionId, aCallback);
 
   Dispatch(aTransactionId, wrapper);
 
 #ifdef DEBUG
   MOZ_ASSERT(!transactionInfo->mFinished);
@@ -12399,19 +12307,17 @@ ConnectionPool::Finish(uint64_t aTransac
 void
 ConnectionPool::WaitForDatabasesToComplete(nsTArray<nsCString>&& aDatabaseIds,
                                            nsIRunnable* aCallback)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!aDatabaseIds.IsEmpty());
   MOZ_ASSERT(aCallback);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::WaitForDatabasesToComplete",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::WaitForDatabasesToComplete", STORAGE);
 
   bool mayRunCallbackImmediately = true;
 
   for (uint32_t index = 0, count = aDatabaseIds.Length();
        index < count;
        index++) {
     const nsCString& databaseId = aDatabaseIds[index];
     MOZ_ASSERT(!databaseId.IsEmpty());
@@ -12433,19 +12339,17 @@ ConnectionPool::WaitForDatabasesToComple
 
 void
 ConnectionPool::Shutdown()
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!mShutdownRequested);
   MOZ_ASSERT(!mShutdownComplete);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::Shutdown",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::Shutdown", STORAGE);
 
   mShutdownRequested = true;
 
   CancelIdleTimer();
   MOZ_ASSERT(mTargetIdleTime.IsNull());
 
   mIdleTimer = nullptr;
 
@@ -12470,19 +12374,17 @@ ConnectionPool::Cleanup()
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mShutdownRequested);
   MOZ_ASSERT(!mShutdownComplete);
   MOZ_ASSERT(!mDatabases.Count());
   MOZ_ASSERT(!mTransactions.Count());
   MOZ_ASSERT(mIdleThreads.IsEmpty());
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::Cleanup",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::Cleanup", STORAGE);
 
   if (!mCompleteCallbacks.IsEmpty()) {
     // Run all callbacks manually now.
     for (uint32_t count = mCompleteCallbacks.Length(), index = 0;
          index < count;
          index++) {
       nsAutoPtr<DatabasesCompleteCallback> completeCallback(
         mCompleteCallbacks[index].forget());
@@ -12505,19 +12407,17 @@ ConnectionPool::Cleanup()
 }
 
 void
 ConnectionPool::AdjustIdleTimer()
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mIdleTimer);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::AdjustIdleTimer",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::AdjustIdleTimer", STORAGE);
 
   // Figure out the next time at which we should release idle resources. This
   // includes both databases and threads.
   TimeStamp newTargetIdleTime;
   MOZ_ASSERT(newTargetIdleTime.IsNull());
 
   if (!mIdleDatabases.IsEmpty()) {
     newTargetIdleTime = mIdleDatabases[0].mIdleTime;
@@ -12606,19 +12506,17 @@ ConnectionPool::ShutdownThread(ThreadInf
 }
 
 void
 ConnectionPool::CloseIdleDatabases()
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mShutdownRequested);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::CloseIdleDatabases",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::CloseIdleDatabases", STORAGE);
 
   if (!mIdleDatabases.IsEmpty()) {
     for (IdleDatabaseInfo& idleInfo : mIdleDatabases) {
       CloseDatabase(idleInfo.mDatabaseInfo);
     }
     mIdleDatabases.Clear();
   }
 
@@ -12632,19 +12530,17 @@ ConnectionPool::CloseIdleDatabases()
 }
 
 void
 ConnectionPool::ShutdownIdleThreads()
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mShutdownRequested);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::ShutdownIdleThreads",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::ShutdownIdleThreads", STORAGE);
 
   if (!mIdleThreads.IsEmpty()) {
     for (uint32_t threadCount = mIdleThreads.Length(), threadIndex = 0;
          threadIndex < threadCount;
          threadIndex++) {
       ShutdownThread(mIdleThreads[threadIndex].mThreadInfo);
     }
     mIdleThreads.Clear();
@@ -12653,19 +12549,17 @@ ConnectionPool::ShutdownIdleThreads()
 
 bool
 ConnectionPool::ScheduleTransaction(TransactionInfo* aTransactionInfo,
                                     bool aFromQueuedTransactions)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aTransactionInfo);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::ScheduleTransaction",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::ScheduleTransaction", STORAGE);
 
   DatabaseInfo* dbInfo = aTransactionInfo->mDatabaseInfo;
   MOZ_ASSERT(dbInfo);
 
   dbInfo->mIdle = false;
 
   if (dbInfo->mClosing) {
     MOZ_ASSERT(!mIdleDatabases.Contains(dbInfo));
@@ -12786,19 +12680,17 @@ ConnectionPool::ScheduleTransaction(Tran
   return true;
 }
 
 void
 ConnectionPool::NoteFinishedTransaction(uint64_t aTransactionId)
 {
   AssertIsOnOwningThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::NoteFinishedTransaction",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::NoteFinishedTransaction", STORAGE);
 
   TransactionInfo* transactionInfo = mTransactions.Get(aTransactionId);
   MOZ_ASSERT(transactionInfo);
   MOZ_ASSERT(transactionInfo->mRunning);
   MOZ_ASSERT(transactionInfo->mFinished);
 
   transactionInfo->mRunning = false;
 
@@ -12874,19 +12766,17 @@ void
 ConnectionPool::ScheduleQueuedTransactions(ThreadInfo& aThreadInfo)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aThreadInfo.mThread);
   MOZ_ASSERT(aThreadInfo.mRunnable);
   MOZ_ASSERT(!mQueuedTransactions.IsEmpty());
   MOZ_ASSERT(!mIdleThreads.Contains(aThreadInfo));
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::ScheduleQueuedTransactions",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::ScheduleQueuedTransactions", STORAGE);
 
   mIdleThreads.InsertElementSorted(aThreadInfo);
 
   aThreadInfo.mRunnable = nullptr;
   aThreadInfo.mThread = nullptr;
 
   uint32_t index = 0;
   for (uint32_t count = mQueuedTransactions.Length(); index < count; index++) {
@@ -12908,19 +12798,17 @@ ConnectionPool::NoteIdleDatabase(Databas
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aDatabaseInfo);
   MOZ_ASSERT(!aDatabaseInfo->TotalTransactionCount());
   MOZ_ASSERT(aDatabaseInfo->mThreadInfo.mThread);
   MOZ_ASSERT(aDatabaseInfo->mThreadInfo.mRunnable);
   MOZ_ASSERT(!mIdleDatabases.Contains(aDatabaseInfo));
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::NoteIdleDatabase",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::NoteIdleDatabase", STORAGE);
 
   const bool otherDatabasesWaiting = !mQueuedTransactions.IsEmpty();
 
   if (mShutdownRequested ||
       otherDatabasesWaiting ||
       aDatabaseInfo->mCloseOnIdle) {
     // Make sure we close the connection if we're shutting down or giving the
     // thread to another database.
@@ -12947,19 +12835,17 @@ ConnectionPool::NoteIdleDatabase(Databas
 void
 ConnectionPool::NoteClosedDatabase(DatabaseInfo* aDatabaseInfo)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aDatabaseInfo);
   MOZ_ASSERT(aDatabaseInfo->mClosing);
   MOZ_ASSERT(!mIdleDatabases.Contains(aDatabaseInfo));
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::NoteClosedDatabase",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::NoteClosedDatabase", STORAGE);
 
   aDatabaseInfo->mClosing = false;
 
   // Figure out what to do with this database's thread. It may have already been
   // given to another database, in which case there's nothing to do here.
   // Otherwise we prioritize the thread as follows:
   //   1. Databases that haven't had an opportunity to run at all are highest
   //      priority. Those live in the |mQueuedTransactions| list.
@@ -13053,19 +12939,17 @@ ConnectionPool::NoteClosedDatabase(Datab
 bool
 ConnectionPool::MaybeFireCallback(DatabasesCompleteCallback* aCallback)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aCallback);
   MOZ_ASSERT(!aCallback->mDatabaseIds.IsEmpty());
   MOZ_ASSERT(aCallback->mCallback);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::MaybeFireCallback",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::MaybeFireCallback", STORAGE);
 
   for (uint32_t count = aCallback->mDatabaseIds.Length(), index = 0;
        index < count;
        index++) {
     const nsCString& databaseId = aCallback->mDatabaseIds[index];
     MOZ_ASSERT(!databaseId.IsEmpty());
 
     if (mDatabases.Get(databaseId)) {
@@ -13126,19 +13010,17 @@ ConnectionPool::CloseDatabase(DatabaseIn
 }
 
 bool
 ConnectionPool::CloseDatabaseWhenIdleInternal(const nsACString& aDatabaseId)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!aDatabaseId.IsEmpty());
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::CloseDatabaseWhenIdleInternal",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::CloseDatabaseWhenIdleInternal", STORAGE);
 
   if (DatabaseInfo* dbInfo = mDatabases.Get(aDatabaseId)) {
     if (mIdleDatabases.RemoveElement(dbInfo) ||
         mDatabasesPerformingIdleMaintenance.RemoveElement(dbInfo)) {
       CloseDatabase(dbInfo);
       AdjustIdleTimer();
     } else {
       dbInfo->mCloseOnIdle = true;
@@ -13210,19 +13092,17 @@ NS_IMPL_ISUPPORTS_INHERITED0(ConnectionP
                              ConnectionPool::ConnectionRunnable)
 
 NS_IMETHODIMP
 ConnectionPool::
 CloseConnectionRunnable::Run()
 {
   MOZ_ASSERT(mDatabaseInfo);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::CloseConnectionRunnable::Run",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::CloseConnectionRunnable::Run", STORAGE);
 
   if (mOwningEventTarget) {
     MOZ_ASSERT(mDatabaseInfo->mClosing);
 
     nsCOMPtr<nsIEventTarget> owningThread;
     mOwningEventTarget.swap(owningThread);
 
     // The connection could be null if EnsureConnection() didn't run or was not
@@ -13342,19 +13222,17 @@ NS_IMPL_ISUPPORTS_INHERITED0(ConnectionP
 nsresult
 ConnectionPool::
 FinishCallbackWrapper::Run()
 {
   MOZ_ASSERT(mConnectionPool);
   MOZ_ASSERT(mCallback);
   MOZ_ASSERT(mOwningEventTarget);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ConnectionPool::FinishCallbackWrapper::Run",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ConnectionPool::FinishCallbackWrapper::Run", STORAGE);
 
   if (!mHasRunOnce) {
     MOZ_ASSERT(!IsOnBackgroundThread());
 
     mHasRunOnce = true;
 
     Unused << mCallback->Run();
 
@@ -13410,19 +13288,17 @@ ThreadRunnable::Run()
     mContinueRunning = false;
     return NS_OK;
   }
 
   mFirstRun = false;
 
   {
     // Scope for the profiler label.
-    PROFILER_LABEL("IndexedDB",
-                   "ConnectionPool::ThreadRunnable::Run",
-                   js::ProfileEntry::Category::STORAGE);
+    AUTO_PROFILER_LABEL("ConnectionPool::ThreadRunnable::Run", STORAGE);
 
     DebugOnly<nsIThread*> currentThread = NS_GetCurrentThread();
     MOZ_ASSERT(currentThread);
 
 #ifdef DEBUG
     if (kDEBUGTransactionThreadPriority !=
           nsISupportsPriority::PRIORITY_NORMAL) {
       NS_WARNING("ConnectionPool thread debugging enabled, priority has been "
@@ -14220,19 +14096,17 @@ Database::Invalidate()
 }
 
 nsresult
 Database::EnsureConnection()
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
 
-  PROFILER_LABEL("IndexedDB",
-                 "Database::EnsureConnection",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Database::EnsureConnection", STORAGE);
 
   if (!mConnection || !mConnection->GetStorageConnection()) {
     nsresult rv =
       gConnectionPool->GetOrCreateConnection(this, getter_AddRefs(mConnection));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
@@ -19690,19 +19564,17 @@ NS_IMETHODIMP
 UpgradeFileIdsFunction::OnFunctionCall(mozIStorageValueArray* aArguments,
                                        nsIVariant** aResult)
 {
   MOZ_ASSERT(aArguments);
   MOZ_ASSERT(aResult);
   MOZ_ASSERT(mFileManager);
   MOZ_ASSERT(mContext);
 
-  PROFILER_LABEL("IndexedDB",
-                 "UpgradeFileIdsFunction::OnFunctionCall",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("UpgradeFileIdsFunction::OnFunctionCall", STORAGE);
 
   uint32_t argc;
   nsresult rv = aArguments->GetNumEntries(&argc);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (argc != 2) {
@@ -19886,19 +19758,18 @@ DatabaseOperationBase::GetStructuredClon
                                                  FileManager* aFileManager,
                                                  const nsAString& aFileIds,
                                                  StructuredCloneReadInfo* aInfo)
 {
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aFileManager);
   MOZ_ASSERT(aInfo);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob", STORAGE);
 
   const char* compressed = reinterpret_cast<const char*>(aBlobData);
   size_t compressedLength = size_t(aBlobDataLength);
 
   size_t uncompressedLength;
   if (NS_WARN_IF(!snappy::GetUncompressedLength(compressed, compressedLength,
                                                 &uncompressedLength))) {
     return NS_ERROR_FILE_CORRUPTED;
@@ -19940,20 +19811,19 @@ DatabaseOperationBase::GetStructuredClon
                                                  FileManager* aFileManager,
                                                  const nsAString& aFileIds,
                                                  StructuredCloneReadInfo* aInfo)
 {
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aFileManager);
   MOZ_ASSERT(aInfo);
 
-  PROFILER_LABEL(
-            "IndexedDB",
-            "DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob",
-            js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob",
+    STORAGE);
 
   nsresult rv;
 
   if (!aFileIds.IsVoid()) {
     rv = DeserializeStructuredCloneFiles(aFileManager,
                                          aFileIds,
                                          aInfo->mFiles,
                                          &aInfo->mHasPreprocessInfo);
@@ -20175,19 +20045,18 @@ nsresult
 DatabaseOperationBase::IndexDataValuesFromUpdateInfos(
                                   const nsTArray<IndexUpdateInfo>& aUpdateInfos,
                                   const UniqueIndexTable& aUniqueIndexTable,
                                   nsTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(aIndexValues.IsEmpty());
   MOZ_ASSERT_IF(!aUpdateInfos.IsEmpty(), aUniqueIndexTable.Count());
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseOperationBase::IndexDataValuesFromUpdateInfos",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseOperationBase::IndexDataValuesFromUpdateInfos", STORAGE);
 
   const uint32_t count = aUpdateInfos.Length();
 
   if (!count) {
     return NS_OK;
   }
 
   if (NS_WARN_IF(!aIndexValues.SetCapacity(count, fallible))) {
@@ -20220,19 +20089,17 @@ DatabaseOperationBase::InsertIndexTableR
                              const int64_t aObjectStoreId,
                              const Key& aObjectStoreKey,
                              const FallibleTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(!aObjectStoreKey.IsUnset());
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseOperationBase::InsertIndexTableRows",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseOperationBase::InsertIndexTableRows", STORAGE);
 
   const uint32_t count = aIndexValues.Length();
   if (!count) {
     return NS_OK;
   }
 
   NS_NAMED_LITERAL_CSTRING(objectStoreIdString, "object_store_id");
   NS_NAMED_LITERAL_CSTRING(objectDataKeyString, "object_data_key");
@@ -20329,19 +20196,18 @@ DatabaseOperationBase::DeleteIndexDataTa
                              DatabaseConnection* aConnection,
                              const Key& aObjectStoreKey,
                              const FallibleTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(!aObjectStoreKey.IsUnset());
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseOperationBase::DeleteIndexDataTableRows",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseOperationBase::DeleteIndexDataTableRows", STORAGE);
 
   const uint32_t count = aIndexValues.Length();
   if (!count) {
     return NS_OK;
   }
 
   NS_NAMED_LITERAL_CSTRING(indexIdString, "index_id");
   NS_NAMED_LITERAL_CSTRING(valueString, "value");
@@ -20423,20 +20289,19 @@ DatabaseOperationBase::DeleteObjectStore
     bool hasIndexes = false;
     MOZ_ASSERT(NS_SUCCEEDED(
       ObjectStoreHasIndexes(aConnection, aObjectStoreId, &hasIndexes)));
     MOZ_ASSERT(hasIndexes,
                "Don't use this slow method if there are no indexes!");
   }
 #endif
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaseOperationBase::"
-                 "DeleteObjectStoreDataTableRowsWithIndexes",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DatabaseOperationBase::DeleteObjectStoreDataTableRowsWithIndexes",
+    STORAGE);
 
   const bool singleRowOnly =
     aKeyRange.type() == OptionalKeyRange::TSerializedKeyRange &&
     aKeyRange.get_SerializedKeyRange().isOnly();
 
   NS_NAMED_LITERAL_CSTRING(objectStoreIdString, "object_store_id");
   NS_NAMED_LITERAL_CSTRING(keyString, "key");
 
@@ -20566,19 +20431,17 @@ DatabaseOperationBase::UpdateIndexValues
                              const int64_t aObjectStoreId,
                              const Key& aObjectStoreKey,
                              const FallibleTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(!aObjectStoreKey.IsUnset());
 
-  PROFILER_LABEL("IndexedDB",
-                 "DatabaunseOperationBase::UpdateIndexValues",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DatabaseOperationBase::UpdateIndexValues", STORAGE);
 
   UniqueFreePtr<uint8_t> indexDataValues;
   uint32_t indexDataValuesLength;
   nsresult rv = MakeCompressedIndexDataValues(aIndexValues,
                                               indexDataValues,
                                               &indexDataValuesLength);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -21712,19 +21575,17 @@ OpenDatabaseOp::DatabaseOpen()
 }
 
 nsresult
 OpenDatabaseOp::DoDatabaseWork()
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(mState == State::DatabaseWorkOpen);
 
-  PROFILER_LABEL("IndexedDB",
-                 "OpenDatabaseOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("OpenDatabaseOp::DoDatabaseWork", STORAGE);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
       !OperationMayProceed()) {
     IDB_REPORT_INTERNAL_ERR();
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   const nsString& databaseName = mCommonParams.metadata().name();
@@ -22894,19 +22755,18 @@ VersionChangeOp::DoDatabaseWork(Database
   MOZ_ASSERT(mOpenDatabaseOp->mState == State::DatabaseWorkVersionChange);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
       !OperationMayProceed()) {
     IDB_REPORT_INTERNAL_ERR();
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
-  PROFILER_LABEL("IndexedDB",
-                 "OpenDatabaseOp::VersionChangeOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "OpenDatabaseOp::VersionChangeOp::DoDatabaseWork", STORAGE);
 
   IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld]: "
                  "Beginning database work",
                "IndexedDB %s: P T[%lld]: DB Start",
                IDB_LOG_ID_STRING(mBackgroundChildLoggingId),
                mLoggingSerialNumber);
 
   Transaction()->SetActiveOnConnectionThread();
@@ -22997,19 +22857,17 @@ VersionChangeOp::Cleanup()
 void
 DeleteDatabaseOp::LoadPreviousVersion(nsIFile* aDatabaseFile)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aDatabaseFile);
   MOZ_ASSERT(mState == State::DatabaseWorkOpen);
   MOZ_ASSERT(!mPreviousVersion);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DeleteDatabaseOp::LoadPreviousVersion",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DeleteDatabaseOp::LoadPreviousVersion", STORAGE);
 
   nsresult rv;
 
   nsCOMPtr<mozIStorageService> ss =
     do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
@@ -23086,19 +22944,17 @@ DeleteDatabaseOp::DatabaseOpen()
 }
 
 nsresult
 DeleteDatabaseOp::DoDatabaseWork()
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(mState == State::DatabaseWorkOpen);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DeleteDatabaseOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DeleteDatabaseOp::DoDatabaseWork", STORAGE);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
       !OperationMayProceed()) {
     IDB_REPORT_INTERNAL_ERR();
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   const nsString& databaseName = mCommonParams.metadata().name();
@@ -23336,19 +23192,17 @@ VersionChangeOp::DeleteFile(nsIFile* aDi
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aDirectory);
   MOZ_ASSERT(!aFilename.IsEmpty());
   MOZ_ASSERT_IF(aQuotaManager, mDeleteDatabaseOp->mEnforcingQuota);
 
   MOZ_ASSERT(mDeleteDatabaseOp->mState == State::DatabaseWorkVersionChange);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DeleteDatabaseOp::VersionChangeOp::DeleteFile",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DeleteDatabaseOp::VersionChangeOp::DeleteFile", STORAGE);
 
   nsCOMPtr<nsIFile> file;
   nsresult rv = aDirectory->Clone(getter_AddRefs(file));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = file->Append(aFilename);
@@ -23397,19 +23251,18 @@ VersionChangeOp::DeleteFile(nsIFile* aDi
 
 nsresult
 DeleteDatabaseOp::
 VersionChangeOp::RunOnIOThread()
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(mDeleteDatabaseOp->mState == State::DatabaseWorkVersionChange);
 
-  PROFILER_LABEL("IndexedDB",
-                 "DeleteDatabaseOp::VersionChangeOp::RunOnIOThread",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "DeleteDatabaseOp::VersionChangeOp::RunOnIOThread", STORAGE);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
       !OperationMayProceed()) {
     IDB_REPORT_INTERNAL_ERR();
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   const PersistenceType& persistenceType =
@@ -23730,19 +23583,18 @@ TransactionDatabaseOperationBase::Dispat
 void
 TransactionDatabaseOperationBase::RunOnConnectionThread()
 {
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(mInternalState == InternalState::DatabaseWork);
   MOZ_ASSERT(mTransaction);
   MOZ_ASSERT(NS_SUCCEEDED(mResultCode));
 
-  PROFILER_LABEL("IndexedDB",
-                 "TransactionDatabaseOperationBase::RunOnConnectionThread",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "TransactionDatabaseOperationBase::RunOnConnectionThread", STORAGE);
 
   // There are several cases where we don't actually have to to any work here.
 
   if (mTransactionIsAborted || mTransaction->IsInvalidatedOnAnyThread()) {
     // This transaction is already set to be aborted or invalidated.
     mResultCode = NS_ERROR_DOM_INDEXEDDB_ABORT_ERR;
   } else if (!OperationMayProceed()) {
     // The operation was canceled in some way, likely because the child process
@@ -24120,19 +23972,17 @@ NS_IMPL_ISUPPORTS_INHERITED0(Transaction
 
 NS_IMETHODIMP
 TransactionBase::
 CommitOp::Run()
 {
   MOZ_ASSERT(mTransaction);
   mTransaction->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "TransactionBase::CommitOp::Run",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("TransactionBase::CommitOp::Run", STORAGE);
 
   IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld] Request[%llu]: "
                  "Beginning database work",
                "IndexedDB %s: P T[%lld] R[%llu]: DB Start",
                IDB_LOG_ID_STRING(mBackgroundChildLoggingId),
                mTransaction->LoggingSerialNumber(),
                mLoggingSerialNumber);
 
@@ -24214,19 +24064,17 @@ CommitOp::Run()
 
 void
 TransactionBase::
 CommitOp::TransactionFinishedBeforeUnblock()
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(mTransaction);
 
-  PROFILER_LABEL("IndexedDB",
-                 "CommitOp::TransactionFinishedBeforeUnblock",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("CommitOp::TransactionFinishedBeforeUnblock", STORAGE);
 
   if (!IsActorDestroyed()) {
     mTransaction->UpdateMetadata(mResultCode);
   }
 }
 
 void
 TransactionBase::
@@ -24381,19 +24229,17 @@ CreateFileOp::CreateMutableFile(MutableF
 }
 
 nsresult
 CreateFileOp::DoDatabaseWork()
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(mState == State::DatabaseWork);
 
-  PROFILER_LABEL("IndexedDB",
-                 "CreateFileOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("CreateFileOp::DoDatabaseWork", STORAGE);
 
   if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
     NS_WARNING("Refusing to create file because disk space is low!");
     return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
   }
 
   if (NS_WARN_IF(QuotaManager::IsShuttingDown()) || !OperationMayProceed()) {
     IDB_REPORT_INTERNAL_ERR();
@@ -24526,19 +24372,17 @@ VersionChangeTransactionOp::Cleanup()
 }
 
 nsresult
 CreateObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "CreateObjectStoreOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("CreateObjectStoreOp::DoDatabaseWork", STORAGE);
 
   if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
     return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
   }
 
 #ifdef DEBUG
   {
     // Make sure that we're not creating an object store with the same name as
@@ -24630,19 +24474,17 @@ CreateObjectStoreOp::DoDatabaseWork(Data
 }
 
 nsresult
 DeleteObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "DeleteObjectStoreOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DeleteObjectStoreOp::DoDatabaseWork", STORAGE);
 
   NS_NAMED_LITERAL_CSTRING(objectStoreIdString, "object_store_id");
 
 #ifdef DEBUG
   {
     // Make sure |mIsLastObjectStore| is telling the truth.
     DatabaseConnection::CachedStatement stmt;
     MOZ_ALWAYS_SUCCEEDS(
@@ -24853,19 +24695,17 @@ DeleteObjectStoreOp::DoDatabaseWork(Data
 }
 
 nsresult
 RenameObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "RenameObjectStoreOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("RenameObjectStoreOp::DoDatabaseWork", STORAGE);
 
   if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
     return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
   }
 
 #ifdef DEBUG
   {
     // Make sure that we're not renaming an object store with the same name as
@@ -24953,19 +24793,17 @@ unsigned int CreateIndexOp::sThreadLocal
 nsresult
 CreateIndexOp::InsertDataFromObjectStore(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(!IndexedDatabaseManager::InLowDiskSpaceMode());
   MOZ_ASSERT(mMaybeUniqueIndexTable);
 
-  PROFILER_LABEL("IndexedDB",
-                 "CreateIndexOp::InsertDataFromObjectStore",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("CreateIndexOp::InsertDataFromObjectStore", STORAGE);
 
   nsCOMPtr<mozIStorageConnection> storageConnection =
     aConnection->GetStorageConnection();
   MOZ_ASSERT(storageConnection);
 
   ThreadLocalJSContext* context = ThreadLocalJSContext::GetOrCreate();
   if (NS_WARN_IF(!context)) {
     IDB_REPORT_INTERNAL_ERR();
@@ -25074,19 +24912,17 @@ CreateIndexOp::Init(TransactionBase* aTr
 }
 
 nsresult
 CreateIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "CreateIndexOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("CreateIndexOp::DoDatabaseWork", STORAGE);
 
   if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
     return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
   }
 
 #ifdef DEBUG
   {
     // Make sure that we're not creating an index with the same name and object
@@ -25316,19 +25152,18 @@ UpdateIndexDataValuesFunction::OnFunctio
 {
   MOZ_ASSERT(aValues);
   MOZ_ASSERT(_retval);
   MOZ_ASSERT(mConnection);
   mConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(mOp);
   MOZ_ASSERT(mCx);
 
-  PROFILER_LABEL("IndexedDB",
-                 "CreateIndexOp::UpdateIndexDataValuesFunction::OnFunctionCall",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL(
+    "CreateIndexOp::UpdateIndexDataValuesFunction::OnFunctionCall", STORAGE);
 
 #ifdef DEBUG
   {
     uint32_t argCount;
     MOZ_ALWAYS_SUCCEEDS(aValues->GetNumEntries(&argCount));
     MOZ_ASSERT(argCount == 4); // key, index_data_values, file_ids, data
 
     int32_t valueType;
@@ -25554,19 +25389,17 @@ DeleteIndexOp::RemoveReferencesToIndex(D
 
     bool
     LessThan(const IndexDataValue& aA, const IndexDataValue& aB) const
     {
       return aA.mIndexId < aB.mIndexId;
     };
   };
 
-  PROFILER_LABEL("IndexedDB",
-                 "DeleteIndexOp::RemoveReferencesToIndex",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DeleteIndexOp::RemoveReferencesToIndex", STORAGE);
 
   if (mIsLastIndex) {
     // There is no need to parse the previous entry in the index_data_values
     // column if this is the last index. Simply set it to NULL.
     DatabaseConnection::CachedStatement stmt;
     nsresult rv = aConnection->GetCachedStatement(NS_LITERAL_CSTRING(
       "UPDATE object_data "
         "SET index_data_values = NULL "
@@ -25696,19 +25529,17 @@ DeleteIndexOp::DoDatabaseWork(DatabaseCo
       }
     }
 
     MOZ_ASSERT_IF(mIsLastIndex, foundThisIndex && !foundOtherIndex);
     MOZ_ASSERT_IF(!mIsLastIndex, foundThisIndex && foundOtherIndex);
   }
 #endif
 
-  PROFILER_LABEL("IndexedDB",
-                 "DeleteIndexOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("DeleteIndexOp::DoDatabaseWork", STORAGE);
 
   DatabaseConnection::AutoSavepoint autoSave;
   nsresult rv = autoSave.Start(Transaction());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   DatabaseConnection::CachedStatement selectStmt;
@@ -25955,19 +25786,17 @@ DeleteIndexOp::DoDatabaseWork(DatabaseCo
 }
 
 nsresult
 RenameIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "RenameIndexOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("RenameIndexOp::DoDatabaseWork", STORAGE);
 
   if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
     return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
   }
 
 #ifdef DEBUG
   {
     // Make sure that we're not renaming an index with the same name as another
@@ -26443,19 +26272,17 @@ ObjectStoreAddOrPutRequestOp::Init(Trans
 
 nsresult
 ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(aConnection->GetStorageConnection());
 
-  PROFILER_LABEL("IndexedDB",
-                 "ObjectStoreAddOrPutRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ObjectStoreAddOrPutRequestOp::DoDatabaseWork", STORAGE);
 
   if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
     return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
   }
 
   DatabaseConnection::AutoSavepoint autoSave;
   nsresult rv = autoSave.Start(Transaction());
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -26947,19 +26774,17 @@ ObjectStoreGetRequestOp::DoDatabaseWork(
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT_IF(!mGetAll,
                 mOptionalKeyRange.type() ==
                   OptionalKeyRange::TSerializedKeyRange);
   MOZ_ASSERT_IF(!mGetAll, mLimit == 1);
 
-  PROFILER_LABEL("IndexedDB",
-                 "ObjectStoreGetRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ObjectStoreGetRequestOp::DoDatabaseWork", STORAGE);
 
   const bool hasKeyRange =
     mOptionalKeyRange.type() == OptionalKeyRange::TSerializedKeyRange;
 
   nsAutoCString keyRangeClause;
   if (hasKeyRange) {
     GetBindingClauseForKeyRange(mOptionalKeyRange.get_SerializedKeyRange(),
                                 NS_LITERAL_CSTRING("key"),
@@ -27158,19 +26983,17 @@ ObjectStoreGetKeyRequestOp::ObjectStoreG
 }
 
 nsresult
 ObjectStoreGetKeyRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "ObjectStoreGetKeyRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ObjectStoreGetKeyRequestOp::DoDatabaseWork", STORAGE);
 
   const bool hasKeyRange =
       mOptionalKeyRange.type() == OptionalKeyRange::TSerializedKeyRange;
 
   nsAutoCString keyRangeClause;
   if (hasKeyRange) {
     GetBindingClauseForKeyRange(mOptionalKeyRange.get_SerializedKeyRange(),
                                 NS_LITERAL_CSTRING("key"),
@@ -27273,19 +27096,17 @@ ObjectStoreDeleteRequestOp::ObjectStoreD
   mObjectStoreMayHaveIndexes = metadata->HasLiveIndexes();
 }
 
 nsresult
 ObjectStoreDeleteRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
-  PROFILER_LABEL("IndexedDB",
-                 "ObjectStoreDeleteRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ObjectStoreDeleteRequestOp::DoDatabaseWork", STORAGE);
 
   DatabaseConnection::AutoSavepoint autoSave;
   nsresult rv = autoSave.Start(Transaction());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   bool objectStoreHasIndexes;
@@ -27366,19 +27187,17 @@ ObjectStoreClearRequestOp::ObjectStoreCl
 }
 
 nsresult
 ObjectStoreClearRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "ObjectStoreClearRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ObjectStoreClearRequestOp::DoDatabaseWork", STORAGE);
 
   DatabaseConnection::AutoSavepoint autoSave;
   nsresult rv = autoSave.Start(Transaction());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   bool objectStoreHasIndexes;
@@ -27429,19 +27248,17 @@ ObjectStoreClearRequestOp::DoDatabaseWor
 }
 
 nsresult
 ObjectStoreCountRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "ObjectStoreCountRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("ObjectStoreCountRequestOp::DoDatabaseWork", STORAGE);
 
   const bool hasKeyRange =
     mParams.optionalKeyRange().type() == OptionalKeyRange::TSerializedKeyRange;
 
   nsAutoCString keyRangeClause;
   if (hasKeyRange) {
     GetBindingClauseForKeyRange(
       mParams.optionalKeyRange().get_SerializedKeyRange(),
@@ -27594,19 +27411,17 @@ IndexGetRequestOp::DoDatabaseWork(Databa
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT_IF(!mGetAll,
                 mOptionalKeyRange.type() ==
                   OptionalKeyRange::TSerializedKeyRange);
   MOZ_ASSERT_IF(!mGetAll, mLimit == 1);
 
-  PROFILER_LABEL("IndexedDB",
-                 "IndexGetRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("IndexGetRequestOp::DoDatabaseWork", STORAGE);
 
   const bool hasKeyRange =
     mOptionalKeyRange.type() == OptionalKeyRange::TSerializedKeyRange;
 
   nsCString indexTable;
   if (mMetadata->mCommonMetadata.unique()) {
     indexTable.AssignLiteral("unique_index_data ");
   }
@@ -27792,19 +27607,17 @@ IndexGetKeyRequestOp::DoDatabaseWork(Dat
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT_IF(!mGetAll,
                 mOptionalKeyRange.type() ==
                   OptionalKeyRange::TSerializedKeyRange);
   MOZ_ASSERT_IF(!mGetAll, mLimit == 1);
 
-  PROFILER_LABEL("IndexedDB",
-                 "IndexGetKeyRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("IndexGetKeyRequestOp::DoDatabaseWork", STORAGE);
 
   const bool hasKeyRange =
     mOptionalKeyRange.type() == OptionalKeyRange::TSerializedKeyRange;
 
   nsCString indexTable;
   if (mMetadata->mCommonMetadata.unique()) {
     indexTable.AssignLiteral("unique_index_data ");
   }
@@ -27898,19 +27711,17 @@ IndexGetKeyRequestOp::GetResponse(Reques
 }
 
 nsresult
 IndexCountRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
 
-  PROFILER_LABEL("IndexedDB",
-                 "IndexCountRequestOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("IndexCountRequestOp::DoDatabaseWork", STORAGE);
 
   const bool hasKeyRange =
     mParams.optionalKeyRange().type() == OptionalKeyRange::TSerializedKeyRange;
 
   nsCString indexTable;
   if (mMetadata->mCommonMetadata.unique()) {
     indexTable.AssignLiteral("unique_index_data ");
   }
@@ -28190,19 +28001,17 @@ OpenOp::DoObjectStoreDatabaseWork(Databa
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(mCursor);
   MOZ_ASSERT(mCursor->mType == OpenCursorParams::TObjectStoreOpenCursorParams);
   MOZ_ASSERT(mCursor->mObjectStoreId);
   MOZ_ASSERT(mCursor->mFileManager);
 
-  PROFILER_LABEL("IndexedDB",
-                 "Cursor::OpenOp::DoObjectStoreDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Cursor::OpenOp::DoObjectStoreDatabaseWork", STORAGE);
 
   const bool usingKeyRange =
     mOptionalKeyRange.type() == OptionalKeyRange::TSerializedKeyRange;
 
   NS_NAMED_LITERAL_CSTRING(keyString, "key");
   NS_NAMED_LITERAL_CSTRING(id, "id");
   NS_NAMED_LITERAL_CSTRING(openLimit, " LIMIT ");
 
@@ -28350,19 +28159,17 @@ OpenOp::DoObjectStoreKeyDatabaseWork(Dat
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(mCursor);
   MOZ_ASSERT(mCursor->mType ==
                OpenCursorParams::TObjectStoreOpenKeyCursorParams);
   MOZ_ASSERT(mCursor->mObjectStoreId);
 
-  PROFILER_LABEL("IndexedDB",
-                 "Cursor::OpenOp::DoObjectStoreKeyDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Cursor::OpenOp::DoObjectStoreKeyDatabaseWork", STORAGE);
 
   const bool usingKeyRange =
     mOptionalKeyRange.type() == OptionalKeyRange::TSerializedKeyRange;
 
   NS_NAMED_LITERAL_CSTRING(keyString, "key");
   NS_NAMED_LITERAL_CSTRING(id, "id");
   NS_NAMED_LITERAL_CSTRING(openLimit, " LIMIT ");
 
@@ -28508,19 +28315,17 @@ OpenOp::DoIndexDatabaseWork(DatabaseConn
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(mCursor);
   MOZ_ASSERT(mCursor->mType == OpenCursorParams::TIndexOpenCursorParams);
   MOZ_ASSERT(mCursor->mObjectStoreId);
   MOZ_ASSERT(mCursor->mIndexId);
 
-  PROFILER_LABEL("IndexedDB",
-                 "Cursor::OpenOp::DoIndexDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Cursor::OpenOp::DoIndexDatabaseWork", STORAGE);
 
   const bool usingKeyRange =
     mOptionalKeyRange.type() == OptionalKeyRange::TSerializedKeyRange;
 
   nsCString indexTable = mCursor->mUniqueIndex ?
     NS_LITERAL_CSTRING("unique_index_data") :
     NS_LITERAL_CSTRING("index_data");
 
@@ -28753,19 +28558,17 @@ OpenOp::DoIndexKeyDatabaseWork(DatabaseC
 {
   MOZ_ASSERT(aConnection);
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(mCursor);
   MOZ_ASSERT(mCursor->mType == OpenCursorParams::TIndexOpenKeyCursorParams);
   MOZ_ASSERT(mCursor->mObjectStoreId);
   MOZ_ASSERT(mCursor->mIndexId);
 
-  PROFILER_LABEL("IndexedDB",
-                 "Cursor::OpenOp::DoIndexKeyDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Cursor::OpenOp::DoIndexKeyDatabaseWork", STORAGE);
 
   const bool usingKeyRange =
     mOptionalKeyRange.type() == OptionalKeyRange::TSerializedKeyRange;
 
   nsCString table = mCursor->mUniqueIndex ?
     NS_LITERAL_CSTRING("unique_index_data") :
     NS_LITERAL_CSTRING("index_data");
 
@@ -28991,19 +28794,17 @@ OpenOp::DoDatabaseWork(DatabaseConnectio
   aConnection->AssertIsOnConnectionThread();
   MOZ_ASSERT(mCursor);
   MOZ_ASSERT(mCursor->mContinueQuery.IsEmpty());
   MOZ_ASSERT(mCursor->mContinueToQuery.IsEmpty());
   MOZ_ASSERT(mCursor->mContinuePrimaryKeyQuery.IsEmpty());
   MOZ_ASSERT(mCursor->mKey.IsUnset());
   MOZ_ASSERT(mCursor->mRangeKey.IsUnset());
 
-  PROFILER_LABEL("IndexedDB",
-                 "Cursor::OpenOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Cursor::OpenOp::DoDatabaseWork", STORAGE);
 
   nsresult rv;
 
   switch (mCursor->mType) {
     case OpenCursorParams::TObjectStoreOpenCursorParams:
       rv = DoObjectStoreDatabaseWork(aConnection);
       break;
 
@@ -29077,19 +28878,17 @@ ContinueOp::DoDatabaseWork(DatabaseConne
 
   MOZ_ASSERT_IF(isIndex &&
                 (mCursor->mDirection == IDBCursor::NEXT ||
                  mCursor->mDirection == IDBCursor::PREV),
                 !mCursor->mContinuePrimaryKeyQuery.IsEmpty());
   MOZ_ASSERT_IF(isIndex, mCursor->mIndexId);
   MOZ_ASSERT_IF(isIndex, !mCursor->mObjectKey.IsUnset());
 
-  PROFILER_LABEL("IndexedDB",
-                 "Cursor::ContinueOp::DoDatabaseWork",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Cursor::ContinueOp::DoDatabaseWork", STORAGE);
 
   // We need to pick a query based on whether or not a key was passed to the
   // continue function. If not we'll grab the the next item in the database that
   // is greater than (or less than, if we're running a PREV cursor) the current
   // key. If a key was passed we'll grab the next item in the database that is
   // greater than (or less than, if we're running a PREV cursor) or equal to the
   // key that was specified.
 
@@ -29866,19 +29665,17 @@ FileHelper::SyncCopy(nsIInputStream* aIn
                      nsIOutputStream* aOutputStream,
                      char* aBuffer,
                      uint32_t aBufferSize)
 {
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aInputStream);
   MOZ_ASSERT(aOutputStream);
 
-  PROFILER_LABEL("IndexedDB",
-                 "FileHelper::SyncCopy",
-                 js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("FileHelper::SyncCopy", STORAGE);
 
   nsresult rv;
 
   do {
     uint32_t numRead;
     rv = SyncRead(aInputStream, aBuffer, aBufferSize, &numRead);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       break;
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2316,19 +2316,18 @@ ContentChild::RecvLoadProcessScript(cons
 
 mozilla::ipc::IPCResult
 ContentChild::RecvAsyncMessage(const nsString& aMsg,
                                InfallibleTArray<CpowEntry>&& aCpows,
                                const IPC::Principal& aPrincipal,
                                const ClonedMessageData& aData)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
-  PROFILER_LABEL_DYNAMIC("ContentChild", "RecvAsyncMessage",
-                        js::ProfileEntry::Category::EVENTS,
-                        messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("ContentChild::RecvAsyncMessage", EVENTS,
+                              messageNameCStr.get());
 
   CrossProcessCpowHolder cpows(this, aCpows);
   RefPtr<nsFrameMessageManager> cpm =
     nsFrameMessageManager::GetChildProcessManager();
   if (cpm) {
     StructuredCloneData data;
     ipc::UnpackClonedMessageDataForChild(aData, data);
     cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1174,17 +1174,17 @@ ContentParent::RecvGetBlocklistState(con
 
 /*static*/ TabParent*
 ContentParent::CreateBrowser(const TabContext& aContext,
                              Element* aFrameElement,
                              ContentParent* aOpenerContentParent,
                              TabParent* aSameTabGroupAs,
                              uint64_t aNextTabParentId)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER);
 
   if (!sCanLaunchSubprocesses) {
     return nullptr;
   }
 
   if (aNextTabParentId) {
     if (TabParent* parent =
           sNextTabParents.GetAndRemove(aNextTabParentId).valueOr(nullptr)) {
@@ -2037,17 +2037,17 @@ ContentParent::GetTestShellSingleton()
 {
   PTestShellParent* p = LoneManagedOrNullAsserts(ManagedPTestShellParent());
   return static_cast<TestShellParent*>(p);
 }
 
 bool
 ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("ContentParent::LaunchSubprocess", OTHER);
 
   std::vector<std::string> extraArgs;
   extraArgs.push_back("-childID");
   char idStr[21];
   SprintfLiteral(idStr, "%" PRId64, static_cast<uint64_t>(mChildID));
   extraArgs.push_back(idStr);
   extraArgs.push_back(IsForBrowser() ? "-isForBrowser" : "-notForBrowser");
 
@@ -2941,17 +2941,17 @@ ContentParent::ForceKillTimerCallback(ns
   self->KillHard("ShutDownKill");
 }
 
 // WARNING: aReason appears in telemetry, so any new value passed in requires
 // data review.
 void
 ContentParent::KillHard(const char* aReason)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("ContentParent::KillHard", OTHER);
 
   // On Windows, calling KillHard multiple times causes problems - the
   // process handle becomes invalid on the first call, causing a second call
   // to crash our process - more details in bug 890840.
   if (mCalledKillHard) {
     return;
   }
   mCalledKillHard = true;
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2136,19 +2136,18 @@ TabChild::RecvLoadRemoteScript(const nsS
 
 mozilla::ipc::IPCResult
 TabChild::RecvAsyncMessage(const nsString& aMessage,
                            InfallibleTArray<CpowEntry>&& aCpows,
                            const IPC::Principal& aPrincipal,
                            const ClonedMessageData& aData)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMessage);
-  PROFILER_LABEL_DYNAMIC("TabChild", "RecvAsyncMessage",
-                         js::ProfileEntry::Category::EVENTS,
-                         messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("TabChild::RecvAsyncMessage", EVENTS,
+                              messageNameCStr.get());
 
   CrossProcessCpowHolder cpows(Manager(), aCpows);
   if (!mTabChildGlobal) {
     return IPC_OK();
   }
 
   // We should have a message manager if the global is alive, but it
   // seems sometimes we don't.  Assert in aurora/nightly, but don't
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -1496,19 +1496,18 @@ TabParent::SendHandleTap(TapType aType,
 mozilla::ipc::IPCResult
 TabParent::RecvSyncMessage(const nsString& aMessage,
                            const ClonedMessageData& aData,
                            InfallibleTArray<CpowEntry>&& aCpows,
                            const IPC::Principal& aPrincipal,
                            nsTArray<StructuredCloneData>* aRetVal)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMessage);
-  PROFILER_LABEL_DYNAMIC("TabParent", "RecvSyncMessage",
-                         js::ProfileEntry::Category::EVENTS,
-                         messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("TabParent::RecvSyncMessage", EVENTS,
+                              messageNameCStr.get());
 
   StructuredCloneData data;
   ipc::UnpackClonedMessageDataForParent(aData, data);
 
   CrossProcessCpowHolder cpows(Manager(), aCpows);
   if (!ReceiveMessage(aMessage, true, &data, &cpows, aPrincipal, aRetVal)) {
     return IPC_FAIL_NO_REASON(this);
   }
@@ -1518,19 +1517,18 @@ TabParent::RecvSyncMessage(const nsStrin
 mozilla::ipc::IPCResult
 TabParent::RecvRpcMessage(const nsString& aMessage,
                           const ClonedMessageData& aData,
                           InfallibleTArray<CpowEntry>&& aCpows,
                           const IPC::Principal& aPrincipal,
                           nsTArray<StructuredCloneData>* aRetVal)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMessage);
-  PROFILER_LABEL_DYNAMIC("TabParent", "RecvRpcMessage",
-                         js::ProfileEntry::Category::EVENTS,
-                         messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("TabParent::RecvRpcMessage", EVENTS,
+                              messageNameCStr.get());
 
   StructuredCloneData data;
   ipc::UnpackClonedMessageDataForParent(aData, data);
 
   CrossProcessCpowHolder cpows(Manager(), aCpows);
   if (!ReceiveMessage(aMessage, true, &data, &cpows, aPrincipal, aRetVal)) {
     return IPC_FAIL_NO_REASON(this);
   }
@@ -1539,19 +1537,18 @@ TabParent::RecvRpcMessage(const nsString
 
 mozilla::ipc::IPCResult
 TabParent::RecvAsyncMessage(const nsString& aMessage,
                             InfallibleTArray<CpowEntry>&& aCpows,
                             const IPC::Principal& aPrincipal,
                             const ClonedMessageData& aData)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMessage);
-  PROFILER_LABEL_DYNAMIC("TabParent", "RecvAsyncMessage",
-                         js::ProfileEntry::Category::EVENTS,
-                         messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("TabParent::RecvAsyncMessage", EVENTS,
+                              messageNameCStr.get());
 
   StructuredCloneData data;
   ipc::UnpackClonedMessageDataForParent(aData, data);
 
   CrossProcessCpowHolder cpows(Manager(), aCpows);
   if (!ReceiveMessage(aMessage, false, &data, &cpows, aPrincipal, nullptr)) {
     return IPC_FAIL_NO_REASON(this);
   }
--- a/dom/ipc/nsIContentChild.cpp
+++ b/dom/ipc/nsIContentChild.cpp
@@ -167,19 +167,18 @@ nsIContentChild::DeallocPFileDescriptorS
 
 mozilla::ipc::IPCResult
 nsIContentChild::RecvAsyncMessage(const nsString& aMsg,
                                   InfallibleTArray<CpowEntry>&& aCpows,
                                   const IPC::Principal& aPrincipal,
                                   const ClonedMessageData& aData)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
-  PROFILER_LABEL_DYNAMIC("nsIContentChild", "RecvAsyncMessage",
-                         js::ProfileEntry::Category::EVENTS,
-                         messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("nsIContentChild::RecvAsyncMessage", EVENTS,
+                              messageNameCStr.get());
 
   CrossProcessCpowHolder cpows(this, aCpows);
   RefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::GetChildProcessManager();
   if (cpm) {
     ipc::StructuredCloneData data;
     ipc::UnpackClonedMessageDataForChild(aData, data);
 
     cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()), nullptr,
--- a/dom/ipc/nsIContentParent.cpp
+++ b/dom/ipc/nsIContentParent.cpp
@@ -224,19 +224,18 @@ nsIContentParent::DeallocPIPCBlobInputSt
 mozilla::ipc::IPCResult
 nsIContentParent::RecvSyncMessage(const nsString& aMsg,
                                   const ClonedMessageData& aData,
                                   InfallibleTArray<CpowEntry>&& aCpows,
                                   const IPC::Principal& aPrincipal,
                                   nsTArray<ipc::StructuredCloneData>* aRetvals)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
-  PROFILER_LABEL_DYNAMIC("nsIContentParent", "RecvSyncMessage",
-                         js::ProfileEntry::Category::EVENTS,
-                         messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("nsIContentParent::RecvSyncMessage", EVENTS,
+                              messageNameCStr.get());
 
   CrossProcessCpowHolder cpows(this, aCpows);
   RefPtr<nsFrameMessageManager> ppm = mMessageManager;
   if (ppm) {
     ipc::StructuredCloneData data;
     ipc::UnpackClonedMessageDataForParent(aData, data);
 
     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
@@ -248,19 +247,18 @@ nsIContentParent::RecvSyncMessage(const 
 mozilla::ipc::IPCResult
 nsIContentParent::RecvRpcMessage(const nsString& aMsg,
                                  const ClonedMessageData& aData,
                                  InfallibleTArray<CpowEntry>&& aCpows,
                                  const IPC::Principal& aPrincipal,
                                  nsTArray<ipc::StructuredCloneData>* aRetvals)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
-  PROFILER_LABEL_DYNAMIC("nsIContentParent", "RecvRpcMessage",
-                         js::ProfileEntry::Category::EVENTS,
-                         messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("nsIContentParent::RecvRpcMessage", EVENTS,
+                              messageNameCStr.get());
 
   CrossProcessCpowHolder cpows(this, aCpows);
   RefPtr<nsFrameMessageManager> ppm = mMessageManager;
   if (ppm) {
     ipc::StructuredCloneData data;
     ipc::UnpackClonedMessageDataForParent(aData, data);
 
     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
@@ -310,19 +308,18 @@ nsIContentParent::DeallocPParentToChildS
 
 mozilla::ipc::IPCResult
 nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
                                    InfallibleTArray<CpowEntry>&& aCpows,
                                    const IPC::Principal& aPrincipal,
                                    const ClonedMessageData& aData)
 {
   NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
-  PROFILER_LABEL_DYNAMIC("nsIContentParent", "RecvAsyncMessage",
-                          js::ProfileEntry::Category::EVENTS,
-                          messageNameCStr.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("nsIContentParent::RecvAsyncMessage", EVENTS,
+                              messageNameCStr.get());
 
   CrossProcessCpowHolder cpows(this, aCpows);
   RefPtr<nsFrameMessageManager> ppm = mMessageManager;
   if (ppm) {
     ipc::StructuredCloneData data;
     ipc::UnpackClonedMessageDataForParent(aData, data);
 
     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
--- a/dom/media/MediaRecorder.cpp
+++ b/dom/media/MediaRecorder.cpp
@@ -607,18 +607,17 @@ private:
   // Destroy this session object in the end of this function.
   // If the bool aForceFlush is true, we will force to dispatch a
   // PushBlobRunnable to main thread.
   void Extract(bool aForceFlush)
   {
     MOZ_ASSERT(mReadThread->EventTarget()->IsOnCurrentThread());
     LOG(LogLevel::Debug, ("Session.Extract %p", this));
 
-    PROFILER_LABEL("MediaRecorder", "Session Extract",
-      js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("MediaRecorder::Session::Extract", OTHER);
 
     // Pull encoded media data from MediaEncoder
     nsTArray<nsTArray<uint8_t> > encodedBuf;
     mEncoder->GetEncodedData(&encodedBuf, mMimeType);
 
     // Append pulled data into cache buffer.
     for (uint32_t i = 0; i < encodedBuf.Length(); i++) {
       if (!encodedBuf[i].IsEmpty()) {
--- a/dom/media/encoder/MediaEncoder.cpp
+++ b/dom/media/encoder/MediaEncoder.cpp
@@ -150,18 +150,17 @@ MediaEncoder::NotifyEvent(MediaStreamGra
 
 /* static */
 already_AddRefed<MediaEncoder>
 MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint32_t aAudioBitrate,
                             uint32_t aVideoBitrate, uint32_t aBitrate,
                             uint8_t aTrackTypes,
                             TrackRate aTrackRate)
 {
-  PROFILER_LABEL("MediaEncoder", "CreateEncoder",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("MediaEncoder::CreateEncoder", OTHER);
 
   nsAutoPtr<ContainerWriter> writer;
   nsAutoPtr<AudioTrackEncoder> audioEncoder;
   nsAutoPtr<VideoTrackEncoder> videoEncoder;
   RefPtr<MediaEncoder> encoder;
   nsString mimeType;
   if (!aTrackTypes) {
     LOG(LogLevel::Error, ("NO TrackTypes!!!"));
@@ -237,18 +236,17 @@ MediaEncoder::CreateEncoder(const nsAStr
  */
 void
 MediaEncoder::GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
                              nsAString& aMIMEType)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   aMIMEType = mMIMEType;
-  PROFILER_LABEL("MediaEncoder", "GetEncodedData",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("MediaEncoder::GetEncodedData", OTHER);
 
   bool reloop = true;
   while (reloop) {
     switch (mState) {
     case ENCODE_METADDATA: {
       LOG(LogLevel::Debug, ("ENCODE_METADDATA TimeStamp = %f", GetEncodeTimeStamp()));
       nsresult rv = CopyMetadataToMuxer(mAudioEncoder.get());
       if (NS_FAILED(rv)) {
@@ -332,18 +330,17 @@ MediaEncoder::WriteEncodedDataToMuxer(Tr
 {
   if (aTrackEncoder == nullptr) {
     return NS_OK;
   }
   if (aTrackEncoder->IsEncodingComplete()) {
     return NS_OK;
   }
 
-  PROFILER_LABEL("MediaEncoder", "WriteEncodedDataToMuxer",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("MediaEncoder::WriteEncodedDataToMuxer", OTHER);
 
   EncodedFrameContainer encodedVideoData;
   nsresult rv = aTrackEncoder->GetEncodedTrack(encodedVideoData);
   if (NS_FAILED(rv)) {
     // Encoding might be canceled.
     LOG(LogLevel::Error, ("Error! Fail to get encoded data from video encoder."));
     mState = ENCODE_ERROR;
     return rv;
@@ -383,18 +380,17 @@ MediaEncoder::WriteEncodedDataToMuxer(Tr
 
 nsresult
 MediaEncoder::CopyMetadataToMuxer(TrackEncoder *aTrackEncoder)
 {
   if (aTrackEncoder == nullptr) {
     return NS_OK;
   }
 
-  PROFILER_LABEL("MediaEncoder", "CopyMetadataToMuxer",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("MediaEncoder::CopyMetadataToMuxer", OTHER);
 
   RefPtr<TrackMetadataBase> meta = aTrackEncoder->GetMetadata();
   if (meta == nullptr) {
     LOG(LogLevel::Error, ("Error! metadata = null"));
     mState = ENCODE_ERROR;
     return NS_ERROR_ABORT;
   }
 
--- a/dom/media/encoder/OpusTrackEncoder.cpp
+++ b/dom/media/encoder/OpusTrackEncoder.cpp
@@ -211,18 +211,17 @@ int
 OpusTrackEncoder::GetPacketDuration()
 {
   return GetOutputSampleRate() * kFrameDurationMs / 1000;
 }
 
 already_AddRefed<TrackMetadataBase>
 OpusTrackEncoder::GetMetadata()
 {
-  PROFILER_LABEL("OpusTrackEncoder", "GetMetadata",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("OpusTrackEncoder::GetMetadata", OTHER);
   {
     // Wait if mEncoder is not initialized.
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     while (!mCanceled && !mInitialized) {
       mReentrantMonitor.Wait();
     }
   }
 
@@ -255,18 +254,17 @@ OpusTrackEncoder::GetMetadata()
                              &meta->mCommentHeader);
 
   return meta.forget();
 }
 
 nsresult
 OpusTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
 {
-  PROFILER_LABEL("OpusTrackEncoder", "GetEncodedTrack",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("OpusTrackEncoder::GetEncodedTrack", OTHER);
   {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     // Wait until initialized or cancelled.
     while (!mCanceled && !mInitialized) {
       mReentrantMonitor.Wait();
     }
     if (mCanceled || mEncodingComplete) {
       return NS_ERROR_FAILURE;
--- a/dom/media/encoder/VP8TrackEncoder.cpp
+++ b/dom/media/encoder/VP8TrackEncoder.cpp
@@ -215,18 +215,17 @@ VP8TrackEncoder::SetConfigurationValues(
   config.kf_max_dist = 60;
 
   return NS_OK;
 }
 
 already_AddRefed<TrackMetadataBase>
 VP8TrackEncoder::GetMetadata()
 {
-  PROFILER_LABEL("VP8TrackEncoder", "GetMetadata",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("VP8TrackEncoder::GetMetadata", OTHER);
   {
     // Wait if mEncoder is not initialized.
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     while (!mCanceled && !mInitialized) {
       mon.Wait();
     }
   }
 
@@ -598,18 +597,17 @@ VP8TrackEncoder::GetNextEncodeOperation(
  *      There is a heuristic: If the frame duration we have processed in
  *      mSourceSegment is 100ms, means that we can't spend more than 100ms to
  *      encode it.
  * 4. Remove the encoded chunks in mSourceSegment after for-loop.
  */
 nsresult
 VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
 {
-  PROFILER_LABEL("VP8TrackEncoder", "GetEncodedTrack",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("VP8TrackEncoder::GetEncodedTrack", OTHER);
   bool EOS;
   {
     // Move all the samples from mRawSegment to mSourceSegment. We only hold
     // the monitor in this block.
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     // Wait if mEncoder is not initialized, or when not enough raw data, but is
     // not the end of stream nor is being canceled.
     while (!mCanceled && (!mInitialized ||
--- a/dom/media/ogg/OggWriter.cpp
+++ b/dom/media/ogg/OggWriter.cpp
@@ -53,18 +53,17 @@ OggWriter::Init()
 
   return (rc == 0) ? NS_OK : NS_ERROR_NOT_INITIALIZED;
 }
 
 nsresult
 OggWriter::WriteEncodedTrack(const EncodedFrameContainer& aData,
                              uint32_t aFlags)
 {
-  PROFILER_LABEL("OggWriter", "WriteEncodedTrack",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("OggWriter::WriteEncodedTrack", OTHER);
 
   uint32_t len = aData.GetEncodedFrames().Length();
   for (uint32_t i = 0; i < len; i++) {
     if (aData.GetEncodedFrames()[i]->GetFrameType() != EncodedFrame::OPUS_AUDIO_FRAME) {
       LOG("[OggWriter] wrong encoded data type!");
       return NS_ERROR_FAILURE;
     }
 
@@ -135,18 +134,17 @@ OggWriter::ProduceOggPage(nsTArray<nsTAr
          mOggPage.body, mOggPage.body_len);
 }
 
 nsresult
 OggWriter::GetContainerData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
                             uint32_t aFlags)
 {
   int rc = -1;
-  PROFILER_LABEL("OggWriter", "GetContainerData",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("OggWriter::GetContainerData", OTHER);
   // Generate the oggOpus Header
   if (aFlags & ContainerWriter::GET_HEADER) {
     OpusMetadata* meta = static_cast<OpusMetadata*>(mMetadata.get());
     NS_ASSERTION(meta, "should have meta data");
     NS_ASSERTION(meta->GetKind() == TrackMetadataBase::METADATA_OPUS,
                  "should have Opus meta data");
 
     nsresult rv = WriteEncodedData(meta->mIdHeader, 0);
@@ -185,18 +183,17 @@ OggWriter::GetContainerData(nsTArray<nsT
   return (rc > 0) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
 OggWriter::SetMetadata(TrackMetadataBase* aMetadata)
 {
   MOZ_ASSERT(aMetadata);
 
-  PROFILER_LABEL("OggWriter", "SetMetadata",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("OggWriter::SetMetadata", OTHER);
 
   if (aMetadata->GetKind() != TrackMetadataBase::METADATA_OPUS) {
     LOG("wrong meta data type!");
     return NS_ERROR_FAILURE;
   }
   // Validate each field of METADATA
   mMetadata = static_cast<OpusMetadata*>(aMetadata);
   if (mMetadata->mIdHeader.Length() == 0) {
--- a/dom/media/webm/WebMWriter.cpp
+++ b/dom/media/webm/WebMWriter.cpp
@@ -20,43 +20,40 @@ WebMWriter::~WebMWriter()
 {
   // Out-of-line dtor so mEbmlComposer nsAutoPtr can delete a complete type.
 }
 
 nsresult
 WebMWriter::WriteEncodedTrack(const EncodedFrameContainer& aData,
                               uint32_t aFlags)
 {
-  PROFILER_LABEL("WebMWriter", "SetMetadata",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("WebMWriter::WriteEncodedTrack", OTHER);
   for (uint32_t i = 0 ; i < aData.GetEncodedFrames().Length(); i++) {
     mEbmlComposer->WriteSimpleBlock(aData.GetEncodedFrames().ElementAt(i).get());
   }
   return NS_OK;
 }
 
 nsresult
 WebMWriter::GetContainerData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
                              uint32_t aFlags)
 {
-  PROFILER_LABEL("WebMWriter", "GetContainerData",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("WebMWriter::GetContainerData", OTHER);
   mEbmlComposer->ExtractBuffer(aOutputBufs, aFlags);
   if (aFlags & ContainerWriter::FLUSH_NEEDED) {
     mIsWritingComplete = true;
   }
   return NS_OK;
 }
 
 nsresult
 WebMWriter::SetMetadata(TrackMetadataBase* aMetadata)
 {
   MOZ_ASSERT(aMetadata);
-  PROFILER_LABEL("WebMWriter", "SetMetadata",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("WebMWriter::SetMetadata", OTHER);
 
   if (aMetadata->GetKind() == TrackMetadataBase::METADATA_VP8) {
     VP8Metadata* meta = static_cast<VP8Metadata*>(aMetadata);
     MOZ_ASSERT(meta, "Cannot find vp8 encoder metadata");
     mEbmlComposer->SetVideoConfig(meta->mWidth, meta->mHeight,
                                   meta->mDisplayWidth, meta->mDisplayHeight);
     mMetadataRequiredFlag = mMetadataRequiredFlag & ~ContainerWriter::CREATE_VIDEO_TRACK;
   }
--- a/dom/media/webspeech/synth/windows/SapiService.cpp
+++ b/dom/media/webspeech/synth/windows/SapiService.cpp
@@ -195,17 +195,17 @@ SapiService::SapiService()
 
 SapiService::~SapiService()
 {
 }
 
 bool
 SapiService::Init()
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("SapiService::Init", OTHER);
 
   MOZ_ASSERT(!mInitialized);
 
   if (Preferences::GetBool("media.webspeech.synth.test") ||
       !Preferences::GetBool("media.webspeech.synth.enabled")) {
     // When enabled, we shouldn't add OS backend (Bug 1160844)
     return false;
   }
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -1652,17 +1652,17 @@ NPObjWrapper_NewEnumerate(JSContext *cx,
 
 static bool
 NPObjWrapper_Resolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
                      bool *resolvedp)
 {
   if (JSID_IS_SYMBOL(id))
     return true;
 
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::JS);
+  AUTO_PROFILER_LABEL("NPObjWrapper_Resolve", JS);
 
   NPObject *npobj = GetNPObject(cx, obj);
 
   if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
       !npobj->_class->hasMethod) {
     ThrowJSExceptionASCII(cx, "Bad NPObject as private data!");
 
     return false;
@@ -2137,17 +2137,17 @@ CreateNPObjectMember(NPP npp, JSContext 
 
   return true;
 }
 
 static bool
 NPObjectMember_GetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
                            JS::MutableHandleValue vp)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("NPObjectMember_GetProperty", OTHER);
 
   if (JSID_IS_SYMBOL(id)) {
     JS::RootedSymbol sym(cx, JSID_TO_SYMBOL(id));
     if (JS::GetSymbolCode(sym) == JS::SymbolCode::toPrimitive) {
       JS::RootedObject obj(cx, JS_GetFunctionObject(
                                  JS_NewFunction(
                                    cx, NPObjectMember_toPrimitive, 1, 0,
                                    "Symbol.toPrimitive")));
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -242,17 +242,17 @@ nsNPAPIPlugin::RunPluginOOP(const nsPlug
 #else
   return true;
 #endif
 }
 
 inline PluginLibrary*
 GetNewPluginLibrary(nsPluginTag *aPluginTag)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("GetNewPluginLibrary", OTHER);
 
   if (!aPluginTag) {
     return nullptr;
   }
 
   if (XRE_IsContentProcess()) {
     return PluginModuleContentParent::LoadModule(aPluginTag->mId, aPluginTag);
   }
@@ -262,17 +262,17 @@ GetNewPluginLibrary(nsPluginTag *aPlugin
   }
   return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
 }
 
 // Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
 nsresult
 nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsNPAPIPlugin::CreatePlugin", OTHER);
   *aResult = nullptr;
 
   if (!aPluginTag) {
     return NS_ERROR_FAILURE;
   }
 
   CheckClassInitialized();
 
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -220,17 +220,17 @@ nsNPAPIPluginInstance::Destroy()
 TimeStamp
 nsNPAPIPluginInstance::StopTime()
 {
   return mStopTime;
 }
 
 nsresult nsNPAPIPluginInstance::Initialize(nsNPAPIPlugin *aPlugin, nsPluginInstanceOwner* aOwner, const nsACString& aMIMEType)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsNPAPIPlugin::Initialize", OTHER);
   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Initialize this=%p\n",this));
 
   NS_ENSURE_ARG_POINTER(aPlugin);
   NS_ENSURE_ARG_POINTER(aOwner);
 
   mPlugin = aPlugin;
   mOwner = aOwner;
 
@@ -585,17 +585,17 @@ nsresult nsNPAPIPluginInstance::Print(NP
 }
 
 nsresult nsNPAPIPluginInstance::HandleEvent(void* event, int16_t* result,
                                             NSPluginCallReentry aSafeToReenterGecko)
 {
   if (RUNNING != mRunning)
     return NS_OK;
 
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsNPAPIPluginInstance::HandleEvent", OTHER);
 
   if (!event)
     return NS_ERROR_FAILURE;
 
   PluginDestructionGuard guard(this);
 
   if (!mPlugin || !mPlugin->GetLibrary())
     return NS_ERROR_FAILURE;
--- a/dom/plugins/base/nsNPAPIPluginStreamListener.cpp
+++ b/dom/plugins/base/nsNPAPIPluginStreamListener.cpp
@@ -281,17 +281,17 @@ nsNPAPIPluginStreamListener::CallURLNoti
                    ("NPP URLNotify called: this=%p, npp=%p, notify=%p, reason=%d, url=%s\n",
                     this, npp, mNPStreamWrapper->mNPStream.notifyData, reason, mNotifyURL));
   }
 }
 
 nsresult
 nsNPAPIPluginStreamListener::OnStartBinding(nsPluginStreamListenerPeer* streamPeer)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsNPAPIPluginStreamListener::OnStartBinding", OTHER);
   if (!mInst || !mInst->CanFireNotifications() || mStreamCleanedUp)
     return NS_ERROR_FAILURE;
 
   PluginDestructionGuard guard(mInst);
 
   nsNPAPIPlugin* plugin = mInst->GetPlugin();
   if (!plugin || !plugin->GetLibrary())
     return NS_ERROR_FAILURE;
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -1288,17 +1288,17 @@ nsresult nsPluginHost::EnsurePluginLoade
     aPluginTag->mPlugin = plugin;
   }
   return NS_OK;
 }
 
 nsresult
 nsPluginHost::GetPluginForContentProcess(uint32_t aPluginId, nsNPAPIPlugin** aPlugin)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsPluginHost::GetPluginForContentProcess", OTHER);
   MOZ_ASSERT(XRE_IsParentProcess());
 
   // If plugins haven't been scanned yet, do so now
   LoadPlugins();
 
   nsPluginTag* pluginTag = PluginWithId(aPluginId);
   if (pluginTag) {
     // When setting up a bridge, double check with chrome to see if this plugin
@@ -3394,17 +3394,17 @@ nsPluginHost::AddHeadersToChannel(const 
       return rv;
     }
   }
 }
 
 nsresult
 nsPluginHost::StopPluginInstance(nsNPAPIPluginInstance* aInstance)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsPluginHost::StopPluginInstance", OTHER);
   if (PluginDestructionGuard::DelayDestroy(aInstance)) {
     return NS_OK;
   }
 
   PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   ("nsPluginHost::StopPluginInstance called instance=%p\n",aInstance));
 
   if (aInstance->HasStartedDestroying()) {
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -3657,17 +3657,18 @@ nsPluginInstanceOwner::ResolutionMayHave
     mLastCSSZoomFactor = zoomFactor;
   }
 
 }
 
 void
 nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsPluginInstanceOwner::UpdateDocumentActiveState",
+                      OTHER);
 
   mPluginDocumentActiveState = aIsActive;
 #ifndef XP_MACOSX
   UpdateWindowPositionAndClipRect(true);
 
 #ifdef MOZ_WIDGET_ANDROID
   if (mInstance) {
     if (!mPluginDocumentActiveState) {
--- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp
+++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp
@@ -423,18 +423,17 @@ nsPluginStreamListenerPeer::SetupPluginC
   return rv;
 }
 
 NS_IMETHODIMP
 nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
                                            nsISupports* aContext)
 {
   nsresult rv = NS_OK;
-  PROFILER_LABEL("nsPluginStreamListenerPeer", "OnStartRequest",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsPluginStreamListenerPeer::OnStartRequest", OTHER);
 
   nsCOMPtr<nsIRequest> baseRequest = GetBaseRequest(request);
   if (mRequests.IndexOfObject(baseRequest) == -1) {
     NS_ASSERTION(mRequests.Count() == 0,
                  "Only our initial stream should be unknown!");
     TrackRequest(request);
   }
 
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -89,17 +89,17 @@ static const char kHangUIMinDisplayPref[
 bool
 mozilla::plugins::SetupBridge(uint32_t aPluginId,
                               dom::ContentParent* aContentParent,
                               bool aForceBridgeNow,
                               nsresult* rv,
                               uint32_t* runID,
                               ipc::Endpoint<PPluginModuleParent>* aEndpoint)
 {
-    PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("plugins::SetupBridge", OTHER);
     if (NS_WARN_IF(!rv) || NS_WARN_IF(!runID)) {
         return false;
     }
 
     PluginModuleChromeParent::ClearInstantiationFlag();
     RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
     RefPtr<nsNPAPIPlugin> plugin;
     *rv = host->GetPluginForContentProcess(aPluginId, getter_AddRefs(plugin));
@@ -1896,18 +1896,17 @@ PluginModuleParent::NPP_Destroy(NPP inst
     return retval;
 }
 
 NPError
 PluginModuleParent::NPP_NewStream(NPP instance, NPMIMEType type,
                                   NPStream* stream, NPBool seekable,
                                   uint16_t* stype)
 {
-    PROFILER_LABEL("PluginModuleParent", "NPP_NewStream",
-      js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("PluginModuleParent::NPP_NewStream", OTHER);
     RESOLVE_AND_CALL(instance, NPP_NewStream(type, stream, seekable, stype));
 }
 
 NPError
 PluginModuleParent::NPP_SetWindow(NPP instance, NPWindow* window)
 {
     RESOLVE_AND_CALL(instance, NPP_SetWindow(window));
 }
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -6164,18 +6164,17 @@ FinalizeOriginEvictionOp::Open()
   MOZ_CRASH("Shouldn't get here!");
 }
 
 nsresult
 FinalizeOriginEvictionOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
 
-  PROFILER_LABEL("Quota", "FinalizeOriginEvictionOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("FinalizeOriginEvictionOp::DoDirectoryWork", OTHER);
 
   for (RefPtr<DirectoryLockImpl>& lock : mLocks) {
     aQuotaManager->OriginClearCompleted(lock->GetPersistenceType().Value(),
                                         lock->GetOriginScope().GetOrigin());
   }
 
   return NS_OK;
 }
@@ -6255,18 +6254,17 @@ NormalOriginOperationBase::DirectoryLock
 
 nsresult
 SaveOriginAccessTimeOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(!mPersistenceType.IsNull());
   MOZ_ASSERT(mOriginScope.IsOrigin());
 
-  PROFILER_LABEL("Quota", "SaveOriginAccessTimeOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("SaveOriginAccessTimeOp::DoDirectoryWork", OTHER);
 
   nsCOMPtr<nsIFile> file;
   nsresult rv =
     aQuotaManager->GetDirectoryForOrigin(mPersistenceType.Value(),
                                          mOriginScope.GetOrigin(),
                                          getter_AddRefs(file));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -6865,18 +6863,17 @@ GetUsageOp::TraverseRepository(QuotaMana
   return NS_OK;
 }
 
 nsresult
 GetUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
 
-  PROFILER_LABEL("Quota", "GetUsageOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("GetUsageOp::DoDirectoryWork", OTHER);
 
   nsresult rv;
 
   for (const PersistenceType type : kAllPersistenceTypes) {
     rv = TraverseRepository(aQuotaManager, type);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
@@ -6953,18 +6950,17 @@ GetOriginUsageOp::DoInitOnMainThread()
 }
 
 nsresult
 GetOriginUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(mUsageInfo.TotalUsage() == 0);
 
-  PROFILER_LABEL("Quota", "GetOriginUsageOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("GetOriginUsageOp::DoDirectoryWork", OTHER);
 
   nsresult rv;
 
   if (mGetGroupUsage) {
     nsCOMPtr<nsIFile> directory;
 
     // Ensure origin is initialized first. It will initialize all origins for
     // temporary storage including origins belonging to our group.
@@ -7061,18 +7057,17 @@ QuotaRequestBase::ActorDestroy(ActorDest
   NoteActorDestroyed();
 }
 
 nsresult
 InitOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
 
-  PROFILER_LABEL("Quota", "InitOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("InitOp::DoDirectoryWork", OTHER);
 
   aQuotaManager->AssertStorageIsInitialized();
 
   return NS_OK;
 }
 
 void
 InitOp::GetResponse(RequestResponse& aResponse)
@@ -7140,18 +7135,17 @@ InitOriginOp::DoInitOnMainThread()
 }
 
 nsresult
 InitOriginOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(!mPersistenceType.IsNull());
 
-  PROFILER_LABEL("Quota", "InitOriginOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("InitOriginOp::DoDirectoryWork", OTHER);
 
   nsCOMPtr<nsIFile> directory;
   bool created;
   nsresult rv =
     aQuotaManager->EnsureOriginIsInitializedInternal(mPersistenceType.Value(),
                                                      mSuffix,
                                                      mGroup,
                                                      mOriginScope.GetOrigin(),
@@ -7230,18 +7224,17 @@ ResetOrClearOp::DeleteFiles(QuotaManager
   }
 }
 
 nsresult
 ResetOrClearOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
 
-  PROFILER_LABEL("Quota", "ResetOrClearOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("ResetOrClearOp::DoDirectoryWork", OTHER);
 
   if (mClear) {
     DeleteFiles(aQuotaManager);
   }
 
   aQuotaManager->RemoveQuota();
 
   aQuotaManager->ResetOrClearCompleted();
@@ -7376,18 +7369,17 @@ ClearRequestBase::DeleteFiles(QuotaManag
 
 }
 
 nsresult
 ClearRequestBase::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
 
-  PROFILER_LABEL("Quota", "OriginClearOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("ClearRequestBase::DoDirectoryWork", OTHER);
 
   if (mPersistenceType.IsNull()) {
     for (const PersistenceType type : kAllPersistenceTypes) {
       DeleteFiles(aQuotaManager, type);
     }
   } else {
     DeleteFiles(aQuotaManager, mPersistenceType.Value());
   }
@@ -7567,18 +7559,17 @@ PersistedOp::PersistedOp(const RequestPa
 nsresult
 PersistedOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(!mPersistenceType.IsNull());
   MOZ_ASSERT(mPersistenceType.Value() == PERSISTENCE_TYPE_DEFAULT);
   MOZ_ASSERT(mOriginScope.IsOrigin());
 
-  PROFILER_LABEL("Quota", "PersistedOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("PersistedOp::DoDirectoryWork", OTHER);
 
   Nullable<bool> persisted =
     aQuotaManager->OriginPersisted(mGroup, mOriginScope.GetOrigin());
 
   if (!persisted.IsNull()) {
     mPersisted = persisted.Value();
     return NS_OK;
   }
@@ -7641,18 +7632,17 @@ PersistOp::PersistOp(const RequestParams
 nsresult
 PersistOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(!mPersistenceType.IsNull());
   MOZ_ASSERT(mPersistenceType.Value() == PERSISTENCE_TYPE_DEFAULT);
   MOZ_ASSERT(mOriginScope.IsOrigin());
 
-  PROFILER_LABEL("Quota", "PersistOp::DoDirectoryWork",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("PersistOp::DoDirectoryWork", OTHER);
 
   // Update directory metadata on disk first.
   nsCOMPtr<nsIFile> directory;
   nsresult rv = aQuotaManager->GetDirectoryForOrigin(mPersistenceType.Value(),
                                                      mOriginScope.GetOrigin(),
                                                      getter_AddRefs(directory));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
--- a/dom/storage/StorageDBThread.cpp
+++ b/dom/storage/StorageDBThread.cpp
@@ -183,17 +183,17 @@ StorageDBThread::Shutdown()
   mThread = nullptr;
 
   return mStatus;
 }
 
 void
 StorageDBThread::SyncPreload(LocalStorageCacheBridge* aCache, bool aForceSync)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("StorageDBThread::SyncPreload", STORAGE);
   if (!aForceSync && aCache->LoadedCount()) {
     // Preload already started for this cache, just wait for it to finish.
     // LoadWait will exit after LoadDone on the cache has been called.
     SetHigherPriority();
     aCache->LoadWait();
     SetDefaultPriority();
     return;
   }
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -1945,18 +1945,17 @@ XMLHttpRequestMainThread::OnDataAvailabl
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 XMLHttpRequestMainThread::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
 {
-  PROFILER_LABEL("XMLHttpRequestMainThread", "OnStartRequest",
-    js::ProfileEntry::Category::NETWORK);
+  AUTO_PROFILER_LABEL("XMLHttpRequestMainThread::OnStartRequest", NETWORK);
 
   nsresult rv = NS_OK;
   if (!mFirstStartRequestSeen && mRequestObserver) {
     mFirstStartRequestSeen = true;
     mRequestObserver->OnStartRequest(request, ctxt);
   }
 
   if (request != mChannel) {
@@ -2221,18 +2220,17 @@ XMLHttpRequestMainThread::OnStartRequest
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 XMLHttpRequestMainThread::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status)
 {
-  PROFILER_LABEL("XMLHttpRequestMainThread", "OnStopRequest",
-    js::ProfileEntry::Category::NETWORK);
+  AUTO_PROFILER_LABEL("XMLHttpRequestMainThread::OnStopRequest", NETWORK);
 
   if (request != mChannel) {
     // Can this still happen?
     return NS_OK;
   }
 
   mWaitingForOnStopRequest = false;
 
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -720,18 +720,17 @@ private:
         return tip;
     }
 
     static void AssertNotPassingStackBufferToTheGL(const void* ptr);
 
 #ifdef MOZ_WIDGET_ANDROID
 // Record the name of the GL call for better hang stacks on Android.
 #define BEFORE_GL_CALL                              \
-            PROFILER_LABEL_FUNC(                    \
-              js::ProfileEntry::Category::GRAPHICS);\
+            AUTO_PROFILER_LABEL(__func__, GRAPHICS);\
             BeforeGLCall(MOZ_FUNCTION_NAME)
 #else
 #define BEFORE_GL_CALL                              \
             do {                                    \
                 BeforeGLCall(MOZ_FUNCTION_NAME);    \
             } while (0)
 #endif
 
@@ -746,17 +745,17 @@ private:
             } while (0)
 
 #define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) AssertNotPassingStackBufferToTheGL(ptr)
 
 #else // ifdef MOZ_GL_DEBUG
 
 #ifdef MOZ_WIDGET_ANDROID
 // Record the name of the GL call for better hang stacks on Android.
-#define BEFORE_GL_CALL PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS)
+#define BEFORE_GL_CALL AUTO_PROFILER_LABEL(__func__, GRAPHICS)
 #else
 #define BEFORE_GL_CALL do { } while (0)
 #endif
 #define AFTER_GL_CALL do { } while (0)
 #define TRACKING_CONTEXT(a) do {} while (0)
 #define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) do {} while (0)
 
 #endif // ifdef MOZ_GL_DEBUG
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -152,18 +152,17 @@ bool
 GLContextCGL::IsDoubleBuffered() const
 {
   return sCGLLibrary.UseDoubleBufferedWindows();
 }
 
 bool
 GLContextCGL::SwapBuffers()
 {
-  PROFILER_LABEL("GLContextCGL", "SwapBuffers",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("GLContextCGL::SwapBuffers", GRAPHICS);
 
   [mContext flushBuffer];
   return true;
 }
 
 void
 GLContextCGL::GetWSIInfo(nsCString* const out) const
 {
--- a/gfx/gl/GLContextProviderEAGL.mm
+++ b/gfx/gl/GLContextProviderEAGL.mm
@@ -142,18 +142,17 @@ bool
 GLContextEAGL::IsDoubleBuffered() const
 {
     return true;
 }
 
 bool
 GLContextEAGL::SwapBuffers()
 {
-  PROFILER_LABEL("GLContextEAGL", "SwapBuffers",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("GLContextEAGL::SwapBuffers", GRAPHICS);
 
   [mContext presentRenderbuffer:LOCAL_GL_RENDERBUFFER];
   return true;
 }
 
 void
 GLContextEAGL::GetWSIInfo(nsCString* const out) const
 {
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -129,17 +129,17 @@ protected:
 public:
     GLLibraryLoader::PlatformLookupFunction GetLookupFunction() const {
         return (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;
     }
 
     ////
 
 #ifdef MOZ_WIDGET_ANDROID
-#define PROFILE_CALL PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
+#define PROFILE_CALL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
 #else
 #define PROFILE_CALL
 #endif
 
 #ifndef MOZ_FUNCTION_NAME
 # ifdef __GNUC__
 #  define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
 # elif defined(_MSC_VER)
--- a/gfx/layers/D3D9SurfaceImage.cpp
+++ b/gfx/layers/D3D9SurfaceImage.cpp
@@ -32,17 +32,17 @@ DXGID3D9TextureData::~DXGID3D9TextureDat
 }
 
 // static
 DXGID3D9TextureData*
 DXGID3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                             TextureFlags aFlags,
                             IDirect3DDevice9* aDevice)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("DXGID3D9TextureData::Create", GRAPHICS);
   MOZ_ASSERT(aFormat == gfx::SurfaceFormat::B8G8R8A8);
   if (aFormat != gfx::SurfaceFormat::B8G8R8A8) {
     return nullptr;
   }
 
   RefPtr<IDirect3DTexture9> texture;
   HANDLE shareHandle = nullptr;
   HRESULT hr = aDevice->CreateTexture(aSize.width, aSize.height,
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RotatedBuffer.h"
 #include <sys/types.h>                  // for int32_t
 #include <algorithm>                    // for max
 #include "BasicImplData.h"              // for BasicImplData
 #include "BasicLayersImpl.h"            // for ToData
 #include "BufferUnrotate.h"             // for BufferUnrotate
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
+#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
 #include "Layers.h"                     // for PaintedLayer, Layer, etc
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPrefs.h"                   // for gfxPrefs
 #include "gfxUtils.h"                   // for gfxUtils
 #include "mozilla/ArrayUtils.h"         // for ArrayLength
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/BaseRect.h"       // for BaseRect
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
@@ -165,18 +165,17 @@ RotatedBuffer::DrawBufferQuadrant(gfx::D
 
 void
 RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource,
                                       float aOpacity,
                                       gfx::CompositionOp aOperator,
                                       gfx::SourceSurface* aMask,
                                       const gfx::Matrix* aMaskTransform) const
 {
-  PROFILER_LABEL("RotatedBuffer", "DrawBufferWithRotation",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("RotatedBuffer::DrawBufferWithRotation", GRAPHICS);
 
   // See above, in Azure Repeat should always be a safe, even faster choice
   // though! Particularly on D2D Repeat should be a lot faster, need to look
   // into that. TODO[Bas]
   DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aOperator, aMask, aMaskTransform);
   DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aOperator, aMask, aMaskTransform);
   DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aOperator, aMask, aMaskTransform);
   DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aOperator,aMask, aMaskTransform);
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stdint.h>                     // for uint32_t
 #include <stdlib.h>                     // for rand, RAND_MAX
 #include <sys/types.h>                  // for int32_t
 #include <stack>                        // for stack
 #include "BasicContainerLayer.h"        // for BasicContainerLayer
 #include "BasicLayersImpl.h"            // for ToData, BasicReadbackLayer, etc
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
+#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
 #include "ImageContainer.h"             // for ImageFactory
 #include "Layers.h"                     // for Layer, ContainerLayer, etc
 #include "ReadbackLayer.h"              // for ReadbackLayer
 #include "ReadbackProcessor.h"          // for ReadbackProcessor
 #include "RenderTrace.h"                // for RenderTraceLayers, etc
 #include "basic/BasicImplData.h"        // for BasicImplData
 #include "basic/BasicLayers.h"          // for BasicLayerManager, etc
 #include "gfxASurface.h"                // for gfxASurface, etc
@@ -557,18 +557,17 @@ BasicLayerManager::AbortTransaction()
   mInTransaction = false;
 }
 
 bool
 BasicLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
                                           void* aCallbackData,
                                           EndTransactionFlags aFlags)
 {
-  PROFILER_LABEL("BasicLayerManager", "EndTransactionInternal",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("BasicLayerManager::EndTransactionInternal", GRAPHICS);
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   MOZ_LAYERS_LOG(("  ----- (beginning paint)"));
   Log();
 #endif
 
   NS_ASSERTION(InConstruction(), "Should be in construction phase");
   mPhase = PHASE_DRAWING;
@@ -809,18 +808,17 @@ InstallLayerClipPreserves3D(gfxContext* 
 void
 BasicLayerManager::PaintLayer(gfxContext* aTarget,
                               Layer* aLayer,
                               DrawPaintedLayerCallback aCallback,
                               void* aCallbackData)
 {
   MOZ_ASSERT(aTarget);
 
-  PROFILER_LABEL("BasicLayerManager", "PaintLayer",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("BasicLayerManager::PaintLayer", GRAPHICS);
 
   PaintLayerContext paintLayerContext(aTarget, aLayer,
                                       aCallback, aCallbackData);
 
   // Don't attempt to paint layers with a singular transform, cairo will
   // just throw an error.
   if (aLayer->GetEffectiveTransform().IsSingular()) {
     return;
--- a/gfx/layers/basic/BasicPaintedLayer.cpp
+++ b/gfx/layers/basic/BasicPaintedLayer.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BasicPaintedLayer.h"
 #include <stdint.h>                     // for uint32_t
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
+#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
 #include "ReadbackLayer.h"              // for ReadbackLayer, ReadbackSink
 #include "ReadbackProcessor.h"          // for ReadbackProcessor::Update, etc
 #include "RenderTrace.h"                // for RenderTraceInvalidateEnd, etc
 #include "BasicLayersImpl.h"            // for AutoMaskData, etc
 #include "gfxContext.h"                 // for gfxContext, etc
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxUtils.h"                   // for gfxUtils
 #include "mozilla/gfx/2D.h"             // for DrawTarget
@@ -43,18 +43,17 @@ IntersectWithClip(const nsIntRegion& aRe
 }
 
 void
 BasicPaintedLayer::PaintThebes(gfxContext* aContext,
                               Layer* aMaskLayer,
                               LayerManager::DrawPaintedLayerCallback aCallback,
                               void* aCallbackData)
 {
-  PROFILER_LABEL("BasicPaintedLayer", "PaintThebes",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("BasicPaintedLayer::PaintThebes", GRAPHICS);
 
   NS_ASSERTION(BasicManager()->InDrawing(),
                "Can only draw in drawing phase");
 
   float opacity = GetEffectiveOpacity();
   CompositionOp effectiveOperator = GetEffectiveOperator(this);
 
   if (!BasicManager()->IsRetained()) {
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -1,31 +1,30 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ClientCanvasLayer.h"
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
+#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
 #include "ClientLayerManager.h"         // for ClientLayerManager, etc
 #include "nsCOMPtr.h"                   // for already_AddRefed
 
 namespace mozilla {
 namespace layers {
 
 ClientCanvasLayer::~ClientCanvasLayer()
 {
   MOZ_COUNT_DTOR(ClientCanvasLayer);
 }
 
 void
 ClientCanvasLayer::RenderLayer()
 {
-  PROFILER_LABEL("ClientCanvasLayer", "RenderLayer",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ClientCanvasLayer::RenderLayer", GRAPHICS);
 
   RenderMaskLayers(this);
 
   UpdateCompositableClient();
   ClientManager()->Hold(this);
 }
 
 already_AddRefed<CanvasLayer>
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ClientLayerManager.h"
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
+#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
 #include "gfxPrefs.h"                   // for gfxPrefs::LayersTile...
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Hal.h"
 #include "mozilla/dom/ScreenOrientation.h"  // for ScreenOrientation
 #include "mozilla/dom/TabChild.h"       // for TabChild
 #include "mozilla/dom/TabGroup.h"       // for TabGroup
 #include "mozilla/hal_sandbox/PHal.h"   // for ScreenConfiguration
 #include "mozilla/layers/CompositableClient.h"
@@ -336,18 +336,17 @@ ClientLayerManager::EndTransactionIntern
 #ifdef WIN32
   if (aCallbackData) {
     // Content processes don't get OnPaint called. So update here whenever we
     // may do Thebes drawing.
     gfxDWriteFont::UpdateClearTypeUsage();
   }
 #endif
 
-  PROFILER_LABEL("ClientLayerManager", "EndTransactionInternal",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ClientLayerManager::EndTransactionInternal", GRAPHICS);
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   MOZ_LAYERS_LOG(("  ----- (beginning paint)"));
   Log();
 #endif
 
   NS_ASSERTION(InConstruction(), "Should be in construction phase");
   mPhase = PHASE_DRAWING;
--- a/gfx/layers/client/ClientPaintedLayer.cpp
+++ b/gfx/layers/client/ClientPaintedLayer.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ClientPaintedLayer.h"
 #include "ClientTiledPaintedLayer.h"     // for ClientTiledPaintedLayer
 #include <stdint.h>                     // for uint32_t
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
+#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
 #include "client/ClientLayerManager.h"  // for ClientLayerManager, etc
 #include "gfxContext.h"                 // for gfxContext
 #include "gfx2DGlue.h"
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxPrefs.h"                   // for gfxPrefs
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/DrawEventRecorder.h"
@@ -172,18 +172,17 @@ ClientPaintedLayer::GetPaintFlags()
    }
   #endif
   return flags;
 }
 
 void
 ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates)
 {
-  PROFILER_LABEL("ClientPaintedLayer", "PaintThebes",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ClientPaintedLayer::PaintThebes", GRAPHICS);
 
   NS_ASSERTION(ClientManager()->InDrawing(),
                "Can only draw in drawing phase");
 
   mContentClient->BeginPaint();
 
   uint32_t flags = GetPaintFlags();
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -246,17 +246,17 @@ static void DestroyTextureData(TextureDa
     aTextureData->Forget(aAllocator);
   }
   delete aTextureData;
 }
 
 void
 TextureChild::ActorDestroy(ActorDestroyReason why)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("TextureChild::ActorDestroy", GRAPHICS);
   MOZ_ASSERT(mIPCOpen);
   mIPCOpen = false;
 
   if (mTextureData) {
     DestroyTextureData(mTextureData, GetAllocator(), mOwnsTextureData, mMainThreadOnly);
     mTextureData = nullptr;
   }
 }
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -2,17 +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 "mozilla/layers/TiledContentClient.h"
 #include <math.h>                       // for ceil, ceilf, floor
 #include <algorithm>
 #include "ClientTiledPaintedLayer.h"     // for ClientTiledPaintedLayer
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
+#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
 #include "ClientLayerManager.h"         // for ClientLayerManager
 #include "gfxContext.h"                 // for gfxContext, etc
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPrefs.h"                   // for gfxPrefs
 #include "gfxRect.h"                    // for gfxRect
 #include "mozilla/MathAlgorithms.h"     // for Abs
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/gfx/Rect.h"           // for Rect
@@ -790,18 +790,17 @@ ClientMultiTiledLayerBuffer::PaintThebes
         printf_stderr(" rect %i, %i, %i, %i\n",
                       rect.x, rect.y, rect.width, rect.height);
       }
     }
   }
   start = PR_IntervalNow();
 #endif
 
-  PROFILER_LABEL("ClientMultiTiledLayerBuffer", "PaintThebesUpdate",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ClientMultiTiledLayerBuffer::PaintThebes", GRAPHICS);
 
   mNewValidRegion = aNewValidRegion;
   Update(aNewValidRegion, aPaintRegion, aDirtyRegion);
 
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
   if (PR_IntervalNow() - start > 10) {
     const IntRect bounds = aPaintRegion.GetBounds();
     printf_stderr("Time to tile %i: %i, %i, %i, %i\n", PR_IntervalNow() - start, bounds.x, bounds.y, bounds.width, bounds.height);
@@ -1038,18 +1037,17 @@ void ClientMultiTiledLayerBuffer::Update
   mPaintedRegion.OrWith(aPaintRegion);
 }
 
 bool
 ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
                                           const nsIntPoint& aTileOrigin,
                                           const nsIntRegion& aDirtyRegion)
 {
-  PROFILER_LABEL("ClientMultiTiledLayerBuffer", "ValidateTile",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ClientMultiTiledLayerBuffer::ValidateTile", GRAPHICS);
 
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
   if (aDirtyRegion.IsComplex()) {
     printf_stderr("Complex region\n");
   }
 #endif
 
   SurfaceMode mode;
@@ -1201,18 +1199,19 @@ ClientMultiTiledLayerBuffer::ComputeProg
   TILING_LOG("TILING %p: Progressive update view transform %s zoom %f abort %d\n",
       &mPaintedLayer, ToString(viewTransform.mTranslation).c_str(), viewTransform.mScale.scale, abortPaint);
 
   if (abortPaint) {
     // We ignore if front-end wants to abort if this is the first,
     // non-low-precision paint, as in that situation, we're about to override
     // front-end's page/viewport metrics.
     if (!aPaintData->mFirstPaint || drawingLowPrecision) {
-      PROFILER_LABEL("ClientMultiTiledLayerBuffer", "ComputeProgressiveUpdateRegion",
-        js::ProfileEntry::Category::GRAPHICS);
+      AUTO_PROFILER_LABEL(
+        "ClientMultiTiledLayerBuffer::ComputeProgressiveUpdateRegion",
+        GRAPHICS);
 
       aRegionToPaint.SetEmpty();
       return aIsRepeated;
     }
   }
 
   Maybe<LayerRect> transformedCompositionBounds =
     GetCompositorSideCompositionBounds(scrollAncestor,
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -1362,18 +1362,17 @@ AsyncCompositionManager::GetFrameUniform
   mLayerTransformRecorder.EndTest(aOutData);
 }
 
 bool
 AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
                                              TimeDuration aVsyncRate,
                                              TransformsToSkip aSkip)
 {
-  PROFILER_LABEL("AsyncCompositionManager", "TransformShadowTree",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("AsyncCompositionManager::TransformShadowTree", GRAPHICS);
 
   Layer* root = mLayerManager->GetRoot();
   if (!root) {
     return false;
   }
 
   // GetAnimationStorage in CompositorBridgeParent expects id as 0
   CompositorAnimationStorage* storage =
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -835,18 +835,17 @@ private:
   const ScreenPoint mOriginalOffset;
   const gfx::Matrix4x4 mOriginalProjection;
 };
 #endif // defined(MOZ_WIDGET_ANDROID)
 
 void
 LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion, const nsIntRegion& aOpaqueRegion)
 {
-  PROFILER_LABEL("LayerManagerComposite", "Render",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("LayerManagerComposite::Render", GRAPHICS);
 
   if (mDestroyed || !mCompositor || mCompositor->IsDestroyed()) {
     NS_WARNING("Call on destroyed layer manager");
     return;
   }
 
   ClearLayerFlags(mRoot);
 
@@ -885,18 +884,17 @@ LayerManagerComposite::Render(const nsIn
   mozilla::widget::WidgetRenderingContext widgetContext;
 #if defined(XP_MACOSX)
   widgetContext.mLayerManager = this;
 #elif defined(MOZ_WIDGET_ANDROID)
   widgetContext.mCompositor = GetCompositor();
 #endif
 
   {
-    PROFILER_LABEL("LayerManagerComposite", "PreRender",
-      js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("LayerManagerComposite::Render:Prerender", GRAPHICS);
 
     if (!mCompositor->GetWidget()->PreRender(&widgetContext)) {
       return;
     }
   }
 
   ParentLayerIntRect clipRect;
   IntRect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height);
@@ -986,18 +984,17 @@ LayerManagerComposite::Render(const nsIn
   RenderToolbar();
   HandlePixelsTarget();
 #endif // defined(MOZ_WIDGET_ANDROID)
 
   // Debugging
   RenderDebugOverlay(actualBounds);
 
   {
-    PROFILER_LABEL("LayerManagerComposite", "EndFrame",
-      js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("LayerManagerComposite::Render:EndFrame", GRAPHICS);
 
     mCompositor->EndFrame();
 
     // Call after EndFrame()
     mCompositor->SetDispAcquireFence(mRoot);
   }
 
   mCompositor->GetWidget()->PostRender(&widgetContext);
--- a/gfx/layers/composite/PaintedLayerComposite.cpp
+++ b/gfx/layers/composite/PaintedLayerComposite.cpp
@@ -91,18 +91,17 @@ PaintedLayerComposite::SetLayerManager(H
 
 void
 PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect,
                                    const Maybe<gfx::Polygon>& aGeometry)
 {
   if (!mBuffer || !mBuffer->IsAttached()) {
     return;
   }
-  PROFILER_LABEL("PaintedLayerComposite", "RenderLayer",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("PaintedLayerComposite::RenderLayer", GRAPHICS);
 
   Compositor* compositor = mCompositeManager->GetCompositor();
 
   MOZ_ASSERT(mBuffer->GetTextureSourceProvider() == compositor &&
              mBuffer->GetLayer() == this,
              "buffer is corrupted");
 
   const nsIntRegion visibleRegion = GetLocalVisibleRegion().ToUnknownRegion();
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -913,18 +913,17 @@ CompositorBridgeParent::SetShadowPropert
       }
     );
 }
 
 void
 CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
 {
   AutoProfilerTracing tracing("Paint", "Composite");
-  PROFILER_LABEL("CompositorBridgeParent", "Composite",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("CompositorBridgeParent::CompositeToTarget", GRAPHICS);
 
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
              "Composite can only be called on the compositor thread");
   TimeStamp start = TimeStamp::Now();
 
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
   TimeDuration scheduleDelta = TimeStamp::Now() - mCompositorScheduler->GetExpectedComposeStartTime();
   if (scheduleDelta > TimeDuration::FromMilliseconds(2) ||
@@ -1083,18 +1082,17 @@ CompositorBridgeParent::RecvRemotePlugin
                 "unexpected on this platform.");
   return IPC_FAIL_NO_REASON(this);
 #endif
 }
 
 void
 CompositorBridgeParent::ForceComposeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
 {
-  PROFILER_LABEL("CompositorBridgeParent", "ForceComposeToTarget",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("CompositorBridgeParent::ForceComposeToTarget", GRAPHICS);
 
   AutoRestore<bool> override(mOverrideComposeReadiness);
   mOverrideComposeReadiness = true;
   mCompositorScheduler->ForceComposeToTarget(aTarget, aRect);
 }
 
 PAPZCTreeManagerParent*
 CompositorBridgeParent::AllocPAPZCTreeManagerParent(const uint64_t& aLayersId)
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -145,18 +145,17 @@ LayerTransactionParent::RecvInitReadLock
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo)
 {
   AutoProfilerTracing tracing("Paint", "LayerTransaction");
-  PROFILER_LABEL("LayerTransactionParent", "RecvUpdate",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("LayerTransactionParent::RecvUpdate", GRAPHICS);
 
   TimeStamp updateStart = TimeStamp::Now();
 
   MOZ_LAYERS_LOG(("[ParentSide] received txn with %" PRIuSIZE " edits", aInfo.cset().Length()));
 
   UpdateFwdTransactionId(aInfo.fwdTransactionId());
   AutoClearReadLocks clearLocks(mReadLocks);
 
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -4,17 +4,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 "ClientLayerManager.h"         // for ClientLayerManager
 #include "ShadowLayers.h"
 #include <set>                          // for _Rb_tree_const_iterator, etc
 #include <vector>                       // for vector
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
+#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
 #include "ISurfaceAllocator.h"          // for IsSurfaceDescriptorValid
 #include "Layers.h"                     // for Layer
 #include "RenderTrace.h"                // for RenderTraceScope
 #include "gfx2DGlue.h"                  // for Moz2D transition helpers
 #include "gfxPlatform.h"                // for gfxImageFormat, gfxPlatform
 #include "gfxPrefs.h"
 //#include "gfxSharedImageSurface.h"      // for gfxSharedImageSurface
 #include "ipc/IPCMessageUtils.h"        // for gfxContentType, null_t
@@ -609,18 +609,17 @@ ShadowLayerForwarder::EndTransaction(con
   if (gfxPrefs::LayersDrawFPS()) {
     startTime = Some(TimeStamp::Now());
   }
 
   GetCompositorBridgeChild()->WillEndTransaction();
 
   MOZ_ASSERT(aId);
 
-  PROFILER_LABEL("ShadowLayerForwarder", "EndTransaction",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ShadowLayerForwarder::EndTransaction", GRAPHICS);
 
   RenderTraceScope rendertrace("Foward Transaction", "000091");
   MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?");
 
   DiagnosticTypes diagnostics = gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes();
   if (mDiagnosticTypes != diagnostics) {
     mDiagnosticTypes = diagnostics;
     mTxn->AddEdit(OpSetDiagnosticTypes(diagnostics));
--- a/gfx/layers/mlgpu/FrameBuilder.cpp
+++ b/gfx/layers/mlgpu/FrameBuilder.cpp
@@ -30,17 +30,17 @@ FrameBuilder::FrameBuilder(LayerManagerM
 
 FrameBuilder::~FrameBuilder()
 {
 }
 
 bool
 FrameBuilder::Build()
 {
-  PROFILER_LABEL("FrameBuilder", "Build", js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("FrameBuilder::Build", GRAPHICS);
 
   // AcquireBackBuffer can fail, so we check the result here.
   RefPtr<MLGRenderTarget> target = mSwapChain->AcquireBackBuffer();
   if (!target) {
     return false;
   }
 
   // This updates the frame sequence number, so layers can quickly check if
@@ -89,17 +89,17 @@ FrameBuilder::Build()
   FinishCurrentLayerBuffer();
   FinishCurrentMaskRectBuffer();
   return true;
 }
 
 void
 FrameBuilder::Render()
 {
-  PROFILER_LABEL("FrameBuilder", "Render", js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("FrameBuilder::Render", GRAPHICS);
 
   // Render combined masks into single mask textures.
   for (const auto& pair : mCombinedTextureMasks) {
     pair.second->Render();
   }
 
   // Render to all targets, front-to-back.
   mWidgetRenderView->Render();
--- a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp
+++ b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp
@@ -224,18 +224,17 @@ public:
 
 private:
   RefPtr<MLGDevice> mDevice;
 };
 
 void
 LayerManagerMLGPU::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFlags aFlags)
 {
-  PROFILER_LABEL("LayerManager", "EndTransaction",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("LayerManagerMLGPU::EndTransaction", GRAPHICS);
 
   SetCompositionTime(aTimeStamp);
 
   TextureSourceProvider::AutoReadUnlockTextures unlock(mTextureSourceProvider);
 
   if (!mRoot || (aFlags & END_NO_IMMEDIATE_REDRAW) || !mWidget) {
     return;
   }
@@ -273,18 +272,17 @@ LayerManagerMLGPU::EndTransaction(const 
 
   // Finish composition.
   mLastCompositionEndTime = TimeStamp::Now();
 }
 
 void
 LayerManagerMLGPU::Composite()
 {
-  PROFILER_LABEL("LayerManagerMLGPU", "Composite",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("LayerManagerMLGPU::Composite", GRAPHICS);
 
   // Don't composite if we're minimized/hidden, or if there is nothing to draw.
   if (mWidget->IsHidden()) {
     return;
   }
 
   // Make sure the diagnostic area gets invalidated. We do this now, rather than
   // earlier, so we don't accidentally cause extra composites.
@@ -326,18 +324,17 @@ LayerManagerMLGPU::Composite()
   RecordFrame();
 
   mDevice->EndFrame();
 }
 
 void
 LayerManagerMLGPU::RenderLayers()
 {
-  PROFILER_LABEL("LayerManagerMLGPU", "RenderLayers",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("LayerManagerMLGPU::RenderLayers", GRAPHICS);
 
   // Traverse the layer tree and assign each layer to a render target.
   FrameBuilder builder(this, mSwapChain);
   mCurrentFrame = &builder;
 
   if (!builder.Build()) {
     return;
   }
@@ -556,18 +553,17 @@ void
 LayerManagerMLGPU::UpdateRenderBounds(const gfx::IntRect& aRect)
 {
   mRenderBounds = aRect;
 }
 
 bool
 LayerManagerMLGPU::PreRender()
 {
-  PROFILER_LABEL("LayerManagerMLGPU", "PreRender",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("LayerManagerMLGPU::PreRender", GRAPHICS);
 
   widget::WidgetRenderingContext context;
   if (!mWidget->PreRender(&context)) {
     return false;
   }
   mWidgetContext = Some(context);
   return true;
 }
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -630,18 +630,17 @@ CompositorOGL::ClearRect(const gfx::Rect
 void
 CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
                           const IntRect *aClipRectIn,
                           const IntRect& aRenderBounds,
                           const nsIntRegion& aOpaqueRegion,
                           IntRect *aClipRectOut,
                           IntRect *aRenderBoundsOut)
 {
-  PROFILER_LABEL("CompositorOGL", "BeginFrame",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("CompositorOGL::BeginFrame", GRAPHICS);
 
   MOZ_ASSERT(!mFrameInProgress, "frame still in progress (should have called EndFrame");
 
   gfx::IntRect rect;
   if (mUseExternalSurfaceSize) {
     rect = gfx::IntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
   } else {
     rect = gfx::IntRect(aRenderBounds.x, aRenderBounds.y, aRenderBounds.width, aRenderBounds.height);
@@ -987,34 +986,32 @@ CompositorOGL::GetLineCoefficients(const
 void
 CompositorOGL::DrawQuad(const Rect& aRect,
                         const IntRect& aClipRect,
                         const EffectChain &aEffectChain,
                         Float aOpacity,
                         const gfx::Matrix4x4& aTransform,
                         const gfx::Rect& aVisibleRect)
 {
-  PROFILER_LABEL("CompositorOGL", "DrawQuad",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("CompositorOGL::DrawQuad", GRAPHICS);
 
   DrawGeometry(aRect, aRect, aClipRect, aEffectChain,
                aOpacity, aTransform, aVisibleRect);
 }
 
 void
 CompositorOGL::DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
                              const gfx::Rect& aRect,
                              const gfx::IntRect& aClipRect,
                              const EffectChain& aEffectChain,
                              gfx::Float aOpacity,
                              const gfx::Matrix4x4& aTransform,
                              const gfx::Rect& aVisibleRect)
 {
-  PROFILER_LABEL("CompositorOGL", "DrawTriangles",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("CompositorOGL::DrawTriangles", GRAPHICS);
 
   DrawGeometry(aTriangles, aRect, aClipRect, aEffectChain,
                aOpacity, aTransform, aVisibleRect);
 }
 
 template<typename Geometry>
 void
 CompositorOGL::DrawGeometry(const Geometry& aGeometry,
@@ -1575,18 +1572,17 @@ CompositorOGL::InitializeVAO(const GLuin
                                    LOCAL_GL_FALSE, aStride,
                                    reinterpret_cast<GLvoid*>(aOffset));
   mGLContext->fEnableVertexAttribArray(aAttrib);
 }
 
 void
 CompositorOGL::EndFrame()
 {
-  PROFILER_LABEL("CompositorOGL", "EndFrame",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("CompositorOGL::EndFrame", GRAPHICS);
 
   MOZ_ASSERT(mCurrentRenderTarget == mWindowRenderTarget, "Rendering target not properly restored");
 
 #ifdef MOZ_DUMP_PAINTING
   if (gfxEnv::DumpCompositorTextures()) {
     LayoutDeviceIntSize size;
     if (mUseExternalSurfaceSize) {
       size = LayoutDeviceIntSize(mSurfaceSize.width, mSurfaceSize.height);
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -186,18 +186,17 @@ void
 gfxContext::Fill()
 {
   Fill(PatternFromState(this));
 }
 
 void
 gfxContext::Fill(const Pattern& aPattern)
 {
-  PROFILER_LABEL("gfxContext", "Fill",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("gfxContext::Fill", GRAPHICS);
   FillAzure(aPattern, 1.0f);
 }
 
 void
 gfxContext::MoveTo(const gfxPoint& pt)
 {
   EnsurePathBuilder();
   mPathBuilder->MoveTo(ToPoint(pt));
@@ -730,18 +729,17 @@ gfxContext::Mask(SourceSurface *surface,
             surface,
             offset,
             DrawOptions(alpha, CurrentState().op, CurrentState().aaMode));
 }
 
 void
 gfxContext::Paint(gfxFloat alpha)
 {
-  PROFILER_LABEL("gfxContext", "Paint",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("gfxContext::Paint", GRAPHICS);
 
   AzureState &state = CurrentState();
 
   if (state.sourceSurface && !state.sourceSurfCairo &&
       !state.patternTransformChanged)
   {
     // This is the case where a PopGroupToSource has been done and this
     // paint is executed without changing the transform or the source.
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -506,17 +506,17 @@ gfxDWriteFontEntry::GetFontTable(uint32_
     }
 
     return nullptr;
 }
 
 nsresult
 gfxDWriteFontEntry::ReadCMAP(FontInfoData *aFontInfoData)
 {
-    PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("gfxDWriteFontEntry::ReadCMAP", GRAPHICS);
 
     // attempt this once, if errors occur leave a blank cmap
     if (mCharacterMap) {
         return NS_OK;
     }
 
     RefPtr<gfxCharacterMap> charmap;
     nsresult rv;
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -135,17 +135,17 @@ GDIFontEntry::GDIFontEntry(const nsAStri
     mIsDataUserFont = aUserFontData != nullptr;
 
     InitLogFont(aFaceName, aFontType);
 }
 
 nsresult
 GDIFontEntry::ReadCMAP(FontInfoData *aFontInfoData)
 {
-    PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("GDIFontEntry::ReadCMAP", OTHER);
 
     // attempt this once, if errors occur leave a blank cmap
     if (mCharacterMap) {
         return NS_OK;
     }
 
     // skip non-SFNT fonts completely
     if (mFontType != GFX_FONT_TYPE_PS_OPENTYPE && 
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -294,18 +294,17 @@ OptimalFillOp()
 // EXTEND_PAD won't help us here; we have to create a temporary surface to hold
 // the subimage of pixels we're allowed to sample.
 static already_AddRefed<gfxDrawable>
 CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable,
                                  gfxContext* aContext,
                                  const ImageRegion& aRegion,
                                  const SurfaceFormat aFormat)
 {
-    PROFILER_LABEL("gfxUtils", "CreateSamplingRestricedDrawable",
-      js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("CreateSamplingRestrictedDrawable", GRAPHICS);
 
     DrawTarget* destDrawTarget = aContext->GetDrawTarget();
     if (destDrawTarget->GetBackendType() == BackendType::DIRECT2D1_1) {
       return nullptr;
     }
 
     gfxRect clipExtents = aContext->GetClipExtents();
 
@@ -517,18 +516,17 @@ gfxUtils::DrawPixelSnapped(gfxContext*  
                            gfxDrawable*        aDrawable,
                            const gfxSize&      aImageSize,
                            const ImageRegion&  aRegion,
                            const SurfaceFormat aFormat,
                            SamplingFilter      aSamplingFilter,
                            uint32_t            aImageFlags,
                            gfxFloat            aOpacity)
 {
-    PROFILER_LABEL("gfxUtils", "DrawPixelSnapped",
-      js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("gfxUtils::DrawPixelSnapped", GRAPHICS);
 
     gfxRect imageRect(gfxPoint(0, 0), aImageSize);
     gfxRect region(aRegion.Rect());
     ExtendMode extendMode = aRegion.GetExtendMode();
 
     RefPtr<gfxDrawable> drawable = aDrawable;
 
     aSamplingFilter =
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -924,17 +924,18 @@ InvalidateWindowForDeviceReset(HWND aWnd
     RedrawWindow(aWnd, nullptr, nullptr,
                  RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_FRAME);
     return TRUE;
 }
 
 void
 gfxWindowsPlatform::SchedulePaintIfDeviceReset()
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("gfxWindowsPlatform::SchedulePaintIfDeviceReset",
+                      GRAPHICS);
 
   DeviceResetReason resetReason = DeviceResetReason::OK;
   if (!DidRenderingDeviceReset(&resetReason)) {
     return;
   }
 
   gfxCriticalNote << "(gfxWindowsPlatform) Detected device reset: " << (int)resetReason;
 
--- a/image/DecodePool.cpp
+++ b/image/DecodePool.cpp
@@ -310,35 +310,42 @@ DecodePool::Observe(nsISupports*, const 
 void
 DecodePool::AsyncRun(IDecodingTask* aTask)
 {
   MOZ_ASSERT(aTask);
   mImpl->PushWork(aTask);
 }
 
 bool
-DecodePool::SyncRunIfPreferred(IDecodingTask* aTask)
+DecodePool::SyncRunIfPreferred(IDecodingTask* aTask, const nsCString& aURI)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aTask);
 
+  AUTO_PROFILER_LABEL_DYNAMIC("DecodePool::SyncRunIfPreferred", GRAPHICS,
+                              aURI.get());
+
   if (aTask->ShouldPreferSyncRun()) {
     aTask->Run();
     return true;
   }
 
   AsyncRun(aTask);
   return false;
 }
 
 void
-DecodePool::SyncRunIfPossible(IDecodingTask* aTask)
+DecodePool::SyncRunIfPossible(IDecodingTask* aTask, const nsCString& aURI)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aTask);
+
+  AUTO_PROFILER_LABEL_DYNAMIC("DecodePool::SyncRunIfPossible", GRAPHICS,
+                              aURI.get());
+
   aTask->Run();
 }
 
 already_AddRefed<nsIEventTarget>
 DecodePool::GetIOEventTarget()
 {
   MutexAutoLock threadPoolLock(mMutex);
   nsCOMPtr<nsIEventTarget> target = do_QueryInterface(mIOThread);
--- a/image/DecodePool.h
+++ b/image/DecodePool.h
@@ -12,16 +12,17 @@
 
 #include "mozilla/Mutex.h"
 #include "mozilla/StaticPtr.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsIEventTarget.h"
 #include "nsIObserver.h"
 #include "mozilla/RefPtr.h"
+#include "nsStringFwd.h"
 
 class nsIThread;
 class nsIThreadPool;
 
 namespace mozilla {
 namespace image {
 
 class Decoder;
@@ -59,25 +60,25 @@ public:
 
   /**
    * Run @aTask synchronously if the task would prefer it. It's up to the task
    * itself to make this decision; @see IDecodingTask::ShouldPreferSyncRun(). If
    * @aTask doesn't prefer it, just run @aTask asynchronously and return
    * immediately.
    * @return true if the task was run sync, false otherwise.
    */
-  bool SyncRunIfPreferred(IDecodingTask* aTask);
+  bool SyncRunIfPreferred(IDecodingTask* aTask, const nsCString& aURI);
 
   /**
    * Run @aTask synchronously. This does not guarantee that @aTask will complete
    * synchronously. If, for example, @aTask doesn't yet have the data it needs to
    * run synchronously, it may recover by scheduling an async task to finish up
    * the work when the remaining data is available.
    */
-  void SyncRunIfPossible(IDecodingTask* aTask);
+  void SyncRunIfPossible(IDecodingTask* aTask, const nsCString& aURI);
 
   /**
    * Returns an event target interface to the DecodePool's I/O thread. Callers
    * who want to deliver data to workers on the DecodePool can use this event
    * target.
    *
    * @return An nsIEventTarget interface to the thread pool's I/O thread.
    */
--- a/image/Decoder.cpp
+++ b/image/Decoder.cpp
@@ -119,17 +119,17 @@ Decoder::Decode(IResumable* aOnResume /*
   // If we're already done, don't attempt to keep decoding.
   if (GetDecodeDone()) {
     return LexerResult(HasError() ? TerminalState::FAILURE
                                   : TerminalState::SUCCESS);
   }
 
   LexerResult lexerResult(TerminalState::FAILURE);
   {
-    PROFILER_LABEL("ImageDecoder", "Decode", js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("Decoder::Decode", GRAPHICS);
     AutoRecordDecoderTelemetry telemetry(this);
 
     lexerResult =  DoDecode(*mIterator, aOnResume);
   };
 
   if (lexerResult.is<Yield>()) {
     // We either need more data to continue (in which case either @aOnResume or
     // the caller will reschedule us to run again later), or the decoder is
--- a/image/FrameAnimator.cpp
+++ b/image/FrameAnimator.cpp
@@ -233,17 +233,17 @@ FrameAnimator::GetCurrentImgFrameEndTime
 
 RefreshResult
 FrameAnimator::AdvanceFrame(AnimationState& aState,
                             DrawableSurface& aFrames,
                             TimeStamp aTime)
 {
   NS_ASSERTION(aTime <= TimeStamp::Now(),
                "Given time appears to be in the future");
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("FrameAnimator::AdvanceFrame", GRAPHICS);
 
   RefreshResult ret;
 
   // Determine what the next frame is, taking into account looping.
   uint32_t currentFrameIndex = aState.mCurrentAnimationFrameIndex;
   uint32_t nextFrameIndex = currentFrameIndex + 1;
 
   // Check if we're at the end of the loop. (FrameCount() returns Nothing() if
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -1188,26 +1188,22 @@ LaunchDecodingTask(IDecodingTask* aTask,
                    uint32_t aFlags,
                    bool aHaveSourceData)
 {
   if (aHaveSourceData) {
     nsCString uri(aImage->GetURIString());
 
     // If we have all the data, we can sync decode if requested.
     if (aFlags & imgIContainer::FLAG_SYNC_DECODE) {
-      PROFILER_LABEL_DYNAMIC("DecodePool", "SyncRunIfPossible",
-        js::ProfileEntry::Category::GRAPHICS, uri.get());
-      DecodePool::Singleton()->SyncRunIfPossible(aTask);
+      DecodePool::Singleton()->SyncRunIfPossible(aTask, uri);
       return true;
     }
 
     if (aFlags & imgIContainer::FLAG_SYNC_DECODE_IF_FAST) {
-      PROFILER_LABEL_DYNAMIC("DecodePool", "SyncRunIfPreferred",
-        js::ProfileEntry::Category::GRAPHICS, uri.get());
-      return DecodePool::Singleton()->SyncRunIfPreferred(aTask);
+      return DecodePool::Singleton()->SyncRunIfPreferred(aTask, uri);
     }
   }
 
   // Perform an async decode. We also take this path if we don't have all the
   // source data yet, since sync decoding is impossible in that situation.
   DecodePool::Singleton()->AsyncRun(aTask);
   return false;
 }
--- a/image/imgFrame.cpp
+++ b/image/imgFrame.cpp
@@ -524,18 +524,17 @@ imgFrame::SurfaceForDrawing(bool        
   return SurfaceWithFormat(new gfxSurfaceDrawable(aSurface, availableSize),
                            mFormat);
 }
 
 bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion,
                     SamplingFilter aSamplingFilter, uint32_t aImageFlags,
                     float aOpacity)
 {
-  PROFILER_LABEL("imgFrame", "Draw",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("imgFrame::Draw", GRAPHICS);
 
   MOZ_ASSERT(NS_IsMainThread());
   NS_ASSERTION(!aRegion.Rect().IsEmpty(), "Drawing empty region!");
   NS_ASSERTION(!aRegion.IsRestricted() ||
                !aRegion.Rect().Intersect(aRegion.Restriction()).IsEmpty(),
                "We must be allowed to sample *some* source pixels!");
   MOZ_ASSERT(mFrameRect.IsEqualEdges(IntRect(IntPoint(), mImageSize)),
              "Directly drawing an image with a non-trivial frame rect!");
--- a/ipc/chromium/src/base/message_pump_default.cc
+++ b/ipc/chromium/src/base/message_pump_default.cc
@@ -50,28 +50,26 @@ void MessagePumpDefault::Run(Delegate* d
     if (!keep_running_)
       break;
 
     if (did_work)
       continue;
 
     if (delayed_work_time_.is_null()) {
       hangMonitor.NotifyWait();
-      PROFILER_LABEL("MessagePump", "Wait",
-        js::ProfileEntry::Category::OTHER);
+      AUTO_PROFILER_LABEL("MessagePumpDefault::Run:Wait", OTHER);
       {
         mozilla::AutoProfilerThreadSleep sleep;
         event_.Wait();
       }
     } else {
       TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
       if (delay > TimeDelta()) {
         hangMonitor.NotifyWait();
-        PROFILER_LABEL("MessagePump", "Wait",
-          js::ProfileEntry::Category::OTHER);
+        AUTO_PROFILER_LABEL("MessagePumpDefault::Run:Wait", OTHER);
         {
           mozilla::AutoProfilerThreadSleep sleep;
           event_.TimedWait(delay);
         }
       } else {
         // It looks like delayed_work_time_ indicates a time in the past, so we
         // need to call DoDelayedWork now.
         delayed_work_time_ = TimeTicks();
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -388,17 +388,17 @@ GeckoChildProcessHost::AsyncLaunch(std::
   }
 
   return true;
 }
 
 bool
 GeckoChildProcessHost::WaitUntilConnected(int32_t aTimeoutMs)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("GeckoChildProcessHost::WaitUntilConnected", OTHER);
 
   // NB: this uses a different mechanism than the chromium parent
   // class.
   PRIntervalTime timeoutTicks = (aTimeoutMs > 0) ?
     PR_MillisecondsToInterval(aTimeoutMs) : PR_INTERVAL_NO_TIMEOUT;
 
   MonitorAutoLock lock(mMonitor);
   PRIntervalTime waitStart = PR_IntervalNow();
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -4674,20 +4674,20 @@ class _GenerateProtocolActorCode(ipdl.as
                                      self.protocol.callOtherPid(actor),
                                      ExprLiteral.String(pfx),
                                      ExprCall(ExprSelect(msgptr, '->', 'type')),
                                      ExprVar('mozilla::ipc::MessageDirection::eReceiving'
                                              if receiving
                                              else 'mozilla::ipc::MessageDirection::eSending') ])) ])
 
     def profilerLabel(self, md):
-        return StmtExpr(ExprCall(ExprVar('PROFILER_LABEL'),
-                                 [ ExprLiteral.String(self.protocol.name),
-                                   ExprLiteral.String(md.prettyMsgName()),
-                                   ExprVar('js::ProfileEntry::Category::OTHER') ]))
+        labelStr = self.protocol.name + '::' + md.prettyMsgName()
+        return StmtExpr(ExprCall(ExprVar('AUTO_PROFILER_LABEL'),
+                                 [ ExprLiteral.String(labelStr),
+                                   ExprVar('OTHER') ]))
 
     def saveActorId(self, md):
         idvar = ExprVar('id__')
         if md.decl.type.hasReply():
             # only save the ID if we're actually going to use it, to
             # avoid unused-variable warnings
             saveIdStmts = [ StmtDecl(Decl(_actorIdType(), idvar.name),
                                      self.protocol.routingId()) ]
--- a/js/ipc/WrapperOwner.cpp
+++ b/js/ipc/WrapperOwner.cpp
@@ -142,17 +142,17 @@ class CPOWProxyHandler : public BaseProx
     static const char family;
     static const CPOWProxyHandler singleton;
 };
 
 const char CPOWProxyHandler::family = 0;
 const CPOWProxyHandler CPOWProxyHandler::singleton;
 
 #define FORWARD(call, args)                                             \
-    PROFILER_LABEL_FUNC(js::ProfileEntry::Category::JS);                \
+    AUTO_PROFILER_LABEL(__func__, JS);                                  \
     WrapperOwner* owner = OwnerOf(proxy);                               \
     if (!owner->active()) {                                             \
         JS_ReportErrorASCII(cx, "cannot use a CPOW whose process is gone"); \
         return false;                                                   \
     }                                                                   \
     if (!owner->allowMessage(cx)) {                                     \
         return false;                                                   \
     }                                                                   \
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -356,19 +356,18 @@ mozJSComponentLoader::LoadModule(FileLoc
     NS_ENSURE_SUCCESS(rv, nullptr);
 
     if (!mInitialized) {
         rv = ReallyInit();
         if (NS_FAILED(rv))
             return nullptr;
     }
 
-    PROFILER_LABEL_DYNAMIC("mozJSComponentLoader", "LoadModule",
-                           js::ProfileEntry::Category::OTHER,
-                           spec.get());
+    AUTO_PROFILER_LABEL_DYNAMIC("mozJSComponentLoader::LoadModule", OTHER,
+                                spec.get());
 
     ModuleEntry* mod;
     if (mModules.Get(spec, &mod))
         return mod;
 
     dom::AutoJSAPI jsapi;
     jsapi.Init();
     JSContext* cx = jsapi.cx();
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -622,19 +622,19 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
 
     nsCOMPtr<nsIIOService> serv = do_GetService(NS_IOSERVICE_CONTRACTID);
     if (!serv) {
         ReportError(cx, NS_LITERAL_CSTRING(LOAD_ERROR_NOSERVICE));
         return NS_OK;
     }
 
     const nsCString& asciiUrl = NS_LossyConvertUTF16toASCII(url);
-    PROFILER_LABEL_DYNAMIC("mozJSSubScriptLoader", "LoadSubScript",
-                           js::ProfileEntry::Category::OTHER,
-                           asciiUrl.get());
+    AUTO_PROFILER_LABEL_DYNAMIC(
+        "mozJSSubScriptLoader::DoLoadSubScriptWithOptions", OTHER,
+        asciiUrl.get());
 
     // Make sure to explicitly create the URI, since we'll need the
     // canonicalized spec.
     rv = NS_NewURI(getter_AddRefs(uri), asciiUrl.get(), nullptr, serv);
     if (NS_FAILED(rv)) {
         ReportError(cx, NS_LITERAL_CSTRING(LOAD_ERROR_NOURI));
         return NS_OK;
     }
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2499,19 +2499,18 @@ nsXPCComponents_Utils::Import(const nsAC
                               MutableHandleValue retval)
 {
     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
     if (!moduleloader)
         return NS_ERROR_FAILURE;
 
     const nsCString& flatLocation = PromiseFlatCString(registryLocation);
-    PROFILER_LABEL_DYNAMIC("Components.utils", "import",
-                           js::ProfileEntry::Category::OTHER,
-                           flatLocation.get());
+    AUTO_PROFILER_LABEL_DYNAMIC("nsXPCComponents_Utils::Import", OTHER,
+                                flatLocation.get());
 
     return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::IsModuleLoaded(const nsACString& registryLocation, bool* retval)
 {
     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
@@ -3034,17 +3033,17 @@ nsXPCComponents_Utils::CrashIfNotInAutom
 {
     xpc::CrashIfNotInAutomation();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext* cx)
 {
-    PROFILER_LABEL_FUNC(js::ProfileEntry::Category::JS);
+    AUTO_PROFILER_LABEL("nsXPCComponents_Utils::NukeSandbox", JS);
     NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG);
     JSObject* wrapper = &obj.toObject();
     NS_ENSURE_TRUE(IsWrapper(wrapper), NS_ERROR_INVALID_ARG);
     RootedObject sb(cx, UncheckedUnwrap(wrapper));
     NS_ENSURE_TRUE(IsSandbox(sb), NS_ERROR_INVALID_ARG);
 
     xpc::NukeAllWrappersForCompartment(cx, GetObjectCompartment(sb));
 
--- a/js/xpconnect/wrappers/AddonWrapper.cpp
+++ b/js/xpconnect/wrappers/AddonWrapper.cpp
@@ -184,17 +184,17 @@ AddonWrapper<Base>::getOwnPropertyDescri
     return Base::getOwnPropertyDescriptor(cx, wrapper, id, desc);
 }
 
 template<typename Base>
 bool
 AddonWrapper<Base>::get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<Value> receiver,
                         JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
 {
-    PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("AddonWrapper::get", OTHER);
 
     Rooted<PropertyDescriptor> desc(cx);
     if (!InterposeProperty(cx, wrapper, nullptr, id, &desc))
         return false;
 
     if (!desc.object())
         return Base::get(cx, wrapper, receiver, id, vp);
 
--- a/layout/base/GeckoRestyleManager.cpp
+++ b/layout/base/GeckoRestyleManager.cpp
@@ -2991,18 +2991,17 @@ ElementRestyler::ComputeStyleChangeFor(n
                                        RestyleTracker&    aRestyleTracker,
                                        nsRestyleHint      aRestyleHint,
                                        const RestyleHintData& aRestyleHintData,
                                        nsTArray<ContextToClear>&
                                          aContextsToClear,
                                        nsTArray<RefPtr<nsStyleContext>>&
                                          aSwappedStructOwners)
 {
-  PROFILER_LABEL("ElementRestyler", "ComputeStyleChangeFor",
-                 js::ProfileEntry::Category::CSS);
+  AUTO_PROFILER_LABEL("ElementRestyler::ComputeStyleChangeFor", CSS);
 
   nsIContent* content = aFrame->GetContent();
   if (aMinChange) {
     aChangeList->AppendChange(aFrame, content, aMinChange);
   }
 
   NS_ASSERTION(!aFrame->GetPrevContinuation(),
                "must start with the first continuation");
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4071,18 +4071,18 @@ PresShell::DoFlushPendingNotifications(m
     "Content",
     "ContentAndNotify",
     "Style",
     "InterruptibleLayout",
     "Layout",
     "Display"
   };
 
-  PROFILER_LABEL_DYNAMIC("PresShell", "Flush",
-    js::ProfileEntry::Category::GRAPHICS, flushTypeNames[flushType]);
+  AUTO_PROFILER_LABEL_DYNAMIC("PresShell::DoFlushPendingNotifications",
+                              GRAPHICS, flushTypeNames[flushType]);
 
 #ifdef ACCESSIBILITY
 #ifdef DEBUG
   nsAccessibilityService* accService = GetAccService();
   if (accService) {
     NS_ASSERTION(!accService->IsProcessingRefreshDriverNotification(),
                  "Flush during accessible tree update!");
   }
@@ -6289,18 +6289,17 @@ PresShell::Paint(nsView*         aViewTo
                  uint32_t        aFlags)
 {
   nsIURI* uri = mDocument->GetDocumentURI();
   nsIDocument* contentRoot = GetPrimaryContentDocument();
   if (contentRoot) {
     uri = contentRoot->GetDocumentURI();
   }
   nsCString uriString = uri ? uri->GetSpecOrDefault() : NS_LITERAL_CSTRING("N/A");
-  PROFILER_LABEL_DYNAMIC("PresShell", "Paint",
-    js::ProfileEntry::Category::GRAPHICS, uriString.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("PresShell::Paint", GRAPHICS, uriString.get());
 
   Maybe<js::AutoAssertNoContentJS> nojs;
 
   // On Android, Flash can call into content JS during painting, so we can't
   // assert there. However, we don't rely on this assertion on Android because
   // we don't paint while JS is running.
 #if !defined(MOZ_WIDGET_ANDROID)
   if (!(aFlags & nsIPresShell::PAINT_COMPOSITE)) {
@@ -9197,18 +9196,17 @@ PresShell::DoReflow(nsIFrame* target, bo
   nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(target);
   while (parent) {
     nsSVGEffects::InvalidateDirectRenderingObservers(parent);
     parent = nsLayoutUtils::GetCrossDocParentFrame(parent);
   }
 
   nsIURI* uri = mDocument->GetDocumentURI();
   nsCString uriString = uri ? uri->GetSpecOrDefault() : NS_LITERAL_CSTRING("N/A");
-  PROFILER_LABEL_DYNAMIC("PresShell", "DoReflow",
-    js::ProfileEntry::Category::GRAPHICS, uriString.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("PresShell::DoReflow", GRAPHICS, uriString.get());
 
   nsDocShell* docShell = static_cast<nsDocShell*>(GetPresContext()->GetDocShell());
   RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
   bool isTimelineRecording = timelines && timelines->HasConsumer(docShell);
 
   if (isTimelineRecording) {
     timelines->AddMarkerForDocShell(docShell, "Reflow", MarkerTracingType::START);
   }
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -1342,18 +1342,17 @@ RestyleManager::ProcessRestyledFrames(ns
   MOZ_ASSERT(!mDestroyedFrames);
 
   if (aChangeList.IsEmpty()) {
     return;
   }
 
   mDestroyedFrames = MakeUnique<nsTHashtable<nsPtrHashKey<const nsIFrame>>>();
 
-  PROFILER_LABEL("RestyleManager", "ProcessRestyledFrames",
-                 js::ProfileEntry::Category::CSS);
+  AUTO_PROFILER_LABEL("RestyleManager::ProcessRestyledFrames", CSS);
 
   nsPresContext* presContext = PresContext();
   nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor();
 
   // Handle nsChangeHint_CSSOverflowChange, by either updating the
   // scrollbars on the viewport, or upgrading the change hint to frame-reconstruct.
   for (nsStyleChangeData& data : aChangeList) {
     if (data.mHint & nsChangeHint_CSSOverflowChange) {
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -109,18 +109,18 @@ RestyleTracker::DoProcessRestyles()
 {
   nsAutoCString docURL("N/A");
   if (profiler_is_active()) {
     nsIURI *uri = Document()->GetDocumentURI();
     if (uri) {
       docURL = uri->GetSpecOrDefault();
     }
   }
-  PROFILER_LABEL_DYNAMIC("RestyleTracker", "ProcessRestyles",
-                         js::ProfileEntry::Category::CSS, docURL.get());
+  AUTO_PROFILER_LABEL_DYNAMIC("RestyleTracker::DoProcessRestyles", CSS,
+                              docURL.get());
 
   nsDocShell* docShell = static_cast<nsDocShell*>(mRestyleManager->PresContext()->GetDocShell());
   RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
   bool isTimelineRecording = timelines && timelines->HasConsumer(docShell);
 
   // Create a AnimationsWithDestroyedFrame during restyling process to
   // stop animations and transitions on elements that have no frame at the end
   // of the restyling process.
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3171,33 +3171,31 @@ struct AutoNestedPaintCount {
   }
 };
 
 #endif
 
 nsIFrame*
 nsLayoutUtils::GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt, uint32_t aFlags)
 {
-  PROFILER_LABEL("nsLayoutUtils", "GetFrameForPoint",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsLayoutUtils::GetFrameForPoint", GRAPHICS);
 
   nsresult rv;
   AutoTArray<nsIFrame*,8> outFrames;
   rv = GetFramesForArea(aFrame, nsRect(aPt, nsSize(1, 1)), outFrames, aFlags);
   NS_ENSURE_SUCCESS(rv, nullptr);
   return outFrames.Length() ? outFrames.ElementAt(0) : nullptr;
 }
 
 nsresult
 nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
                                 nsTArray<nsIFrame*> &aOutFrames,
                                 uint32_t aFlags)
 {
-  PROFILER_LABEL("nsLayoutUtils", "GetFramesForArea",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsLayoutUtils::GetFramesForArea", GRAPHICS);
 
   nsDisplayListBuilder builder(aFrame,
                                nsDisplayListBuilderMode::EVENT_DELIVERY,
                                false);
   nsDisplayList list;
 
   if (aFlags & IGNORE_PAINT_SUPPRESSION) {
     builder.IgnorePaintSuppression();
@@ -3420,18 +3418,17 @@ nsLayoutUtils::ExpireDisplayPortOnAsyncS
 }
 
 nsresult
 nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
                           const nsRegion& aDirtyRegion, nscolor aBackstop,
                           nsDisplayListBuilderMode aBuilderMode,
                           PaintFrameFlags aFlags)
 {
-  PROFILER_LABEL("nsLayoutUtils", "PaintFrame",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame", GRAPHICS);
 
 #ifdef MOZ_DUMP_PAINTING
   if (!gPaintCountStack) {
     gPaintCountStack = new nsTArray<int>();
     ClearOnShutdown(&gPaintCountStack);
 
     gPaintCountStack->AppendElement(0);
   }
@@ -3532,18 +3529,18 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
       canvasArea.UnionRect(canvasArea,
         canvasFrame->CanvasArea() + builder.ToReferenceFrame(canvasFrame));
     }
   }
 
   nsRect dirtyRect = visibleRegion.GetBounds();
 
   {
-    PROFILER_LABEL("nsLayoutUtils", "PaintFrame::BuildDisplayList",
-      js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame:BuildDisplayList",
+                        GRAPHICS);
     AutoProfilerTracing tracing("Paint", "DisplayList");
 
     PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::DisplayList);
 
     builder.EnterPresShell(aFrame);
     {
       // If a scrollable container layer is created in nsDisplayList::PaintForFrame,
       // it will be the scroll parent for display items that are built in the
@@ -6845,18 +6842,17 @@ nsLayoutUtils::DrawBackgroundImage(gfxCo
                                    const nsRect&       aFill,
                                    const nsSize&       aRepeatSize,
                                    const nsPoint&      aAnchor,
                                    const nsRect&       aDirty,
                                    uint32_t            aImageFlags,
                                    ExtendMode          aExtendMode,
                                    float               aOpacity)
 {
-  PROFILER_LABEL("layout", "nsLayoutUtils::DrawBackgroundImage",
-                 js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsLayoutUtils::DrawBackgroundImage", GRAPHICS);
 
   Maybe<SVGImageContext> svgContext(Some(SVGImageContext(Some(aImageSize))));
   SVGImageContext::MaybeStoreContextPaint(svgContext, aForFrame, aImage);
 
   /* Fast path when there is no need for image spacing */
   if (aRepeatSize.width == aDest.width && aRepeatSize.height == aDest.height) {
     return DrawImageInternal(aContext, aPresContext, aImage,
                              aSamplingFilter, aDest, aFill, aAnchor,
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1740,18 +1740,17 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
                   "Shouldn't have a JSContext on the stack");
 
   if (nsNPAPIPluginInstance::InPluginCallUnsafeForReentry()) {
     NS_ERROR("Refresh driver should not run during plugin call!");
     // Try to survive this by just ignoring the refresh tick.
     return;
   }
 
-  PROFILER_LABEL("nsRefreshDriver", "Tick",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsRefreshDriver::Tick", GRAPHICS);
 
   // We're either frozen or we were disconnected (likely in the middle
   // of a tick iteration).  Just do nothing here, since our
   // prescontext went away.
   if (IsFrozen() || !mPresContext) {
     return;
   }
 
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -51,18 +51,17 @@ ViewportFrame::Init(nsIContent*       aC
   }
 }
 
 void
 ViewportFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists)
 {
-  PROFILER_LABEL("ViewportFrame", "BuildDisplayList",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ViewportFrame::BuildDisplayList", GRAPHICS);
 
   if (nsIFrame* kid = mFrames.FirstChild()) {
     // make the kid's BorderBackground our own. This ensures that the canvas
     // frame's background becomes our own background and therefore appears
     // below negative z-index elements.
     BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
   }
 
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -82,17 +82,17 @@ NS_QUERYFRAME_HEAD(nsSubDocumentFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsAtomicContainerFrame)
 
 class AsyncFrameInit : public Runnable
 {
 public:
   explicit AsyncFrameInit(nsIFrame* aFrame) : mFrame(aFrame) {}
   NS_IMETHOD Run() override
   {
-    PROFILER_LABEL("mozilla", "AsyncFrameInit::Run", js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("AsyncFrameInit::Run", OTHER);
     if (mFrame.IsAlive()) {
       static_cast<nsSubDocumentFrame*>(mFrame.GetFrame())->ShowViewer();
     }
     return NS_OK;
   }
 private:
   WeakFrame mFrame;
 };
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5150,18 +5150,17 @@ nsDisplayText::GetLayerState(nsDisplayLi
   }
   MOZ_ASSERT(mMergedFrames.IsEmpty());
   return mozilla::LAYER_NONE;
 }
 
 void
 nsDisplayText::Paint(nsDisplayListBuilder* aBuilder,
                      gfxContext* aCtx) {
-  PROFILER_LABEL("nsDisplayText", "Paint",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsDisplayText::Paint", GRAPHICS);
 
   MOZ_ASSERT(mMergedFrames.IsEmpty());
 
   DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
                                                     mDisableSubpixelAA);
   RenderToContext(aCtx, aBuilder);
 }
 
@@ -6305,18 +6304,17 @@ AddHyphenToMetrics(nsTextFrame* aTextFra
   aMetrics->CombineWith(hyphenMetrics, aBaseTextRun->IsRightToLeft());
 }
 
 void
 nsTextFrame::PaintOneShadow(const PaintShadowParams& aParams,
                             nsCSSShadowItem* aShadowDetails,
                             gfxRect& aBoundingBox, uint32_t aBlurFlags)
 {
-  PROFILER_LABEL("nsTextFrame", "PaintOneShadow",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsTextFrame::PaintOneShadow", GRAPHICS);
 
   gfxPoint shadowOffset(aShadowDetails->mXOffset, aShadowDetails->mYOffset);
   nscoord blurRadius = std::max(aShadowDetails->mRadius, 0);
 
   // This rect is the box which is equivalent to where the shadow will be painted.
   // The origin of aBoundingBox is the text baseline left, so we must translate it by
   // that much in order to make the origin the top-left corner of the text bounding box.
   // Note that aLeftSideOffset is line-left, so actually means top offset in
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -3961,18 +3961,17 @@ IsScrollThumbLayer(nsDisplayItem* aItem)
  * individually when we draw them.)
  * We set the visible rect for all layers, although the actual setting
  * of visible rects for some PaintedLayers is deferred until the calling
  * of ContainerState::Finish.
  */
 void
 ContainerState::ProcessDisplayItems(nsDisplayList* aList)
 {
-  PROFILER_LABEL("ContainerState", "ProcessDisplayItems",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ContainerState::ProcessDisplayItems", GRAPHICS);
 
   AnimatedGeometryRoot* lastAnimatedGeometryRoot = mContainerAnimatedGeometryRoot;
   const ActiveScrolledRoot* lastASR = mContainerASR;
   nsPoint lastAGRTopLeft;
   nsPoint topLeft(0,0);
 
   // When NO_COMPONENT_ALPHA is set, items will be flattened into a single
   // layer, so we need to choose which active scrolled root to use for all
@@ -6017,21 +6016,20 @@ FrameLayerBuilder::PaintItems(nsTArray<C
   for (uint32_t i = 0; i < aItems.Length(); ++i) {
     ClippedDisplayItem* cdi = &aItems[i];
 
     nsRect paintRect = cdi->mItem->GetVisibleRect().Intersect(boundRect);
     if (paintRect.IsEmpty())
       continue;
 
 #ifdef MOZ_DUMP_PAINTING
-    PROFILER_LABEL_DYNAMIC("DisplayList", "Draw",
-      js::ProfileEntry::Category::GRAPHICS, cdi->mItem->Name());
+    AUTO_PROFILER_LABEL_DYNAMIC("FrameLayerBuilder::PaintItems", GRAPHICS,
+                                cdi->mItem->Name());
 #else
-    PROFILER_LABEL("DisplayList", "Draw",
-      js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("FrameLayerBuilder::PaintItems", GRAPHICS);
 #endif
 
     // If the new desired clip state is different from the current state,
     // update the clip.
     const DisplayItemClip* clip = &cdi->mItem->GetClip();
     if (clip->GetRoundedRectCount() > 0 &&
         !clip->IsRectClippedByRoundedCorner(cdi->mItem->GetVisibleRect())) {
       tmpClip = *clip;
@@ -6061,20 +6059,19 @@ FrameLayerBuilder::PaintItems(nsTArray<C
     } else {
       nsIFrame* frame = cdi->mItem->Frame();
       if (aBuilder->IsPaintingToWindow()) {
         frame->AddStateBits(NS_FRAME_PAINTED_THEBES);
       }
 #ifdef MOZ_DUMP_PAINTING
       if (gfxEnv::DumpPaintItems()) {
         DebugPaintItem(aDrawTarget, aPresContext, cdi->mItem, aBuilder);
-      } else {
-#else
+      } else
+#endif
       {
-#endif
         cdi->mItem->Paint(aBuilder, aRC);
       }
     }
 
     if (CheckDOMModified())
       break;
   }
 
@@ -6143,18 +6140,17 @@ FrameLayerBuilder::DrawPaintedLayer(Pain
                                    const nsIntRegion& aRegionToDraw,
                                    const nsIntRegion& aDirtyRegion,
                                    DrawRegionClip aClip,
                                    const nsIntRegion& aRegionToInvalidate,
                                    void* aCallbackData)
 {
   DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
 
-  PROFILER_LABEL("FrameLayerBuilder", "DrawPaintedLayer",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("FrameLayerBuilder::DrawPaintedLayer", GRAPHICS);
 
   nsDisplayListBuilder* builder = static_cast<nsDisplayListBuilder*>
     (aCallbackData);
 
   FrameLayerBuilder *layerBuilder = aLayer->Manager()->GetLayerBuilder();
   NS_ASSERTION(layerBuilder, "Unexpectedly null layer builder!");
 
   if (layerBuilder->CheckDOMModified())
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -631,18 +631,17 @@ nsCSSRendering::PaintBorder(nsPresContex
                             gfxContext& aRenderingContext,
                             nsIFrame* aForFrame,
                             const nsRect& aDirtyRect,
                             const nsRect& aBorderArea,
                             nsStyleContext* aStyleContext,
                             PaintBorderFlags aFlags,
                             Sides aSkipSides)
 {
-  PROFILER_LABEL("nsCSSRendering", "PaintBorder",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsCSSRendering::PaintBorder", GRAPHICS);
 
   nsStyleContext *styleIfVisited = aStyleContext->GetStyleIfVisited();
   const nsStyleBorder *styleBorder = aStyleContext->StyleBorder();
   // Don't check RelevantLinkVisited here, since we want to take the
   // same amount of time whether or not it's true.
   if (!styleIfVisited) {
     return PaintBorderWithStyleBorder(aPresContext, aRenderingContext, aForFrame,
                                       aDirtyRect, aBorderArea, *styleBorder,
@@ -1906,21 +1905,20 @@ nsCSSRendering::PaintBGParams::ForSingle
 
   return result;
 }
 
 DrawResult
 nsCSSRendering::PaintStyleImageLayer(const PaintBGParams& aParams,
                                      gfxContext& aRenderingCtx)
 {
-  PROFILER_LABEL("nsCSSRendering", "PaintBackground",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsCSSRendering::PaintStyleImageLayer", GRAPHICS);
 
   NS_PRECONDITION(aParams.frame,
-                  "Frame is expected to be provided to PaintBackground");
+                  "Frame is expected to be provided to PaintStyleImageLayer");
 
   nsStyleContext *sc;
   if (!FindBackground(aParams.frame, &sc)) {
     // We don't want to bail out if moz-appearance is set on a root
     // node. If it has a parent content node, bail because it's not
     // a root, otherwise keep going in order to let the theme stuff
     // draw the background. The canvas really should be drawing the
     // bg, but there's no way to hook that up via css.
@@ -2502,17 +2500,17 @@ DetermineCompositionOp(const nsCSSRender
 
 DrawResult
 nsCSSRendering::PaintStyleImageLayerWithSC(const PaintBGParams& aParams,
                                            gfxContext& aRenderingCtx,
                                            nsStyleContext *aBackgroundSC,
                                            const nsStyleBorder& aBorder)
 {
   NS_PRECONDITION(aParams.frame,
-                  "Frame is expected to be provided to PaintBackground");
+                  "Frame is expected to be provided to PaintStyleImageLayerWithSC");
 
   // If we're drawing all layers, aCompositonOp is ignored, so make sure that
   // it was left at its default value.
   MOZ_ASSERT(aParams.layer != -1 ||
              aParams.compositionOp == CompositionOp::OP_OVER);
 
   // Check to see if we have an appearance defined.  If so, we let the theme
   // renderer draw the background and bail out.
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3368,18 +3368,17 @@ nsCSSBorderRenderer::DrawBorders()
 
   PrintAsFormatString(" allBordersSame: %d dashedSides: 0x%02x\n", allBordersSame, dashedSides);
 
   if (allBordersSame && !forceSeparateCorners) {
     /* Draw everything in one go */
     DrawBorderSides(eSideBitsAll);
     PrintAsStringNewline("---------------- (1)");
   } else {
-    PROFILER_LABEL("nsCSSBorderRenderer", "DrawBorders::multipass",
-      js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("nsCSSBorderRenderer::DrawBorders:multipass", GRAPHICS);
 
     /* We have more than one pass to go.  Draw the corners separately from the sides. */
 
     /*
      * If we have a 1px-wide border, the corners are going to be
      * negligible, so don't bother doing anything fancy.  Just extend
      * the top and bottom borders to the right 1px and the left border
      * to the bottom 1px.  We do this by twiddling the corner dimensions,
--- a/layout/painting/nsCSSRenderingGradients.cpp
+++ b/layout/painting/nsCSSRenderingGradients.cpp
@@ -655,18 +655,17 @@ void
 nsCSSGradientRenderer::Paint(gfxContext& aContext,
                              const nsRect& aDest,
                              const nsRect& aFillArea,
                              const nsSize& aRepeatSize,
                              const CSSIntRect& aSrc,
                              const nsRect& aDirtyRect,
                              float aOpacity)
 {
-  PROFILER_LABEL("nsCSSRendering", "PaintGradient",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsCSSGradientRenderer::Paint", GRAPHICS);
   Telemetry::AutoTimer<Telemetry::GRADIENT_DURATION, Telemetry::Microsecond> gradientTimer;
 
   if (aDest.IsEmpty() || aFillArea.IsEmpty()) {
     return;
   }
 
   nscoord appUnitsPerDevPixel = mPresContext->AppUnitsPerDevPixel();
 
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -1917,18 +1917,17 @@ nsDisplayList::GetVisibleRect() const {
     result.UnionRect(result, i->GetVisibleRect());
   }
   return result;
 }
 
 bool
 nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
                                         nsRegion* aVisibleRegion) {
-  PROFILER_LABEL("nsDisplayList", "ComputeVisibilityForRoot",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsDisplayList::ComputeVisibilityForRoot", GRAPHICS);
 
   nsRegion r;
   const ActiveScrolledRoot* rootASR = nullptr;
   if (gfxPrefs::LayoutUseContainersForRootFrames()) {
     rootASR = aBuilder->ActiveScrolledRootForRootScrollframe();
   }
   r.And(*aVisibleRegion, GetClippedBoundsWithRespectToASR(aBuilder, rootASR));
   return ComputeVisibilityForSublist(aBuilder, aVisibleRegion, r.GetBounds());
@@ -2060,19 +2059,19 @@ nsDisplayListBuilder::GetWidgetLayerMana
 
 /**
  * We paint by executing a layer manager transaction, constructing a
  * single layer representing the display list, and then making it the
  * root of the layer manager, drawing into the PaintedLayers.
  */
 already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aBuilder,
                                                         gfxContext* aCtx,
-                                                        uint32_t aFlags) {
-  PROFILER_LABEL("nsDisplayList", "PaintRoot",
-    js::ProfileEntry::Category::GRAPHICS);
+                                                        uint32_t aFlags)
+{
+  AUTO_PROFILER_LABEL("nsDisplayList::PaintRoot", GRAPHICS);
 
   RefPtr<LayerManager> layerManager;
   bool widgetTransaction = false;
   bool doBeginTransaction = true;
   nsView *view = nullptr;
   if (aFlags & PAINT_USE_WIDGET_LAYERS) {
     layerManager = aBuilder->GetWidgetLayerManager(&view);
     if (layerManager) {
@@ -5078,18 +5077,17 @@ void
 nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
                                gfxContext* aCtx) {
   nsPoint offset = ToReferenceFrame();
   nsRect borderRect = mFrame->VisualBorderRectRelativeToSelf() + offset;
   nsPresContext* presContext = mFrame->PresContext();
   AutoTArray<nsRect,10> rects;
   ComputeDisjointRectangles(mVisibleRegion, &rects);
 
-  PROFILER_LABEL("nsDisplayBoxShadowOuter", "Paint",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsDisplayBoxShadowOuter::Paint", GRAPHICS);
 
   for (uint32_t i = 0; i < rects.Length(); ++i) {
     nsCSSRendering::PaintBoxShadowOuter(presContext, *aCtx, mFrame,
                                         borderRect, rects[i], mOpacity);
   }
 }
 
 nsRect
@@ -5310,18 +5308,17 @@ void
 nsDisplayBoxShadowInner::Paint(nsDisplayListBuilder* aBuilder,
                                gfxContext* aCtx) {
   nsPoint offset = ToReferenceFrame();
   nsRect borderRect = nsRect(offset, mFrame->GetSize());
   nsPresContext* presContext = mFrame->PresContext();
   AutoTArray<nsRect,10> rects;
   ComputeDisjointRectangles(mVisibleRegion, &rects);
 
-  PROFILER_LABEL("nsDisplayBoxShadowInner", "Paint",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("nsDisplayBoxShadowInner::Paint", GRAPHICS);
 
   DrawTarget* drawTarget = aCtx->GetDrawTarget();
   gfxContext* gfx = aCtx;
   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
 
   for (uint32_t i = 0; i < rects.Length(); ++i) {
     gfx->Save();
     gfx->Clip(NSRectToSnappedRect(rects[i], appUnitsPerDevPixel, *drawTarget));
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -236,18 +236,17 @@ nsStyleContext::MoveTo(nsStyleContext* a
 }
 
 template<class StyleContextLike>
 nsChangeHint
 nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext,
                                             uint32_t* aEqualStructs,
                                             uint32_t* aSamePointerStructs)
 {
-  PROFILER_LABEL("nsStyleContext", "CalcStyleDifference",
-    js::ProfileEntry::Category::CSS);
+  AUTO_PROFILER_LABEL("nsStyleContext::CalcStyleDifferenceInternal", CSS);
 
   static_assert(nsStyleStructID_Length <= 32,
                 "aEqualStructs is not big enough");
 
   *aEqualStructs = 0;
 
   nsChangeHint hint = nsChangeHint(0);
   NS_ENSURE_TRUE(aNewContext, hint);
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -1096,18 +1096,17 @@ nsStyleSet::AssertNoCSSRules(nsRuleNode*
 #endif
 
 // Enumerate the rules in a way that cares about the order of the rules.
 void
 nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
                       RuleProcessorData* aData, Element* aElement,
                       nsRuleWalker* aRuleWalker)
 {
-  PROFILER_LABEL("nsStyleSet", "FileRules",
-    js::ProfileEntry::Category::CSS);
+  AUTO_PROFILER_LABEL("nsStyleSet::FileRules", CSS);
 
   NS_ASSERTION(mBatching == 0, "rule processors out of date");
 
   // Cascading order:
   // [least important]
   //  - UA normal rules                    = Agent        normal
   //  - User normal rules                  = User         normal
   //  - Presentation hints                 = PresHint     normal
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -1203,18 +1203,17 @@ Preferences::SavePrefFileInternal(nsIFil
 
 nsresult
 Preferences::WritePrefFile(nsIFile* aFile, SaveMethod aSaveMethod)
 {
   if (!gHashTable) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  PROFILER_LABEL("Preferences", "WritePrefFile",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("Preferences::WritePrefFile", OTHER);
 
   if (AllowOffMainThreadSave()) {
 
     nsresult rv = NS_OK;
     mozilla::UniquePtr<PrefSaveData> prefs =
       MakeUnique<PrefSaveData>(pref_savePrefs(gHashTable));
 
     // Put the newly constructed preference data into sPendingWriteData
--- a/netwerk/base/nsIncrementalStreamLoader.cpp
+++ b/netwerk/base/nsIncrementalStreamLoader.cpp
@@ -82,18 +82,17 @@ nsIncrementalStreamLoader::OnStartReques
   mContext = ctxt;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsIncrementalStreamLoader::OnStopRequest(nsIRequest* request, nsISupports *ctxt,
                                          nsresult aStatus)
 {
-  PROFILER_LABEL("nsIncrementalStreamLoader", "OnStopRequest",
-    js::ProfileEntry::Category::NETWORK);
+  AUTO_PROFILER_LABEL("nsIncrementalStreamLoader::OnStopRequest", NETWORK);
 
   if (mObserver) {
     // provide nsIIncrementalStreamLoader::request during call to OnStreamComplete
     mRequest = request;
     size_t length = mData.length();
     uint8_t* elems = mData.extractOrCopyRawBuffer();
     nsresult rv = mObserver->OnStreamComplete(this, mContext, aStatus,
                                               length, elems);
--- a/netwerk/base/nsInputStreamPump.cpp
+++ b/netwerk/base/nsInputStreamPump.cpp
@@ -403,18 +403,17 @@ nsInputStreamPump::AsyncRead(nsIStreamLi
 // nsInputStreamPump::nsIInputStreamCallback implementation
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream *stream)
 {
     LOG(("nsInputStreamPump::OnInputStreamReady [this=%p]\n", this));
 
-    PROFILER_LABEL("nsInputStreamPump", "OnInputStreamReady",
-        js::ProfileEntry::Category::NETWORK);
+    AUTO_PROFILER_LABEL("nsInputStreamPump::OnInputStreamReady", NETWORK);
 
     // this function has been called from a PLEvent, so we can safely call
     // any listener or progress sink methods directly from here.
 
     for (;;) {
         // There should only be one iteration of this loop happening at a time. 
         // To prevent AsyncWait() (called during callbacks or on other threads)
         // from creating a parallel OnInputStreamReady(), we use:
@@ -509,18 +508,17 @@ nsInputStreamPump::OnInputStreamReady(ns
     return NS_OK;
 }
 
 uint32_t
 nsInputStreamPump::OnStateStart()
 {
     mMonitor.AssertCurrentThreadIn();
 
-    PROFILER_LABEL("nsInputStreamPump", "OnStateStart",
-        js::ProfileEntry::Category::NETWORK);
+    AUTO_PROFILER_LABEL("nsInputStreamPump::OnStateStart", NETWORK);
 
     LOG(("  OnStateStart [this=%p]\n", this));
 
     nsresult rv;
 
     // need to check the reason why the stream is ready.  this is required
     // so our listener can check our status from OnStartRequest.
     // XXX async streams should have a GetStatus method!
@@ -548,18 +546,17 @@ nsInputStreamPump::OnStateStart()
     return NS_SUCCEEDED(mStatus) ? STATE_TRANSFER : STATE_STOP;
 }
 
 uint32_t
 nsInputStreamPump::OnStateTransfer()
 {
     mMonitor.AssertCurrentThreadIn();
 
-    PROFILER_LABEL("nsInputStreamPump", "OnStateTransfer",
-        js::ProfileEntry::Category::NETWORK);
+    AUTO_PROFILER_LABEL("nsInputStreamPump::OnStateTransfer", NETWORK);
 
     LOG(("  OnStateTransfer [this=%p]\n", this));
 
     // if canceled, go directly to STATE_STOP...
     if (NS_FAILED(mStatus))
         return STATE_STOP;
 
     nsresult rv = CreateBufferedStreamIfNeeded();
@@ -697,18 +694,17 @@ nsInputStreamPump::OnStateStop()
         MOZ_ASSERT(NS_IsMainThread(),
                    "OnStateStop should only be called on the main thread.");
         nsresult rv = NS_DispatchToMainThread(
             NewRunnableMethod(this, &nsInputStreamPump::CallOnStateStop));
         NS_ENSURE_SUCCESS(rv, STATE_IDLE);
         return STATE_IDLE;
     }
 
-    PROFILER_LABEL("nsInputStreamPump", "OnStateStop",
-        js::ProfileEntry::Category::NETWORK);
+    AUTO_PROFILER_LABEL("nsInputStreamPump::OnStateStop", NETWORK);
 
     LOG(("  OnStateStop [this=%p status=%" PRIx32 "]\n", this, static_cast<uint32_t>(mStatus)));
 
     // if an error occurred, we must be sure to pass the error onto the async
     // stream.  in some cases, this is redundant, but since close is idempotent,
     // this is OK.  otherwise, be sure to honor the "close-when-done" option.
 
     if (!mAsyncStream || !mListener) {
--- a/netwerk/base/nsStreamLoader.cpp
+++ b/netwerk/base/nsStreamLoader.cpp
@@ -89,18 +89,17 @@ nsStreamLoader::OnStartRequest(nsIReques
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStreamLoader::OnStopRequest(nsIRequest* request, nsISupports *ctxt,
                               nsresult aStatus)
 {
-  PROFILER_LABEL("nsStreamLoader", "OnStopRequest",
-    js::ProfileEntry::Category::NETWORK);
+  AUTO_PROFILER_LABEL("nsStreamLoader::OnStopRequest", NETWORK);
 
   if (mObserver) {
     // provide nsIStreamLoader::request during call to OnStreamComplete
     mRequest = request;
     size_t length = mData.length();
     uint8_t* elems = mData.extractOrCopyRawBuffer();
     nsresult rv = mObserver->OnStreamComplete(this, mContext, aStatus,
                                               length, elems);
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -6943,18 +6943,17 @@ nsHttpChannel::GetRequestMethod(nsACStri
 // nsHttpChannel::nsIRequestObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
 {
     nsresult rv;
 
-    PROFILER_LABEL("nsHttpChannel", "OnStartRequest",
-        js::ProfileEntry::Category::NETWORK);
+    AUTO_PROFILER_LABEL("nsHttpChannel::OnStartRequest", NETWORK);
 
     if (!(mCanceled || NS_FAILED(mStatus)) && !WRONG_RACING_RESPONSE_SOURCE(request)) {
         // capture the request's status, so our consumers will know ASAP of any
         // connection failures, etc - bug 93581
         request->GetStatus(&mStatus);
     }
 
     LOG(("nsHttpChannel::OnStartRequest [this=%p request=%p status=%" PRIx32 "]\n",
@@ -7110,18 +7109,17 @@ nsHttpChannel::ContinueOnStartRequest3(n
         return NS_OK;
 
     return CallOnStartRequest();
 }
 
 NS_IMETHODIMP
 nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status)
 {
-    PROFILER_LABEL("nsHttpChannel", "OnStopRequest",
-        js::ProfileEntry::Category::NETWORK);
+    AUTO_PROFILER_LABEL("nsHttpChannel::OnStopRequest", NETWORK);
 
     LOG(("nsHttpChannel::OnStopRequest [this=%p request=%p status=%" PRIx32 "]\n",
          this, request, static_cast<uint32_t>(status)));
 
     LOG(("OnStopRequest %p requestFromCache: %d mFirstResponseSource: %d\n", this, request == mCachePump, mFirstResponseSource));
 
     MOZ_ASSERT(NS_IsMainThread(),
                "OnStopRequest should only be called from the main thread");
@@ -7484,18 +7482,17 @@ private:
 };
 
 NS_IMETHODIMP
 nsHttpChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
                                nsIInputStream *input,
                                uint64_t offset, uint32_t count)
 {
     nsresult rv;
-    PROFILER_LABEL("nsHttpChannel", "OnDataAvailable",
-        js::ProfileEntry::Category::NETWORK);
+    AUTO_PROFILER_LABEL("nsHttpChannel::OnDataAvailable", NETWORK);
 
     LOG(("nsHttpChannel::OnDataAvailable [this=%p request=%p offset=%" PRIu64
          " count=%" PRIu32 "]\n",
         this, request, offset, count));
 
     LOG(("  requestFromCache: %d mFirstResponseSource: %d\n",
         request == mCachePump, mFirstResponseSource));
 
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -343,18 +343,17 @@ class nsHtml5FlushLoopGuard
 };
 
 /**
  * The purpose of the loop here is to avoid returning to the main event loop
  */
 void
 nsHtml5TreeOpExecutor::RunFlushLoop()
 {
-  PROFILER_LABEL("nsHtml5TreeOpExecutor", "RunFlushLoop",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsHtml5TreeOpExecutor::RunFlushLoop", OTHER);
 
   if (mRunFlushLoopOnStack) {
     // There's already a RunFlushLoop() on the call stack.
     return;
   }
   
   nsHtml5FlushLoopGuard guard(this); // this is also the self-kungfu!
   
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -264,17 +264,17 @@ GetBufferFromZipArchive(nsZipArchive *zi
 
 } /* anonymous namespace */
 
 // NOTE: this will not find a new entry until it has been written to disk!
 // Consumer should take ownership of the resulting buffer.
 nsresult
 StartupCache::GetBuffer(const char* id, UniquePtr<char[]>* outbuf, uint32_t* length) 
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("StartupCache::GetBuffer", OTHER);
 
   NS_ASSERTION(NS_IsMainThread(), "Startup cache only available on main thread");
 
   WaitOnWriteThread();
   if (!mStartupWriteInitiated) {
     CacheEntry* entry; 
     nsDependentCString idStr(id);
     mTable.Get(idStr, &entry);
--- a/storage/mozStorageConnection.cpp
+++ b/storage/mozStorageConnection.cpp
@@ -617,18 +617,17 @@ Connection::getAsyncExecutionTarget()
   return mAsyncExecutionThread;
 }
 
 nsresult
 Connection::initialize()
 {
   NS_ASSERTION (!mDBConn, "Initialize called on already opened database!");
   MOZ_ASSERT(!mIgnoreLockingMode, "Can't ignore locking on an in-memory db.");
-  PROFILER_LABEL("mozStorageConnection", "initialize",
-    js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Connection::initialize", STORAGE);
 
   // in memory database requested, sqlite uses a magic file name
   int srv = ::sqlite3_open_v2(":memory:", &mDBConn, mFlags, nullptr);
   if (srv != SQLITE_OK) {
     mDBConn = nullptr;
     return convertResultCode(srv);
   }
 
@@ -641,18 +640,17 @@ Connection::initialize()
   return NS_OK;
 }
 
 nsresult
 Connection::initialize(nsIFile *aDatabaseFile)
 {
   NS_ASSERTION (aDatabaseFile, "Passed null file!");
   NS_ASSERTION (!mDBConn, "Initialize called on already opened database!");
-  PROFILER_LABEL("mozStorageConnection", "initialize",
-    js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Connection::initialize", STORAGE);
 
   mDatabaseFile = aDatabaseFile;
 
   nsAutoString path;
   nsresult rv = aDatabaseFile->GetPath(path);
   NS_ENSURE_SUCCESS(rv, rv);
 
 #ifdef XP_WIN
@@ -679,18 +677,17 @@ Connection::initialize(nsIFile *aDatabas
   return NS_OK;
 }
 
 nsresult
 Connection::initialize(nsIFileURL *aFileURL)
 {
   NS_ASSERTION (aFileURL, "Passed null file URL!");
   NS_ASSERTION (!mDBConn, "Initialize called on already opened database!");
-  PROFILER_LABEL("mozStorageConnection", "initialize",
-    js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Connection::initialize", STORAGE);
 
   nsCOMPtr<nsIFile> databaseFile;
   nsresult rv = aFileURL->GetFile(getter_AddRefs(databaseFile));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString spec;
   rv = aFileURL->GetSpec(spec);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1428,18 +1425,17 @@ Connection::AsyncClose(mozIStorageComple
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Connection::AsyncClone(bool aReadOnly,
                        mozIStorageCompletionCallback *aCallback)
 {
-  PROFILER_LABEL("mozStorageConnection", "AsyncClone",
-    js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Connection::AsyncClone", STORAGE);
 
   NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_NOT_SAME_THREAD);
   if (!mDBConn)
     return NS_ERROR_NOT_INITIALIZED;
   if (!mDatabaseFile)
     return NS_ERROR_UNEXPECTED;
 
   int flags = mFlags;
@@ -1560,18 +1556,17 @@ Connection::initializeClone(Connection* 
 }
 
 NS_IMETHODIMP
 Connection::Clone(bool aReadOnly,
                   mozIStorageConnection **_connection)
 {
   MOZ_ASSERT(threadOpenedOn == NS_GetCurrentThread());
 
-  PROFILER_LABEL("mozStorageConnection", "Clone",
-    js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Connection::Clone", STORAGE);
 
   if (!mDBConn)
     return NS_ERROR_NOT_INITIALIZED;
   if (!mDatabaseFile)
     return NS_ERROR_UNEXPECTED;
 
   int flags = mFlags;
   if (aReadOnly) {
--- a/storage/mozStorageStatement.cpp
+++ b/storage/mozStorageStatement.cpp
@@ -550,18 +550,17 @@ Statement::Execute()
   nsresult rv2 = Reset();
 
   return NS_FAILED(rv) ? rv : rv2;
 }
 
 NS_IMETHODIMP
 Statement::ExecuteStep(bool *_moreResults)
 {
-  PROFILER_LABEL("Statement", "ExecuteStep",
-    js::ProfileEntry::Category::STORAGE);
+  AUTO_PROFILER_LABEL("Statement::ExecuteStep", STORAGE);
 
   if (!mDBStatement)
     return NS_ERROR_NOT_INITIALIZED;
 
   // Bind any parameters first before executing.
   if (mParamsArray) {
     // If we have more than one row of parameters to bind, they shouldn't be
     // calling this method (and instead use executeAsync).
--- a/toolkit/components/places/nsAnnotationService.cpp
+++ b/toolkit/components/places/nsAnnotationService.cpp
@@ -261,18 +261,17 @@ nsAnnotationService::SetPageAnnotation(n
 NS_IMETHODIMP
 nsAnnotationService::SetItemAnnotation(int64_t aItemId,
                                        const nsACString& aName,
                                        nsIVariant* aValue,
                                        int32_t aFlags,
                                        uint16_t aExpiration,
                                        uint16_t aSource)
 {
-  PROFILER_LABEL("AnnotationService", "SetItemAnnotation",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsAnnotationService::SetItemAnnotation", OTHER);
 
   NS_ENSURE_ARG_MIN(aItemId, 1);
   NS_ENSURE_ARG(aValue);
 
   if (aExpiration == EXPIRE_WITH_HISTORY)
     return NS_ERROR_INVALID_ARG;
 
   uint16_t dataType;
--- a/toolkit/components/places/nsNavBookmarks.cpp
+++ b/toolkit/components/places/nsNavBookmarks.cpp
@@ -680,18 +680,17 @@ nsNavBookmarks::InsertBookmark(int64_t a
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsNavBookmarks::RemoveItem(int64_t aItemId, uint16_t aSource)
 {
-  PROFILER_LABEL("nsNavBookmarks", "RemoveItem",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsNavBookmarks::RemoveItem", OTHER);
 
   NS_ENSURE_ARG(!IsRoot(aItemId));
 
   BookmarkData bookmark;
   nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mozStorageTransaction transaction(mDB->MainConn(), false);
@@ -1171,18 +1170,17 @@ nsNavBookmarks::GetDescendantChildren(in
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsNavBookmarks::RemoveFolderChildren(int64_t aFolderId, uint16_t aSource)
 {
-  PROFILER_LABEL("nsNavBookmarks", "RemoveFolderChilder",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsNavBookmarks::RemoveFolderChilder", OTHER);
 
   NS_ENSURE_ARG_MIN(aFolderId, 1);
   NS_ENSURE_ARG(aFolderId != mRoot);
 
   BookmarkData folder;
   nsresult rv = FetchItemInfo(aFolderId, folder);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_ARG(folder.type == TYPE_FOLDER);
@@ -3086,18 +3084,17 @@ nsNavBookmarks::GetKeywordForBookmark(in
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsNavBookmarks::RunInBatchMode(nsINavHistoryBatchCallback* aCallback,
                                nsISupports* aUserData) {
-  PROFILER_LABEL("nsNavBookmarks", "RunInBatchMode",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsNavBookmarks::RunInBatchMode", OTHER);
 
   NS_ENSURE_ARG(aCallback);
 
   mBatching = true;
 
   // Just forward the request to history.  History service must exist for
   // bookmarks to work and we are observing it, thus batch notifications will be
   // forwarded to bookmarks observers.
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
@@ -1888,17 +1888,18 @@ nsUrlClassifierDBService::ClassifyLocalW
                                                                   &rv,
                                                                   &aTableResults);
     if (result) {
       return rv;
     }
     return NS_ERROR_FAILURE;
   }
 
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsUrlClassifierDBService::ClassifyLocalWithTables",
+                      OTHER);
   Telemetry::AutoTimer<Telemetry::URLCLASSIFIER_CLASSIFYLOCAL_TIME> timer;
 
   nsCOMPtr<nsIURI> uri = NS_GetInnermostURI(aURI);
   NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
 
   nsAutoCString key;
   // Canonicalize the url
   nsCOMPtr<nsIUrlClassifierUtils> utilsService =
--- a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
+++ b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
@@ -173,17 +173,17 @@ nsWindowsSystemProxySettings::PatternMat
                                            const nsACString& aOverride)
 {
     return mozilla::toolkit::system::IsHostProxyEntry(aHost, aOverride);
 }
 
 nsresult
 nsWindowsSystemProxySettings::GetPACURI(nsACString& aResult)
 {
-    PROFILER_LABEL_FUNC(js::ProfileEntry::Category::STORAGE);
+    AUTO_PROFILER_LABEL("nsWindowsSystemProxySettings::GetPACURI", OTHER);
     nsresult rv;
     uint32_t flags = 0;
     nsAutoString buf;
 
     rv = ReadInternetOption(INTERNET_PER_CONN_AUTOCONFIG_URL, flags, buf);
     if (!(flags & PROXY_TYPE_AUTO_PROXY_URL)) {
         aResult.Truncate();
         return rv;
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -4653,18 +4653,17 @@ XREMain::XRE_main(int argc, char* argv[]
 
 #ifdef MOZ_CODE_COVERAGE
   CodeCoverageHandler::Init();
 #endif
 
   char aLocal;
   AutoProfilerInit profilerInit(&aLocal);
 
-  PROFILER_LABEL("Startup", "XRE_Main",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("XREMain::XRE_main", OTHER);
 
   nsresult rv = NS_OK;
 
   gArgc = argc;
   gArgv = argv;
 
   if (aConfig.appData) {
       mAppData = MakeUnique<XREAppData>(*aConfig.appData);
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -417,18 +417,17 @@ XRE_InitChildProcess(int aArgc,
   // See bug 1279614.
   Telemetry::CreateStatisticsRecorder();
 
   mozilla::LogModule::Init();
 
   char aLocal;
   AutoProfilerInit profilerInit(&aLocal);
 
-  PROFILER_LABEL("Startup", "XRE_InitChildProcess",
-    js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("XRE_InitChildProcess", OTHER);
 
   // Ensure AbstractThread is minimally setup, so async IPC messages
   // work properly.
   AbstractThread::InitTLS();
 
   // Complete 'task_t' exchange for Mac OS X. This structure has the same size
   // regardless of architecture so we don't have any cross-arch issues here.
 #ifdef XP_MACOSX
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -1083,17 +1083,17 @@ nsXREDirProvider::DoStartup()
 #endif
   }
   return NS_OK;
 }
 
 void
 nsXREDirProvider::DoShutdown()
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsXREDirProvider::DoShutdown", OTHER);
 
   if (mProfileNotified) {
     nsCOMPtr<nsIObserverService> obsSvc =
       mozilla::services::GetObserverService();
     NS_ASSERTION(obsSvc, "No observer service?");
     if (obsSvc) {
       static const char16_t kShutdownPersist[] = u"shutdown-persist";
       obsSvc->NotifyObservers(nullptr, "profile-change-net-teardown", kShutdownPersist);
--- a/tools/profiler/public/GeckoProfiler.h
+++ b/tools/profiler/public/GeckoProfiler.h
@@ -319,60 +319,51 @@ PROFILER_FUNC(PseudoStack* profiler_get_
 //---------------------------------------------------------------------------
 
 #define PROFILER_APPEND_LINE_NUMBER_PASTE(id, line) id ## line
 #define PROFILER_APPEND_LINE_NUMBER_EXPAND(id, line) \
   PROFILER_APPEND_LINE_NUMBER_PASTE(id, line)
 #define PROFILER_APPEND_LINE_NUMBER(id) \
   PROFILER_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
 
-#if defined(__GNUC__) || defined(_MSC_VER)
-# define PROFILER_FUNCTION_NAME __FUNCTION__
-#else
-  // From C99, supported by some C++ compilers. Just the raw function name.
-# define PROFILER_FUNCTION_NAME __func__
-#endif
-
 // Insert an RAII object in this scope to enter a pseudo stack frame. Any
 // samples collected in this scope will contain this label in their pseudo
-// stack. The name_space and info arguments must be string literals.
-// Use PROFILER_LABEL_DYNAMIC if you want to add additional / dynamic
+// stack. The label argument must be a string literal. It is usually of the
+// form "ClassName::FunctionName". (Ideally we'd use the compiler to provide
+// that for us, but __func__ gives us the function name without the class
+// name.) If the label applies to only part of a function, you can qualify it
+// like this: "ClassName::FunctionName:PartName".
+//
+// Use AUTO_PROFILER_LABEL_DYNAMIC if you want to add additional / dynamic
 // information to the pseudo stack frame.
-#define PROFILER_LABEL(name_space, info, category) \
+#define AUTO_PROFILER_LABEL(label, category) \
   mozilla::AutoProfilerLabel \
-  PROFILER_APPEND_LINE_NUMBER(profiler_raii)(name_space "::" info, nullptr, \
-                                             __LINE__, category)
+  PROFILER_APPEND_LINE_NUMBER(profiler_raii)( \
+    label, nullptr, __LINE__, js::ProfileEntry::Category::category)
 
-// Similar to PROFILER_LABEL, PROFILER_LABEL_FUNC will push/pop the enclosing
-// functon name as the pseudostack label.
-#define PROFILER_LABEL_FUNC(category) \
-  mozilla::AutoProfilerLabel \
-  PROFILER_APPEND_LINE_NUMBER(profiler_raii)(PROFILER_FUNCTION_NAME, nullptr, \
-                                             __LINE__, category)
-
-// Similar to PROFILER_LABEL, but with an additional string. The inserted RAII
-// object stores the dynamicStr pointer in a field; it does not copy the string.
-// This means that the string you pass to this macro needs to live at least
-// until the end of the current scope.
+// Similar to AUTO_PROFILER_LABEL, but with an additional string. The inserted
+// RAII object stores the dynamicStr pointer in a field; it does not copy the
+// string. This means that the string you pass to this macro needs to live at
+// least until the end of the current scope.
 //
 // If the profiler samples the current thread and walks the pseudo stack while
 // this RAII object is on the stack, it will copy the supplied string into the
 // profile buffer. So there's one string copy operation, and it happens at
 // sample time.
 //
-// Compare this to the plain PROFILER_LABEL macro, which only accepts literal
-// strings: When the pseudo stack frames generated by PROFILER_LABEL are
-// sampled, no string copy needs to be made because the profile buffer can
-// just store the raw pointers to the literal strings. Consequently,
-// PROFILER_LABEL frames take up considerably less space in the profile buffer
-// than PROFILER_LABEL_DYNAMIC frames.
-#define PROFILER_LABEL_DYNAMIC(name_space, info, category, dynamicStr) \
+// Compare this to the plain AUTO_PROFILER_LABEL macro, which only accepts
+// literal strings: When the pseudo stack frames generated by
+// AUTO_PROFILER_LABEL are sampled, no string copy needs to be made because the
+// profile buffer can just store the raw pointers to the literal strings.
+// Consequently, AUTO_PROFILER_LABEL frames take up considerably less space in
+// the profile buffer than AUTO_PROFILER_LABEL_DYNAMIC frames.
+#define AUTO_PROFILER_LABEL_DYNAMIC(label, category, dynamicStr) \
   mozilla::AutoProfilerLabel \
-  PROFILER_APPEND_LINE_NUMBER(profiler_raii)(name_space "::" info, dynamicStr, \
-                                             __LINE__, category)
+  PROFILER_APPEND_LINE_NUMBER(profiler_raii)( \
+    label, dynamicStr, __LINE__, js::ProfileEntry::Category::category)
 
 // Insert a marker in the profile timeline. This is useful to delimit something
 // important happening such as the first paint. Unlike labels, which are only
 // recorded in the profile buffer if a sample is collected while the label is
 // on the pseudostack, markers will always be recorded in the profile buffer.
 // A no-op if the profiler is inactive or in privacy mode.
 PROFILER_FUNC_VOID(profiler_add_marker(const char* aMarkerName))
 PROFILER_FUNC_VOID(
--- a/tools/profiler/tests/gtest/GeckoProfiler.cpp
+++ b/tools/profiler/tests/gtest/GeckoProfiler.cpp
@@ -562,23 +562,21 @@ TEST(GeckoProfiler, StreamJSONForThisPro
   ASSERT_TRUE(!profiler_stream_json_for_this_process(w));
 }
 
 TEST(GeckoProfiler, PseudoStack)
 {
   uint32_t features = ProfilerFeature::StackWalk;
   const char* filters[] = { "GeckoMain" };
 
-  PROFILER_LABEL("A", "B", js::ProfileEntry::Category::OTHER);
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("A::B", OTHER);
 
   UniqueFreePtr<char> dynamic(strdup("dynamic"));
   {
-    PROFILER_LABEL_DYNAMIC("A", "C", js::ProfileEntry::Category::JS,
-                           dynamic.get());
+    AUTO_PROFILER_LABEL_DYNAMIC("A::C", JS, dynamic.get());
 
     profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
                    features, filters, MOZ_ARRAY_LENGTH(filters));
 
     ASSERT_TRUE(profiler_get_backtrace());
   }
 
   AutoProfilerLabel label1("A", nullptr, 888,
--- a/view/nsViewManager.cpp
+++ b/view/nsViewManager.cpp
@@ -748,18 +748,17 @@ void nsViewManager::DidPaintWindow()
   }
 }
 
 void
 nsViewManager::DispatchEvent(WidgetGUIEvent *aEvent,
                              nsView* aView,
                              nsEventStatus* aStatus)
 {
-  PROFILER_LABEL("nsViewManager", "DispatchEvent",
-    js::ProfileEntry::Category::EVENTS);
+  AUTO_PROFILER_LABEL("nsViewManager::DispatchEvent", EVENTS);
 
   WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
   if ((mouseEvent &&
        // Ignore mouse events that we synthesize.
        mouseEvent->mReason == WidgetMouseEvent::eReal &&
        // Ignore mouse exit and enter (we'll get moves if the user
        // is really moving the mouse) since we get them when we
        // create and destroy widgets.
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -672,18 +672,17 @@ nsAppShell::Observe(nsISupports* aSubjec
     return NS_OK;
 }
 
 bool
 nsAppShell::ProcessNextNativeEvent(bool mayWait)
 {
     EVLOG("nsAppShell::ProcessNextNativeEvent %d", mayWait);
 
-    PROFILER_LABEL("nsAppShell", "ProcessNextNativeEvent",
-        js::ProfileEntry::Category::EVENTS);
+    AUTO_PROFILER_LABEL("nsAppShell::ProcessNextNativeEvent", EVENTS);
 
     mozilla::UniquePtr<Event> curEvent;
 
     {
         curEvent = mEventQueue.Pop(/* mayWait */ false);
 
         if (!curEvent && mayWait) {
             // This processes messages in the Android Looper. Note that we only
@@ -691,18 +690,18 @@ nsAppShell::ProcessNextNativeEvent(bool 
             // (bug 750713). Looper messages effectively have the lowest
             // priority because we only process them before we're about to
             // wait for new events.
             if (jni::IsAvailable() && XRE_IsParentProcess() &&
                     AndroidBridge::Bridge()->PumpMessageLoop()) {
                 return true;
             }
 
-            PROFILER_LABEL("nsAppShell", "ProcessNextNativeEvent::Wait",
-                js::ProfileEntry::Category::EVENTS);
+            AUTO_PROFILER_LABEL("nsAppShell::ProcessNextNativeEvent:Wait",
+                                EVENTS);
             mozilla::HangMonitor::Suspend();
 
             curEvent = mEventQueue.Pop(/* mayWait */ true);
         }
     }
 
     if (!curEvent)
         return false;
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -76,17 +76,17 @@ using mozilla::Unused;
 #include "GeneratedJNINatives.h"
 #include "GeckoEditableSupport.h"
 #include "KeyEvent.h"
 #include "MotionEvent.h"
 
 #include "imgIEncoder.h"
 
 #include "nsString.h"
-#include "GeckoProfiler.h" // For PROFILER_LABEL
+#include "GeckoProfiler.h" // For AUTO_PROFILER_LABEL
 #include "nsIXULRuntime.h"
 #include "nsPrintfCString.h"
 
 #include "mozilla/ipc/Shmem.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
@@ -1248,18 +1248,17 @@ nsWindow::GeckoViewSupport::Open(const j
                                  jni::Object::Param aDispatcher,
                                  jni::String::Param aChromeURI,
                                  jni::Object::Param aSettings,
                                  int32_t aScreenId,
                                  bool aPrivateMode)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
-    PROFILER_LABEL("nsWindow", "GeckoViewSupport::Open",
-                   js::ProfileEntry::Category::OTHER);
+    AUTO_PROFILER_LABEL("nsWindow::GeckoViewSupport::Open", OTHER);
 
     nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
     MOZ_RELEASE_ASSERT(ww);
 
     nsAdoptingCString url;
     if (aChromeURI) {
         url = aChromeURI->ToCString();
     } else {
--- a/widget/cocoa/nsAppShell.mm
+++ b/widget/cocoa/nsAppShell.mm
@@ -357,18 +357,17 @@ nsAppShell::Init()
 // to ScheduleNativeEventCallback(), if processing of Gecko events via "native
 // methods" hasn't been suspended).  This happens in NativeEventCallback().
 //
 // protected static
 void
 nsAppShell::ProcessGeckoEvents(void* aInfo)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-  PROFILER_LABEL("Events", "ProcessGeckoEvents",
-    js::ProfileEntry::Category::EVENTS);
+  AUTO_PROFILER_LABEL("nsAppShell::ProcessGeckoEvents", EVENTS);
 
   nsAppShell* self = static_cast<nsAppShell*> (aInfo);
 
   if (self->mRunningEventLoop) {
     self->mRunningEventLoop = false;
 
     // The run loop may be sleeping -- [NSRunLoop runMode:...]
     // won't return until it's given a reason to wake up.  Awaken it by
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -3802,18 +3802,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
     mGeckoChild->ClearVibrantAreas();
     [self clearCorners];
 
     // Do GL composition and return.
     [self drawUsingOpenGL];
     return;
   }
 
-  PROFILER_LABEL("ChildView", "drawRect",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ChildView::drawRect", GRAPHICS);
 
   // The CGContext that drawRect supplies us with comes with a transform that
   // scales one user space unit to one Cocoa point, which can consist of
   // multiple dev pixels. But Gecko expects its supplied context to be scaled
   // to device pixels, so we need to reverse the scaling.
   double scale = mGeckoChild->BackingScaleFactor();
   CGContextSaveGState(aContext);
   CGContextScaleCTM(aContext, 1.0 / scale, 1.0 / scale);
@@ -3870,18 +3869,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
   if (!mGeckoChild || ![self window])
     return NO;
 
   return mGLContext || mUsingOMTCompositor || [self isUsingMainThreadOpenGL];
 }
 
 - (void)drawUsingOpenGL
 {
-  PROFILER_LABEL("ChildView", "drawUsingOpenGL",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ChildView::drawUsingOpenGL", GRAPHICS);
 
   if (![self isUsingOpenGL] || !mGeckoChild->IsVisible())
     return;
 
   mWaitingForPaint = NO;
 
   LayoutDeviceIntRect geckoBounds = mGeckoChild->GetBounds();
   LayoutDeviceIntRegion region(geckoBounds);
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -1489,17 +1489,17 @@ nsWindow::GetClientBounds()
     LayoutDeviceIntRect rect = GetBounds();
     rect.MoveBy(GetClientOffset());
     return rect;
 }
 
 void
 nsWindow::UpdateClientOffset()
 {
-    PROFILER_LABEL("nsWindow", "UpdateClientOffset", js::ProfileEntry::Category::GRAPHICS);
+    AUTO_PROFILER_LABEL("nsWindow::UpdateClientOffset", GRAPHICS);
 
     if (!mIsTopLevel || !mShell || !mGdkWindow || !mIsX11Display ||
         gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP) {
         mClientOffset = nsIntPoint(0, 0);
         return;
     }
 
     GdkAtom cardinal_atom = gdk_x11_xatom_to_atom(XA_CARDINAL);
--- a/widget/nsBaseDragService.cpp
+++ b/widget/nsBaseDragService.cpp
@@ -206,17 +206,17 @@ nsBaseDragService::SetDataTransfer(nsIDO
 NS_IMETHODIMP
 nsBaseDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
                                      nsIArray* aTransferableArray,
                                      nsIScriptableRegion* aDragRgn,
                                      uint32_t aActionType,
                                      nsContentPolicyType aContentPolicyType =
                                        nsIContentPolicy::TYPE_OTHER)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsBaseDragService::InvokeDragSession", OTHER);
 
   NS_ENSURE_TRUE(aDOMNode, NS_ERROR_INVALID_ARG);
   NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
 
   // stash the document of the dom node
   aDOMNode->GetOwnerDocument(getter_AddRefs(mSourceDocument));
   mSourceNode = aDOMNode;
   mContentPolicyType = aContentPolicyType;
--- a/widget/uikit/nsWindow.mm
+++ b/widget/uikit/nsWindow.mm
@@ -265,18 +265,17 @@ private:
     return NO;
 
   return mGeckoChild->GetLayerManager(nullptr)->GetBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL;
 }
 
 - (void)drawUsingOpenGL
 {
     ALOG("drawUsingOpenGL");
-  PROFILER_LABEL("ChildView", "drawUsingOpenGL",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ChildView::drawUsingOpenGL", GRAPHICS);
 
   if (!mGeckoChild->IsVisible())
     return;
 
   mWaitingForPaint = NO;
 
   LayoutDeviceIntRect geckoBounds = mGeckoChild->GetBounds();
   LayoutDeviceIntRegion region(geckoBounds);
@@ -321,18 +320,17 @@ private:
     // drawRect.
     // Paints that come through here are triggered by something that Cocoa
     // controls, for example by window resizing or window focus changes.
 
     // Do GL composition and return.
     [self drawUsingOpenGL];
     return;
   }
-  PROFILER_LABEL("ChildView", "drawRect",
-    js::ProfileEntry::Category::GRAPHICS);
+  AUTO_PROFILER_LABEL("ChildView::drawRect", GRAPHICS);
 
   // The CGContext that drawRect supplies us with comes with a transform that
   // scales one user space unit to one Cocoa point, which can consist of
   // multiple dev pixels. But Gecko expects its supplied context to be scaled
   // to device pixels, so we need to reverse the scaling.
   double scale = mGeckoChild->BackingScaleFactor();
   CGContextSaveGState(aContext);
   CGContextScaleCTM(aContext, 1.0 / scale, 1.0 / scale);
--- a/widget/windows/nsFilePicker.cpp
+++ b/widget/windows/nsFilePicker.cpp
@@ -419,17 +419,17 @@ nsFilePicker::ShowFolderPicker(const nsS
  *
  * @param aInitialDir   The initial directory, the last used directory will be
  *                      used if left blank.
  * @return true if a file was selected successfully.
 */
 bool
 nsFilePicker::ShowFilePicker(const nsString& aInitialDir)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsFilePicker::ShowFilePicker", OTHER);
 
   if (!IsWin8OrLater()) {
     // Some Windows 7 users are experiencing a race condition when some dlls
     // that are loaded by the file picker cause a crash while attempting to shut
     // down the COM multithreaded apartment. By instantiating EnsureMTA, we hold
     // an additional reference to the MTA that should prevent this race, since
     // the MTA will remain alive until shutdown.
     EnsureMTA ensureMTA;
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -4126,18 +4126,17 @@ nsCycleCollector_forgetSkippable(bool aR
                                  bool aAsyncSnowWhiteFreeing)
 {
   CollectorData* data = sCollectorData.get();
 
   // We should have started the cycle collector by now.
   MOZ_ASSERT(data);
   MOZ_ASSERT(data->mCollector);
 
-  PROFILER_LABEL("nsCycleCollector", "forgetSkippable",
-                 js::ProfileEntry::Category::CC);
+  AUTO_PROFILER_LABEL("nsCycleCollector_forgetSkippable", CC);
 
   TimeLog timeLog;
   data->mCollector->ForgetSkippable(aRemoveChildlessNodes,
                                     aAsyncSnowWhiteFreeing);
   timeLog.Checkpoint("ForgetSkippable()");
 }
 
 void
@@ -4173,35 +4172,33 @@ void
 nsCycleCollector_collect(nsICycleCollectorListener* aManualListener)
 {
   CollectorData* data = sCollectorData.get();
 
   // We should have started the cycle collector by now.
   MOZ_ASSERT(data);
   MOZ_ASSERT(data->mCollector);
 
-  PROFILER_LABEL("nsCycleCollector", "collect",
-                 js::ProfileEntry::Category::CC);
+  AUTO_PROFILER_LABEL("nsCycleCollector_collect", CC);
 
   SliceBudget unlimitedBudget = SliceBudget::unlimited();
   data->mCollector->Collect(ManualCC, unlimitedBudget, aManualListener);
 }
 
 void
 nsCycleCollector_collectSlice(SliceBudget& budget,
                               bool aPreferShorterSlices)
 {
   CollectorData* data = sCollectorData.get();
 
   // We should have started the cycle collector by now.
   MOZ_ASSERT(data);
   MOZ_ASSERT(data->mCollector);
 
-  PROFILER_LABEL("nsCycleCollector", "collectSlice",
-                 js::ProfileEntry::Category::CC);
+  AUTO_PROFILER_LABEL("nsCycleCollector_collectSlice", CC);
 
   data->mCollector->Collect(SliceCC, budget, nullptr, aPreferShorterSlices);
 }
 
 void
 nsCycleCollector_prepareForGarbageCollection()
 {
   CollectorData* data = sCollectorData.get();
@@ -4231,18 +4228,17 @@ nsCycleCollector_finishAnyCurrentCollect
 
 void
 nsCycleCollector_shutdown(bool aDoCollect)
 {
   CollectorData* data = sCollectorData.get();
 
   if (data) {
     MOZ_ASSERT(data->mCollector);
-    PROFILER_LABEL("nsCycleCollector", "shutdown",
-                   js::ProfileEntry::Category::CC);
+    AUTO_PROFILER_LABEL("nsCycleCollector_shutdown", CC);
 
     if (gMainThreadCollector == data->mCollector) {
       gMainThreadCollector = nullptr;
     }
     data->mCollector->Shutdown(aDoCollect);
     data->mCollector = nullptr;
     if (data->mContext) {
       // Run any remaining tasks that may have been enqueued via
--- a/xpcom/ds/nsObserverService.cpp
+++ b/xpcom/ds/nsObserverService.cpp
@@ -279,18 +279,18 @@ NS_IMETHODIMP nsObserverService::NotifyO
 
   NS_ENSURE_VALIDCALL
   if (NS_WARN_IF(!aTopic)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   mozilla::TimeStamp start = TimeStamp::Now();
 
-  PROFILER_LABEL_DYNAMIC("nsObserverService", "NotifyObservers",
-                         js::ProfileEntry::Category::OTHER, aTopic);
+  AUTO_PROFILER_LABEL_DYNAMIC("nsObserverService::NotifyObservers", OTHER,
+                              aTopic);
 
   nsObserverList* observerList = mObserverTopicTable.GetEntry(aTopic);
   if (observerList) {
     observerList->NotifyObservers(aSubject, aTopic, aSomeData);
   }
 
 #ifdef NOTIFY_GLOBAL_OBSERVERS
   observerList = mObserverTopicTable.GetEntry("*");
--- a/xpcom/io/FileUtilsWin.cpp
+++ b/xpcom/io/FileUtilsWin.cpp
@@ -35,17 +35,17 @@ typedef mozilla::Scoped<ScopedMappedView
 } // namespace
 
 namespace mozilla {
 
 bool
 HandleToFilename(HANDLE aHandle, const LARGE_INTEGER& aOffset,
                  nsAString& aFilename)
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::NETWORK);
+  AUTO_PROFILER_LABEL("HandletoFilename", NETWORK);
 
   aFilename.Truncate();
   // This implementation is nice because it uses fully documented APIs that
   // are available on all Windows versions that we support.
   nsAutoHandle fileMapping(CreateFileMapping(aHandle, nullptr, PAGE_READONLY,
                                              0, 1, nullptr));
   if (!fileMapping) {
     return false;
--- a/xpcom/io/nsLocalFileWin.cpp
+++ b/xpcom/io/nsLocalFileWin.cpp
@@ -1011,17 +1011,17 @@ nsLocalFile::ResolveShortcut()
 nsresult
 nsLocalFile::ResolveAndStat()
 {
   // if we aren't dirty then we are already done
   if (!mDirty) {
     return NS_OK;
   }
 
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsLocalFile::ResolveAndStat", OTHER);
   // we can't resolve/stat anything that isn't a valid NSPR addressable path
   if (mWorkingPath.IsEmpty()) {
     return NS_ERROR_FILE_INVALID_PATH;
   }
 
   // this is usually correct
   mResolvedPath.Assign(mWorkingPath);
 
--- a/xpcom/threads/nsTimerImpl.cpp
+++ b/xpcom/threads/nsTimerImpl.cpp
@@ -486,18 +486,17 @@ nsTimerImpl::Fire(int32_t aGeneration)
     oldDelay = mDelay.ToMilliseconds();
     oldTimeout = mTimeout;
     // Ensure that the nsITimer does not unhook from the nsTimerImpl during
     // Fire; this will cause null pointer crashes if the user of the timer drops
     // its reference, and then uses the nsITimer* passed in the callback.
     kungFuDeathGrip = mITimer;
   }
 
-  PROFILER_LABEL("Timer", "Fire",
-                 js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsTimerImpl::Fire", OTHER);
 
   TimeStamp now = TimeStamp::Now();
   if (MOZ_LOG_TEST(GetTimerLog(), LogLevel::Debug)) {
     TimeDuration   delta = now - oldTimeout;
     int32_t       d = delta.ToMilliseconds(); // delta in ms
     sDeltaSum += abs(d);
     sDeltaSumSquared += double(d) * double(d);
     sDeltaNum++;
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -366,17 +366,17 @@ NS_IMETHODIMP nsXULWindow::AddChildWindo
 NS_IMETHODIMP nsXULWindow::RemoveChildWindow(nsIXULWindow *aChild)
 {
   // we're not really keeping track of this right now
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULWindow::ShowModal()
 {
-  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
+  AUTO_PROFILER_LABEL("nsXULWindow::ShowModal", OTHER);
 
   // Store locally so it doesn't die on us
   nsCOMPtr<nsIWidget> window = mWindow;
   nsCOMPtr<nsIXULWindow> tempRef = this;  
 
   window->SetModal(true);
   mContinueModalLoop = true;
   EnableParent(false);