Bug 1375299 (part 1) - Reduce usage of MOZ_GECKO_PROFILER. r=mstange.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 22 Jun 2017 06:26:16 +1000
changeset 401522 42f3af3d5d54a5c48a8768aef1d9a2666e067058
parent 401521 b7a44b036e41ce83507fe02f3b3a0e36921bb78e
child 401523 a10187ddb379bea8234228f157e6380e566fcaaa
push idunknown
push userunknown
push dateunknown
reviewersmstange
bugs1375299
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1375299 (part 1) - Reduce usage of MOZ_GECKO_PROFILER. r=mstange. This patch reduces the differences between builds where the profiler is enabled and those where the profiler is disabled. It does this by removing numerous MOZ_GECKO_PROFILER checks. These changes have the following consequences. - Various functions and classes are now defined in all builds, and so can be used unconditionally: profiler_add_marker(), profiler_set_js_context(), profiler_clear_js_context(), profiler_get_pseudo_stack(), AutoProfilerLabel. (They are effectively no-ops in non-profiler builds, of course.) - The no-op versions of PROFILER_* are now gone. The remaining versions are almost no-ops when the profiler isn't built.
dom/base/nsFrameMessageManager.cpp
dom/base/nsJSUtils.cpp
dom/base/nsJSUtils.h
dom/events/EventListenerManager.cpp
dom/workers/RuntimeService.cpp
image/DecodePool.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSContext.cpp
layout/base/PresShell.cpp
mozglue/build/WindowsDllBlocklist.cpp
mozglue/misc/AutoProfilerLabel.h
mozglue/misc/moz.build
toolkit/components/telemetry/Telemetry.cpp
tools/profiler/core/ProfilerBacktrace.h
tools/profiler/core/platform.cpp
tools/profiler/gecko/ProfilerIOInterposeObserver.h
tools/profiler/public/GeckoProfiler.h
tools/profiler/tests/gtest/GeckoProfiler.cpp
xpcom/base/CycleCollectedJSRuntime.cpp
xpcom/base/CycleCollectedJSRuntime.h
xpcom/build/XPCOMInit.cpp
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -1516,22 +1516,23 @@ nsMessageManagerScriptExecutor::Shutdown
     sScriptCacheCleaner = nullptr;
   }
 }
 
 void
 nsMessageManagerScriptExecutor::LoadScriptInternal(const nsAString& aURL,
                                                    bool aRunInGlobalScope)
 {
-#ifdef MOZ_GECKO_PROFILER
-  NS_LossyConvertUTF16toASCII urlCStr(aURL);
-  PROFILER_LABEL_DYNAMIC("nsMessageManagerScriptExecutor", "LoadScriptInternal",
-                          js::ProfileEntry::Category::OTHER,
-                          urlCStr.get());
-#endif
+  if (profiler_is_active()) {
+    NS_LossyConvertUTF16toASCII urlCStr(aURL);
+    PROFILER_LABEL_DYNAMIC("nsMessageManagerScriptExecutor",
+                           "LoadScriptInternal",
+                           js::ProfileEntry::Category::OTHER,
+                           urlCStr.get());
+  }
 
   if (!mGlobal || !sCachedScripts) {
     return;
   }
 
   JS::RootingContext* rcx = RootingCx();
   JS::Rooted<JSScript*> script(rcx);
 
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -130,20 +130,18 @@ 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,20 +63,18 @@ 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
@@ -1304,18 +1304,16 @@ EventListenerManager::HandleEventInterna
 
               TimeStamp endTime = TimeStamp::Now();
               uint16_t phase;
               (*aDOMEvent)->GetEventPhase(&phase);
               PROFILER_MARKER_PAYLOAD(
                 "DOMEvent",
                 MakeUnique<DOMEventMarkerPayload>(typeStr, phase,
                                                   startTime, endTime));
-#else
-              MOZ_CRASH("Gecko Profiler is N/A but profiler_is_active() returned true");
 #endif
             } else {
               rv = HandleEventSubType(listener, *aDOMEvent, aCurrentTarget);
             }
 
             if (NS_FAILED(rv)) {
               aEvent->mFlags.mExceptionWasRaised = true;
             }
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2900,35 +2900,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;
     }
 
     {
-#ifdef MOZ_GECKO_PROFILER
       profiler_set_js_context(cx);
-#endif
 
       {
         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();
 
-#ifdef MOZ_GECKO_PROFILER
       profiler_clear_js_context();
-#endif
     }
 
     // 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();
--- a/image/DecodePool.cpp
+++ b/image/DecodePool.cpp
@@ -175,19 +175,17 @@ public:
       switch (work.mType) {
         case Work::Type::TASK:
           work.mTask->Run();
           break;
 
         case Work::Type::SHUTDOWN:
           DecodePoolImpl::ShutdownThread(thisThread);
 
-#ifdef MOZ_GECKO_PROFILER
           profiler_unregister_thread();
-#endif // MOZ_GECKO_PROFILER
 
           return NS_OK;
 
         default:
           MOZ_ASSERT_UNREACHABLE("Unknown work type");
       }
     } while (true);
 
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2498,22 +2498,20 @@ nsXPCComponents_Utils::Import(const nsAC
                               uint8_t optionalArgc,
                               MutableHandleValue retval)
 {
     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
     if (!moduleloader)
         return NS_ERROR_FAILURE;
 
-#ifdef MOZ_GECKO_PROFILER
     const nsCString& flatLocation = PromiseFlatCString(registryLocation);
     PROFILER_LABEL_DYNAMIC("Components.utils", "import",
                            js::ProfileEntry::Category::OTHER,
                            flatLocation.get());
-#endif
 
     return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::IsModuleLoaded(const nsACString& registryLocation, bool* retval)
 {
     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
--- a/js/xpconnect/src/XPCJSContext.cpp
+++ b/js/xpconnect/src/XPCJSContext.cpp
@@ -723,19 +723,17 @@ XPCJSContext::~XPCJSContext()
 
     if (mCallContext)
         mCallContext->SystemIsBeingShutDown();
 
     auto rtPrivate = static_cast<PerThreadAtomCache*>(JS_GetContextPrivate(Context()));
     delete rtPrivate;
     JS_SetContextPrivate(Context(), nullptr);
 
-#ifdef MOZ_GECKO_PROFILER
     profiler_clear_js_context();
-#endif
 
     gTlsContext.set(nullptr);
 }
 
 XPCJSContext::XPCJSContext()
  : mCallContext(nullptr),
    mAutoRoots(nullptr),
    mResolveName(JSID_VOID),
@@ -903,19 +901,17 @@ XPCJSContext::Initialize(XPCJSContext* a
     // default.
     (void) kDefaultStackQuota;
 
     JS_SetNativeStackQuota(cx,
                            kStackQuota,
                            kStackQuota - kSystemCodeBuffer,
                            kStackQuota - kSystemCodeBuffer - kTrustedScriptBuffer);
 
-#ifdef MOZ_GECKO_PROFILER
     profiler_set_js_context(cx);
-#endif
 
     js::SetActivityCallback(cx, ActivityCallback, this);
     JS_AddInterruptCallback(cx, InterruptCallback);
 
     // Set up locale information and callbacks for the newly-created context so
     // that the various toLocaleString() methods, localeCompare(), and other
     // internationalization APIs work as desired.
     if (!xpc_LocalizeContext(cx))
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4059,33 +4059,30 @@ 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 = {
     "",
     "Content",
     "ContentAndNotify",
     "Style",
     "InterruptibleLayout",
     "Layout",
     "Display"
   };
 
   PROFILER_LABEL_DYNAMIC("PresShell", "Flush",
-    js::ProfileEntry::Category::GRAPHICS,
-    flushTypeNames[flushType]);
-#endif
+    js::ProfileEntry::Category::GRAPHICS, flushTypeNames[flushType]);
 
 #ifdef ACCESSIBILITY
 #ifdef DEBUG
   nsAccessibilityService* accService = GetAccService();
   if (accService) {
     NS_ASSERTION(!accService->IsProcessingRefreshDriverNotification(),
                  "Flush during accessible tree update!");
   }
@@ -6286,26 +6283,24 @@ PresShell::RecordShadowStyleChange(Shado
   mStyleSet->RecordShadowStyleChange(aShadowRoot);
 }
 
 void
 PresShell::Paint(nsView*         aViewToPaint,
                  const nsRegion& aDirtyRegion,
                  uint32_t        aFlags)
 {
-#ifdef MOZ_GECKO_PROFILER
   nsIURI* uri = mDocument->GetDocumentURI();
   nsIDocument* contentRoot = GetPrimaryContentDocument();
   if (contentRoot) {
     uri = contentRoot->GetDocumentURI();
   }
   nsCString uriString = uri ? uri->GetSpecOrDefault() : NS_LITERAL_CSTRING("N/A");
   PROFILER_LABEL_DYNAMIC("PresShell", "Paint",
     js::ProfileEntry::Category::GRAPHICS, uriString.get());
-#endif
 
   Maybe<js::AutoAssertNoContentJS> nojs;
 
   // On Android, Flash can call into content JS during painting, so we can't
   // assert there. However, we don't rely on this assertion on Android because
   // we don't paint while JS is running.
 #if !defined(MOZ_WIDGET_ANDROID)
   if (!(aFlags & nsIPresShell::PAINT_COMPOSITE)) {
@@ -9200,22 +9195,20 @@ PresShell::DoReflow(nsIFrame* target, bo
 
   target->SchedulePaint();
   nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(target);
   while (parent) {
     nsSVGEffects::InvalidateDirectRenderingObservers(parent);
     parent = nsLayoutUtils::GetCrossDocParentFrame(parent);
   }
 
-#ifdef MOZ_GECKO_PROFILER
   nsIURI* uri = mDocument->GetDocumentURI();
   nsCString uriString = uri ? uri->GetSpecOrDefault() : NS_LITERAL_CSTRING("N/A");
   PROFILER_LABEL_DYNAMIC("PresShell", "DoReflow",
     js::ProfileEntry::Category::GRAPHICS, uriString.get());
-#endif
 
   nsDocShell* docShell = static_cast<nsDocShell*>(GetPresContext()->GetDocShell());
   RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
   bool isTimelineRecording = timelines && timelines->HasConsumer(docShell);
 
   if (isTimelineRecording) {
     timelines->AddMarkerForDocShell(docShell, "Reflow", MarkerTracingType::START);
   }
--- a/mozglue/build/WindowsDllBlocklist.cpp
+++ b/mozglue/build/WindowsDllBlocklist.cpp
@@ -759,23 +759,21 @@ patched_LdrLoadDll (PWCHAR filePath, PUL
     }
   }
 
 continue_loading:
 #ifdef DEBUG_very_verbose
   printf_stderr("LdrLoadDll: continuing load... ('%S')\n", moduleFileName->Buffer);
 #endif
 
-#ifdef MOZ_GECKO_PROFILER
   // A few DLLs such as xul.dll and nss3.dll get loaded before mozglue's
   // AutoProfilerLabel is initialized, and this is a no-op in those cases. But
   // the vast majority of DLLs do get labelled here.
   AutoProfilerLabel label("WindowsDllBlocklist::patched_LdrLoadDll", dllName,
                           __LINE__);
-#endif
 
 #ifdef _M_AMD64
   // Prevent the stack walker from suspending this thread when LdrLoadDll
   // holds the RtlLookupFunctionEntry lock.
   AutoSuppressStackWalking suppress;
 #endif
 
   return stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
--- a/mozglue/misc/AutoProfilerLabel.h
+++ b/mozglue/misc/AutoProfilerLabel.h
@@ -2,18 +2,16 @@
 /* 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_AutoProfilerLabel_h
 #define mozilla_AutoProfilerLabel_h
 
-#ifdef MOZ_GECKO_PROFILER
-
 #include "mozilla/Attributes.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/Types.h"
 
 // The Gecko Profiler defines AutoProfilerLabel, an RAII class for
 // pushing/popping entries to/from the PseudoStack.
 //
 // This file defines a class of the same name that does much the same thing,
@@ -56,11 +54,9 @@ private:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   PseudoStack* mPseudoStack;
 };
 
 #endif
 
 } // namespace mozilla
 
-#endif // MOZ_GECKO_PROFILER
-
 #endif // mozilla_AutoProfilerLabel_h
--- a/mozglue/misc/moz.build
+++ b/mozglue/misc/moz.build
@@ -17,26 +17,22 @@ EXPORTS.mozilla += [
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS.mozilla += [
         'StackWalk_windows.h',
         'TimeStamp_windows.h',
     ]
 
 SOURCES += [
+    'AutoProfilerLabel.cpp',
     'Printf.cpp',
     'StackWalk.cpp',
     'TimeStamp.cpp',
 ]
 
-if CONFIG['MOZ_GECKO_PROFILER']:
-    SOURCES += [
-	'AutoProfilerLabel.cpp',
-    ]
-
 OS_LIBS += CONFIG['REALTIME_LIBS']
 
 DEFINES['IMPL_MFBT'] = True
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     SOURCES += [
         'TimeStamp_windows.cpp',
     ]
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -2065,25 +2065,23 @@ TelemetryImpl::RecordChromeHang(uint32_t
 
   MutexAutoLock hangReportMutex(sTelemetry->mHangReportsMutex);
 
   sTelemetry->mHangReports.AddHang(aStack, aDuration,
                                    aSystemUptime, aFirefoxUptime,
                                    Move(annotations));
 }
 
-#if defined(MOZ_GECKO_PROFILER)
 void
 TelemetryImpl::DoStackCapture(const nsACString& aKey) {
   if (Telemetry::CanRecordExtended() && XRE_IsParentProcess()) {
     sTelemetry->mStackCapturer.Capture(aKey);
   }
 }
 #endif
-#endif
 
 nsresult
 TelemetryImpl::CaptureStack(const nsACString& aKey) {
 #if defined(MOZ_GECKO_PROFILER)
   TelemetryImpl::DoStackCapture(aKey);
 #endif
   return NS_OK;
 }
--- a/tools/profiler/core/ProfilerBacktrace.h
+++ b/tools/profiler/core/ProfilerBacktrace.h
@@ -9,16 +9,20 @@
 
 #include "mozilla/UniquePtrExtensions.h"
 
 class ProfileBuffer;
 class SpliceableJSONWriter;
 class ThreadInfo;
 class UniqueStacks;
 
+namespace mozilla {
+class TimeStamp;
+}
+
 // ProfilerBacktrace encapsulates a synchronous sample.
 class ProfilerBacktrace
 {
 public:
   ProfilerBacktrace(const char* aName, int aThreadId,
                     mozilla::UniquePtr<ProfileBuffer> aBuffer);
   ~ProfilerBacktrace();
 
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -566,39 +566,40 @@ Atomic<uint32_t> RacyFeatures::sActiveAn
 // Each live thread has a ThreadInfo, and we store a reference to it in TLS.
 // This class encapsulates that TLS.
 class TLSInfo
 {
 public:
   static bool Init(PSLockRef)
   {
     bool ok1 = sThreadInfo.init();
-    bool ok2 = sPseudoStack.init();
+    bool ok2 = AutoProfilerLabel::sPseudoStack.init();
     return ok1 && ok2;
   }
 
   // Get the entire ThreadInfo. Accesses are guarded by gPSMutex.
   static ThreadInfo* Info(PSLockRef) { return sThreadInfo.get(); }
 
   // Get only the RacyThreadInfo. Accesses are not guarded by gPSMutex.
   static RacyThreadInfo* RacyInfo()
   {
     ThreadInfo* info = sThreadInfo.get();
     return info ? info->RacyInfo().get() : nullptr;
   }
 
   // Get only the PseudoStack. Accesses are not guarded by gPSMutex. RacyInfo()
   // can also be used to get the PseudoStack, but that is marginally slower
   // because it requires an extra pointer indirection.
-  static PseudoStack* Stack() { return sPseudoStack.get(); }
+  static PseudoStack* Stack() { return AutoProfilerLabel::sPseudoStack.get(); }
 
   static void SetInfo(PSLockRef, ThreadInfo* aInfo)
   {
     sThreadInfo.set(aInfo);
-    sPseudoStack.set(aInfo ? aInfo->RacyInfo().get() : nullptr);  // an upcast
+    AutoProfilerLabel::sPseudoStack.set(
+      aInfo ? aInfo->RacyInfo().get() : nullptr);  // an upcast
   }
 
 private:
   // This is a non-owning reference to the ThreadInfo; CorePS::mLiveThreads is
   // the owning reference. On thread destruction, this reference is cleared and
   // the ThreadInfo is destroyed or transferred to CorePS::mDeadThreads.
   static MOZ_THREAD_LOCAL(ThreadInfo*) sThreadInfo;
 };
@@ -612,19 +613,18 @@ MOZ_THREAD_LOCAL(ThreadInfo*) TLSInfo::s
 //   AutoProfilerLabel.
 //
 // - The class functions are hot and must be defined in GeckoProfiler.h so they
 //   can be inlined.
 //
 // - We don't want to expose TLSInfo (and ThreadInfo) in GeckoProfiler.h.
 //
 // This second pointer isn't ideal, but does provide a way to satisfy those
-// constraints. TLSInfo manages it, except for the uses in
-// AutoProfilerLabel.
-MOZ_THREAD_LOCAL(PseudoStack*) sPseudoStack;
+// constraints. TLSInfo is responsible for updating it.
+MOZ_THREAD_LOCAL(PseudoStack*) AutoProfilerLabel::sPseudoStack;
 
 // The name of the main thread.
 static const char* const kMainThreadName = "GeckoMain";
 
 ////////////////////////////////////////////////////////////////////////
 // BEGIN sampling/unwinding code
 
 // The registers used for stack unwinding and a few other sampling purposes.
@@ -2078,17 +2078,17 @@ locked_profiler_start(PSLockRef aLock, c
                       uint32_t aFeatures,
                       const char** aFilters, uint32_t aFilterCount);
 
 // This basically duplicates AutoProfilerLabel's constructor.
 PseudoStack*
 MozGlueLabelEnter(const char* aLabel, const char* aDynamicString, void* aSp,
                   uint32_t aLine)
 {
-  PseudoStack* pseudoStack = sPseudoStack.get();
+  PseudoStack* pseudoStack = AutoProfilerLabel::sPseudoStack.get();
   if (pseudoStack) {
     pseudoStack->pushCppFrame(aLabel, aDynamicString, aSp, aLine,
                               js::ProfileEntry::Kind::CPP_NORMAL,
                               js::ProfileEntry::Category::OTHER);
   }
   return pseudoStack;
 }
 
--- a/tools/profiler/gecko/ProfilerIOInterposeObserver.h
+++ b/tools/profiler/gecko/ProfilerIOInterposeObserver.h
@@ -1,17 +1,15 @@
 /* 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 PROFILERIOINTERPOSEOBSERVER_H
 #define PROFILERIOINTERPOSEOBSERVER_H
 
-#ifdef MOZ_GECKO_PROFILER
-
 #include "mozilla/IOInterposer.h"
 #include "nsISupportsImpl.h"
 
 namespace mozilla {
 
 /**
  * This class is the observer that calls into the profiler whenever
  * main thread I/O occurs.
@@ -24,11 +22,9 @@ public:
   virtual void Observe(Observation& aObservation);
 
 protected:
   virtual ~ProfilerIOInterposeObserver() {}
 };
 
 } // namespace mozilla
 
-#endif // MOZ_GECKO_PROFILER
-
 #endif // PROFILERIOINTERPOSEOBSERVER_H
--- a/tools/profiler/public/GeckoProfiler.h
+++ b/tools/profiler/public/GeckoProfiler.h
@@ -11,57 +11,61 @@
 //
 // 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
 
-#include <stdint.h>
+#include <functional>
+#include <signal.h>
 #include <stdarg.h>
-#include <functional>
+#include <stdint.h>
+#include <stdlib.h>
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/GuardObjects.h"
+#include "mozilla/Sprintf.h"
+#include "mozilla/ThreadLocal.h"
+#include "mozilla/UniquePtr.h"
 #include "js/TypeDecls.h"
-#include "mozilla/GuardObjects.h"
-#include "mozilla/UniquePtr.h"
+#include "js/ProfilingStack.h"
+#include "nscore.h"
 
+// Make sure that we can use std::min here without the Windows headers messing
+// with us.
+#ifdef min
+# undef min
+#endif
+
+class ProfilerBacktrace;
+class ProfilerMarkerPayload;
 class SpliceableJSONWriter;
 
 namespace mozilla {
 class MallocAllocPolicy;
 template <class T, size_t MinInlineCapacity, class AllocPolicy> class Vector;
 } // namespace mozilla
 
 enum TracingKind {
   TRACING_EVENT,
   TRACING_INTERVAL_START,
   TRACING_INTERVAL_END,
 };
 
-class ProfilerBacktrace;
-
 struct ProfilerBacktraceDestructor
 {
   void operator()(ProfilerBacktrace*);
 };
+
 using UniqueProfilerBacktrace =
   mozilla::UniquePtr<ProfilerBacktrace, ProfilerBacktraceDestructor>;
 
-#if defined(MOZ_GECKO_PROFILER)
-
-// Use these for functions below that must be visible whether the profiler is
-// enabled or not. When the profiler is disabled they are static inline
-// functions (with a simple return value if they are non-void) that should be
-// optimized away during compilation.
-#define PROFILER_FUNC(decl, rv)  decl;
-#define PROFILER_FUNC_VOID(decl) void decl;
-
 #define PROFILER_APPEND_LINE_NUMBER_PASTE(id, line) id ## line
 #define PROFILER_APPEND_LINE_NUMBER_EXPAND(id, line) \
   PROFILER_APPEND_LINE_NUMBER_PASTE(id, line)
 #define PROFILER_APPEND_LINE_NUMBER(id) \
   PROFILER_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
 
 #if defined(__GNUC__) || defined(_MSC_VER)
 # define PROFILER_FUNCTION_NAME __FUNCTION__
@@ -113,37 +117,16 @@ using UniqueProfilerBacktrace =
 // 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.
 #define PROFILER_MARKER(marker_name) profiler_add_marker(marker_name)
 
 // Like PROFILER_MARKER, but with an additional payload.
 #define PROFILER_MARKER_PAYLOAD(marker_name, payload) \
   profiler_add_marker(marker_name, payload)
 
-#else   // defined(MOZ_GECKO_PROFILER)
-
-#define PROFILER_FUNC(decl, rv)  static inline decl { return rv; }
-#define PROFILER_FUNC_VOID(decl) static inline void decl {}
-
-#define PROFILER_LABEL(name_space, info, category) do {} while (0)
-#define PROFILER_LABEL_FUNC(category) do {} while (0)
-#define PROFILER_LABEL_DYNAMIC(name_space, info, category, dynamicStr) \
-  do {} while (0)
-
-#define PROFILER_MARKER(marker_name) do {} while (0)
-
-// Note: this is deliberately not defined when MOZ_GECKO_PROFILER is undefined.
-// This macro should not be used in that case -- i.e. all uses of this macro
-// should be guarded by a MOZ_GECKO_PROFILER check -- because payload creation
-// requires allocation, which is something we should not do in builds that
-// don't contain the profiler.
-//#define PROFILER_MARKER_PAYLOAD(marker_name, payload) /* undefined */
-
-#endif  // defined(MOZ_GECKO_PROFILER)
-
 // Higher-order macro containing all the feature info in one place. Define
 // |macro| appropriately to extract the relevant parts. Note that the number
 // values are used internally only and so can be changed without consequence.
 // Any changes to this list should also be applied to the feature list in
 // browser/components/extensions/schemas/geckoProfiler.json.
 #define PROFILER_FOR_EACH_FEATURE(macro) \
   /* Dump the display list with the textures. */ \
   macro(0, "displaylistdump", DisplayListDump) \
@@ -194,17 +177,26 @@ struct ProfilerFeature
     static void Clear##Name_(uint32_t& aFeatures) { aFeatures &= ~Name_; }
 
   // Define a bitfield constant, a getter, and two setters for each feature.
   PROFILER_FOR_EACH_FEATURE(DECLARE)
 
   #undef DECLARE
 };
 
-// These functions are defined whether the profiler is enabled or not.
+// 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
 
 // 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 = TRACING_EVENT))
 PROFILER_FUNC_VOID(profiler_tracing(const char* aCategory,
                                     const char* aMarkerName,
@@ -252,17 +244,17 @@ PROFILER_FUNC(bool profiler_is_paused(),
 // 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)
 
 PROFILER_FUNC_VOID(profiler_get_backtrace_noalloc(char* aOutput,
                                                   size_t aOutputSize))
 
 // Free a ProfilerBacktrace returned by profiler_get_backtrace().
-#if !defined(MOZ_GECKO_PROFILER)
+#ifndef MOZ_GECKO_PROFILER
 inline void
 ProfilerBacktraceDestructor::operator()(ProfilerBacktrace* aBacktrace) {}
 #endif
 
 // 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
 // pattern of usage is the following:
@@ -379,102 +371,88 @@ PROFILER_FUNC(int profiler_current_threa
 //
 // WARNING: The target thread is suspended during the callback. Do not try to
 // allocate or acquire any locks, or you could deadlock. The target thread will
 // have resumed by the time that this function returns.
 PROFILER_FUNC_VOID(profiler_suspend_and_sample_thread(int aThreadId,
                                                       const std::function<void(void**, size_t)>& aCallback,
                                                       bool aSampleNative = true))
 
-// End of the functions defined whether the profiler is enabled or not.
-
-#if defined(MOZ_GECKO_PROFILER)
-
-#include <stdlib.h>
-#include <signal.h>
-#include "js/ProfilingStack.h"
-#include "mozilla/Sprintf.h"
-#include "mozilla/ThreadLocal.h"
-#include "nscore.h"
-
-// Make sure that we can use std::min here without the Windows headers messing with us.
-#ifdef min
-# undef min
-#endif
-
-class ProfilerMarkerPayload;
-
-// This exists purely for AutoProfilerLabel. See the comment on the
-// definition in platform.cpp for details.
-extern MOZ_THREAD_LOCAL(PseudoStack*) sPseudoStack;
-
 // Adds a marker to the PseudoStack. A no-op if the profiler is inactive or in
 // privacy mode.
-void profiler_add_marker(const char* aMarkerName);
-void profiler_add_marker(const char* aMarkerName,
-                         mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
+PROFILER_FUNC_VOID(profiler_add_marker(const char* aMarkerName))
+PROFILER_FUNC_VOID(profiler_add_marker(const char* aMarkerName,
+                                       mozilla::UniquePtr<ProfilerMarkerPayload> aPayload))
+
+// Get the current thread's PseudoStack.
+PROFILER_FUNC(PseudoStack* profiler_get_pseudo_stack(), nullptr)
+
+// Set and clear the current thread's JSContext.
+PROFILER_FUNC_VOID(profiler_set_js_context(JSContext* aCx))
+PROFILER_FUNC_VOID(profiler_clear_js_context())
 
 #if !defined(ARCH_ARMV6)
 # define PROFILER_DEFAULT_ENTRIES 1000000
 #else
 # define PROFILER_DEFAULT_ENTRIES 100000
 #endif
 
 #define PROFILER_DEFAULT_INTERVAL 1
 
 namespace mozilla {
 
 // This class creates a non-owning PseudoStack reference. Objects of this class
 // are stack-allocated, and so exist within a thread, and are thus bounded by
 // the lifetime of the thread, which ensures that the references held can't be
 // used after the PseudoStack is destroyed.
-class MOZ_RAII AutoProfilerLabel {
+class MOZ_RAII AutoProfilerLabel
+{
 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
 };
 
-} // namespace mozilla
-
-PseudoStack* profiler_get_pseudo_stack();
-
-void profiler_set_js_context(JSContext* aCx);
-void profiler_clear_js_context();
-
-#endif  // defined(MOZ_GECKO_PROFILER)
-
-namespace mozilla {
-
 class MOZ_RAII AutoProfilerInit
 {
 public:
   explicit AutoProfilerInit(void* stackTop
                             MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     profiler_init(stackTop);
--- a/tools/profiler/tests/gtest/GeckoProfiler.cpp
+++ b/tools/profiler/tests/gtest/GeckoProfiler.cpp
@@ -576,23 +576,21 @@ TEST(GeckoProfiler, PseudoStack)
                            dynamic.get());
 
     profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
                    features, filters, MOZ_ARRAY_LENGTH(filters));
 
     ASSERT_TRUE(profiler_get_backtrace());
   }
 
-#if defined(MOZ_GECKO_PROFILER)
   AutoProfilerLabel label1("A", nullptr, 888,
                            js::ProfileEntry::Category::STORAGE);
   AutoProfilerLabel label2("A", dynamic.get(), 888,
                            js::ProfileEntry::Category::NETWORK);
   ASSERT_TRUE(profiler_get_backtrace());
-#endif
 
   profiler_stop();
 
   ASSERT_TRUE(!profiler_get_profile());
 }
 
 TEST(GeckoProfiler, Bug1355807)
 {
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -925,29 +925,29 @@ CycleCollectedJSRuntime::GCNurseryCollec
 
   RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
   if (timelines && !timelines->IsEmpty()) {
     UniquePtr<AbstractTimelineMarker> abstractMarker(
       MakeUnique<MinorGCMarker>(aProgress, aReason));
     timelines->AddMarkerForAllObservedDocShells(abstractMarker);
   }
 
-#ifdef MOZ_GECKO_PROFILER
   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
     PROFILER_MARKER_PAYLOAD(
       "GCMinor",
       MakeUnique<GCMinorMarkerPayload>(self->mLatestNurseryCollectionStart,
                                        TimeStamp::Now(),
                                        JS::MinorGcToJSON(aContext)));
+#endif
   }
-#endif
 
   if (self->mPrevGCNurseryCollectionCallback) {
     self->mPrevGCNurseryCollectionCallback(aContext, aProgress, aReason);
   }
 }
 
 
 /* static */ void
--- a/xpcom/base/CycleCollectedJSRuntime.h
+++ b/xpcom/base/CycleCollectedJSRuntime.h
@@ -297,19 +297,17 @@ private:
 
   JSZoneParticipant mJSZoneCycleCollectorGlobal;
 
   JSRuntime* mJSRuntime;
 
   JS::GCSliceCallback mPrevGCSliceCallback;
   JS::GCNurseryCollectionCallback mPrevGCNurseryCollectionCallback;
 
-#ifdef MOZ_GECKO_PROFILER
   mozilla::TimeStamp mLatestNurseryCollectionStart;
-#endif
 
   nsDataHashtable<nsPtrHashKey<void>, nsScriptObjectTracer*> mJSHolders;
 
   typedef nsDataHashtable<nsFuncPtrHashKey<DeferredFinalizeFunction>, void*>
     DeferredFinalizerTable;
   DeferredFinalizerTable mDeferredFinalizerTable;
 
   RefPtr<IncrementalFinalizeRunnable> mFinalizeRunnable;
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -1005,27 +1005,25 @@ ShutdownXPCOM(nsIServiceManager* aServMg
   // a refcount to the component manager to release it.
   if (nsComponentManagerImpl::gComponentManager) {
     rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
     NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
   } else {
     NS_WARNING("Component Manager was never created ...");
   }
 
-#ifdef MOZ_GECKO_PROFILER
   // 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();
-#endif
 
   if (sInitializedJS) {
     // Shut down the JS engine.
     JS_ShutDown();
     sInitializedJS = false;
   }
 
   // Release our own singletons