Bug 1403868 (part 4) - Reduce tools/profiler/public/*.h to almost nothing in non-MOZ_GECKO_PROFILER builds. r=mstange.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 04 Oct 2017 09:11:18 +1100
changeset 385096 672b02d8600717613ffe84ee46de8b277f1bc977
parent 385095 530bb3db13ad9a3fcb37d35dd5520e3e23b2e5cd
child 385097 613f64109bdef590b9748355441b3c620efa7be5
child 385171 373a038aafbd1f59db53fa4bb07e407d149611e0
push id52884
push userarchaeopteryx@coole-files.de
push dateMon, 09 Oct 2017 09:23:46 +0000
treeherderautoland@f2f6cc2e67ca [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1403868
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1403868 (part 4) - Reduce tools/profiler/public/*.h to almost nothing in non-MOZ_GECKO_PROFILER builds. r=mstange. Currently the Gecko Profiler defines a moderate amount of stuff when MOZ_GECKO_PROFILER is undefined. It also #includes various headers, including JS ones. This is making it difficult to separate Gecko's media stack for inclusion in Servo. This patch greatly simplifies how things are exposed. The starting point is: - GeckoProfiler.h can be #included unconditionally; - everything else from the profiler must be guarded by MOZ_GECKO_PROFILER. In practice this introduces way too many #ifdefs, so the patch loosens it by adding no-op macros for a number of the most common operations. The net result is that #ifdefs and macros are used a bit more, but almost nothing is exposed in non-MOZ_GECKO_PROFILER builds (including ProfilerMarkerPayload.h and GeckoProfiler.h), and understanding what is exposed is much simpler than before. Note also that in BHR, ThreadStackHelper is now entirely absent in non-MOZ_GECKO_PROFILER builds.
accessible/generic/Accessible.cpp
dom/base/nsDOMNavigationTiming.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsFrameMessageManager.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSUtils.cpp
dom/base/nsJSUtils.h
dom/events/EventListenerManager.cpp
dom/indexedDB/ProfilerHelpers.h
dom/media/webaudio/blink/HRTFDatabaseLoader.cpp
dom/performance/Performance.cpp
dom/storage/StorageDBThread.cpp
dom/vr/VRDisplay.cpp
dom/workers/RuntimeService.cpp
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ContentClient.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TiledContentClient.cpp
gfx/layers/composite/ContainerLayerComposite.cpp
gfx/layers/composite/LayerManagerComposite.cpp
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TiledContentHost.cpp
gfx/layers/ipc/CompositorBench.cpp
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/thebes/ContextStateTracker.cpp
gfx/vr/VRDisplayHost.cpp
gfx/vr/ipc/VRManagerChild.cpp
gfx/webrender_bindings/RenderThread.cpp
image/DecodePool.cpp
ipc/chromium/src/base/message_pump_default.cc
ipc/chromium/src/base/thread.cc
ipc/glue/GeckoChildProcessHost.cpp
ipc/ipdl/ipdl/lower.py
ipc/mscom/MainThreadInvoker.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSContext.cpp
js/xpconnect/src/XPCShellImpl.cpp
layout/base/PresShell.cpp
layout/base/RestyleTracker.cpp
layout/base/RestyleTracker.h
layout/base/nsLayoutUtils.cpp
layout/base/nsRefreshDriver.cpp
layout/base/nsRefreshDriver.h
layout/generic/nsGfxScrollFrame.cpp
layout/painting/nsDisplayList.cpp
layout/style/ServoBindings.cpp
netwerk/dns/nsHostResolver.cpp
security/manager/ssl/nsKeygenThread.cpp
security/manager/ssl/nsProtectedAuthThread.cpp
security/manager/ssl/nsSmartCardMonitor.cpp
startupcache/StartupCache.cpp
toolkit/components/backgroundhangmonitor/BackgroundHangMonitor.cpp
toolkit/components/backgroundhangmonitor/ThreadStackHelper.h
toolkit/components/backgroundhangmonitor/moz.build
toolkit/components/startup/StartupTimeline.h
toolkit/components/startup/nsAppStartup.cpp
toolkit/components/telemetry/CombinedStacks.h
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/terminator/nsTerminator.cpp
toolkit/xre/EventTracer.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbedFunctions.cpp
tools/profiler/moz.build
tools/profiler/public/GeckoProfiler.h
tools/profiler/public/ProfilerMarkerPayload.h
tools/profiler/tests/gtest/GeckoProfiler.cpp
widget/android/ANRReporter.cpp
widget/cocoa/nsChildView.mm
widget/gtk/nsAppShell.cpp
widget/windows/nsAppShell.cpp
xpcom/base/CycleCollectedJSRuntime.cpp
xpcom/base/nsMemoryReporterManager.cpp
xpcom/build/MainThreadIOLogger.cpp
xpcom/build/XPCOMInit.cpp
xpcom/threads/BlockingResourceBase.cpp
xpcom/threads/CondVar.h
xpcom/threads/HangMonitor.cpp
xpcom/threads/ReentrantMonitor.h
xpcom/threads/Scheduler.cpp
xpcom/threads/nsProcessCommon.cpp
xpcom/threads/nsThread.cpp
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -840,24 +840,26 @@ Accessible::XULElmName(DocAccessible* aD
   }
 }
 
 nsresult
 Accessible::HandleAccEvent(AccEvent* aEvent)
 {
   NS_ENSURE_ARG_POINTER(aEvent);
 
+#ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
     nsAutoCString strEventType;
     GetAccService()->GetStringEventType(aEvent->GetEventType(), strEventType);
     nsAutoCString strMarker;
     strMarker.AppendLiteral("A11y Event - ");
     strMarker.Append(strEventType);
     profiler_add_marker(strMarker.get());
   }
+#endif
 
   if (IPCAccessibilityActive() && Document()) {
     DocAccessibleChild* ipcDoc = mDoc->IPCDoc();
     MOZ_ASSERT(ipcDoc);
     if (ipcDoc) {
       uint64_t id = aEvent->GetAccessible()->IsDoc() ? 0 :
         reinterpret_cast<uintptr_t>(aEvent->GetAccessible());
 
--- a/dom/base/nsDOMNavigationTiming.cpp
+++ b/dom/base/nsDOMNavigationTiming.cpp
@@ -64,17 +64,17 @@ nsDOMNavigationTiming::TimeStampToDOM(Ti
 }
 
 void
 nsDOMNavigationTiming::NotifyNavigationStart(DocShellState aDocShellState)
 {
   mNavigationStartHighRes = (double)PR_Now() / PR_USEC_PER_MSEC;
   mNavigationStart = TimeStamp::Now();
   mDocShellHasBeenActiveSinceNavigationStart = (aDocShellState == DocShellState::eActive);
-  profiler_add_marker("Navigation::Start");
+  PROFILER_ADD_MARKER("Navigation::Start");
 }
 
 void
 nsDOMNavigationTiming::NotifyFetchStart(nsIURI* aURI, Type aNavigationType)
 {
   mNavigationType = aNavigationType;
   // At the unload event time we don't really know the loading uri.
   // Need it for later check for unload timing access.
@@ -93,51 +93,51 @@ nsDOMNavigationTiming::NotifyUnloadAccep
   mUnloadStart = mBeforeUnloadStart;
   mUnloadedURI = aOldURI;
 }
 
 void
 nsDOMNavigationTiming::NotifyUnloadEventStart()
 {
   mUnloadStart = TimeStamp::Now();
-  profiler_tracing("Navigation", "Unload", TRACING_INTERVAL_START);
+  PROFILER_TRACING("Navigation", "Unload", TRACING_INTERVAL_START);
 }
 
 void
 nsDOMNavigationTiming::NotifyUnloadEventEnd()
 {
   mUnloadEnd = TimeStamp::Now();
-  profiler_tracing("Navigation", "Unload", TRACING_INTERVAL_END);
+  PROFILER_TRACING("Navigation", "Unload", TRACING_INTERVAL_END);
 }
 
 void
 nsDOMNavigationTiming::NotifyLoadEventStart()
 {
   if (!mLoadEventStart.IsNull()) {
     return;
   }
   mLoadEventStart = TimeStamp::Now();
 
-  profiler_tracing("Navigation", "Load", TRACING_INTERVAL_START);
+  PROFILER_TRACING("Navigation", "Load", TRACING_INTERVAL_START);
 
   if (IsTopLevelContentDocumentInContentProcess()) {
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_START_MS,
                                    mNavigationStart);
   }
 }
 
 void
 nsDOMNavigationTiming::NotifyLoadEventEnd()
 {
   if (!mLoadEventEnd.IsNull()) {
     return;
   }
   mLoadEventEnd = TimeStamp::Now();
 
-  profiler_tracing("Navigation", "Load", TRACING_INTERVAL_END);
+  PROFILER_TRACING("Navigation", "Load", TRACING_INTERVAL_END);
 
   if (IsTopLevelContentDocumentInContentProcess()) {
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_END_MS,
                                    mNavigationStart);
   }
 }
 
 void
@@ -154,54 +154,54 @@ void
 nsDOMNavigationTiming::NotifyDOMLoading(nsIURI* aURI)
 {
   if (!mDOMLoading.IsNull()) {
     return;
   }
   mLoadedURI = aURI;
   mDOMLoading = TimeStamp::Now();
 
-  profiler_add_marker("Navigation::DOMLoading");
+  PROFILER_ADD_MARKER("Navigation::DOMLoading");
 }
 
 void
 nsDOMNavigationTiming::NotifyDOMInteractive(nsIURI* aURI)
 {
   if (!mDOMInteractive.IsNull()) {
     return;
   }
   mLoadedURI = aURI;
   mDOMInteractive = TimeStamp::Now();
 
-  profiler_add_marker("Navigation::DOMInteractive");
+  PROFILER_ADD_MARKER("Navigation::DOMInteractive");
 }
 
 void
 nsDOMNavigationTiming::NotifyDOMComplete(nsIURI* aURI)
 {
   if (!mDOMComplete.IsNull()) {
     return;
   }
   mLoadedURI = aURI;
   mDOMComplete = TimeStamp::Now();
 
-  profiler_add_marker("Navigation::DOMComplete");
+  PROFILER_ADD_MARKER("Navigation::DOMComplete");
 }
 
 void
 nsDOMNavigationTiming::NotifyDOMContentLoadedStart(nsIURI* aURI)
 {
   if (!mDOMContentLoadedEventStart.IsNull()) {
     return;
   }
 
   mLoadedURI = aURI;
   mDOMContentLoadedEventStart = TimeStamp::Now();
 
-  profiler_tracing("Navigation", "DOMContentLoaded", TRACING_INTERVAL_START);
+  PROFILER_TRACING("Navigation", "DOMContentLoaded", TRACING_INTERVAL_START);
 
   if (IsTopLevelContentDocumentInContentProcess()) {
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_START_MS,
                                    mNavigationStart);
   }
 }
 
 void
@@ -209,17 +209,17 @@ nsDOMNavigationTiming::NotifyDOMContentL
 {
   if (!mDOMContentLoadedEventEnd.IsNull()) {
     return;
   }
 
   mLoadedURI = aURI;
   mDOMContentLoadedEventEnd = TimeStamp::Now();
 
-  profiler_tracing("Navigation", "DOMContentLoaded", TRACING_INTERVAL_END);
+  PROFILER_TRACING("Navigation", "DOMContentLoaded", TRACING_INTERVAL_END);
 
   if (IsTopLevelContentDocumentInContentProcess()) {
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_END_MS,
                                    mNavigationStart);
   }
 }
 
 void
@@ -228,28 +228,30 @@ nsDOMNavigationTiming::NotifyNonBlankPai
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mNavigationStart.IsNull());
 
   if (!mNonBlankPaint.IsNull()) {
     return;
   }
 
   mNonBlankPaint = TimeStamp::Now();
-  TimeDuration elapsed = mNonBlankPaint - mNavigationStart;
 
+#ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
+    TimeDuration elapsed = mNonBlankPaint - mNavigationStart;
     nsAutoCString spec;
     if (mLoadedURI) {
       mLoadedURI->GetSpec(spec);
     }
     nsPrintfCString marker("Non-blank paint after %dms for URL %s, %s",
                            int(elapsed.ToMilliseconds()), spec.get(),
                            mDocShellHasBeenActiveSinceNavigationStart ? "foreground tab" : "this tab was inactive some of the time between navigation start and first non-blank paint");
     profiler_add_marker(marker.get());
   }
+#endif
 
   if (mDocShellHasBeenActiveSinceNavigationStart) {
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_NON_BLANK_PAINT_MS,
                                    mNavigationStart,
                                    mNonBlankPaint);
   }
 }
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3516,17 +3516,17 @@ PrepareForFullscreenChange(nsIPresShell*
       viewManager->SetWindowDimensions(aSize.width, aSize.height);
     }
   }
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::HandleFullscreenRequests(bool* aRetVal)
 {
-  profiler_add_marker("Enter fullscreen");
+  PROFILER_ADD_MARKER("Enter fullscreen");
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
   // Notify the pres shell that we are starting fullscreen change, and
   // set the window dimensions in advance. Since the resize message
   // comes after the fullscreen change call, doing so could avoid an
   // extra resize reflow after this point.
   nsRect screenRect;
@@ -3539,17 +3539,17 @@ nsDOMWindowUtils::HandleFullscreenReques
 
   *aRetVal = nsIDocument::HandlePendingFullscreenRequests(doc);
   return NS_OK;
 }
 
 nsresult
 nsDOMWindowUtils::ExitFullscreen()
 {
-  profiler_add_marker("Exit fullscreen");
+  PROFILER_ADD_MARKER("Exit fullscreen");
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
   // Although we would not use the old size if we have already exited
   // fullscreen, we still want to cleanup in case we haven't.
   nsSize oldSize = OldWindowSize::GetAndRemove(mWindow);
   if (!doc->GetFullscreenElement()) {
     return NS_OK;
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -595,21 +595,23 @@ 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)
 {
+#ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
     NS_LossyConvertUTF16toASCII messageNameCStr(aMessageName);
     AUTO_PROFILER_LABEL_DYNAMIC("nsFrameMessageManager::SendMessage", EVENTS,
                                 messageNameCStr.get());
   }
+#endif
 
   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);
 
@@ -1534,22 +1536,24 @@ nsMessageManagerScriptExecutor::Shutdown
     sScriptCacheCleaner = nullptr;
   }
 }
 
 void
 nsMessageManagerScriptExecutor::LoadScriptInternal(const nsAString& aURL,
                                                    bool aRunInGlobalScope)
 {
+#ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
     NS_LossyConvertUTF16toASCII urlCStr(aURL);
     AUTO_PROFILER_LABEL_DYNAMIC(
       "nsMessageManagerScriptExecutor::LoadScriptInternal", OTHER,
       urlCStr.get());
   }
+#endif
 
   if (!mGlobal || !sCachedScripts) {
     return;
   }
 
   JS::RootingContext* rcx = RootingCx();
   JS::Rooted<JSScript*> script(rcx);
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7055,22 +7055,22 @@ FullscreenTransitionTask::Run()
   mStage = Stage(mStage + 1);
   if (MOZ_UNLIKELY(mWidget->Destroyed())) {
     // If the widget has been destroyed before we get here, don't try to
     // do anything more. Just let it go and release ourselves.
     NS_WARNING("The widget to fullscreen has been destroyed");
     return NS_OK;
   }
   if (stage == eBeforeToggle) {
-    profiler_add_marker("Fullscreen transition start");
+    PROFILER_ADD_MARKER("Fullscreen transition start");
     mWidget->PerformFullscreenTransition(nsIWidget::eBeforeFullscreenToggle,
                                          mDuration.mFadeIn, mTransitionData,
                                          this);
   } else if (stage == eToggleFullscreen) {
-    profiler_add_marker("Fullscreen toggle start");
+    PROFILER_ADD_MARKER("Fullscreen toggle start");
     mFullscreenChangeStartTime = TimeStamp::Now();
     if (MOZ_UNLIKELY(mWindow->mFullScreen != mFullscreen)) {
       // This could happen in theory if several fullscreen requests in
       // different direction happen continuously in a short time. We
       // need to ensure the fullscreen state matches our target here,
       // otherwise the widget would change the window state as if we
       // toggle for Fullscreen Mode instead of Fullscreen API.
       NS_WARNING("The fullscreen state of the window does not match");
@@ -7104,17 +7104,17 @@ FullscreenTransitionTask::Run()
     mTimer->Init(observer, timeout, nsITimer::TYPE_ONE_SHOT);
   } else if (stage == eAfterToggle) {
     Telemetry::AccumulateTimeDelta(Telemetry::FULLSCREEN_TRANSITION_BLACK_MS,
                                    mFullscreenChangeStartTime);
     mWidget->PerformFullscreenTransition(nsIWidget::eAfterFullscreenToggle,
                                          mDuration.mFadeOut, mTransitionData,
                                          this);
   } else if (stage == eEnd) {
-    profiler_add_marker("Fullscreen transition end");
+    PROFILER_ADD_MARKER("Fullscreen transition end");
   }
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(FullscreenTransitionTask::Observer, nsIObserver)
 
 NS_IMETHODIMP
 FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject,
@@ -7125,28 +7125,28 @@ FullscreenTransitionTask::Observer::Obse
   if (strcmp(aTopic, FullscreenTransitionTask::kPaintedTopic) == 0) {
     nsCOMPtr<nsPIDOMWindowInner> win(do_QueryInterface(aSubject));
     nsCOMPtr<nsIWidget> widget = win ?
       nsGlobalWindow::Cast(win)->GetMainWidget() : nullptr;
     if (widget == mTask->mWidget) {
       // The paint notification arrives first. Cancel the timer.
       mTask->mTimer->Cancel();
       shouldContinue = true;
-      profiler_add_marker("Fullscreen toggle end");
+      PROFILER_ADD_MARKER("Fullscreen toggle end");
     }
   } else {
 #ifdef DEBUG
     MOZ_ASSERT(strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC) == 0,
                "Should only get fullscreen-painted or timer-callback");
     nsCOMPtr<nsITimer> timer(do_QueryInterface(aSubject));
     MOZ_ASSERT(timer && timer == mTask->mTimer,
                "Should only trigger this with the timer the task created");
 #endif
     shouldContinue = true;
-    profiler_add_marker("Fullscreen toggle timeout");
+    PROFILER_ADD_MARKER("Fullscreen toggle timeout");
   }
   if (shouldContinue) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     obs->RemoveObserver(this, kPaintedTopic);
     mTask->mTimer = nullptr;
     mTask->Run();
   }
   return NS_OK;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1234,18 +1234,18 @@ FinishAnyIncrementalGC()
     JS::FinishIncrementalGC(jsapi.cx(), JS::gcreason::CC_FORCED);
   }
 }
 
 static void
 FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless,
                     TimeStamp aDeadline)
 {
-  AutoProfilerTracing
-    tracing("CC", aDeadline.IsNull() ? "ForgetSkippable" : "IdleForgetSkippable");
+  AUTO_PROFILER_TRACING("CC", aDeadline.IsNull() ? "ForgetSkippable"
+                                                 : "IdleForgetSkippable");
   PRTime startTime = PR_Now();
   TimeStamp startTimeStamp = TimeStamp::Now();
   FinishAnyIncrementalGC();
   bool earlyForgetSkippable =
     sCleanupsSinceLastGC < NS_MAJOR_FORGET_SKIPPABLE_CALLS;
 
   int64_t budgetMs = aDeadline.IsNull() ?
     kForgetSkippableSliceDuration :
@@ -1484,18 +1484,17 @@ nsJSContext::CycleCollectNow(nsICycleCol
 //static
 void
 nsJSContext::RunCycleCollectorSlice(TimeStamp aDeadline)
 {
   if (!NS_IsMainThread()) {
     return;
   }
 
-  AutoProfilerTracing
-    tracing("CC", aDeadline.IsNull() ? "CCSlice" : "IdleCCSlice");
+  AUTO_PROFILER_TRACING("CC", aDeadline.IsNull() ? "CCSlice" : "IdleCCSlice");
 
   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();
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -130,18 +130,20 @@ EvaluationExceptionToNSResult(JSContext*
     return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
   }
   return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE;
 }
 
 nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
                                               JS::Handle<JSObject*> aGlobal)
   :
+#ifdef MOZ_GECKO_PROFILER
     mAutoProfilerLabel("nsJSUtils::ExecutionContext", /* dynamicStr */ nullptr,
                        __LINE__, js::ProfileEntry::Category::JS),
+#endif
     mCx(aCx)
   , mCompartment(aCx, aGlobal)
   , mRetValue(aCx)
   , mScopeChain(aCx)
   , mRv(NS_OK)
   , mSkip(false)
   , mCoerceToString(false)
   , mEncodeBytecode(false)
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -63,18 +63,20 @@ public:
                                   uint32_t aArgCount,
                                   const char** aArgArray,
                                   const nsAString& aBody,
                                   JSObject** aFunctionObject);
 
 
   // ExecutionContext is used to switch compartment.
   class MOZ_STACK_CLASS ExecutionContext {
+#ifdef MOZ_GECKO_PROFILER
     // Register stack annotations for the Gecko profiler.
     mozilla::AutoProfilerLabel mAutoProfilerLabel;
+#endif
 
     JSContext* mCx;
 
     // Handles switching to our global's compartment.
     JSAutoCompartment mCompartment;
 
     // Set to a valid handle if a return value is expected.
     JS::Rooted<JS::Value> mRetValue;
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -25,17 +25,16 @@
 #include "mozilla/dom/EventTargetBinding.h"
 #include "mozilla/dom/TouchEvent.h"
 #include "mozilla/TimelineConsumers.h"
 #include "mozilla/EventTimelineMarker.h"
 #include "mozilla/TimeStamp.h"
 
 #include "EventListenerService.h"
 #include "GeckoProfiler.h"
-#include "ProfilerMarkerPayload.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsDOMCID.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsIContentSecurityPolicy.h"
@@ -48,16 +47,20 @@
 #include "nsJSUtils.h"
 #include "nsNameSpaceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsSandboxFlags.h"
 #include "xpcpublic.h"
 #include "nsIFrame.h"
 #include "nsDisplayList.h"
 
+#ifdef MOZ_GECKO_PROFILER
+#include "ProfilerMarkerPayload.h"
+#endif
+
 namespace mozilla {
 
 using namespace dom;
 using namespace hal;
 
 #define EVENT_TYPE_EQUALS(ls, message, userType, typeString, allEvents) \
   ((ls->mEventMessage == message &&                                     \
     (ls->mEventMessage != eUnidentifiedEvent ||                         \
@@ -1257,16 +1260,17 @@ EventListenerManager::HandleEventInterna
               // The order is important, otherwise the listener could be
               // called again inside the listener.
               listenerHolder.emplace(Move(*listener));
               listener = listenerHolder.ptr();
               hasRemovedListener = true;
             }
 
             nsresult rv = NS_OK;
+#ifdef MOZ_GECKO_PROFILER
             if (profiler_is_active()) {
               // 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);
@@ -1280,17 +1284,19 @@ EventListenerManager::HandleEventInterna
               TimeStamp endTime = TimeStamp::Now();
               uint16_t phase;
               (*aDOMEvent)->GetEventPhase(&phase);
               profiler_add_marker(
                 "DOMEvent",
                 MakeUnique<DOMEventMarkerPayload>(typeStr, phase,
                                                   aEvent->mTimeStamp,
                                                   startTime, endTime));
-            } else {
+            } else
+#endif
+            {
               rv = HandleEventSubType(listener, *aDOMEvent, aCurrentTarget);
             }
 
             if (NS_FAILED(rv)) {
               aEvent->mFlags.mExceptionWasRaised = true;
             }
             aEvent->mFlags.mInPassiveListener = false;
 
--- a/dom/indexedDB/ProfilerHelpers.h
+++ b/dom/indexedDB/ProfilerHelpers.h
@@ -286,32 +286,37 @@ LoggingHelper(bool aUseProfiler, const c
   MOZ_ASSERT(aFmt);
 
   mozilla::LogModule* logModule = IndexedDatabaseManager::GetLoggingModule();
   MOZ_ASSERT(logModule);
 
   static const mozilla::LogLevel logLevel = LogLevel::Warning;
 
   if (MOZ_LOG_TEST(logModule, logLevel) ||
-      (aUseProfiler && profiler_is_active())) {
+#ifdef MOZ_GECKO_PROFILER
+      (aUseProfiler && profiler_is_active())
+#else
+      false
+#endif
+     ) {
     nsAutoCString message;
 
     {
       va_list args;
       va_start(args, aFmt);
 
       message.AppendPrintf(aFmt, args);
 
       va_end(args);
     }
 
     MOZ_LOG(logModule, logLevel, ("%s", message.get()));
 
     if (aUseProfiler) {
-      profiler_add_marker(message.get());
+      PROFILER_ADD_MARKER(message.get());
     }
   }
 }
 
 } // namespace indexedDB
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/media/webaudio/blink/HRTFDatabaseLoader.cpp
+++ b/dom/media/webaudio/blink/HRTFDatabaseLoader.cpp
@@ -153,17 +153,17 @@ void HRTFDatabaseLoader::MainThreadRelea
         // on this (main) thread.
         delete this;
     }
 }
 
 // Asynchronously load the database in this thread.
 static void databaseLoaderEntry(void* threadData)
 {
-    AutoProfilerRegisterThread registerThread("HRTFDatabaseLdr");
+    AUTO_PROFILER_REGISTER_THREAD("HRTFDatabaseLdr");
     NS_SetCurrentThreadName("HRTFDatabaseLdr");
 
     HRTFDatabaseLoader* loader = reinterpret_cast<HRTFDatabaseLoader*>(threadData);
     MOZ_ASSERT(loader);
     loader->load();
 }
 
 void HRTFDatabaseLoader::load()
--- a/dom/performance/Performance.cpp
+++ b/dom/performance/Performance.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Performance.h"
 
 #include "GeckoProfiler.h"
 #include "nsRFPService.h"
-#include "ProfilerMarkerPayload.h"
 #include "PerformanceEntry.h"
 #include "PerformanceMainThread.h"
 #include "PerformanceMark.h"
 #include "PerformanceMeasure.h"
 #include "PerformanceObserver.h"
 #include "PerformanceResourceTiming.h"
 #include "PerformanceService.h"
 #include "PerformanceWorker.h"
@@ -23,16 +22,20 @@
 #include "mozilla/dom/PerformanceNavigationBinding.h"
 #include "mozilla/dom/PerformanceObserverBinding.h"
 #include "mozilla/dom/PerformanceNavigationTiming.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Preferences.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 
+#ifdef MOZ_GECKO_PROFILER
+#include "ProfilerMarkerPayload.h"
+#endif
+
 #define PERFLOG(msg, ...) printf_stderr(msg, ##__VA_ARGS__)
 
 namespace mozilla {
 namespace dom {
 
 using namespace workers;
 
 namespace {
@@ -261,21 +264,23 @@ Performance::Mark(const nsAString& aName
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
     return;
   }
 
   RefPtr<PerformanceMark> performanceMark =
     new PerformanceMark(GetParentObject(), aName, Now());
   InsertUserEntry(performanceMark);
 
+#ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
     profiler_add_marker(
       "UserTiming",
       MakeUnique<UserTimingMarkerPayload>(aName, TimeStamp::Now()));
   }
+#endif
 }
 
 void
 Performance::ClearMarks(const Optional<nsAString>& aName)
 {
   ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
 }
 
@@ -347,25 +352,27 @@ Performance::Measure(const nsAString& aN
   } else {
     endTime = Now();
   }
 
   RefPtr<PerformanceMeasure> performanceMeasure =
     new PerformanceMeasure(GetParentObject(), aName, startTime, endTime);
   InsertUserEntry(performanceMeasure);
 
+#ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
     TimeStamp startTimeStamp = CreationTimeStamp() +
                                TimeDuration::FromMilliseconds(startTime);
     TimeStamp endTimeStamp = CreationTimeStamp() +
                              TimeDuration::FromMilliseconds(endTime);
     profiler_add_marker(
       "UserTiming",
       MakeUnique<UserTimingMarkerPayload>(aName, startTimeStamp, endTimeStamp));
   }
+#endif
 }
 
 void
 Performance::ClearMeasures(const Optional<nsAString>& aName)
 {
   ClearUserEntries(aName, NS_LITERAL_STRING("measure"));
 }
 
--- a/dom/storage/StorageDBThread.cpp
+++ b/dom/storage/StorageDBThread.cpp
@@ -484,17 +484,17 @@ StorageDBThread::SetDefaultPriority()
   if (--mPriorityCounter <= 0) {
     PR_SetThreadPriority(mThread, PR_PRIORITY_LOW);
   }
 }
 
 void
 StorageDBThread::ThreadFunc(void* aArg)
 {
-  AutoProfilerRegisterThread registerThread("localStorage DB");
+  AUTO_PROFILER_REGISTER_THREAD("localStorage DB");
   NS_SetCurrentThreadName("localStorage DB");
   mozilla::IOInterposer::RegisterCurrentThread();
 
   StorageDBThread* thread = static_cast<StorageDBThread*>(aArg);
   thread->ThreadFunc();
   mozilla::IOInterposer::UnregisterCurrentThread();
 }
 
--- a/dom/vr/VRDisplay.cpp
+++ b/dom/vr/VRDisplay.cpp
@@ -651,17 +651,17 @@ VRDisplay::GetLayers(nsTArray<VRLayer>& 
   } else {
     result = nsTArray<VRLayer>();
   }
 }
 
 void
 VRDisplay::SubmitFrame()
 {
-  AutoProfilerTracing tracing("VR", "SubmitFrameAtVRDisplay");
+  AUTO_PROFILER_TRACING("VR", "SubmitFrameAtVRDisplay");
 
   if (mPresentation) {
     mPresentation->SubmitFrame();
   }
   mFrameInfo.Clear();
 }
 
 int32_t
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -591,17 +591,17 @@ LoadJSGCMemoryOptions(const char* aPrefN
 
 bool
 InterruptCallback(JSContext* aCx)
 {
   WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
   MOZ_ASSERT(worker);
 
   // Now is a good time to turn on profiling if it's pending.
-  profiler_js_interrupt_callback();
+  PROFILER_JS_INTERRUPT_CALLBACK();
 
   return worker->InterruptCallback(aCx);
 }
 
 class LogViolationDetailsRunnable final : public WorkerMainThreadRunnable
 {
   nsString mFileName;
   uint32_t mLineNum;
@@ -2760,26 +2760,24 @@ LogViolationDetailsRunnable::MainThreadR
 
 NS_IMPL_ISUPPORTS_INHERITED0(WorkerThreadPrimaryRunnable, Runnable)
 
 NS_IMETHODIMP
 WorkerThreadPrimaryRunnable::Run()
 {
   using mozilla::ipc::BackgroundChild;
 
-  char stackBaseGuess;
-
   NS_SetCurrentThreadName("DOM Worker");
 
   nsAutoCString threadName;
   threadName.AssignLiteral("DOM Worker '");
   threadName.Append(NS_LossyConvertUTF16toASCII(mWorkerPrivate->ScriptURL()));
   threadName.Append('\'');
 
-  profiler_register_thread(threadName.get(), &stackBaseGuess);
+  AUTO_PROFILER_REGISTER_THREAD(threadName.get());
 
   // Note: GetOrCreateForCurrentThread() must be called prior to
   //       mWorkerPrivate->SetThread() in order to avoid accidentally consuming
   //       worker messages here.
   if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread())) {
     // XXX need to fire an error at parent.
     // Failed in creating BackgroundChild: probably in shutdown. Continue to run
     // without BackgroundChild created.
@@ -2834,31 +2832,31 @@ WorkerThreadPrimaryRunnable::Run()
 
     if (!InitJSContextForWorker(mWorkerPrivate, cx)) {
       // XXX need to fire an error at parent.
       NS_ERROR("Failed to create context!");
       return NS_ERROR_FAILURE;
     }
 
     {
-      profiler_set_js_context(cx);
+      PROFILER_SET_JS_CONTEXT(cx);
 
       {
         JSAutoRequest ar(cx);
 
         mWorkerPrivate->DoRunLoop(cx);
         // The AutoJSAPI in DoRunLoop should have reported any exceptions left
         // on cx.  Note that we still need the JSAutoRequest above because
         // AutoJSAPI on workers does NOT enter a request!
         MOZ_ASSERT(!JS_IsExceptionPending(cx));
       }
 
       BackgroundChild::CloseForCurrentThread();
 
-      profiler_clear_js_context();
+      PROFILER_CLEAR_JS_CONTEXT();
     }
 
     // There may still be runnables on the debugger event queue that hold a
     // strong reference to the debugger global scope. These runnables are not
     // visible to the cycle collector, so we need to make sure to clear the
     // debugger event queue before we try to destroy the context. If we don't,
     // the garbage collector will crash.
     mWorkerPrivate->ClearDebuggerEventQueue();
@@ -2888,17 +2886,16 @@ WorkerThreadPrimaryRunnable::Run()
   nsCOMPtr<nsIEventTarget> mainTarget = GetMainThreadEventTarget();
   MOZ_ASSERT(mainTarget);
 
   RefPtr<FinishedRunnable> finishedRunnable =
     new FinishedRunnable(mThread.forget());
   MOZ_ALWAYS_SUCCEEDS(mainTarget->Dispatch(finishedRunnable,
                                            NS_DISPATCH_NORMAL));
 
-  profiler_unregister_thread();
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(WorkerThreadPrimaryRunnable::FinishedRunnable,
                              Runnable)
 
 NS_IMETHODIMP
 WorkerThreadPrimaryRunnable::FinishedRunnable::Run()
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -326,17 +326,17 @@ ClientLayerManager::BeginTransaction()
 }
 
 bool
 ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
                                            void* aCallbackData,
                                            EndTransactionFlags)
 {
   PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Rasterization);
-  AutoProfilerTracing tracing("Paint", "Rasterize");
+  AUTO_PROFILER_TRACING("Paint", "Rasterize");
 
   Maybe<TimeStamp> startTime;
   if (gfxPrefs::LayersDrawFPS()) {
     startTime = Some(TimeStamp::Now());
   }
 
 #ifdef WIN32
   if (aCallbackData) {
@@ -718,17 +718,17 @@ ClientLayerManager::StopFrameTimeRecordi
   if (renderer) {
     renderer->SendStopFrameTimeRecording(aStartIndex, &aFrameIntervals);
   }
 }
 
 void
 ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
 {
-  AutoProfilerTracing tracing("Paint", "ForwardTransaction");
+  AUTO_PROFILER_TRACING("Paint", "ForwardTransaction");
   TimeStamp start = TimeStamp::Now();
 
   // Skip the synchronization for buffer since we also skip the painting during
   // device-reset status. With OMTP, we have to wait for async paints
   // before we synchronize and it's done on the paint thread.
   RefPtr<SyncObjectClient> syncObject = nullptr;
   if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
     if (mForwarder->GetSyncObject() &&
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -104,17 +104,17 @@ ContentClient::EndPaint(nsTArray<Readbac
 }
 
 void
 ContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   aStream << aPrefix;
   aStream << nsPrintfCString("ContentClient (0x%p)", this).get();
 
-  if (profiler_feature_active(ProfilerFeature::DisplayListDump)) {
+  if (PROFILER_FEATURE_ACTIVE(ProfilerFeature::DisplayListDump)) {
     nsAutoCString pfx(aPrefix);
     pfx += "  ";
 
     Dump(aStream, pfx.get(), false);
   }
 }
 
 // We pass a null pointer for the ContentClient Forwarder argument, which means
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -1392,17 +1392,17 @@ TextureClient::PrintInfo(std::stringstre
   aStream << aPrefix;
   aStream << nsPrintfCString("TextureClient (0x%p)", this).get();
   AppendToString(aStream, GetSize(), " [size=", "]");
   AppendToString(aStream, GetFormat(), " [format=", "]");
   AppendToString(aStream, mFlags, " [flags=", "]");
 
 #ifdef MOZ_DUMP_PAINTING
   if (gfxPrefs::LayersDumpTexture() ||
-      profiler_feature_active(ProfilerFeature::LayersDump)) {
+      PROFILER_FEATURE_ACTIVE(ProfilerFeature::LayersDump)) {
     nsAutoCString pfx(aPrefix);
     pfx += "  ";
 
     aStream << "\n" << pfx.get() << "Surface: ";
     RefPtr<gfx::DataSourceSurface> dSurf = GetAsSurface();
     if (dSurf) {
       aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get();
     }
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -1395,17 +1395,17 @@ ClientMultiTiledLayerBuffer::Progressive
 }
 
 void
 TiledContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   aStream << aPrefix;
   aStream << nsPrintfCString("%sTiledContentClient (0x%p)", mName, this).get();
 
-  if (profiler_feature_active(ProfilerFeature::DisplayListDump)) {
+  if (PROFILER_FEATURE_ACTIVE(ProfilerFeature::DisplayListDump)) {
     nsAutoCString pfx(aPrefix);
     pfx += "  ";
 
     Dump(aStream, pfx.get(), false);
   }
 }
 
 void
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -30,17 +30,20 @@
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsISupportsUtils.h"           // for NS_ADDREF, NS_RELEASE
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for AutoTArray
 #include <stack>
 #include "TextRenderer.h"               // for TextRenderer
 #include <vector>
 #include "GeckoProfiler.h"              // for GeckoProfiler
+
+#ifdef MOZ_GECKO_PROFILER
 #include "ProfilerMarkerPayload.h"      // for LayerTranslationMarkerPayload
+#endif
 
 #define CULLING_LOG(...)
 // #define CULLING_LOG(...) printf_stderr("CULLING: " __VA_ARGS__)
 
 #define DUMP(...) do { if (gfxEnv::DumpDebug()) { printf_stderr(__VA_ARGS__); } } while(0)
 #define XYWH(k)  (k).x, (k).y, (k).Width(), (k).Height()
 #define XY(k)    (k).x, (k).y
 #define WH(k)    (k).Width(), (k).Height()
@@ -76,16 +79,17 @@ DrawLayerInfo(const RenderTargetIntRect&
     topLeft,
     aLayer->GetEffectiveTransform(), 16,
     maxWidth);
 }
 
 static void
 PrintUniformityInfo(Layer* aLayer)
 {
+#if defined(MOZ_GECKO_PROFILER)
   if (!profiler_is_active()) {
     return;
   }
 
   // Don't want to print a log for smaller layers
   if (aLayer->GetLocalVisibleRegion().GetBounds().Width() < 300 ||
       aLayer->GetLocalVisibleRegion().GetBounds().Height() < 300) {
     return;
@@ -96,16 +100,17 @@ PrintUniformityInfo(Layer* aLayer)
     return;
   }
 
   Point translation = transform.As2D().GetTranslation();
   profiler_add_marker(
     "LayerTranslation",
     MakeUnique<LayerTranslationMarkerPayload>(aLayer, translation,
                                               TimeStamp::Now()));
+#endif
 }
 
 static Maybe<gfx::Polygon>
 SelectLayerGeometry(const Maybe<gfx::Polygon>& aParentGeometry,
                     const Maybe<gfx::Polygon>& aChildGeometry)
 {
   // Both the parent and the child layer were split.
   if (aParentGeometry && aChildGeometry) {
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -860,20 +860,20 @@ LayerManagerComposite::Render(const nsIn
   bool haveLayerEffects = (invertVal || grayscaleVal || contrastVal != 0.0);
 
   // Set LayerScope begin/end frame
   LayerScopeAutoFrame frame(PR_Now());
 
   // Dump to console
   if (gfxPrefs::LayersDump()) {
     this->Dump(/* aSorted= */true);
-  } else if (profiler_feature_active(ProfilerFeature::LayersDump)) {
+  } else if (PROFILER_FEATURE_ACTIVE(ProfilerFeature::LayersDump)) {
     std::stringstream ss;
     Dump(ss);
-    profiler_tracing("log", ss.str().c_str(), TRACING_EVENT);
+    PROFILER_TRACING("log", ss.str().c_str(), TRACING_EVENT);
   }
 
   // Dump to LayerScope Viewer
   if (LayerScope::CheckSendable()) {
     // Create a LayersPacket, dump Layers into it and transfer the
     // packet('s ownership) to LayerScope.
     auto packet = MakeUnique<layerscope::Packet>();
     layerscope::LayersPacket* layersPacket = packet->mutable_layers();
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -406,17 +406,17 @@ TextureHost::PrintInfo(std::stringstream
   if (Lock()) {
     AppendToString(aStream, GetSize(), " [size=", "]");
     AppendToString(aStream, GetFormat(), " [format=", "]");
     Unlock();
   }
   AppendToString(aStream, mFlags, " [flags=", "]");
 #ifdef MOZ_DUMP_PAINTING
   if (gfxPrefs::LayersDumpTexture() ||
-      profiler_feature_active(ProfilerFeature::LayersDump)) {
+      PROFILER_FEATURE_ACTIVE(ProfilerFeature::LayersDump)) {
     nsAutoCString pfx(aPrefix);
     pfx += "  ";
 
     aStream << "\n" << pfx.get() << "Surface: ";
     RefPtr<gfx::DataSourceSurface> dSurf = GetAsSurface();
     if (dSurf) {
       aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get();
     }
--- a/gfx/layers/composite/TiledContentHost.cpp
+++ b/gfx/layers/composite/TiledContentHost.cpp
@@ -620,23 +620,25 @@ TiledContentHost::RenderLayerBuffer(Tile
 }
 
 void
 TiledContentHost::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   aStream << aPrefix;
   aStream << nsPrintfCString("TiledContentHost (0x%p)", this).get();
 
+#if defined(MOZ_DUMP_PAINTING)
   if (gfxPrefs::LayersDumpTexture() ||
-      profiler_feature_active(ProfilerFeature::LayersDump)) {
+      PROFILER_FEATURE_ACTIVE(ProfilerFeature::LayersDump)) {
     nsAutoCString pfx(aPrefix);
     pfx += "  ";
 
     Dump(aStream, pfx.get(), false);
   }
+#endif
 }
 
 void
 TiledContentHost::Dump(std::stringstream& aStream,
                        const char* aPrefix,
                        bool aDumpHtml)
 {
   mTiledBuffer.Dump(aStream, aPrefix, aDumpHtml,
--- a/gfx/layers/ipc/CompositorBench.cpp
+++ b/gfx/layers/ipc/CompositorBench.cpp
@@ -281,17 +281,17 @@ static void RunCompositorBench(Composito
   tests.push_back(new EffectSolidColorStressBench());
   tests.push_back(new TrivialTexturedQuadBench());
   tests.push_back(new StressTexturedQuadBench());
 
   for (size_t i = 0; i < tests.size(); i++) {
     BenchTest* test = tests[i];
     std::vector<TimeDuration> results;
     int testsOverThreshold = 0;
-    profiler_add_marker(test->ToString());
+    PROFILER_ADD_MARKER(test->ToString());
     for (size_t j = 0; j < TEST_STEPS; j++) {
       test->Setup(aCompositor, j);
 
       TimeStamp start = TimeStamp::Now();
       IntRect screenRect(aScreenRect.x, aScreenRect.y,
                            aScreenRect.width, aScreenRect.height);
       aCompositor->BeginFrame(
         IntRect(screenRect.x, screenRect.y,
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -79,20 +79,22 @@
 #endif
 #include "GeckoProfiler.h"
 #include "mozilla/ipc/ProtocolTypes.h"
 #include "mozilla/Unused.h"
 #include "mozilla/Hal.h"
 #include "mozilla/HalTypes.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Telemetry.h"
-#include "ProfilerMarkerPayload.h"
+#ifdef MOZ_GECKO_PROFILER
+# include "ProfilerMarkerPayload.h"
+#endif
 #include "mozilla/VsyncDispatcher.h"
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
-#include "VsyncSource.h"
+# include "VsyncSource.h"
 #endif
 #include "mozilla/widget/CompositorWidget.h"
 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
 # include "mozilla/widget/CompositorWidgetParent.h"
 #endif
 #ifdef XP_WIN
 # include "mozilla/gfx/DeviceManagerDx.h"
 #endif
@@ -932,17 +934,17 @@ CompositorBridgeParent::SetShadowPropert
         layerCompositor->SetShadowOpacitySetByAnimation(false);
       }
     );
 }
 
 void
 CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
 {
-  AutoProfilerTracing tracing("Paint", "Composite");
+  AUTO_PROFILER_TRACING("Paint", "Composite");
   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();
@@ -1834,33 +1836,37 @@ CompositorBridgeParent::GetAPZCTreeManag
   LayerTreeState* lts = &cit->second;
 
   RefPtr<APZCTreeManager> apzctm = lts->mParent
                                    ? lts->mParent->mApzcTreeManager.get()
                                    : nullptr;
   return apzctm.forget();
 }
 
+#if defined(MOZ_GECKO_PROFILER)
 static void
 InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   profiler_add_marker(
     "VsyncTimestamp",
     MakeUnique<VsyncMarkerPayload>(aVsyncTimestamp));
 }
+#endif
 
 /*static */ void
 CompositorBridgeParent::PostInsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
 {
+#if defined(MOZ_GECKO_PROFILER)
   // Called in the vsync thread
   if (profiler_is_active() && CompositorThreadHolder::IsActive()) {
     CompositorLoop()->PostTask(
       NewRunnableFunction(InsertVsyncProfilerMarker, aVsyncTimestamp));
   }
+#endif
 }
 
 widget::PCompositorWidgetParent*
 CompositorBridgeParent::AllocPCompositorWidgetParent(const CompositorWidgetInitData& aInitData)
 {
 #if defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
   if (mWidget) {
     // Should not create two widgets on the same compositor.
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -165,17 +165,17 @@ LayerTransactionParent::RecvInitReadLock
     return IPC_FAIL_NO_REASON(this);
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo)
 {
-  AutoProfilerTracing tracing("Paint", "LayerTransaction");
+  AUTO_PROFILER_TRACING("Paint", "LayerTransaction");
   AUTO_PROFILER_LABEL("LayerTransactionParent::RecvUpdate", GRAPHICS);
 
   TimeStamp updateStart = TimeStamp::Now();
 
   MOZ_LAYERS_LOG(("[ParentSide] received txn with %zu edits", aInfo.cset().Length()));
 
   UpdateFwdTransactionId(aInfo.fwdTransactionId());
   AutoClearReadLocks clearLocks(mReadLocks);
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -529,17 +529,17 @@ WebRenderBridgeParent::RecvSetDisplayLis
     for (const auto& op : aToDestroy) {
       DestroyActor(op);
     }
     DeallocShmems(aSmallShmems);
     DeallocShmems(aLargeShmems);
     return IPC_OK();
   }
 
-  AutoProfilerTracing tracing("Paint", "SetDisplayList");
+  AUTO_PROFILER_TRACING("Paint", "SetDisplayList");
   UpdateFwdTransactionId(aFwdTransactionId);
   AutoClearReadLocks clearLocks(mReadLocks);
 
   // This ensures that destroy operations are always processed. It is not safe
   // to early-return from RecvDPEnd without doing so.
   AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
 
   uint32_t wrEpoch = GetNextWrEpoch();
@@ -1082,17 +1082,17 @@ WebRenderBridgeParent::SampleAnimations(
       }
     }
   }
 }
 
 void
 WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
 {
-  AutoProfilerTracing tracing("Paint", "CompositeToTraget");
+  AUTO_PROFILER_TRACING("Paint", "CompositeToTraget");
   if (mPaused) {
     return;
   }
 
   const uint32_t maxPendingFrameCount = 1;
 
   if (!mForceRendering &&
       wr::RenderThread::Get()->GetPendingFrameCount(mApi->GetId()) >= maxPendingFrameCount) {
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -226,17 +226,17 @@ WebRenderLayerManager::EndTransaction(Dr
 
 void
 WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
                                                   nsDisplayListBuilder* aDisplayListBuilder)
 {
   MOZ_ASSERT(aDisplayList && aDisplayListBuilder);
   WrBridge()->RemoveExpiredFontKeys();
 
-  AutoProfilerTracing tracing("Paint", "RenderLayers");
+  AUTO_PROFILER_TRACING("Paint", "RenderLayers");
   mTransactionIncomplete = false;
 
   if (gfxPrefs::LayersDump()) {
     this->Dump();
   }
 
   // Since we don't do repeat transactions right now, just set the time
   mAnimationReadyTime = TimeStamp::Now();
@@ -298,18 +298,18 @@ WebRenderLayerManager::EndTransactionWit
     }
   }
 
   wr::BuiltDisplayList dl;
   builder.Finalize(contentSize, dl);
   mLastDisplayListSize = dl.dl.inner.capacity;
 
   {
-    AutoProfilerTracing
-      tracing("Paint", sync ? "ForwardDPTransactionSync":"ForwardDPTransaction");
+    AUTO_PROFILER_TRACING("Paint", sync ? "ForwardDPTransactionSync"
+                                        : "ForwardDPTransaction");
     WrBridge()->EndTransaction(contentSize, dl, resourceUpdates, size.ToUnknownSize(), sync,
                                mLatestTransactionId, mScrollData, transactionStart);
   }
 
   MakeSnapshotIfRequired(size);
   mNeedsComposite = false;
 
   ClearDisplayItemLayers();
--- a/gfx/thebes/ContextStateTracker.cpp
+++ b/gfx/thebes/ContextStateTracker.cpp
@@ -1,48 +1,53 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ContextStateTracker.h"
 #include "GLContext.h"
 #include "GeckoProfiler.h"
+
+#ifdef MOZ_GECKO_PROFILER
 #include "ProfilerMarkerPayload.h"
+#endif
 
 namespace mozilla {
 
 void
 ContextStateTrackerOGL::PushOGLSection(GLContext* aGL, const char* aSectionName)
 {
+#ifdef MOZ_GECKO_PROFILER
   if (!profiler_feature_active(ProfilerFeature::GPU)) {
     return;
   }
 
   if (!aGL->IsSupported(gl::GLFeature::query_objects)) {
     return;
   }
 
   if (mSectionStack.Length() > 0) {
-    // We need to end the query since we're starting a new section and restore it
-    // when this section is finished.
+    // We need to end the query since we're starting a new section and restore
+    // it when this section is finished.
     aGL->fEndQuery(LOCAL_GL_TIME_ELAPSED);
     Top().mCpuTimeEnd = TimeStamp::Now();
   }
 
   ContextState newSection(aSectionName);
 
   GLuint queryObject;
   aGL->fGenQueries(1, &queryObject);
   newSection.mStartQueryHandle = queryObject;
   newSection.mCpuTimeStart = TimeStamp::Now();
 
   aGL->fBeginQuery(LOCAL_GL_TIME_ELAPSED_EXT, queryObject);
 
   mSectionStack.AppendElement(newSection);
+#endif
 }
 
 void
 ContextStateTrackerOGL::PopOGLSection(GLContext* aGL, const char* aSectionName)
 {
   // We might have ignored a section start if we started profiling
   // in the middle section. If so we will ignore this unmatched end.
   if (mSectionStack.Length() == 0) {
@@ -104,23 +109,25 @@ ContextStateTrackerOGL::Flush(GLContext*
       break;
     }
 
     GLuint gpuTime = 0;
     aGL->fGetQueryObjectuiv(handle, LOCAL_GL_QUERY_RESULT, &gpuTime);
 
     aGL->fDeleteQueries(1, &handle);
 
+#ifdef MOZ_GECKO_PROFILER
     if (profiler_is_active()) {
       profiler_add_marker(
         "gpu_timer_query",
         MakeUnique<GPUMarkerPayload>(mCompletedSections[0].mCpuTimeStart,
                                      mCompletedSections[0].mCpuTimeEnd,
                                      0, gpuTime));
     }
+#endif
 
     mCompletedSections.RemoveElementAt(0);
   }
 }
 
 void
 ContextStateTrackerOGL::DestroyOGL(GLContext* aGL)
 {
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -177,17 +177,17 @@ VRDisplayHost::RemoveLayer(VRLayerParent
   // Ensure that the content process receives the change immediately
   VRManager* vm = VRManager::Get();
   vm->RefreshVRDisplays();
 }
 
 void
 VRDisplayHost::StartFrame()
 {
-  AutoProfilerTracing tracing("VR", "GetSensorState");
+  AUTO_PROFILER_TRACING("VR", "GetSensorState");
 
   mLastFrameStart = TimeStamp::Now();
   ++mDisplayInfo.mFrameId;
   mDisplayInfo.mLastSensorState[mDisplayInfo.mFrameId % kVRMaxLatencyFrames] = GetSensorState();
   mFrameStarted = true;
 }
 
 void
@@ -256,17 +256,17 @@ VRDisplayHost::NotifyVSync()
 
 void
 VRDisplayHost::SubmitFrame(VRLayerParent* aLayer,
                            const layers::SurfaceDescriptor &aTexture,
                            uint64_t aFrameId,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect)
 {
-  AutoProfilerTracing tracing("VR", "SubmitFrameAtVRDisplayHost");
+  AUTO_PROFILER_TRACING("VR", "SubmitFrameAtVRDisplayHost");
 
   if ((mDisplayInfo.mGroupMask & aLayer->GetGroup()) == 0) {
     // Suppress layers hidden by the group mask
     return;
   }
 
   // Ensure that we only accept the first SubmitFrame call per RAF cycle.
   if (!mFrameStarted || aFrameId != mDisplayInfo.mFrameId) {
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -444,17 +444,17 @@ VRManagerChild::RecvReplyCreateVRService
   p->MaybeResolve(new VRMockController(aID, aDeviceID));
   mPromiseList.Remove(aPromiseID);
   return IPC_OK();
 }
 
 void
 VRManagerChild::RunFrameRequestCallbacks()
 {
-  AutoProfilerTracing tracing("VR", "RunFrameRequestCallbacks");
+  AUTO_PROFILER_TRACING("VR", "RunFrameRequestCallbacks");
 
   TimeStamp nowTime = TimeStamp::Now();
   mozilla::TimeDuration duration = nowTime - mStartTimeStamp;
   DOMHighResTimeStamp timeStamp = duration.ToMilliseconds();
 
 
   nsTArray<FrameRequest> callbacks;
   callbacks.AppendElements(mFrameRequestCallbacks);
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -200,17 +200,17 @@ NotifyDidRender(layers::CompositorBridge
     aBridge->NotifyDidCompositeToPipeline(pipeline, epoch, aStart, aEnd);
   }
   wr_rendered_epochs_delete(aEpochs);
 }
 
 void
 RenderThread::UpdateAndRender(wr::WindowId aWindowId)
 {
-  AutoProfilerTracing tracing("Paint", "Composite");
+  AUTO_PROFILER_TRACING("Paint", "Composite");
   MOZ_ASSERT(IsInRenderThread());
 
   auto it = mRenderers.find(aWindowId);
   MOZ_ASSERT(it != mRenderers.end());
   if (it == mRenderers.end()) {
     return;
   }
 
--- a/image/DecodePool.cpp
+++ b/image/DecodePool.cpp
@@ -175,19 +175,17 @@ public:
       Work work = mImpl->PopWork();
       switch (work.mType) {
         case Work::Type::TASK:
           work.mTask->Run();
           break;
 
         case Work::Type::SHUTDOWN:
           DecodePoolImpl::ShutdownThread(thisThread);
-
-          profiler_unregister_thread();
-
+          PROFILER_UNREGISTER_THREAD();
           return NS_OK;
 
         default:
           MOZ_ASSERT_UNREACHABLE("Unknown work type");
       }
     } while (true);
 
     MOZ_ASSERT_UNREACHABLE("Exiting thread without Work::Type::SHUTDOWN");
--- a/ipc/chromium/src/base/message_pump_default.cc
+++ b/ipc/chromium/src/base/message_pump_default.cc
@@ -52,26 +52,26 @@ void MessagePumpDefault::Run(Delegate* d
 
     if (did_work)
       continue;
 
     if (delayed_work_time_.is_null()) {
       hangMonitor.NotifyWait();
       AUTO_PROFILER_LABEL("MessagePumpDefault::Run:Wait", OTHER);
       {
-        mozilla::AutoProfilerThreadSleep sleep;
+        AUTO_PROFILER_THREAD_SLEEP;
         event_.Wait();
       }
     } else {
       TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
       if (delay > TimeDelta()) {
         hangMonitor.NotifyWait();
         AUTO_PROFILER_LABEL("MessagePumpDefault::Run:Wait", OTHER);
         {
-          mozilla::AutoProfilerThreadSleep sleep;
+          AUTO_PROFILER_THREAD_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/chromium/src/base/thread.cc
+++ b/ipc/chromium/src/base/thread.cc
@@ -149,17 +149,17 @@ void Thread::StopSoon() {
   // to someone calling Quit() on our message loop directly.
   DCHECK(message_loop_);
 
   RefPtr<ThreadQuitTask> task = new ThreadQuitTask();
   message_loop_->PostTask(task.forget());
 }
 
 void Thread::ThreadMain() {
-  mozilla::AutoProfilerRegisterThread registerThread(name_.c_str());
+  AUTO_PROFILER_REGISTER_THREAD(name_.c_str());
   mozilla::IOInterposer::RegisterCurrentThread();
 
   // The message loop for this thread.
   MessageLoop message_loop(startup_data_->options.message_loop_type,
                            NS_GetCurrentThread());
 
   // Complete the initialization of our Thread object.
   thread_id_ = PlatformThread::CurrentId();
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -567,17 +567,19 @@ GeckoChildProcessHost::SetChildLogName(c
   // for the time we launch the sub-process.  It's copied to the new
   // environment.
   PR_SetEnv(buffer.BeginReading());
 }
 
 bool
 GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, base::ProcessArchitecture arch)
 {
+#ifdef MOZ_GECKO_PROFILER
   AutoSetProfilerEnvVarsForChildProcess profilerEnvironment;
+#endif
 
   const char* origNSPRLogName = PR_GetEnv("NSPR_LOG_FILE");
   const char* origMozLogName = PR_GetEnv("MOZ_LOG_FILE");
   const char* origRustLog = PR_GetEnv("RUST_LOG");
   const char* childRustLog = PR_GetEnv("RUST_LOG_CHILD");
 
   // - Note: this code is not called re-entrantly, nor are restoreOrig*LogName
   //   or mChildCounter touched by any other thread, so this is safe.
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -4621,20 +4621,19 @@ class _GenerateProtocolActorCode(ipdl.as
             sendok,
             ([ Whitespace.NL,
                self.logMessage(md, msgexpr, 'Sending ', actor),
                self.profilerLabel(md) ]
             + self.transition(md, actor)
             + [ Whitespace.NL,
                 StmtDecl(Decl(Type.BOOL, sendok.name)),
                 StmtBlock([
-                    StmtDecl(Decl(Type('AutoProfilerTracing'),
-                                  'syncIPCTracer'),
-                             initargs=[ ExprLiteral.String("IPC"),
-                                        ExprLiteral.String(self.protocol.name + "::" + md.prettyMsgName()) ]),
+                    StmtExpr(ExprCall(ExprVar('AUTO_PROFILER_TRACING'),
+                             [ ExprLiteral.String("IPC"),
+                               ExprLiteral.String(self.protocol.name + "::" + md.prettyMsgName()) ])),
                     StmtExpr(ExprAssn(sendok,
                                       ExprCall(ExprSelect(self.protocol.callGetChannel(actor),
                                                           '->',
                                                           _sendPrefix(md.decl.type)),
                                                args=[ msgexpr, ExprAddrOf(replyexpr) ]))),
                 ])
             ])
         )
--- a/ipc/mscom/MainThreadInvoker.cpp
+++ b/ipc/mscom/MainThreadInvoker.cpp
@@ -124,17 +124,17 @@ MainThreadInvoker::Invoke(already_AddRef
   }
 
   return syncRunnable->WaitUntilComplete();
 }
 
 /* static */ VOID CALLBACK
 MainThreadInvoker::MainThreadAPC(ULONG_PTR aParam)
 {
-  AutoProfilerThreadWake wake;
+  AUTO_PROFILER_THREAD_WAKE;
   mozilla::HangMonitor::NotifyActivity(mozilla::HangMonitor::kGeneralActivity);
   MOZ_ASSERT(NS_IsMainThread());
   auto runnable = reinterpret_cast<SyncRunnable*>(aParam);
   runnable->Run();
   NS_RELEASE(runnable);
 }
 
 } // namespace mscom
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2499,19 +2499,21 @@ nsXPCComponents_Utils::Import(const nsAC
                               HandleValue targetObj,
                               JSContext* cx,
                               uint8_t optionalArgc,
                               MutableHandleValue retval)
 {
     RefPtr<mozJSComponentLoader> moduleloader = mozJSComponentLoader::Get();
     MOZ_ASSERT(moduleloader);
 
+#ifdef MOZ_GECKO_PROFILER
     const nsCString& flatLocation = PromiseFlatCString(registryLocation);
     AUTO_PROFILER_LABEL_DYNAMIC("nsXPCComponents_Utils::Import", OTHER,
                                 flatLocation.get());
+#endif
 
     return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::IsModuleLoaded(const nsACString& registryLocation, bool* retval)
 {
     RefPtr<mozJSComponentLoader> moduleloader = mozJSComponentLoader::Get();
--- a/js/xpconnect/src/XPCJSContext.cpp
+++ b/js/xpconnect/src/XPCJSContext.cpp
@@ -467,17 +467,17 @@ AutoLockWatchdog::~AutoLockWatchdog()
     if (mWatchdog) {
         PR_Unlock(mWatchdog->GetLock());
     }
 }
 
 static void
 WatchdogMain(void* arg)
 {
-    mozilla::AutoProfilerRegisterThread registerThread("JS Watchdog");
+    AUTO_PROFILER_REGISTER_THREAD("JS Watchdog");
     NS_SetCurrentThreadName("JS Watchdog");
 
     Watchdog* self = static_cast<Watchdog*>(arg);
     WatchdogManager* manager = self->Manager();
 
     // Lock lasts until we return
     AutoLockWatchdog lock(self);
 
@@ -596,17 +596,17 @@ IsWebExtensionContentScript(BasePrincipa
 
 // static
 bool
 XPCJSContext::InterruptCallback(JSContext* cx)
 {
     XPCJSContext* self = XPCJSContext::Get();
 
     // Now is a good time to turn on profiling if it's pending.
-    profiler_js_interrupt_callback();
+    PROFILER_JS_INTERRUPT_CALLBACK();
 
     // Normally we record mSlowScriptCheckpoint when we start to process an
     // event. However, we can run JS outside of event handlers. This code takes
     // care of that case.
     if (self->mSlowScriptCheckpoint.IsNull()) {
         self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
         self->mSlowScriptSecondHalf = false;
         self->mSlowScriptActualWait = mozilla::TimeDuration();
@@ -905,17 +905,17 @@ XPCJSContext::~XPCJSContext()
 
     if (mCallContext)
         mCallContext->SystemIsBeingShutDown();
 
     auto rtPrivate = static_cast<PerThreadAtomCache*>(JS_GetContextPrivate(Context()));
     delete rtPrivate;
     JS_SetContextPrivate(Context(), nullptr);
 
-    profiler_clear_js_context();
+    PROFILER_CLEAR_JS_CONTEXT();
 
     gTlsContext.set(nullptr);
 }
 
 XPCJSContext::XPCJSContext()
  : mCallContext(nullptr),
    mAutoRoots(nullptr),
    mResolveName(JSID_VOID),
@@ -1088,17 +1088,17 @@ XPCJSContext::Initialize(XPCJSContext* a
     // default.
     (void) kDefaultStackQuota;
 
     JS_SetNativeStackQuota(cx,
                            kStackQuota,
                            kStackQuota - kSystemCodeBuffer,
                            kStackQuota - kSystemCodeBuffer - kTrustedScriptBuffer);
 
-    profiler_set_js_context(cx);
+    PROFILER_SET_JS_CONTEXT(cx);
 
     js::SetActivityCallback(cx, ActivityCallback, this);
     JS_AddInterruptCallback(cx, InterruptCallback);
 
     if (!aPrimaryContext) {
         Runtime()->Initialize(cx);
     }
 
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -1088,18 +1088,20 @@ XRE_XPCShellMain(int argc, char** argv, 
     gErrFile = stderr;
     gOutFile = stdout;
     gInFile = stdin;
 
     NS_LogInit();
 
     mozilla::LogModule::Init();
 
+#ifdef MOZ_GECKO_PROFILER
     char aLocal;
     profiler_init(&aLocal);
+#endif
 
     if (PR_GetEnv("MOZ_CHAOSMODE")) {
         ChaosFeature feature = ChaosFeature::Any;
         long featureInt = strtol(PR_GetEnv("MOZ_CHAOSMODE"), nullptr, 16);
         if (featureInt) {
             // NOTE: MOZ_CHAOSMODE=0 or a non-hex value maps to Any feature.
             feature = static_cast<ChaosFeature>(featureInt);
         }
@@ -1412,19 +1414,21 @@ XRE_XPCShellMain(int argc, char** argv, 
     MOZ_ASSERT(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
 
 #ifdef MOZ_CRASHREPORTER
     // Shut down the crashreporter service to prevent leaking some strings it holds.
     if (CrashReporter::GetEnabled())
         CrashReporter::UnsetExceptionHandler();
 #endif
 
+#ifdef MOZ_GECKO_PROFILER
     // This must precede NS_LogTerm(), otherwise xpcshell return non-zero
     // during some tests, which causes failures.
     profiler_shutdown();
+#endif
 
     NS_LogTerm();
 
     return result;
 }
 
 void
 XPCShellDirProvider::SetGREDirs(nsIFile* greDir)
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -3694,17 +3694,17 @@ FlushLayoutRecursive(nsIDocument* aDocum
   aDocument->FlushPendingNotifications(FlushType::Layout);
   return true;
 }
 
 void
 PresShell::DispatchSynthMouseMove(WidgetGUIEvent* aEvent,
                                   bool aFlushOnHoverChange)
 {
-  AutoProfilerTracing tracing("Paint", "DispatchSynthMouseMove");
+  AUTO_PROFILER_TRACING("Paint", "DispatchSynthMouseMove");
   RestyleManager* restyleManager = mPresContext->RestyleManager();
   uint32_t hoverGenerationBefore =
     restyleManager->GetHoverGeneration();
   nsEventStatus status = nsEventStatus_eIgnore;
   nsView* targetView = nsView::GetViewFor(aEvent->mWidget);
   if (!targetView)
     return;
   targetView->GetViewManager()->DispatchEvent(aEvent, targetView, &status);
@@ -4028,34 +4028,35 @@ PresShell::DoFlushPendingNotifications(m
    * VERY IMPORTANT: If you add some sort of new flushing to this
    * method, make sure to add the relevant SetNeedLayoutFlush or
    * SetNeedStyleFlush calls on the shell.
    */
   FlushType flushType = aFlush.mFlushType;
 
   MOZ_ASSERT(NeedFlush(flushType), "Why did we get called?");
 
+#ifdef MOZ_GECKO_PROFILER
   static const EnumeratedArray<FlushType,
                                FlushType::Count,
                                const char*> flushTypeNames = {
     "",
     "Event",
     "Content",
     "ContentAndNotify",
     // As far as the profiler is concerned, EnsurePresShellInitAndFrames and
     // Frames are the same
     "Style",
     "Style",
     "InterruptibleLayout",
     "Layout",
     "Display"
   };
-
   AUTO_PROFILER_LABEL_DYNAMIC("PresShell::DoFlushPendingNotifications",
                               GRAPHICS, flushTypeNames[flushType]);
+#endif
 
 #ifdef ACCESSIBILITY
 #ifdef DEBUG
   nsAccessibilityService* accService = GetAccService();
   if (accService) {
     NS_ASSERTION(!accService->IsProcessingRefreshDriverNotification(),
                  "Flush during accessible tree update!");
   }
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -55,17 +55,19 @@ inline nsIDocument*
 RestyleTracker::Document() const {
   return mRestyleManager->PresContext()->Document();
 }
 
 #define RESTYLE_ARRAY_STACKSIZE 128
 
 struct RestyleEnumerateData : RestyleTracker::Hints {
   RefPtr<dom::Element> mElement;
+#ifdef MOZ_GECKO_PROFILER
   UniqueProfilerBacktrace mBacktrace;
+#endif
 };
 
 inline void
 RestyleTracker::ProcessOneRestyle(Element* aElement,
                                   nsRestyleHint aRestyleHint,
                                   nsChangeHint aChangeHint,
                                   const RestyleHintData& aRestyleHintData)
 {
@@ -101,25 +103,27 @@ RestyleTracker::ProcessOneRestyle(Elemen
     changeList.AppendChange(primaryFrame, aElement, aChangeHint);
     mRestyleManager->ProcessRestyledFrames(changeList);
   }
 }
 
 void
 RestyleTracker::DoProcessRestyles()
 {
+#ifdef MOZ_GECKO_PROFILER
   nsAutoCString docURL("N/A");
   if (profiler_is_active()) {
     nsIURI *uri = Document()->GetDocumentURI();
     if (uri) {
       docURL = uri->GetSpecOrDefault();
     }
   }
   AUTO_PROFILER_LABEL_DYNAMIC("RestyleTracker::DoProcessRestyles", CSS,
                               docURL.get());
+#endif
 
   // Create a AnimationsWithDestroyedFrame during restyling process to
   // stop animations and transitions on elements that have no frame at the end
   // of the restyling process.
   RestyleManager::AnimationsWithDestroyedFrame
     animationsWithDestroyedFrame(mRestyleManager);
 
   // Create a ReframingStyleContexts struct on the stack and put it in our
@@ -247,20 +251,22 @@ RestyleTracker::DoProcessRestyles()
           LOG_RESTYLE("skipping, already restyled");
           continue;
         }
 
         {
           AutoRestyleTimelineMarker marker(
             mRestyleManager->PresContext()->GetDocShell(),
             data->mRestyleHint & eRestyle_AllHintsWithAnimations);
+#ifdef MOZ_GECKO_PROFILER
           Maybe<AutoProfilerTracing> tracing;
           if (profiler_feature_active(ProfilerFeature::Restyle)) {
             tracing.emplace("Paint", "Styles", Move(data->mBacktrace));
           }
+#endif
           ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint,
                             data->mRestyleHintData);
           AddRestyleRootsIfAwaitingRestyle(data->mDescendants);
         }
       }
 
       if (mHaveLaterSiblingRestyles) {
         // Keep processing restyles for now
@@ -320,17 +326,19 @@ RestyleTracker::DoProcessRestyles()
                               ConditionalDescendantsBit());
 
           restyle->mElement = element;
           restyle->mRestyleHint = data->mRestyleHint;
           restyle->mChangeHint = data->mChangeHint;
           // We can move data since we'll be clearing mPendingRestyles after
           // we finish enumerating it.
           restyle->mRestyleHintData = Move(data->mRestyleHintData);
+#ifdef MOZ_GECKO_PROFILER
           restyle->mBacktrace = Move(data->mBacktrace);
+#endif
 
 #ifdef RESTYLE_LOGGING
           count++;
 #endif
 
           // Increment to the next slot in the array
           restyle++;
         }
@@ -346,20 +354,23 @@ RestyleTracker::DoProcessRestyles()
         for (RestyleEnumerateData* currentRestyle = restylesToProcess;
              currentRestyle != lastRestyle;
              ++currentRestyle) {
           LOG_RESTYLE("processing pending restyle %s at index %d/%d",
                       FrameTagToString(currentRestyle->mElement).get(),
                       index++, count);
           LOG_RESTYLE_INDENT();
 
+#ifdef MOZ_GECKO_PROFILER
           Maybe<AutoProfilerTracing> tracing;
           if (profiler_feature_active(ProfilerFeature::Restyle)) {
-            tracing.emplace("Paint", "Styles", Move(currentRestyle->mBacktrace));
+            tracing.emplace("Paint", "Styles",
+                            Move(currentRestyle->mBacktrace));
           }
+#endif
 
           {
             AutoRestyleTimelineMarker marker(
               mRestyleManager->PresContext()->GetDocShell(),
               currentRestyle->mRestyleHint & eRestyle_AllHintsWithAnimations);
             ProcessOneRestyle(currentRestyle->mElement,
                               currentRestyle->mRestyleHint,
                               currentRestyle->mChangeHint,
--- a/layout/base/RestyleTracker.h
+++ b/layout/base/RestyleTracker.h
@@ -119,17 +119,19 @@ public:
       }
     }
 
     // Descendant elements we must check that we ended up restyling, ordered
     // with the same invariant as mRestyleRoots.  The elements here are those
     // that we called AddPendingRestyle for and found the element this is
     // the RestyleData for as its nearest restyle root.
     nsTArray<RefPtr<Element>> mDescendants;
+#if defined(MOZ_GECKO_PROFILER)
     UniqueProfilerBacktrace mBacktrace;
+#endif
   };
 
   /**
    * If the given Element has a restyle pending for it, return the
    * relevant restyle data.  This function will clear everything other
    * than a possible eRestyle_LaterSiblings hint for aElement out of
    * our hashtable.  The returned aData will never have an
    * eRestyle_LaterSiblings hint in it.
@@ -254,19 +256,21 @@ RestyleTracker::AddPendingRestyleToTable
                  "why are we getting eRestyle_SomeDescendants in an "
                  "animation-only restyle?");
     aElement->SetFlags(ConditionalDescendantsBit());
   }
 
   if (!existingData) {
     RestyleData* rd =
       new RestyleData(aRestyleHint, aMinChangeHint, aRestyleHintData);
+#if defined(MOZ_GECKO_PROFILER)
     if (profiler_feature_active(ProfilerFeature::Restyle)) {
       rd->mBacktrace = profiler_get_backtrace();
     }
+#endif
     mPendingRestyles.Put(aElement, rd);
     return false;
   }
 
   bool hadRestyleLaterSiblings =
     (existingData->mRestyleHint & eRestyle_LaterSiblings) != 0;
   existingData->mRestyleHint =
     nsRestyleHint(existingData->mRestyleHint | aRestyleHint);
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3701,17 +3701,17 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
     MaybeCreateDisplayPortInFirstScrollFrameEncountered(aFrame, builder);
   }
 
   nsRect dirtyRect = visibleRegion.GetBounds();
 
   {
     AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame:BuildDisplayList",
                         GRAPHICS);
-    AutoProfilerTracing tracing("Paint", "DisplayList");
+    AUTO_PROFILER_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
       // BuildDisplayListForStackingContext call below. We need to set the scroll
@@ -3754,17 +3754,17 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
       }
     }
   }
 
   Telemetry::AccumulateTimeDelta(Telemetry::PAINT_BUILD_DISPLAYLIST_TIME,
                                  startBuildDisplayList);
 
   bool profilerNeedsDisplayList =
-    profiler_feature_active(ProfilerFeature::DisplayListDump);
+    PROFILER_FEATURE_ACTIVE(ProfilerFeature::DisplayListDump);
   bool consoleNeedsDisplayList = gfxUtils::DumpDisplayList() || gfxEnv::DumpPaint();
 #ifdef MOZ_DUMP_PAINTING
   FILE* savedDumpFile = gfxUtils::sDumpPaintFile;
 #endif
 
   UniquePtr<std::stringstream> ss;
   if (consoleNeedsDisplayList || profilerNeedsDisplayList) {
     ss = MakeUnique<std::stringstream>();
@@ -3799,17 +3799,17 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
     *ss << nsPrintfCString("Painting --- before optimization (dirty %d,%d,%d,%d):\n",
             dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height).get();
     nsFrame::PrintDisplayList(&builder, list, *ss, gfxEnv::DumpPaintToFile());
 
     if (gfxEnv::DumpPaint() || gfxEnv::DumpPaintItems()) {
       // Flush stream now to avoid reordering dump output relative to
       // messages dumped by PaintRoot below.
       if (profilerNeedsDisplayList && !consoleNeedsDisplayList) {
-        profiler_tracing("log", ss->str().c_str(), TRACING_EVENT);
+        PROFILER_TRACING("log", ss->str().c_str(), TRACING_EVENT);
       } else {
         fprint_stderr(gfxUtils::sDumpPaintFile, *ss);
       }
       ss = MakeUnique<std::stringstream>();
     }
   }
 
   uint32_t flags = nsDisplayList::PAINT_DEFAULT;
@@ -3872,17 +3872,17 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
 
     *ss << "Painting --- layer tree:\n";
     if (layerManager) {
       FrameLayerBuilder::DumpRetainedLayerTree(layerManager, *ss,
                                                gfxEnv::DumpPaintToFile());
     }
 
     if (profilerNeedsDisplayList && !consoleNeedsDisplayList) {
-      profiler_tracing("log", ss->str().c_str(), TRACING_EVENT);
+      PROFILER_TRACING("log", ss->str().c_str(), TRACING_EVENT);
     } else {
       fprint_stderr(gfxUtils::sDumpPaintFile, *ss);
     }
 
 #ifdef MOZ_DUMP_PAINTING
     if (gfxEnv::DumpPaintToFile()) {
       *ss << "</body></html>";
     }
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -318,17 +318,17 @@ protected:
     ScheduleNextTick(now);
 
     mLastFireEpoch = jsnow;
     mLastFireTime = now;
     mLastFireSkipped = false;
 
     LOG("[%p] ticking drivers...", this);
     // RD is short for RefreshDriver
-    AutoProfilerTracing tracing("Paint", "RefreshDriverTick");
+    AUTO_PROFILER_TRACING("Paint", "RefreshDriverTick");
 
     TickRefreshDrivers(jsnow, now, mContentRefreshDrivers);
     TickRefreshDrivers(jsnow, now, mRootRefreshDrivers);
 
     LOG("[%p] done.", this);
   }
 
   static void TickDriver(nsRefreshDriver* driver, int64_t jsnow, TimeStamp now)
@@ -1722,17 +1722,17 @@ nsRefreshDriver::RunFrameRequestCallback
   for (nsIDocument* doc : mFrameRequestCallbackDocs) {
     TakeFrameRequestCallbacksFrom(doc, frameRequestCallbacks);
   }
 
   // Reset mFrameRequestCallbackDocs so they can be readded as needed.
   mFrameRequestCallbackDocs.Clear();
 
   if (!frameRequestCallbacks.IsEmpty()) {
-    AutoProfilerTracing tracing("Paint", "Scripts");
+    AUTO_PROFILER_TRACING("Paint", "Scripts");
     for (const DocumentFrameCallbacks& docCallbacks : frameRequestCallbacks) {
       // XXXbz Bug 863140: GetInnerWindow can return the outer
       // window in some cases.
       nsPIDOMWindowInner* innerWindow =
         docCallbacks.mDocument->GetInnerWindow();
       DOMHighResTimeStamp timeStamp = 0;
       if (innerWindow && innerWindow->IsInnerWindow()) {
         mozilla::dom::Performance* perf = innerWindow->GetPerformance();
@@ -1896,62 +1896,70 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
       // This is the FlushType::Style case.
 
       DispatchAnimationEvents();
       DispatchPendingEvents();
       RunFrameRequestCallbacks(aNowTime);
       DispatchScrollEvents();
 
       if (mPresContext && mPresContext->GetPresShell()) {
+#ifdef MOZ_GECKO_PROFILER
         Maybe<AutoProfilerTracing> tracingStyleFlush;
+#endif
         AutoTArray<nsIPresShell*, 16> observers;
         observers.AppendElements(mStyleFlushObservers);
         for (uint32_t j = observers.Length();
              j && mPresContext && mPresContext->GetPresShell(); --j) {
           // Make sure to not process observers which might have been removed
           // during previous iterations.
           nsIPresShell* shell = observers[j - 1];
           if (!mStyleFlushObservers.RemoveElement(shell))
             continue;
 
+#ifdef MOZ_GECKO_PROFILER
           if (!tracingStyleFlush) {
             tracingStyleFlush.emplace("Paint", "Styles", Move(mStyleCause));
             mStyleCause = nullptr;
           }
+#endif
 
           nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
           shell->mObservingStyleFlushes = false;
           shell->FlushPendingNotifications(ChangesToFlush(FlushType::Style, false));
           // Inform the FontFaceSet that we ticked, so that it can resolve its
           // ready promise if it needs to (though it might still be waiting on
           // a layout flush).
           nsPresContext* presContext = shell->GetPresContext();
           if (presContext) {
             presContext->NotifyFontFaceSetOnRefresh();
           }
           mNeedToRecomputeVisibility = true;
         }
       }
     } else if  (i == 2) {
       // This is the FlushType::Layout case.
+#ifdef MOZ_GECKO_PROFILER
       Maybe<AutoProfilerTracing> tracingLayoutFlush;
+#endif
       AutoTArray<nsIPresShell*, 16> observers;
       observers.AppendElements(mLayoutFlushObservers);
       for (uint32_t j = observers.Length();
            j && mPresContext && mPresContext->GetPresShell(); --j) {
         // Make sure to not process observers which might have been removed
         // during previous iterations.
         nsIPresShell* shell = observers[j - 1];
         if (!mLayoutFlushObservers.RemoveElement(shell))
           continue;
 
+#ifdef MOZ_GECKO_PROFILER
         if (!tracingLayoutFlush) {
           tracingLayoutFlush.emplace("Paint", "Reflow", Move(mReflowCause));
           mReflowCause = nullptr;
         }
+#endif
 
         nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
         shell->mObservingLayoutFlushes = false;
         shell->mWasLastReflowInterrupted = false;
         FlushType flushType = HasPendingAnimations(shell)
                                ? FlushType::Layout
                                : FlushType::InterruptibleLayout;
         shell->FlushPendingNotifications(ChangesToFlush(flushType, false));
@@ -2182,17 +2190,17 @@ nsRefreshDriver::Thaw()
 
 void
 nsRefreshDriver::FinishedWaitingForTransaction()
 {
   mWaitingForTransaction = false;
   if (mSkippedPaints &&
       !IsInRefresh() &&
       (ObserverCount() || ImageRequestCount())) {
-    AutoProfilerTracing tracing("Paint", "RefreshDriverTick");
+    AUTO_PROFILER_TRACING("Paint", "RefreshDriverTick");
     DoRefresh();
   }
   mSkippedPaints = false;
   mWarningThreshold = 1;
 }
 
 uint64_t
 nsRefreshDriver::GetTransactionId(bool aThrottle)
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -159,37 +159,41 @@ public:
    */
   bool AddStyleFlushObserver(nsIPresShell* aShell) {
     NS_ASSERTION(!mStyleFlushObservers.Contains(aShell),
                  "Double-adding style flush observer");
     // We only get the cause for the first observer each frame because capturing
     // a stack is expensive. This is still useful if (1) you're trying to remove
     // all flushes for a particial frame or (2) the costly flush is triggered
     // near the call site where the first observer is triggered.
+#ifdef MOZ_GECKO_PROFILER
     if (!mStyleCause) {
       mStyleCause = profiler_get_backtrace();
     }
+#endif
     bool appended = mStyleFlushObservers.AppendElement(aShell) != nullptr;
     EnsureTimerStarted();
 
     return appended;
   }
   void RemoveStyleFlushObserver(nsIPresShell* aShell) {
     mStyleFlushObservers.RemoveElement(aShell);
   }
   bool AddLayoutFlushObserver(nsIPresShell* aShell) {
     NS_ASSERTION(!IsLayoutFlushObserver(aShell),
                  "Double-adding layout flush observer");
+#ifdef MOZ_GECKO_PROFILER
     // We only get the cause for the first observer each frame because capturing
     // a stack is expensive. This is still useful if (1) you're trying to remove
     // all flushes for a particial frame or (2) the costly flush is triggered
     // near the call site where the first observer is triggered.
     if (!mReflowCause) {
       mReflowCause = profiler_get_backtrace();
     }
+#endif
     bool appended = mLayoutFlushObservers.AppendElement(aShell) != nullptr;
     EnsureTimerStarted();
     return appended;
   }
   void RemoveLayoutFlushObserver(nsIPresShell* aShell) {
     mLayoutFlushObservers.RemoveElement(aShell);
   }
   bool IsLayoutFlushObserver(nsIPresShell* aShell) {
@@ -411,18 +415,20 @@ private:
     return mFrameRequestCallbackDocs.Length() != 0;
   }
 
   void FinishedWaitingForTransaction();
 
   mozilla::RefreshDriverTimer* ChooseTimer() const;
   mozilla::RefreshDriverTimer* mActiveTimer;
 
+#ifdef MOZ_GECKO_PROFILER
   UniqueProfilerBacktrace mReflowCause;
   UniqueProfilerBacktrace mStyleCause;
+#endif
 
   // nsPresContext passed in constructor and unset in Disconnect.
   mozilla::WeakPtr<nsPresContext> mPresContext;
 
   RefPtr<nsRefreshDriver> mRootRefresh;
 
   // The most recently allocated transaction id.
   uint64_t mPendingTransaction;
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -4750,17 +4750,17 @@ ScrollFrameHelper::ScrollEvent::Run()
     mHelper->FireScrollEvent();
   }
   return NS_OK;
 }
 
 void
 ScrollFrameHelper::FireScrollEvent()
 {
-  AutoProfilerTracing tracing("Paint", "FireScrollEvent");
+  AUTO_PROFILER_TRACING("Paint", "FireScrollEvent");
   MOZ_ASSERT(mScrollEvent);
   mScrollEvent->Revoke();
   mScrollEvent = nullptr;
 
   ActiveLayerTracker::SetCurrentScrollHandlerFrame(mOuter);
   WidgetGUIEvent event(true, eScroll, nullptr);
   nsEventStatus status = nsEventStatus_eIgnore;
   nsIContent* content = mOuter->GetContent();
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2204,17 +2204,17 @@ already_AddRefed<LayerManager> nsDisplay
   FrameLayerBuilder *layerBuilder = new FrameLayerBuilder();
   layerBuilder->Init(aBuilder, layerManager);
 
   if (aFlags & PAINT_COMPRESSED) {
     layerBuilder->SetLayerTreeCompressionMode();
   }
 
   {
-    AutoProfilerTracing tracing("Paint", "LayerBuilding");
+    AUTO_PROFILER_TRACING("Paint", "LayerBuilding");
 
     if (doBeginTransaction) {
       if (aCtx) {
         if (!layerManager->BeginTransactionWithTarget(aCtx)) {
           return nullptr;
         }
       } else {
         if (!layerManager->BeginTransaction()) {
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -2699,24 +2699,23 @@ void                                    
 Gecko_Destroy_nsStyle##name(nsStyle##name* ptr)                               \
 {                                                                             \
   ptr->~nsStyle##name();                                                      \
 }
 
 void
 Gecko_RegisterProfilerThread(const char* name)
 {
-  char stackTop;
-  profiler_register_thread(name, &stackTop);
+  PROFILER_REGISTER_THREAD(name);
 }
 
 void
 Gecko_UnregisterProfilerThread()
 {
-  profiler_unregister_thread();
+  PROFILER_UNREGISTER_THREAD();
 }
 
 bool
 Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed aPresContext,
                                       const nsACString* aPattern,
                                       css::URLMatchingFunction aURLMatchingFunction)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -1451,25 +1451,23 @@ nsHostResolver::SizeOfIncludingThis(Mall
     //   |mDB| is measured.
 
     return n;
 }
 
 void
 nsHostResolver::ThreadFunc(void *arg)
 {
-    char stackTop;
-
     LOG(("DNS lookup thread - starting execution.\n"));
 
     static nsThreadPoolNaming naming;
     nsCString name = naming.GetNextThreadName("DNS Resolver");
 
+    AUTO_PROFILER_REGISTER_THREAD(name.BeginReading());
     NS_SetCurrentThreadName(name.BeginReading());
-    profiler_register_thread(name.BeginReading(), &stackTop);
 
 #if defined(RES_RETRY_ON_FAILURE)
     nsResState rs;
 #endif
     nsHostResolver *resolver = (nsHostResolver *)arg;
     nsHostRecord *rec  = nullptr;
     AddrInfo *ai = nullptr;
 
@@ -1530,18 +1528,16 @@ nsHostResolver::ThreadFunc(void *arg)
                  LOG_HOST(rec->host, rec->netInterface)));
         } else {
             rec = nullptr;
         }
     }
     resolver->mThreadCount--;
     NS_RELEASE(resolver);
     LOG(("DNS lookup thread - queue empty, thread finished.\n"));
-
-    profiler_unregister_thread();
 }
 
 nsresult
 nsHostResolver::Create(uint32_t maxCacheEntries,
                        uint32_t defaultCacheEntryLifetime,
                        uint32_t defaultGracePeriod,
                        nsHostResolver **result)
 {
--- a/security/manager/ssl/nsKeygenThread.cpp
+++ b/security/manager/ssl/nsKeygenThread.cpp
@@ -113,17 +113,17 @@ nsresult nsKeygenThread::ConsumeResult(
       rv = NS_ERROR_FAILURE;
     }
 
   return rv;
 }
 
 static void nsKeygenThreadRunner(void *arg)
 {
-  AutoProfilerRegisterThread registerThread("Keygen");
+  AUTO_PROFILER_REGISTER_THREAD("Keygen");
   NS_SetCurrentThreadName("Keygen");
   nsKeygenThread *self = static_cast<nsKeygenThread *>(arg);
   self->Run();
 }
 
 nsresult nsKeygenThread::StartKeyGeneration(nsIObserver* aObserver)
 {
   if (!NS_IsMainThread()) {
--- a/security/manager/ssl/nsProtectedAuthThread.cpp
+++ b/security/manager/ssl/nsProtectedAuthThread.cpp
@@ -17,17 +17,17 @@
 
 using namespace mozilla;
 using namespace mozilla::psm;
 
 NS_IMPL_ISUPPORTS(nsProtectedAuthThread, nsIProtectedAuthThread)
 
 static void nsProtectedAuthThreadRunner(void *arg)
 {
-    AutoProfilerRegisterThread registerThread("Protected Auth");
+    AUTO_PROFILER_REGISTER_THREAD("Protected Auth");
     NS_SetCurrentThreadName("Protected Auth");
 
     nsProtectedAuthThread *self = static_cast<nsProtectedAuthThread *>(arg);
     self->Run();
 }
 
 nsProtectedAuthThread::nsProtectedAuthThread()
 : mMutex("nsProtectedAuthThread.mMutex")
--- a/security/manager/ssl/nsSmartCardMonitor.cpp
+++ b/security/manager/ssl/nsSmartCardMonitor.cpp
@@ -385,13 +385,13 @@ void SmartCardMonitoringThread::Execute(
 const SECMODModule* SmartCardMonitoringThread::GetModule()
 {
   return mModule;
 }
 
 // C-like calling sequence to glue into PR_CreateThread.
 void SmartCardMonitoringThread::LaunchExecute(void* arg)
 {
-  AutoProfilerRegisterThread registerThread("SmartCard");
+  AUTO_PROFILER_REGISTER_THREAD("SmartCard");
   NS_SetCurrentThreadName("SmartCard");
 
   ((SmartCardMonitoringThread*)arg)->Execute();
 }
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -496,17 +496,17 @@ StartupCache::WaitOnWriteThread()
 
   PR_JoinThread(mWriteThread);
   mWriteThread = nullptr;
 }
 
 void
 StartupCache::ThreadedWrite(void *aClosure)
 {
-  AutoProfilerRegisterThread registerThread("StartupCache");
+  AUTO_PROFILER_REGISTER_THREAD("StartupCache");
   NS_SetCurrentThreadName("StartupCache");
   mozilla::IOInterposer::RegisterCurrentThread();
   /*
    * It is safe to use the pointer passed in aClosure to reference the
    * StartupCache object because the thread's lifetime is tightly coupled to
    * the lifetime of the StartupCache object; this thread is joined in the
    * StartupCache destructor, guaranteeing that this function runs if and only
    * if the StartupCache object is valid.
--- a/toolkit/components/backgroundhangmonitor/BackgroundHangMonitor.cpp
+++ b/toolkit/components/backgroundhangmonitor/BackgroundHangMonitor.cpp
@@ -60,17 +60,17 @@ namespace mozilla {
  * manages all instances of BackgroundHangThread.
  */
 class BackgroundHangManager : public nsIObserver
 {
 private:
   // Background hang monitor thread function
   static void MonitorThread(void* aData)
   {
-    AutoProfilerRegisterThread registerThread("BgHangMonitor");
+    AUTO_PROFILER_REGISTER_THREAD("BgHangMonitor");
     NS_SetCurrentThreadName("BgHangManager");
 
     /* We do not hold a reference to BackgroundHangManager here
        because the monitor thread only exists as long as the
        BackgroundHangManager instance exists. We stop the monitor
        thread in the BackgroundHangManager destructor, and we can
        only get to the destructor if we don't hold a reference here. */
     static_cast<BackgroundHangManager*>(aData)->RunMonitorThread();
@@ -187,18 +187,20 @@ public:
   // Time when a hang started
   PRIntervalTime mHangStart;
   // Is the thread in a hang
   bool mHanging;
   // Is the thread in a waiting state
   bool mWaiting;
   // Is the thread dedicated to a single BackgroundHangMonitor
   BackgroundHangMonitor::ThreadType mThreadType;
+#ifdef MOZ_GECKO_PROFILER
   // Platform-specific helper to get hang stacks
   ThreadStackHelper mStackHelper;
+#endif
   // Stack of current hang
   HangStack mHangStack;
   // Annotations for the current hang
   HangMonitor::HangAnnotations mAnnotations;
   // Annotators registered for this thread
   HangMonitor::Observer::Annotators mAnnotators;
   // The name of the runnable which is hanging the current process
   nsCString mRunnableName;
@@ -354,21 +356,23 @@ BackgroundHangManager::RunMonitorThread(
         currentThread->mWaiting = true;
         currentThread->mHanging = false;
         currentThread->ReportPermaHang();
         continue;
       }
 
       if (MOZ_LIKELY(!currentThread->mHanging)) {
         if (MOZ_UNLIKELY(hangTime >= currentThread->mTimeout)) {
+#ifdef MOZ_GECKO_PROFILER
           // A hang started, collect a stack
           currentThread->mStackHelper.GetStack(
             currentThread->mHangStack,
             currentThread->mRunnableName,
             true);
+#endif
 
           // If we hang immediately on waking, then the most recently collected
           // CPU usage is going to be an average across the whole time we were
           // sleeping. Accordingly, we want to make sure that when we hang, we
           // collect a fresh value.
           if (systemTime != lastCheckedCPUUsage) {
             Unused << NS_WARN_IF(mCPUUsageWatcher.CollectCPUUsage().isErr());
             lastCheckedCPUUsage = systemTime;
--- a/toolkit/components/backgroundhangmonitor/ThreadStackHelper.h
+++ b/toolkit/components/backgroundhangmonitor/ThreadStackHelper.h
@@ -2,16 +2,18 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ThreadStackHelper_h
 #define mozilla_ThreadStackHelper_h
 
+#ifdef MOZ_GECKO_PROFILER
+
 #include "js/ProfilingStack.h"
 #include "HangDetails.h"
 #include "nsThread.h"
 
 #include <stddef.h>
 
 #if defined(XP_LINUX)
 #include <signal.h>
@@ -20,20 +22,18 @@
 #elif defined(XP_WIN)
 #include <windows.h>
 #elif defined(XP_MACOSX)
 #include <mach/mach.h>
 #endif
 
 // Support pseudostack and native stack on these platforms.
 #if defined(XP_LINUX) || defined(XP_WIN) || defined(XP_MACOSX)
-#  ifdef MOZ_GECKO_PROFILER
-#    define MOZ_THREADSTACKHELPER_PSEUDO
-#    define MOZ_THREADSTACKHELPER_NATIVE
-#  endif
+#  define MOZ_THREADSTACKHELPER_PSEUDO
+#  define MOZ_THREADSTACKHELPER_NATIVE
 #endif
 
 
 // Android x86 builds consistently crash in the Background Hang Reporter. bug
 // 1368520.
 #if defined(__ANDROID__)
 #  undef MOZ_THREADSTACKHELPER_PSEUDO
 #  undef MOZ_THREADSTACKHELPER_NATIVE
@@ -101,9 +101,11 @@ private:
   void TryAppendFrame(mozilla::HangStack::Frame aFrame);
 
   // The profiler's unique thread identifier for the target thread.
   int mThreadId;
 };
 
 } // namespace mozilla
 
+#endif // MOZ_GECKO_PROFILER
+
 #endif // mozilla_ThreadStackHelper_h
--- a/toolkit/components/backgroundhangmonitor/moz.build
+++ b/toolkit/components/backgroundhangmonitor/moz.build
@@ -34,18 +34,22 @@ EXPORTS.mozilla += [
     'HangDetails.h',
     'HangStack.h',
 ]
 
 UNIFIED_SOURCES += [
     'BackgroundHangMonitor.cpp',
     'HangDetails.cpp',
     'HangStack.cpp',
-    'ThreadStackHelper.cpp',
 ]
 
+if CONFIG['MOZ_GECKO_PROFILER']:
+    UNIFIED_SOURCES += [
+        'ThreadStackHelper.cpp',
+    ]
+
 LOCAL_INCLUDES += [
     '/caps', # For nsScriptSecurityManager.h
 ]
 
 FINAL_LIBRARY = 'xul'
 
 include('/ipc/chromium/chromium-config.mozbuild')
--- a/toolkit/components/startup/StartupTimeline.h
+++ b/toolkit/components/startup/StartupTimeline.h
@@ -54,17 +54,17 @@ public:
   }
 
   static const char *Describe(Event ev) {
     return sStartupTimelineDesc[ev];
   }
 
 #ifdef MOZILLA_INTERNAL_API
   static void Record(Event ev) {
-    profiler_add_marker(Describe(ev));
+    PROFILER_ADD_MARKER(Describe(ev));
     Record(ev, TimeStamp::Now());
   }
 
   static void Record(Event ev, TimeStamp when) {
     sStartupTimeline[ev] = when;
   }
 
   static void RecordOnce(Event ev);
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
@@ -382,17 +382,17 @@ nsAppStartup::Quit(uint32_t aMode)
             if (!domWindow->CanClose())
               return NS_OK;
           }
           windowEnumerator->HasMoreElements(&more);
         }
       }
     }
 
-    profiler_add_marker("Shutdown start");
+    PROFILER_ADD_MARKER("Shutdown start");
     mozilla::RecordShutdownStartTimeStamp();
     mShuttingDown = true;
     if (!mRestart) {
       mRestart = (aMode & eRestart) != 0;
     }
 
     if (!mRestartNotSameProfile) {
       mRestartNotSameProfile = (aMode & eRestartNotSameProfile) != 0;
--- a/toolkit/components/telemetry/CombinedStacks.h
+++ b/toolkit/components/telemetry/CombinedStacks.h
@@ -29,18 +29,18 @@ public:
   const Telemetry::ProcessedStack::Module& GetModule(unsigned aIndex) const;
   size_t GetModuleCount() const;
   const Stack& GetStack(unsigned aIndex) const;
   size_t AddStack(const Telemetry::ProcessedStack& aStack);
   size_t GetStackCount() const;
   size_t SizeOfExcludingThis() const;
 
 #if defined(MOZ_GECKO_PROFILER)
-    /** Clears the contents of vectors and resets the index. */
-    void Clear();
+  /** Clears the contents of vectors and resets the index. */
+  void Clear();
 #endif
 
 private:
   std::vector<Telemetry::ProcessedStack::Module> mModules;
   // A circular buffer to hold the stacks.
   std::vector<Stack> mStacks;
   // The index of the next buffer element to write to in mStacks.
   size_t mNextIndex;
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -1535,17 +1535,17 @@ TelemetryImpl::DoStackCapture(const nsAC
   if (Telemetry::CanRecordExtended() && XRE_IsParentProcess()) {
     sTelemetry->mStackCapturer.Capture(aKey);
   }
 }
 #endif
 
 nsresult
 TelemetryImpl::CaptureStack(const nsACString& aKey) {
-#if defined(MOZ_GECKO_PROFILER)
+#ifdef MOZ_GECKO_PROFILER
   TelemetryImpl::DoStackCapture(aKey);
 #endif
   return NS_OK;
 }
 
 bool
 TelemetryImpl::CanRecordBase()
 {
@@ -1986,17 +1986,17 @@ void RecordChromeHang(uint32_t duration,
 {
   TelemetryImpl::RecordChromeHang(duration, aStack,
                                   aSystemUptime, aFirefoxUptime,
                                   Move(aAnnotations));
 }
 
 void CaptureStack(const nsACString& aKey)
 {
-#if defined(MOZ_GECKO_PROFILER)
+#ifdef MOZ_GECKO_PROFILER
   TelemetryImpl::DoStackCapture(aKey);
 #endif
 }
 #endif
 
 void
 WriteFailedProfileLock(nsIFile* aProfileDir)
 {
--- a/toolkit/components/terminator/nsTerminator.cpp
+++ b/toolkit/components/terminator/nsTerminator.cpp
@@ -211,17 +211,17 @@ public:
 // The data written by the writer thread will be read by another
 // module upon the next restart and fed to Telemetry.
 //
 Atomic<nsCString*> gWriteData(nullptr);
 PRMonitor* gWriteReady = nullptr;
 
 void RunWriter(void* arg)
 {
-  AutoProfilerRegisterThread registerThread("Shutdown Statistics Writer");
+  AUTO_PROFILER_REGISTER_THREAD("Shutdown Statistics Writer");
   NS_SetCurrentThreadName("Shutdown Statistics Writer");
 
   MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(arg);
   // Shutdown will generally complete before we have a chance to
   // deallocate. This is not a leak.
 
   // Setup destinationPath and tmpFilePath
 
--- a/toolkit/xre/EventTracer.cpp
+++ b/toolkit/xre/EventTracer.cpp
@@ -88,17 +88,17 @@ struct TracerStartClosure {
  * it will not send another event until the previous response is received.
  *
  * The output defaults to stdout, but can be redirected to a file by
  * settting the environment variable MOZ_INSTRUMENT_EVENT_LOOP_OUTPUT
  * to the name of a file to use.
  */
 void TracerThread(void *arg)
 {
-  AutoProfilerRegisterThread registerThread("Event Tracer");
+  AUTO_PROFILER_REGISTER_THREAD("Event Tracer");
   NS_SetCurrentThreadName("Event Tracer");
 
   TracerStartClosure* threadArgs = static_cast<TracerStartClosure*>(arg);
 
   // These are the defaults. They can be overridden by environment vars.
   // This should be set to the maximum latency we'd like to allow
   // for responsiveness.
   int32_t thresholdInterval = threadArgs->mThresholdInterval;
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1509,17 +1509,17 @@ ScopedXPCOMStartup::~ScopedXPCOMStartup(
     mozilla::MacAutoreleasePool pool;
 #endif
 
     nsCOMPtr<nsIAppStartup> appStartup (do_GetService(NS_APPSTARTUP_CONTRACTID));
     if (appStartup)
       appStartup->DestroyHiddenWindow();
 
     gDirServiceProvider->DoShutdown();
-    profiler_add_marker("Shutdown early");
+    PROFILER_ADD_MARKER("Shutdown early");
 
     WriteConsoleLog();
 
     NS_ShutdownXPCOM(mServiceManager);
     mServiceManager = nullptr;
   }
 }
 
@@ -4735,18 +4735,17 @@ XREMain::XRE_main(int argc, char* argv[]
 #if defined(MOZ_SANDBOX) && defined(XP_LINUX) && !defined(ANDROID)
   SandboxInfo::ThreadingCheck();
 #endif
 
 #ifdef MOZ_CODE_COVERAGE
   CodeCoverageHandler::Init();
 #endif
 
-  AutoProfilerInit profilerInit;
-
+  AUTO_PROFILER_INIT;
   AUTO_PROFILER_LABEL("XREMain::XRE_main", OTHER);
 
   nsresult rv = NS_OK;
 
   gArgc = argc;
   gArgv = argv;
 
   if (aConfig.appData) {
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -394,18 +394,17 @@ XRE_InitChildProcess(int aArgc,
 #endif
 #endif
 
   // NB: This must be called before profiler_init
   ScopedLogging logger;
 
   mozilla::LogModule::Init();
 
-  AutoProfilerInit profilerInit;
-
+  AUTO_PROFILER_INIT;
   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.
@@ -766,17 +765,17 @@ XRE_InitParentProcess(int aArgc,
   NS_ENSURE_ARG_POINTER(aArgv);
   NS_ENSURE_ARG_POINTER(aArgv[0]);
 
   // Set main thread before we initialize the profiler
   NS_SetMainThread();
 
   mozilla::LogModule::Init();
 
-  AutoProfilerInit profilerInit;
+  AUTO_PROFILER_INIT;
 
   ScopedXREEmbed embed;
 
   gArgc = aArgc;
   gArgv = aArgv;
   nsresult rv = XRE_InitCommandLine(gArgc, gArgv);
   if (NS_FAILED(rv))
       return NS_ERROR_FAILURE;
--- a/tools/profiler/moz.build
+++ b/tools/profiler/moz.build
@@ -6,17 +6,19 @@
 
 if CONFIG['MOZ_GECKO_PROFILER']:
     XPIDL_MODULE = 'profiler'
     XPIDL_SOURCES += [
         'gecko/nsIProfiler.idl',
     ]
     EXPORTS += [
         'public/ChildProfilerController.h',
+        'public/GeckoProfilerReporter.h',
         'public/ProfilerChild.h',
+        'public/ProfilerMarkerPayload.h',
         'public/ProfilerParent.h',
         'public/shared-libraries.h',
     ]
     UNIFIED_SOURCES += [
         'core/platform.cpp',
         'core/ProfileBuffer.cpp',
         'core/ProfileBufferEntry.cpp',
         'core/ProfileJSONWriter.cpp',
@@ -112,20 +114,20 @@ if CONFIG['MOZ_GECKO_PROFILER']:
 
 IPDL_SOURCES += [
     'gecko/PProfiler.ipdl',
     'gecko/ProfilerTypes.ipdlh',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
+# GeckoProfiler.h is the only code that's visible in non-MOZ_GECKO_PROFILER
+# builds, and it only contains no-op macros in that case.
 EXPORTS += [
     'public/GeckoProfiler.h',
-    'public/GeckoProfilerReporter.h',
-    'public/ProfilerMarkerPayload.h',
 ]
 
 if CONFIG['MOZ_TASK_TRACER']:
     EXPORTS += [
         'tasktracer/GeckoTaskTracer.h',
         'tasktracer/GeckoTaskTracerImpl.h',
         'tasktracer/SourceEventTypeMap.h',
         'tasktracer/TracedTaskCommon.h',
--- a/tools/profiler/public/GeckoProfiler.h
+++ b/tools/profiler/public/GeckoProfiler.h
@@ -11,16 +11,49 @@
 //
 // Samples are collected to form a timeline with optional timeline event
 // (markers) used for filtering. The samples include both native stacks and
 // platform-independent "pseudostacks".
 
 #ifndef GeckoProfiler_h
 #define GeckoProfiler_h
 
+#ifndef MOZ_GECKO_PROFILER
+
+// This file can be #included unconditionally. However, everything within this
+// file must be guarded by a #ifdef MOZ_GECKO_PROFILER, *except* for the
+// following macros, which encapsulate the most common operations and thus
+// avoid the need for many #ifdefs.
+
+#define AUTO_PROFILER_INIT
+
+#define PROFILER_REGISTER_THREAD(name)
+#define PROFILER_UNREGISTER_THREAD()
+#define AUTO_PROFILER_REGISTER_THREAD(name)
+
+#define AUTO_PROFILER_THREAD_SLEEP
+#define AUTO_PROFILER_THREAD_WAKE
+
+#define PROFILER_JS_INTERRUPT_CALLBACK()
+
+#define PROFILER_SET_JS_CONTEXT(cx)
+#define PROFILER_CLEAR_JS_CONTEXT()
+
+#define PROFILER_FEATURE_ACTIVE(feature) false
+
+#define AUTO_PROFILER_LABEL(label, category)
+#define AUTO_PROFILER_LABEL_DYNAMIC(label, category, dynamicStr)
+
+#define PROFILER_ADD_MARKER(markerName)
+
+#define PROFILER_TRACING(category, markerName, kind)
+#define AUTO_PROFILER_TRACING(category, markerName)
+
+#else // !MOZ_GECKO_PROFILER
+
 #include <functional>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdlib.h>
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
@@ -44,27 +77,16 @@ class ProfilerMarkerPayload;
 class SpliceableJSONWriter;
 
 namespace mozilla {
 class MallocAllocPolicy;
 template <class T, size_t MinInlineCapacity, class AllocPolicy> class Vector;
 class TimeStamp;
 } // namespace mozilla
 
-// When the profiler is disabled functions declared with these macros are
-// static inline functions (with a trivial return value if they are non-void)
-// that will be optimized away during compilation.
-#ifdef MOZ_GECKO_PROFILER
-# define PROFILER_FUNC(decl, rv)  decl;
-# define PROFILER_FUNC_VOID(decl) void decl;
-#else
-# define PROFILER_FUNC(decl, rv)  static inline decl { return rv; }
-# define PROFILER_FUNC_VOID(decl) static inline void decl {}
-#endif
-
 // Macros used by the AUTO_PROFILER_* macros below.
 #define PROFILER_RAII_PASTE(id, line) id ## line
 #define PROFILER_RAII_EXPAND(id, line) PROFILER_RAII_PASTE(id, line)
 #define PROFILER_RAII PROFILER_RAII_EXPAND(raiiObject, __LINE__)
 
 //---------------------------------------------------------------------------
 // Profiler features
 //---------------------------------------------------------------------------
@@ -140,83 +162,100 @@ struct ProfilerFeature
 #endif
 
 #define PROFILER_DEFAULT_INTERVAL 1
 
 // Initialize the profiler. If MOZ_PROFILER_STARTUP is set the profiler will
 // also be started. This call must happen before any other profiler calls
 // (except profiler_start(), which will call profiler_init() if it hasn't
 // already run).
-PROFILER_FUNC_VOID(profiler_init(void* stackTop))
+void profiler_init(void* stackTop);
+
+#define AUTO_PROFILER_INIT \
+  mozilla::AutoProfilerInit PROFILER_RAII
 
 // Clean up the profiler module, stopping it if required. This function may
 // also save a shutdown profile if requested. No profiler calls should happen
 // after this point and all pseudo labels should have been popped.
-PROFILER_FUNC_VOID(profiler_shutdown())
+void profiler_shutdown();
 
 // Start the profiler -- initializing it first if necessary -- with the
 // selected options. Stops and restarts the profiler if it is already active.
 // After starting the profiler is "active". The samples will be recorded in a
 // circular buffer.
 //   "aEntries" is the number of entries in the profiler's circular buffer.
 //   "aInterval" the sampling interval, measured in millseconds.
 //   "aFeatures" is the feature set. Features unsupported by this
 //               platform/configuration are ignored.
-PROFILER_FUNC_VOID(profiler_start(int aEntries, double aInterval,
-                                  uint32_t aFeatures,
-                                  const char** aFilters, uint32_t aFilterCount))
+void profiler_start(int aEntries, double aInterval, uint32_t aFeatures,
+                    const char** aFilters, uint32_t aFilterCount);
 
 // Stop the profiler and discard the profile without saving it. A no-op if the
 // profiler is inactive. After stopping the profiler is "inactive".
-PROFILER_FUNC_VOID(profiler_stop())
+void profiler_stop();
 
 // If the profiler is inactive, start it. If it's already active, restart it if
 // the requested settings differ from the current settings. Both the check and
 // the state change are performed while the profiler state is locked.
 // The only difference to profiler_start is that the current buffer contents are
 // not discarded if the profiler is already running with the requested settings.
-PROFILER_FUNC_VOID(profiler_ensure_started(int aEntries, double aInterval,
-                                           uint32_t aFeatures,
-                                           const char** aFilters,
-                                           uint32_t aFilterCount))
+void profiler_ensure_started(int aEntries, double aInterval,
+                             uint32_t aFeatures, const char** aFilters,
+                             uint32_t aFilterCount);
 
 //---------------------------------------------------------------------------
 // Control the profiler
 //---------------------------------------------------------------------------
 
 // Register/unregister threads with the profiler. Both functions operate the
 // same whether the profiler is active or inactive.
-PROFILER_FUNC_VOID(profiler_register_thread(const char* name,
-                                            void* guessStackTop))
-PROFILER_FUNC_VOID(profiler_unregister_thread())
+#define PROFILER_REGISTER_THREAD(name) \
+  do { char stackTop; profiler_register_thread(name, &stackTop); } while (0)
+#define PROFILER_UNREGISTER_THREAD() \
+  profiler_unregister_thread()
+void profiler_register_thread(const char* name, void* guessStackTop);
+void profiler_unregister_thread();
+
+// Register and unregister a thread within a scope.
+#define AUTO_PROFILER_REGISTER_THREAD(name) \
+  mozilla::AutoProfilerRegisterThread PROFILER_RAII(name)
 
 // Pause and resume the profiler. No-ops if the profiler is inactive. While
 // paused the profile will not take any samples and will not record any data
 // into its buffers. The profiler remains fully initialized in this state.
 // Timeline markers will still be stored. This feature will keep JavaScript
 // profiling enabled, thus allowing toggling the profiler without invalidating
 // the JIT.
-PROFILER_FUNC_VOID(profiler_pause())
-PROFILER_FUNC_VOID(profiler_resume())
+void profiler_pause();
+void profiler_resume();
 
 // These functions tell the profiler that a thread went to sleep so that we can
 // avoid sampling it while it's sleeping. Calling profiler_thread_sleep()
 // twice without an intervening profiler_thread_wake() is an error. All three
 // functions operate the same whether the profiler is active or inactive.
-PROFILER_FUNC_VOID(profiler_thread_sleep())
-PROFILER_FUNC_VOID(profiler_thread_wake())
+void profiler_thread_sleep();
+void profiler_thread_wake();
+
+// Mark a thread as asleep/awake within a scope.
+#define AUTO_PROFILER_THREAD_SLEEP \
+  mozilla::AutoProfilerThreadSleep PROFILER_RAII
+#define AUTO_PROFILER_THREAD_WAKE \
+  mozilla::AutoProfilerThreadWake PROFILER_RAII
 
 // Called by the JSRuntime's operation callback. This is used to start profiling
 // on auxiliary threads. Operates the same whether the profiler is active or
 // not.
-PROFILER_FUNC_VOID(profiler_js_interrupt_callback())
+#define PROFILER_JS_INTERRUPT_CALLBACK() profiler_js_interrupt_callback()
+void profiler_js_interrupt_callback();
 
 // Set and clear the current thread's JSContext.
-PROFILER_FUNC_VOID(profiler_set_js_context(JSContext* aCx))
-PROFILER_FUNC_VOID(profiler_clear_js_context())
+#define PROFILER_SET_JS_CONTEXT(cx) profiler_set_js_context(cx)
+#define PROFILER_CLEAR_JS_CONTEXT() profiler_clear_js_context()
+void profiler_set_js_context(JSContext* aCx);
+void profiler_clear_js_context();
 
 //---------------------------------------------------------------------------
 // Get information from the profiler
 //---------------------------------------------------------------------------
 
 // Is the profiler active? Note: the return value of this function can become
 // immediately out-of-date. E.g. the profile might be active but then
 // profiler_stop() is called immediately afterward. One common and reasonable
@@ -228,52 +267,52 @@ PROFILER_FUNC_VOID(profiler_clear_js_con
 //   }
 //
 // where PROFILER_OPERATION is a no-op if the profiler is inactive. In this
 // case the profiler_is_active() check is just an optimization -- it prevents
 // us calling CreateExpensiveData() unnecessarily in most cases, but the
 // expensive data will end up being created but not used if another thread
 // stops the profiler between the CreateExpensiveData() and PROFILER_OPERATION
 // calls.
-PROFILER_FUNC(bool profiler_is_active(), false)
+bool profiler_is_active();
 
 // Is the profiler active and paused? Returns false if the profiler is inactive.
-PROFILER_FUNC(bool profiler_is_paused(), false)
+bool profiler_is_paused();
 
 // Is the current thread sleeping?
-PROFILER_FUNC(bool profiler_thread_is_sleeping(), false)
+bool profiler_thread_is_sleeping();
 
 // Get all the features supported by the profiler that are accepted by
 // profiler_start(). The result is the same whether the profiler is active or
 // not.
-PROFILER_FUNC(uint32_t profiler_get_available_features(), 0)
+uint32_t profiler_get_available_features();
 
 // Check if a profiler feature (specified via the ProfilerFeature type) is
 // active. Returns false if the profiler is inactive. Note: the return value
 // can become immediately out-of-date, much like the return value of
 // profiler_is_active().
-PROFILER_FUNC(bool profiler_feature_active(uint32_t aFeature), false)
+#define PROFILER_FEATURE_ACTIVE(feature) profiler_feature_active(feature)
+bool profiler_feature_active(uint32_t aFeature);
 
 // Get the params used to start the profiler. Returns 0 and an empty vector
 // (via outparams) if the profile is inactive. It's possible that the features
 // returned may be slightly different to those requested due to required
 // adjustments.
-PROFILER_FUNC_VOID(
-  profiler_get_start_params(int* aEntrySize, double* aInterval,
-                            uint32_t* aFeatures,
-                            mozilla::Vector<const char*, 0,
-                                            mozilla::MallocAllocPolicy>*
-                              aFilters))
+void profiler_get_start_params(int* aEntrySize, double* aInterval,
+                               uint32_t* aFeatures,
+                               mozilla::Vector<const char*, 0,
+                                               mozilla::MallocAllocPolicy>*
+                                 aFilters);
 
 // The number of milliseconds since the process started. Operates the same
 // whether the profiler is active or inactive.
-PROFILER_FUNC(double profiler_time(), 0)
+double profiler_time();
 
 // Get the current thread's ID.
-PROFILER_FUNC(int profiler_current_thread_id(), 0)
+int profiler_current_thread_id();
 
 // An object of this class is passed to profiler_suspend_and_sample_thread().
 // For each stack frame, one of the Collect methods will be called.
 class ProfilerStackCollector
 {
 public:
   // Some collectors need to worry about possibly overwriting previous
   // generations of data. If that's not an issue, this can return Nothing,
@@ -297,44 +336,38 @@ public:
 
   virtual void CollectPseudoEntry(const js::ProfileEntry& aEntry) = 0;
 };
 
 // This method suspends the thread identified by aThreadId, samples its
 // pseudo-stack, JS stack, and (optionally) native stack, passing the collected
 // frames into aCollector. aFeatures dictates which compiler features are used.
 // |Privacy| and |Leaf| are the only relevant ones.
-PROFILER_FUNC_VOID(
-  profiler_suspend_and_sample_thread(int aThreadId,
-                                     uint32_t aFeatures,
-                                     ProfilerStackCollector& aCollector,
-                                     bool aSampleNative = true))
+void profiler_suspend_and_sample_thread(int aThreadId, uint32_t aFeatures,
+                                        ProfilerStackCollector& aCollector,
+                                        bool aSampleNative = true);
 
 struct ProfilerBacktraceDestructor
 {
-#ifdef MOZ_GECKO_PROFILER
   void operator()(ProfilerBacktrace*);
-#else
-  void operator()(ProfilerBacktrace*) {}
-#endif
 };
 
 using UniqueProfilerBacktrace =
   mozilla::UniquePtr<ProfilerBacktrace, ProfilerBacktraceDestructor>;
 
 // Immediately capture the current thread's call stack and return it. A no-op
 // if the profiler is inactive or in privacy mode.
-PROFILER_FUNC(UniqueProfilerBacktrace profiler_get_backtrace(), nullptr)
+UniqueProfilerBacktrace profiler_get_backtrace();
 
 // Get information about the current buffer status. A no-op when the profiler
 // is inactive. Do not call this function; call profiler_get_buffer_info()
 // instead.
-PROFILER_FUNC_VOID(profiler_get_buffer_info_helper(uint32_t* aCurrentPosition,
-                                                   uint32_t* aEntries,
-                                                   uint32_t* aGeneration))
+void profiler_get_buffer_info_helper(uint32_t* aCurrentPosition,
+                                     uint32_t* aEntries,
+                                     uint32_t* aGeneration);
 
 // Get information about the current buffer status. Returns (via outparams) the
 // current write position in the buffer, the total size of the buffer, and the
 // generation of the buffer. Returns zeroes if the profiler is inactive.
 //
 // This information may be useful to a user-interface displaying the current
 // status of the profiler, allowing the user to get a sense for how fast the
 // buffer is being written to, and how much data is visible.
@@ -345,17 +378,17 @@ static inline void profiler_get_buffer_i
   *aCurrentPosition = 0;
   *aEntries = 0;
   *aGeneration = 0;
 
   profiler_get_buffer_info_helper(aCurrentPosition, aEntries, aGeneration);
 }
 
 // Get the current thread's PseudoStack.
-PROFILER_FUNC(PseudoStack* profiler_get_pseudo_stack(), nullptr)
+PseudoStack* profiler_get_pseudo_stack();
 
 //---------------------------------------------------------------------------
 // Put profiling data into the profiler (labels and markers)
 //---------------------------------------------------------------------------
 
 // 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 label argument must be a string literal. It is usually of the
@@ -392,68 +425,67 @@ PROFILER_FUNC(PseudoStack* profiler_get_
 
 // 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.
 // aMarkerName is copied, so the caller does not need to ensure it lives for a
 // certain length of time. A no-op if the profiler is inactive or in privacy
 // mode.
-PROFILER_FUNC_VOID(profiler_add_marker(const char* aMarkerName))
-PROFILER_FUNC_VOID(
-  profiler_add_marker(const char* aMarkerName,
-                      mozilla::UniquePtr<ProfilerMarkerPayload> aPayload))
+#define PROFILER_ADD_MARKER(markerName) \
+  profiler_add_marker(markerName)
+void profiler_add_marker(const char* aMarkerName);
+void profiler_add_marker(const char* aMarkerName,
+                         mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
 
 enum TracingKind {
   TRACING_EVENT,
   TRACING_INTERVAL_START,
   TRACING_INTERVAL_END,
 };
 
+// Adds a tracing marker to the profile. A no-op if the profiler is inactive or
+// in privacy mode.
+#define PROFILER_TRACING(category, markerName, kind) \
+  profiler_tracing(category, markerName, kind)
+void profiler_tracing(const char* aCategory, const char* aMarkerName,
+                      TracingKind aKind);
+void profiler_tracing(const char* aCategory, const char* aMarkerName,
+                      TracingKind aKind, UniqueProfilerBacktrace aCause);
 
-// Adds a tracing marker to the PseudoStack. A no-op if the profiler is
-// inactive or in privacy mode.
-PROFILER_FUNC_VOID(profiler_tracing(const char* aCategory,
-                                    const char* aMarkerName,
-                                    TracingKind aKind))
-PROFILER_FUNC_VOID(profiler_tracing(const char* aCategory,
-                                    const char* aMarkerName,
-                                    TracingKind aKind,
-                                    UniqueProfilerBacktrace aCause))
+// Adds a START/END pair of tracing markers.
+#define AUTO_PROFILER_TRACING(category, markerName) \
+  mozilla::AutoProfilerTracing PROFILER_RAII(category, markerName)
 
 //---------------------------------------------------------------------------
 // Output profiles
 //---------------------------------------------------------------------------
 
 // Get the profile encoded as a JSON string. A no-op (returning nullptr) if the
 // profiler is inactive.
 // If aIsShuttingDown is true, the current time is included as the process
 // shutdown time in the JSON's "meta" object.
-PROFILER_FUNC(
-  mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0,
-                                                  bool aIsShuttingDown = false),
-  nullptr)
+mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0,
+                                                bool aIsShuttingDown = false);
 
 // Write the profile for this process (excluding subprocesses) into aWriter.
 // Returns false if the profiler is inactive.
-PROFILER_FUNC(
-  bool profiler_stream_json_for_this_process(SpliceableJSONWriter& aWriter,
-                                             double aSinceTime = 0,
-                                             bool aIsShuttingDown = false,
-                                             mozilla::TimeStamp* aOutFirstSampleTime = nullptr),
-  false)
+bool profiler_stream_json_for_this_process(SpliceableJSONWriter& aWriter,
+                                           double aSinceTime = 0,
+                                           bool aIsShuttingDown = false,
+                                           mozilla::TimeStamp* aOutFirstSampleTime = nullptr);
 
 // Get the profile and write it into a file. A no-op if the profile is
 // inactive.
 //
 // This function is 'extern "C"' so that it is easily callable from a debugger
 // in a build without debugging information (a workaround for
 // http://llvm.org/bugs/show_bug.cgi?id=22211).
 extern "C" {
-PROFILER_FUNC_VOID(profiler_save_profile_to_file(const char* aFilename))
+void profiler_save_profile_to_file(const char* aFilename);
 }
 
 //---------------------------------------------------------------------------
 // RAII classes
 //---------------------------------------------------------------------------
 
 namespace mozilla {
 
@@ -473,17 +505,17 @@ private:
 };
 
 // Convenience class to register and unregister a thread with the profiler.
 // Needs to be the first object on the stack of the thread.
 class MOZ_RAII AutoProfilerRegisterThread final
 {
 public:
   explicit AutoProfilerRegisterThread(const char* aName
-                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+                                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     profiler_register_thread(aName, this);
   }
 
   ~AutoProfilerRegisterThread() { profiler_unregister_thread(); }
 
 private:
@@ -545,48 +577,42 @@ public:
   AutoProfilerLabel(const char* aLabel, const char* aDynamicString,
                     uint32_t aLine, js::ProfileEntry::Category aCategory
                     MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
     // This function runs both on and off the main thread.
 
-#ifdef MOZ_GECKO_PROFILER
     mPseudoStack = sPseudoStack.get();
     if (mPseudoStack) {
       mPseudoStack->pushCppFrame(aLabel, aDynamicString, this, aLine,
                                  js::ProfileEntry::Kind::CPP_NORMAL, aCategory);
     }
-#endif
   }
 
   ~AutoProfilerLabel()
   {
     // This function runs both on and off the main thread.
 
-#ifdef MOZ_GECKO_PROFILER
     if (mPseudoStack) {
       mPseudoStack->pop();
     }
-#endif
   }
 
 private:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 
-#ifdef MOZ_GECKO_PROFILER
   // We save a PseudoStack pointer in the ctor so we don't have to redo the TLS
   // lookup in the dtor.
   PseudoStack* mPseudoStack;
 
 public:
   // See the comment on the definition in platform.cpp for details about this.
   static MOZ_THREAD_LOCAL(PseudoStack*) sPseudoStack;
-#endif
 };
 
 class MOZ_RAII AutoProfilerTracing
 {
 public:
   AutoProfilerTracing(const char* aCategory, const char* aMarkerName
                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     : mCategory(aCategory)
@@ -616,31 +642,27 @@ protected:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   const char* mCategory;
   const char* mMarkerName;
 };
 
 // Set MOZ_PROFILER_STARTUP* environment variables that will be inherited into
 // a child process that is about to be launched, in order to make that child
 // process start with the same profiler settings as in the current process.
-#ifdef MOZ_GECKO_PROFILER
 class MOZ_RAII AutoSetProfilerEnvVarsForChildProcess
 {
 public:
   explicit AutoSetProfilerEnvVarsForChildProcess(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
   ~AutoSetProfilerEnvVarsForChildProcess();
 
 private:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   char mSetEntries[64];
   char mSetInterval[64];
   char mSetFeaturesBitfield[64];
   char mSetFilters[1024];
 };
-#else
-class AutoSetProfilerEnvVarsForChildProcess
-{
-};
-#endif
 
 } // namespace mozilla
 
+#endif // !MOZ_GECKO_PROFILER
+
 #endif  // GeckoProfiler_h
--- a/tools/profiler/public/ProfilerMarkerPayload.h
+++ b/tools/profiler/public/ProfilerMarkerPayload.h
@@ -67,27 +67,20 @@ protected:
   }
 
 private:
   mozilla::TimeStamp mStartTime;
   mozilla::TimeStamp mEndTime;
   UniqueProfilerBacktrace mStack;
 };
 
-#define DECL_STREAM_PAYLOAD_BASE  \
+#define DECL_STREAM_PAYLOAD \
   virtual void StreamPayload(SpliceableJSONWriter& aWriter, \
                              const mozilla::TimeStamp& aProcessStartTime, \
-                             UniqueStacks& aUniqueStacks) override
-
-// If the profiler is disabled then StreamPayload() will never be called.
-#ifdef MOZ_GECKO_PROFILER
-# define DECL_STREAM_PAYLOAD DECL_STREAM_PAYLOAD_BASE ;
-#else
-# define DECL_STREAM_PAYLOAD DECL_STREAM_PAYLOAD_BASE { MOZ_CRASH(); }
-#endif
+                             UniqueStacks& aUniqueStacks) override;
 
 class TracingMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   TracingMarkerPayload(const char* aCategory, TracingKind aKind,
                        UniqueProfilerBacktrace aCause = nullptr)
     : mCategory(aCategory)
     , mKind(aKind)
--- a/tools/profiler/tests/gtest/GeckoProfiler.cpp
+++ b/tools/profiler/tests/gtest/GeckoProfiler.cpp
@@ -452,30 +452,30 @@ TEST(GeckoProfiler, Markers)
 {
   uint32_t features = ProfilerFeature::StackWalk;
   const char* filters[] = { "GeckoMain" };
 
   profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
                  features, filters, MOZ_ARRAY_LENGTH(filters));
 
   profiler_tracing("A", "B", TRACING_EVENT);
-  profiler_tracing("A", "C", TRACING_INTERVAL_START);
-  profiler_tracing("A", "C", TRACING_INTERVAL_END);
+  PROFILER_TRACING("A", "C", TRACING_INTERVAL_START);
+  PROFILER_TRACING("A", "C", TRACING_INTERVAL_END);
 
   UniqueProfilerBacktrace bt = profiler_get_backtrace();
   profiler_tracing("B", "A", TRACING_EVENT, Move(bt));
 
   {
-    AutoProfilerTracing tracing("C", "A");
+    AUTO_PROFILER_TRACING("C", "A");
   }
 
   profiler_add_marker("M1");
-  profiler_add_marker("M2",
-                      MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT));
-  profiler_add_marker("M3");
+  profiler_add_marker(
+    "M2", MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT));
+  PROFILER_ADD_MARKER("M3");
   profiler_add_marker(
     "M4",
     MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT,
                                      profiler_get_backtrace()));
 
   for (int i = 0; i < 10; i++) {
     profiler_add_marker("M5", MakeUnique<GTestMarkerPayload>(i));
   }
--- a/widget/android/ANRReporter.cpp
+++ b/widget/android/ANRReporter.cpp
@@ -8,16 +8,17 @@
 
 #include <unistd.h>
 
 namespace mozilla {
 
 bool
 ANRReporter::RequestNativeStack(bool aUnwind)
 {
+#ifdef MOZ_GECKO_PROFILER
     if (profiler_is_active()) {
         // Don't proceed if profiler is already running
         return false;
     }
 
     // WARNING: we are on the ANR reporter thread at this point and it is
     // generally unsafe to use the profiler from off the main thread. However,
     // the risk here is limited because for most users, the profiler is not run
@@ -28,31 +29,32 @@ ANRReporter::RequestNativeStack(bool aUn
                         ProfilerFeature::Threads;
 
     const char *NATIVE_STACK_THREADS[] = {"GeckoMain", "Compositor"};
 
     // Buffer one sample and let the profiler wait a long time
     profiler_start(/* entries */ 100, /* interval */ 10000, features,
                    NATIVE_STACK_THREADS,
                    sizeof(NATIVE_STACK_THREADS) / sizeof(char*));
+#endif
     return true;
 }
 
 jni::String::LocalRef
 ANRReporter::GetNativeStack()
 {
+#ifdef MOZ_GECKO_PROFILER
     // Timeout if we don't get a profiler sample after 5 seconds.
     const PRIntervalTime timeout = PR_SecondsToInterval(5);
     const PRIntervalTime startTime = PR_IntervalNow();
 
     // Pointer to a profile JSON string
     typedef mozilla::UniquePtr<char[]> ProfilePtr;
 
-    // profiler_get_profile() will return nullptr if the profiler is disabled
-    // or inactive.
+    // profiler_get_profile() will return nullptr if the profiler is inactive.
     ProfilePtr profile(profiler_get_profile());
     if (!profile) {
         return nullptr;
     }
 
     while (profile && !strstr(profile.get(), "\"samples\":[{")) {
         // no sample yet?
         if (PR_IntervalNow() - startTime >= timeout) {
@@ -60,23 +62,26 @@ ANRReporter::GetNativeStack()
         }
         usleep(100000ul); // Sleep for 100ms
         profile = ProfilePtr(profiler_get_profile());
     }
 
     if (profile) {
         return jni::String::Param(profile.get());
     }
+#endif
     return nullptr;
 }
 
 void
 ANRReporter::ReleaseNativeStack()
 {
+#ifdef MOZ_GECKO_PROFILER
     if (!profiler_is_active()) {
         // Maybe profiler support is disabled?
         return;
     }
     profiler_stop();
+#endif
 }
 
 } // namespace
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -6741,18 +6741,17 @@ HandleEvent(CGEventTapProxy aProxy, CGEv
             CGEventRef aEvent, void* aClosure)
 {
   [(EventThreadRunner*)aClosure handleEvent:aEvent type:aType];
   return aEvent;
 }
 
 - (void)runEventThread
 {
-  char aLocal;
-  profiler_register_thread("APZC Event Thread", &aLocal);
+  PROFILER_REGISTER_THREAD("APZC Event Thread");
   NS_SetCurrentThreadName("APZC Event Thread");
 
   mThread = [NSThread currentThread];
   ProcessSerialNumber currentProcess;
   GetCurrentProcess(&currentProcess);
   CFMachPortRef eventPort =
     CGEventTapCreateForPSN(&currentProcess,
                            kCGHeadInsertEventTap,
--- a/widget/gtk/nsAppShell.cpp
+++ b/widget/gtk/nsAppShell.cpp
@@ -41,19 +41,21 @@ LazyLogModule gWidgetDrawLog("WidgetDraw
 
 static GPollFunc sPollFunc;
 
 // Wrapper function to disable hang monitoring while waiting in poll().
 static gint
 PollWrapper(GPollFD *ufds, guint nfsd, gint timeout_)
 {
     mozilla::HangMonitor::Suspend();
-    profiler_thread_sleep();
-    gint result = (*sPollFunc)(ufds, nfsd, timeout_);
-    profiler_thread_wake();
+    gint result;
+    {
+        AUTO_PROFILER_THREAD_SLEEP;
+        result = (*sPollFunc)(ufds, nfsd, timeout_);
+    }
     mozilla::HangMonitor::NotifyActivity();
     return result;
 }
 
 #if MOZ_WIDGET_GTK == 3
 // For bug 726483.
 static decltype(GtkContainerClass::check_resize) sReal_gtk_window_check_resize;
 
--- a/widget/windows/nsAppShell.cpp
+++ b/widget/windows/nsAppShell.cpp
@@ -350,17 +350,17 @@ nsAppShell::ProcessNextNativeEvent(bool 
 
         ::TranslateMessage(&msg);
         ::DispatchMessageW(&msg);
       }
     } else if (mayWait) {
       // Block and wait for any posted application message
       mozilla::HangMonitor::Suspend();
       {
-        AutoProfilerThreadSleep sleep;
+        AUTO_PROFILER_THREAD_SLEEP;
         WinUtils::WaitForMessage();
       }
     }
   } while (!gotMessage && mayWait);
 
   // See DoProcessNextNativeEvent, mEventloopNestingLevel will be
   // one when a modal loop unwinds.
   if (mNativeCallbackPending && mEventloopNestingLevel == 1)
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -80,17 +80,20 @@
 #include "nsCycleCollectionNoteRootCallback.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCycleCollector.h"
 #include "nsDOMJSUtils.h"
 #include "nsJSUtils.h"
 #include "nsWrapperCache.h"
 #include "nsStringBuffer.h"
 #include "GeckoProfiler.h"
+
+#ifdef MOZ_GECKO_PROFILER
 #include "ProfilerMarkerPayload.h"
+#endif
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 
 #include "nsIException.h"
 #include "nsIPlatformInfo.h"
 #include "nsThread.h"
@@ -828,31 +831,33 @@ CycleCollectedJSRuntime::GCCallback(JSCo
 /* static */ void
 CycleCollectedJSRuntime::GCSliceCallback(JSContext* aContext,
                                          JS::GCProgress aProgress,
                                          const JS::GCDescription& aDesc)
 {
   CycleCollectedJSRuntime* self = CycleCollectedJSRuntime::Get();
   MOZ_ASSERT(CycleCollectedJSContext::Get()->Context() == aContext);
 
+#ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
     if (aProgress == JS::GC_CYCLE_END) {
       profiler_add_marker(
         "GCMajor",
         MakeUnique<GCMajorMarkerPayload>(aDesc.startTime(aContext),
                                          aDesc.endTime(aContext),
                                          aDesc.summaryToJSON(aContext)));
     } else if (aProgress == JS::GC_SLICE_END) {
       profiler_add_marker(
         "GCSlice",
         MakeUnique<GCSliceMarkerPayload>(aDesc.lastSliceStart(aContext),
                                          aDesc.lastSliceEnd(aContext),
                                          aDesc.sliceToJSON(aContext)));
     }
   }
+#endif
 
   if (aProgress == JS::GC_CYCLE_END &&
       JS::dbg::FireOnGarbageCollectionHookRequired(aContext)) {
     JS::gcreason::Reason reason = aDesc.reason_;
     Unused <<
       NS_WARN_IF(NS_FAILED(DebuggerOnGCRunnable::Enqueue(aContext, aDesc)) &&
                  reason != JS::gcreason::SHUTDOWN_CC &&
                  reason != JS::gcreason::DESTROY_RUNTIME &&
@@ -925,25 +930,28 @@ CycleCollectedJSRuntime::GCNurseryCollec
   if (timelines && !timelines->IsEmpty()) {
     UniquePtr<AbstractTimelineMarker> abstractMarker(
       MakeUnique<MinorGCMarker>(aProgress, aReason));
     timelines->AddMarkerForAllObservedDocShells(abstractMarker);
   }
 
   if (aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_START) {
     self->mLatestNurseryCollectionStart = TimeStamp::Now();
-  } else if ((aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END) &&
-             profiler_is_active())
+  }
+#ifdef MOZ_GECKO_PROFILER
+  else if (aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END &&
+           profiler_is_active())
   {
     profiler_add_marker(
       "GCMinor",
       MakeUnique<GCMinorMarkerPayload>(self->mLatestNurseryCollectionStart,
                                        TimeStamp::Now(),
                                        JS::MinorGcToJSON(aContext)));
   }
+#endif
 
   if (self->mPrevGCNurseryCollectionCallback) {
     self->mPrevGCNurseryCollectionCallback(aContext, aProgress, aReason);
   }
 }
 
 
 /* static */ void
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -13,17 +13,19 @@
 #include "nsServiceManagerUtils.h"
 #include "nsMemoryReporterManager.h"
 #include "nsITimer.h"
 #include "nsThreadUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsIObserverService.h"
 #include "nsIGlobalObject.h"
 #include "nsIXPConnect.h"
+#ifdef MOZ_GECKO_PROFILER
 #include "GeckoProfilerReporter.h"
+#endif
 #if defined(XP_UNIX) || defined(MOZ_DMD)
 #include "nsMemoryInfoDumper.h"
 #endif
 #include "nsNetCID.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReportingProcess.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/Preferences.h"
--- a/xpcom/build/MainThreadIOLogger.cpp
+++ b/xpcom/build/MainThreadIOLogger.cpp
@@ -24,29 +24,36 @@
 #include <prprf.h>
 #include <prthread.h>
 #include <vector>
 
 namespace {
 
 struct ObservationWithStack
 {
-  ObservationWithStack(mozilla::IOInterposeObserver::Observation& aObs,
-                       ProfilerBacktrace* aStack)
+  explicit ObservationWithStack(mozilla::IOInterposeObserver::Observation& aObs
+#ifdef MOZ_GECKO_PROFILER
+                                , ProfilerBacktrace* aStack
+#endif
+                                )
     : mObservation(aObs)
+#ifdef MOZ_GECKO_PROFILER
     , mStack(aStack)
+#endif
   {
     const char16_t* filename = aObs.Filename();
     if (filename) {
       mFilename = filename;
     }
   }
 
   mozilla::IOInterposeObserver::Observation mObservation;
+#ifdef MOZ_GECKO_PROFILER
   ProfilerBacktrace*                        mStack;
+#endif
   nsString                                  mFilename;
 };
 
 class MainThreadIOLoggerImpl final : public mozilla::IOInterposeObserver
 {
 public:
   MainThreadIOLoggerImpl();
   ~MainThreadIOLoggerImpl();
@@ -110,17 +117,18 @@ MainThreadIOLoggerImpl::Init()
     return false;
   }
   return true;
 }
 
 /* static */ void
 MainThreadIOLoggerImpl::sIOThreadFunc(void* aArg)
 {
-  AutoProfilerRegisterThread registerThread("MainThreadIOLogger");
+  AUTO_PROFILER_REGISTER_THREAD("MainThreadIOLogger");
+
   NS_SetCurrentThreadName("MainThreadIOLogger");
   MainThreadIOLoggerImpl* obj = static_cast<MainThreadIOLoggerImpl*>(aArg);
   obj->IOThreadFunc();
 }
 
 void
 MainThreadIOLoggerImpl::IOThreadFunc()
 {
@@ -169,18 +177,20 @@ MainThreadIOLoggerImpl::IOThreadFunc()
         /**
          * Format:
          * Start Timestamp (Milliseconds), Operation, Duration (Milliseconds), Event Source, Filename
          */
         if (PR_fprintf(fd, "%f,%s,%f,%s,%s\n",
                        (i->mObservation.Start() - mLogStartTime).ToMilliseconds(),
                        i->mObservation.ObservedOperationString(), durationMs,
                        i->mObservation.Reference(), nativeFilename.get()) > 0) {
+#ifdef MOZ_GECKO_PROFILER
           // TODO: Write out the callstack
           i->mStack = nullptr;
+#endif
         }
       }
     }
   }
   PR_Close(fd);
 }
 
 void
@@ -190,17 +200,21 @@ MainThreadIOLoggerImpl::Observe(Observat
     return;
   }
   IOInterposer::MonitorAutoLock lock(mMonitor);
   if (mShutdownRequired) {
     // The writer thread isn't running. Don't enqueue any more data.
     return;
   }
   // Passing nullptr as aStack parameter for now
-  mObservations.push_back(ObservationWithStack(aObservation, nullptr));
+  mObservations.push_back(ObservationWithStack(aObservation
+#ifdef MOZ_GECKO_PROFILER
+                                               , nullptr
+#endif
+                                               ));
   lock.Notify();
 }
 
 } // namespace
 
 namespace mozilla {
 
 namespace MainThreadIOLogger {
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -979,17 +979,17 @@ ShutdownXPCOM(nsIServiceManager* aServMg
   bool shutdownCollect;
 #ifdef NS_FREE_PERMANENT_DATA
   shutdownCollect = true;
 #else
   shutdownCollect = !!PR_GetEnv("MOZ_CC_RUN_DURING_SHUTDOWN");
 #endif
   nsCycleCollector_shutdown(shutdownCollect);
 
-  profiler_add_marker("Shutdown xpcom");
+  PROFILER_ADD_MARKER("Shutdown xpcom");
   // If we are doing any shutdown checks, poison writes.
   if (gShutdownChecks != SCM_NOTHING) {
 #ifdef XP_MACOSX
     mozilla::OnlyReportDirtyWrites();
 #endif /* XP_MACOSX */
     mozilla::BeginLateWriteChecks();
   }
 
@@ -1011,17 +1011,17 @@ ShutdownXPCOM(nsIServiceManager* aServMg
   // In optimized builds we don't do shutdown collections by default, so
   // uncollected (garbage) objects may keep the nsXPConnect singleton alive,
   // and its XPCJSContext along with it. However, we still destroy various
   // bits of state in JS_ShutDown(), so we need to make sure the profiler
   // can't access them when it shuts down. This call nulls out the
   // JS pseudo-stack's internal reference to the main thread JSContext,
   // duplicating the call in XPCJSContext::~XPCJSContext() in case that
   // never fired.
-  profiler_clear_js_context();
+  PROFILER_CLEAR_JS_CONTEXT();
 
   if (sInitializedJS) {
     // Shut down the JS engine.
     JS_ShutDown();
     sInitializedJS = false;
   }
 
   // Release our own singletons
--- a/xpcom/threads/BlockingResourceBase.cpp
+++ b/xpcom/threads/BlockingResourceBase.cpp
@@ -501,28 +501,24 @@ ReentrantMonitor::Wait(PRIntervalTime aI
   int32_t savedEntryCount = mEntryCount;
   AcquisitionState savedAcquisitionState = GetAcquisitionState();
   BlockingResourceBase* savedChainPrev = mChainPrev;
   mEntryCount = 0;
   ClearAcquisitionState();
   mChainPrev = 0;
 
   nsresult rv;
+  {
 #if defined(MOZILLA_INTERNAL_API)
-  {
-    AutoProfilerThreadSleep sleep;
-#endif //MOZILLA_INTERNAL_API
-
+    AUTO_PROFILER_THREAD_SLEEP;
+#endif
     // give up the monitor until we're back from Wait()
     rv = PR_Wait(mReentrantMonitor, aInterval) == PR_SUCCESS ? NS_OK :
                                                                NS_ERROR_FAILURE;
-
-#if defined(MOZILLA_INTERNAL_API)
   }
-#endif //MOZILLA_INTERNAL_API
 
   // restore saved state
   mEntryCount = savedEntryCount;
   SetAcquisitionState(savedAcquisitionState);
   mChainPrev = savedChainPrev;
 
   return rv;
 }
--- a/xpcom/threads/CondVar.h
+++ b/xpcom/threads/CondVar.h
@@ -57,17 +57,17 @@ public:
   /**
    * Wait
    * @see prcvar.h
    **/
   nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
   {
 
 #ifdef MOZILLA_INTERNAL_API
-    AutoProfilerThreadSleep sleep;
+    AUTO_PROFILER_THREAD_SLEEP;
 #endif //MOZILLA_INTERNAL_API
     if (aInterval == PR_INTERVAL_NO_TIMEOUT) {
       mImpl.wait(*mLock);
     } else {
       mImpl.wait_for(*mLock, TimeDuration::FromMilliseconds(double(aInterval)));
     }
     return NS_OK;
   }
--- a/xpcom/threads/HangMonitor.cpp
+++ b/xpcom/threads/HangMonitor.cpp
@@ -191,17 +191,17 @@ GetChromeHangReport(Telemetry::Processed
   }
 }
 
 #endif
 
 void
 ThreadMain(void*)
 {
-  AutoProfilerRegisterThread registerThread("Hang Monitor");
+  AUTO_PROFILER_REGISTER_THREAD("Hang Monitor");
   NS_SetCurrentThreadName("Hang Monitor");
 
   MonitorAutoLock lock(*gMonitor);
 
   // In order to avoid issues with the hang monitor incorrectly triggering
   // during a general system stop such as sleeping, the monitor thread must
   // run twice to trigger hang protection.
   PRIntervalTime lastTimestamp = 0;
--- a/xpcom/threads/ReentrantMonitor.h
+++ b/xpcom/threads/ReentrantMonitor.h
@@ -81,17 +81,17 @@ public:
 
   /**
    * Wait
    * @see prmon.h
    **/
   nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
   {
 #ifdef MOZILLA_INTERNAL_API
-    AutoProfilerThreadSleep sleep;
+    AUTO_PROFILER_THREAD_SLEEP;
 #endif //MOZILLA_INTERNAL_API
     return PR_Wait(mReentrantMonitor, aInterval) == PR_SUCCESS ?
       NS_OK : NS_ERROR_FAILURE;
   }
 
 #else // ifndef DEBUG
   void Enter();
   void Exit();
--- a/xpcom/threads/Scheduler.cpp
+++ b/xpcom/threads/Scheduler.cpp
@@ -626,17 +626,17 @@ SchedulerImpl::ThreadController::OnStart
   // Causes GetCurrentVirtualThread() to return mMainVirtual and NS_IsMainThread()
   // to return true.
   NS_SetMainThread(mMainVirtual);
 
   // This will initialize the thread's mVirtualThread to mMainVirtual since
   // GetCurrentVirtualThread() now returns mMainVirtual.
   nsThreadManager::get().CreateCurrentThread(mMainQueue, nsThread::MAIN_THREAD);
 
-  profiler_register_thread(aName.BeginReading(), &aStackTop);
+  PROFILER_REGISTER_THREAD(aName.BeginReading());
 
   mOldMainLoop = MessageLoop::current();
 
   MessageLoop::set_current(mMainLoop);
 
   xpc::CreateCooperativeContext();
 
   JSContext* cx = dom::danger::GetJSContext();
@@ -654,17 +654,17 @@ SchedulerImpl::ThreadController::OnStopT
   xpc::DestroyCooperativeContext();
 
   NS_UnsetMainThread();
   MessageLoop::set_current(mOldMainLoop);
 
   RefPtr<nsThread> self = static_cast<nsThread*>(NS_GetCurrentThread());
   nsThreadManager::get().UnregisterCurrentThread(*self);
 
-  profiler_unregister_thread();
+  PROFILER_UNREGISTER_THREAD();
 }
 
 void
 SchedulerImpl::ThreadController::OnSuspendThread(size_t aIndex)
 {
   xpc::YieldCooperativeContext();
 }
 
--- a/xpcom/threads/nsProcessCommon.cpp
+++ b/xpcom/threads/nsProcessCommon.cpp
@@ -233,23 +233,26 @@ assembleCmdLine(char* const* aArgv, wcha
   free(cmdLine);
   return 0;
 }
 #endif
 
 void
 nsProcess::Monitor(void* aArg)
 {
-  char stackBaseGuess;
-
   RefPtr<nsProcess> process = dont_AddRef(static_cast<nsProcess*>(aArg));
 
+#ifdef MOZ_GECKO_PROFILER
+  Maybe<AutoProfilerRegisterThread> registerThread;
+  if (!process->mBlocking) {
+    registerThread.emplace("RunProcess");
+  }
+#endif
   if (!process->mBlocking) {
     NS_SetCurrentThreadName("RunProcess");
-    profiler_register_thread("RunProcess", &stackBaseGuess);
   }
 
 #if defined(PROCESSMODEL_WINAPI)
   DWORD dwRetVal;
   unsigned long exitCode = -1;
 
   dwRetVal = WaitForSingleObject(process->mProcess, INFINITE);
   if (dwRetVal != WAIT_FAILED) {
@@ -306,20 +309,16 @@ nsProcess::Monitor(void* aArg)
   // If we ran a background thread for the monitor then notify on the main
   // thread
   if (NS_IsMainThread()) {
     process->ProcessComplete();
   } else {
     NS_DispatchToMainThread(NewRunnableMethod(
       "nsProcess::ProcessComplete", process, &nsProcess::ProcessComplete));
   }
-
-  if (!process->mBlocking) {
-    profiler_unregister_thread();
-  }
 }
 
 void
 nsProcess::ProcessComplete()
 {
   if (mThread) {
     nsCOMPtr<nsIObserverService> os =
       mozilla::services::GetObserverService();
--- a/xpcom/threads/nsThread.cpp
+++ b/xpcom/threads/nsThread.cpp
@@ -378,18 +378,16 @@ struct ThreadInitData {
 
 }
 
 /*static*/ void
 nsThread::ThreadFunc(void* aArg)
 {
   using mozilla::ipc::BackgroundChild;
 
-  char stackTop;
-
   ThreadInitData* initData = static_cast<ThreadInitData*>(aArg);
   nsThread* self = initData->thread;  // strong reference
 
   self->mThread = PR_GetCurrentThread();
   self->mVirtualThread = GetCurrentVirtualThread();
   self->mEventTarget->SetCurrentThread();
   SetupCurrentThreadForChaosMode();
 
@@ -401,17 +399,17 @@ nsThread::ThreadFunc(void* aArg)
   nsThreadManager::get().RegisterCurrentThread(*self);
 
   mozilla::IOInterposer::RegisterCurrentThread();
 
   // This must come after the call to nsThreadManager::RegisterCurrentThread(),
   // because that call is needed to properly set up this thread as an nsThread,
   // which profiler_register_thread() requires. See bug 1347007.
   if (!initData->name.IsEmpty()) {
-    profiler_register_thread(initData->name.BeginReading(), &stackTop);
+    PROFILER_REGISTER_THREAD(initData->name.BeginReading());
   }
 
   // Wait for and process startup event
   nsCOMPtr<nsIRunnable> event = self->mEvents->GetEvent(true, nullptr);
   MOZ_ASSERT(event);
 
   initData = nullptr; // clear before unblocking nsThread::Init
 
@@ -448,17 +446,17 @@ nsThread::ThreadFunc(void* aArg)
     }
   }
 
   mozilla::IOInterposer::UnregisterCurrentThread();
 
   // Inform the threadmanager that this thread is going away
   nsThreadManager::get().UnregisterCurrentThread(*self);
 
-  profiler_unregister_thread();
+  PROFILER_UNREGISTER_THREAD();
 
   // Dispatch shutdown ACK
   NotNull<nsThreadShutdownContext*> context =
     WrapNotNull(self->mShutdownContext);
   MOZ_ASSERT(context->mTerminatingThread == self);
   event = do_QueryObject(new nsThreadShutdownAckEvent(context));
   if (context->mIsMainThreadJoining) {
     SystemGroup::Dispatch(TaskCategory::Other, event.forget());