Bug 1492121 - MOZ_BASE_PROFILER may be defined in BaseProfiler.h to enable Base Profiler - r=njn
☠☠ backed out by d57670df353e ☠ ☠
authorGerald Squelart <gsquelart@mozilla.com>
Wed, 05 Jun 2019 23:39:28 +0000
changeset 477533 1f10b50f758f54902e7423f4de0da9c0e0c2944b
parent 477532 db1506f94d0d2eec4c1955ee27a68ad77d84329e
child 477534 77e7b13c6237fdded3e33fb664962cef2a636a95
push id113351
push usershindli@mozilla.com
push dateThu, 06 Jun 2019 10:13:05 +0000
treeherdermozilla-inbound@6a80a4f48253 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1492121
milestone69.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 1492121 - MOZ_BASE_PROFILER may be defined in BaseProfiler.h to enable Base Profiler - r=njn Added baseprofiler to mozglue/moz.build, so it will be built. However all cpp files are dependent on `MOZ_BASE_PROFILER`, which is currently not #defined by default (in public/BaseProfiler.h). Added mozglue/mozprofiler to js/src/make-source-package.sh, because mozglue/moz.build now refers to it. Differential Revision: https://phabricator.services.mozilla.com/D33258
mozglue/baseprofiler/core/EHABIStackWalk.cpp
mozglue/baseprofiler/core/PageInformation.cpp
mozglue/baseprofiler/core/ProfileBuffer.cpp
mozglue/baseprofiler/core/ProfileBufferEntry.cpp
mozglue/baseprofiler/core/ProfileJSONWriter.cpp
mozglue/baseprofiler/core/ProfiledThreadData.cpp
mozglue/baseprofiler/core/ProfilerBacktrace.cpp
mozglue/baseprofiler/core/ProfilerMarkerPayload.cpp
mozglue/baseprofiler/core/ProfilingCategory.cpp
mozglue/baseprofiler/core/ProfilingStack.cpp
mozglue/baseprofiler/core/RegisteredThread.cpp
mozglue/baseprofiler/core/VTuneProfiler.cpp
mozglue/baseprofiler/core/platform.cpp
mozglue/baseprofiler/core/shared-libraries-linux.cc
mozglue/baseprofiler/core/shared-libraries-macos.cc
mozglue/baseprofiler/core/shared-libraries-win32.cc
mozglue/baseprofiler/lul/AutoObjectMapper.cpp
mozglue/baseprofiler/lul/LulCommon.cpp
mozglue/baseprofiler/lul/LulDwarf.cpp
mozglue/baseprofiler/lul/LulDwarfSummariser.cpp
mozglue/baseprofiler/lul/LulElf.cpp
mozglue/baseprofiler/lul/LulMain.cpp
mozglue/baseprofiler/lul/platform-linux-lul.cpp
mozglue/baseprofiler/public/BaseProfileJSONWriter.h
mozglue/baseprofiler/public/BaseProfiler.h
mozglue/baseprofiler/public/BaseProfilerMarkerPayload.h
mozglue/baseprofiler/public/BaseProfilerSharedLibraries.h
mozglue/baseprofiler/public/BaseProfilingCategory.h
mozglue/baseprofiler/public/BaseProfilingStack.h
mozglue/moz.build
--- a/mozglue/baseprofiler/core/EHABIStackWalk.cpp
+++ b/mozglue/baseprofiler/core/EHABIStackWalk.cpp
@@ -17,44 +17,48 @@
  * possible places where an async signal could occur (e.g., in a
  * prologue or epilogue), this bounds-checks all stack accesses.
  *
  * This file uses "struct" for structures in the exception tables and
  * "class" otherwise.  We should avoid violating the C++11
  * standard-layout rules in the former.
  */
 
-#include "EHABIStackWalk.h"
+#include "BaseProfiler.h"
 
-#include "BaseProfilerSharedLibraries.h"
-#include "platform.h"
+#ifdef MOZ_BASE_PROFILER
 
-#include "mozilla/Atomics.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/EndianUtils.h"
+#  include "EHABIStackWalk.h"
+
+#  include "BaseProfilerSharedLibraries.h"
+#  include "platform.h"
 
-#include <algorithm>
-#include <elf.h>
-#include <stdint.h>
-#include <vector>
-#include <string>
+#  include "mozilla/Atomics.h"
+#  include "mozilla/Attributes.h"
+#  include "mozilla/DebugOnly.h"
+#  include "mozilla/EndianUtils.h"
 
-#ifndef PT_ARM_EXIDX
-#  define PT_ARM_EXIDX 0x70000001
-#endif
+#  include <algorithm>
+#  include <elf.h>
+#  include <stdint.h>
+#  include <vector>
+#  include <string>
+
+#  ifndef PT_ARM_EXIDX
+#    define PT_ARM_EXIDX 0x70000001
+#  endif
 
 // Bug 1082817: ICS B2G has a buggy linker that doesn't always ensure
 // that the EXIDX is sorted by address, as the spec requires.  So in
 // that case we build and sort an array of pointers into the index,
 // and binary-search that; otherwise, we search the index in place
 // (avoiding the time and space overhead of the indirection).
-#if defined(ANDROID_VERSION) && ANDROID_VERSION < 16
-#  define HAVE_UNSORTED_EXIDX
-#endif
+#  if defined(ANDROID_VERSION) && ANDROID_VERSION < 16
+#    define HAVE_UNSORTED_EXIDX
+#  endif
 
 namespace mozilla {
 
 struct PRel31 {
   uint32_t mBits;
   bool topBit() const { return mBits & 0x80000000; }
   uint32_t value() const { return mBits & 0x7fffffff; }
   int32_t offset() const { return (static_cast<int32_t>(mBits) << 1) >> 1; }
@@ -85,52 +89,52 @@ class EHState {
   bool unwind(const EHEntry* aEntry, const void* stackBase);
   uint32_t& operator[](int i) { return mRegs[i]; }
   const uint32_t& operator[](int i) const { return mRegs[i]; }
   explicit EHState(const mcontext_t&);
 };
 
 enum { R_SP = 13, R_LR = 14, R_PC = 15 };
 
-#ifdef HAVE_UNSORTED_EXIDX
+#  ifdef HAVE_UNSORTED_EXIDX
 class EHEntryHandle {
   const EHEntry* mValue;
 
  public:
   EHEntryHandle(const EHEntry* aEntry) : mValue(aEntry) {}
   const EHEntry* value() const { return mValue; }
 };
 
 bool operator<(const EHEntryHandle& lhs, const EHEntryHandle& rhs) {
   return lhs.value()->startPC.compute() < rhs.value()->startPC.compute();
 }
-#endif
+#  endif
 
 class EHTable {
   uint32_t mStartPC;
   uint32_t mEndPC;
   uint32_t mBaseAddress;
-#ifdef HAVE_UNSORTED_EXIDX
+#  ifdef HAVE_UNSORTED_EXIDX
   // In principle we should be able to binary-search the index section in
   // place, but the ICS toolchain's linker is noncompliant and produces
   // indices that aren't entirely sorted (e.g., libc).  So we have this:
   std::vector<EHEntryHandle> mEntries;
   typedef std::vector<EHEntryHandle>::const_iterator EntryIterator;
   EntryIterator entriesBegin() const { return mEntries.begin(); }
   EntryIterator entriesEnd() const { return mEntries.end(); }
   static const EHEntry* entryGet(EntryIterator aEntry) {
     return aEntry->value();
   }
-#else
+#  else
   typedef const EHEntry* EntryIterator;
   EntryIterator mEntriesBegin, mEntriesEnd;
   EntryIterator entriesBegin() const { return mEntriesBegin; }
   EntryIterator entriesEnd() const { return mEntriesEnd; }
   static const EHEntry* entryGet(EntryIterator aEntry) { return aEntry; }
-#endif
+#  endif
   std::string mName;
 
  public:
   EHTable(const void* aELF, size_t aSize, const std::string& aName);
   const EHEntry* lookup(uint32_t aPC) const;
   bool isValid() const { return entriesEnd() != entriesBegin(); }
   const std::string& name() const { return mName; }
   uint32_t startPC() const { return mStartPC; }
@@ -325,19 +329,19 @@ bool EHState::unwind(const EHEntry* aEnt
   return interp.unwind();
 }
 
 bool EHInterp::unwind() {
   mState[R_PC] = 0;
   checkStack();
   while (!mFailed) {
     uint8_t insn = next();
-#if DEBUG_EHABI_UNWIND
+#  if DEBUG_EHABI_UNWIND
     LOG("unwind insn = %02x", (unsigned)insn);
-#endif
+#  endif
     // Try to put the common cases first.
 
     // 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4
     // 01xxxxxx: vsp = vsp - (xxxxxx << 2) - 4
     if ((insn & M_ADDSP) == I_ADDSP) {
       uint32_t offset = ((insn & 0x3f) << 2) + 4;
       if (insn & 0x40) {
         vSP() -= offset;
@@ -451,19 +455,19 @@ bool EHInterp::unwind() {
     if ((insn & M_POPFDX8) == I_POPFDX8) {
       uint8_t n = (insn & 0x07) + 1;
       vSP() += 8 * n + 4;
       checkStackBase();
       continue;
     }
 
     // unhandled instruction
-#ifdef DEBUG_EHABI_UNWIND
+#  ifdef DEBUG_EHABI_UNWIND
     LOG("Unhandled EHABI instruction 0x%02x", insn);
-#endif
+#  endif
     mFailed = true;
   }
   return false;
 }
 
 bool operator<(const EHTable& lhs, const EHTable& rhs) {
   return lhs.startPC() < rhs.startPC();
 }
@@ -496,47 +500,47 @@ const EHEntry* EHTable::lookup(uint32_t 
 
   EntryIterator begin = entriesBegin();
   EntryIterator end = entriesEnd();
   MOZ_ASSERT(begin < end);
   if (aPC < reinterpret_cast<uint32_t>(entryGet(begin)->startPC.compute()))
     return nullptr;
 
   while (end - begin > 1) {
-#ifdef EHABI_UNWIND_MORE_ASSERTS
+#  ifdef EHABI_UNWIND_MORE_ASSERTS
     if (entryGet(end - 1)->startPC.compute() <
         entryGet(begin)->startPC.compute()) {
       MOZ_CRASH("unsorted exidx");
     }
-#endif
+#  endif
     EntryIterator mid = begin + (end - begin) / 2;
     if (aPC < reinterpret_cast<uint32_t>(entryGet(mid)->startPC.compute()))
       end = mid;
     else
       begin = mid;
   }
   return entryGet(begin);
 }
 
-#if MOZ_LITTLE_ENDIAN
+#  if MOZ_LITTLE_ENDIAN
 static const unsigned char hostEndian = ELFDATA2LSB;
-#elif MOZ_BIG_ENDIAN
+#  elif MOZ_BIG_ENDIAN
 static const unsigned char hostEndian = ELFDATA2MSB;
-#else
-#  error "No endian?"
-#endif
+#  else
+#    error "No endian?"
+#  endif
 
 // Async signal unsafe: std::vector::reserve, std::string copy ctor.
 EHTable::EHTable(const void* aELF, size_t aSize, const std::string& aName)
     : mStartPC(~0),  // largest uint32_t
       mEndPC(0),
-#ifndef HAVE_UNSORTED_EXIDX
+#  ifndef HAVE_UNSORTED_EXIDX
       mEntriesBegin(nullptr),
       mEntriesEnd(nullptr),
-#endif
+#  endif
       mName(aName) {
   const uint32_t fileHeaderAddr = reinterpret_cast<uint32_t>(aELF);
 
   if (aSize < sizeof(Elf32_Ehdr)) return;
 
   const Elf32_Ehdr& file = *(reinterpret_cast<Elf32_Ehdr*>(fileHeaderAddr));
   if (memcmp(&file.e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
       file.e_ident[EI_CLASS] != ELFCLASS32 ||
@@ -569,24 +573,24 @@ EHTable::EHTable(const void* aELF, size_
   mStartPC += mBaseAddress;
   mEndPC += mBaseAddress;
 
   // Create a sorted index of the index to work around linker bugs.
   const EHEntry* startTable =
       reinterpret_cast<const EHEntry*>(mBaseAddress + exidxHdr->p_vaddr);
   const EHEntry* endTable = reinterpret_cast<const EHEntry*>(
       mBaseAddress + exidxHdr->p_vaddr + exidxHdr->p_memsz);
-#ifdef HAVE_UNSORTED_EXIDX
+#  ifdef HAVE_UNSORTED_EXIDX
   mEntries.reserve(endTable - startTable);
   for (const EHEntry* i = startTable; i < endTable; ++i) mEntries.push_back(i);
   std::sort(mEntries.begin(), mEntries.end());
-#else
+#  else
   mEntriesBegin = startTable;
   mEntriesEnd = endTable;
-#endif
+#  endif
 }
 
 mozilla::Atomic<const EHAddrSpace*> EHAddrSpace::sCurrent(nullptr);
 
 // Async signal safe; can fail if Update() hasn't returned yet.
 const EHAddrSpace* EHAddrSpace::Get() { return sCurrent; }
 
 // Collect unwinding information from loaded objects.  Calls after the
@@ -611,31 +615,33 @@ void EHAddrSpace::Update() {
 
   if (!sCurrent.compareExchange(nullptr, space)) {
     delete space;
     space = sCurrent;
   }
 }
 
 EHState::EHState(const mcontext_t& context) {
-#ifdef linux
+#  ifdef linux
   mRegs[0] = context.arm_r0;
   mRegs[1] = context.arm_r1;
   mRegs[2] = context.arm_r2;
   mRegs[3] = context.arm_r3;
   mRegs[4] = context.arm_r4;
   mRegs[5] = context.arm_r5;
   mRegs[6] = context.arm_r6;
   mRegs[7] = context.arm_r7;
   mRegs[8] = context.arm_r8;
   mRegs[9] = context.arm_r9;
   mRegs[10] = context.arm_r10;
   mRegs[11] = context.arm_fp;
   mRegs[12] = context.arm_ip;
   mRegs[13] = context.arm_sp;
   mRegs[14] = context.arm_lr;
   mRegs[15] = context.arm_pc;
-#else
-#  error "Unhandled OS for ARM EHABI unwinding"
-#endif
+#  else
+#    error "Unhandled OS for ARM EHABI unwinding"
+#  endif
 }
 
 }  // namespace mozilla
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/PageInformation.cpp
+++ b/mozglue/baseprofiler/core/PageInformation.cpp
@@ -1,17 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "PageInformation.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
 
-#include "BaseProfileJSONWriter.h"
+#  include "PageInformation.h"
+
+#  include "BaseProfileJSONWriter.h"
 
 PageInformation::PageInformation(const nsID& aDocShellId,
                                  uint32_t aDocShellHistoryId,
                                  const nsCString& aUrl, bool aIsSubFrame)
     : mDocShellId(aDocShellId),
       mDocShellHistoryId(aDocShellHistoryId),
       mUrl(aUrl),
       mIsSubFrame(aIsSubFrame) {}
@@ -30,8 +34,10 @@ void PageInformation::StreamJSON(Splicea
   aWriter.BoolProperty("isSubFrame", IsSubFrame());
   aWriter.EndObject();
 }
 
 size_t PageInformation::SizeOfIncludingThis(
     mozilla::MallocSizeOf aMallocSizeOf) const {
   return aMallocSizeOf(this);
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/ProfileBuffer.cpp
+++ b/mozglue/baseprofiler/core/ProfileBuffer.cpp
@@ -1,22 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "ProfileBuffer.h"
+#include "BaseProfiler.h"
 
-#include "ProfilerMarker.h"
+#ifdef MOZ_BASE_PROFILER
+
+#  include "ProfileBuffer.h"
 
-#include "jsfriendapi.h"
-#include "mozilla/MathAlgorithms.h"
-#include "nsJSPrincipals.h"
-#include "nsScriptSecurityManager.h"
+#  include "ProfilerMarker.h"
+
+#  include "jsfriendapi.h"
+#  include "mozilla/MathAlgorithms.h"
+#  include "nsJSPrincipals.h"
+#  include "nsScriptSecurityManager.h"
 
 using namespace mozilla;
 
 ProfileBuffer::ProfileBuffer(uint32_t aCapacity)
     : mEntryIndexMask(0), mRangeStart(0), mRangeEnd(0), mCapacity(0) {
   // Round aCapacity up to the nearest power of two, so that we can index
   // mEntries with a simple mask and don't need to do a slow modulo operation.
   const uint32_t UINT32_MAX_POWER_OF_TWO = 1 << 31;
@@ -183,8 +187,10 @@ void ProfileBufferCollector::CollectProf
     } else if (strlen(dynamicString) >= ProfileBuffer::kMaxFrameKeyLength) {
       dynamicString = "(too long)";
     }
   }
 
   mBuf.CollectCodeLocation(label, dynamicString, aFrame.flags(), line, column,
                            Some(aFrame.categoryPair()));
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/ProfileBufferEntry.cpp
+++ b/mozglue/baseprofiler/core/ProfileBufferEntry.cpp
@@ -1,29 +1,33 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "ProfileBufferEntry.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
 
-#include "platform.h"
-#include "ProfileBuffer.h"
+#  include "ProfileBufferEntry.h"
+
+#  include "platform.h"
+#  include "ProfileBuffer.h"
 
-#include "js/TrackedOptimizationInfo.h"
-#include "jsapi.h"
-#include "jsfriendapi.h"
-#include "mozilla/Logging.h"
-#include "mozilla/Sprintf.h"
-#include "mozilla/StackWalk.h"
-#include "nsThreadUtils.h"
-#include "nsXULAppAPI.h"
+#  include "js/TrackedOptimizationInfo.h"
+#  include "jsapi.h"
+#  include "jsfriendapi.h"
+#  include "mozilla/Logging.h"
+#  include "mozilla/Sprintf.h"
+#  include "mozilla/StackWalk.h"
+#  include "nsThreadUtils.h"
+#  include "nsXULAppAPI.h"
 
-#include <ostream>
+#  include <ostream>
 
 using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////
 // BEGIN ProfileBufferEntry
 
 ProfileBufferEntry::ProfileBufferEntry()
     : mKind(Kind::INVALID), mStorage{0, 0, 0, 0, 0, 0, 0, 0} {}
@@ -882,22 +886,22 @@ class EntryGetter {
 //     DynamicStringFragment("aaa44d75")
 //     DynamicStringFragment("a800.bun")
 //     DynamicStringFragment("dle.js:2")
 //     DynamicStringFragment("5)")
 
 // Because this is a format entirely internal to the Profiler, any parsing
 // error indicates a bug in the ProfileBuffer writing or the parser itself,
 // or possibly flaky hardware.
-#define ERROR_AND_CONTINUE(msg)                            \
-  {                                                        \
-    fprintf(stderr, "ProfileBuffer parse error: %s", msg); \
-    MOZ_ASSERT(false, msg);                                \
-    continue;                                              \
-  }
+#  define ERROR_AND_CONTINUE(msg)                            \
+    {                                                        \
+      fprintf(stderr, "ProfileBuffer parse error: %s", msg); \
+      MOZ_ASSERT(false, msg);                                \
+      continue;                                              \
+    }
 
 void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter,
                                         int aThreadId, double aSinceTime,
                                         UniqueStacks& aUniqueStacks) const {
   UniquePtr<char[]> dynStrBuf = MakeUnique<char[]>(kMaxFrameKeyLength);
 
   EntryGetter e(*this);
 
@@ -1312,27 +1316,27 @@ void ProfileBuffer::StreamProfilerOverhe
   // therefore at least two samplings.)
   if (intervals.n > 0) {
     aWriter.StartObjectProperty("statistics");
     aWriter.DoubleProperty("profiledDuration", lastTime - firstTime);
     aWriter.IntProperty("samplingCount", overheads.n);
     aWriter.DoubleProperty("overheadDurations", overheads.sum);
     aWriter.DoubleProperty("overheadPercentage",
                            overheads.sum / (lastTime - firstTime));
-#define PROFILER_STATS(name, var)                           \
-  aWriter.DoubleProperty("mean" name, (var).sum / (var).n); \
-  aWriter.DoubleProperty("min" name, (var).min);            \
-  aWriter.DoubleProperty("max" name, (var).max);
+#  define PROFILER_STATS(name, var)                           \
+    aWriter.DoubleProperty("mean" name, (var).sum / (var).n); \
+    aWriter.DoubleProperty("min" name, (var).min);            \
+    aWriter.DoubleProperty("max" name, (var).max);
     PROFILER_STATS("Interval", intervals);
     PROFILER_STATS("Overhead", overheads);
     PROFILER_STATS("Lockings", lockings);
     PROFILER_STATS("Cleaning", cleanings);
     PROFILER_STATS("Counter", counters);
     PROFILER_STATS("Thread", threads);
-#undef PROFILER_STATS
+#  undef PROFILER_STATS
     aWriter.EndObject();  // statistics
   }
   aWriter.EndObject();  // profilerOverhead
 }
 
 struct CounterKeyedSample {
   double mTime;
   uint64_t mNumber;
@@ -1567,17 +1571,17 @@ void ProfileBuffer::StreamMemoryToJSON(S
       }
     }
     e.Next();
   }
   aWriter.EndArray();   // data
   aWriter.EndObject();  // samples
   aWriter.EndObject();  // memory
 }
-#undef ERROR_AND_CONTINUE
+#  undef ERROR_AND_CONTINUE
 
 static void AddPausedRange(SpliceableJSONWriter& aWriter, const char* aReason,
                            const Maybe<double>& aStartTime,
                            const Maybe<double>& aEndTime) {
   aWriter.Start();
   if (aStartTime) {
     aWriter.DoubleProperty("startTime", *aStartTime);
   } else {
@@ -1767,8 +1771,10 @@ void ProfileBuffer::DiscardSamplesBefore
         return;
       }
     }
   }
 }
 
 // END ProfileBuffer
 ////////////////////////////////////////////////////////////////////////
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/ProfileJSONWriter.cpp
+++ b/mozglue/baseprofiler/core/ProfileJSONWriter.cpp
@@ -1,16 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "BaseProfileJSONWriter.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
 
-#include "mozilla/HashFunctions.h"
+#  include "BaseProfileJSONWriter.h"
+
+#  include "mozilla/HashFunctions.h"
 
 void ChunkedJSONWriteFunc::Write(const char* aStr) {
   MOZ_ASSERT(mChunkPtr >= mChunkList.back().get() && mChunkPtr <= mChunkEnd);
   MOZ_ASSERT(mChunkEnd >= mChunkList.back().get() + mChunkLengths.back());
   MOZ_ASSERT(*mChunkPtr == '\0');
 
   size_t len = strlen(aStr);
 
@@ -107,8 +111,10 @@ void SpliceableJSONWriter::Splice(const 
   mNeedComma[mDepth] = true;
 }
 
 void SpliceableChunkedJSONWriter::TakeAndSplice(ChunkedJSONWriteFunc* aFunc) {
   Separator();
   WriteFunc()->Take(std::move(*aFunc));
   mNeedComma[mDepth] = true;
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/ProfiledThreadData.cpp
+++ b/mozglue/baseprofiler/core/ProfiledThreadData.cpp
@@ -1,25 +1,29 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "ProfiledThreadData.h"
+#include "BaseProfiler.h"
 
-#include "ProfileBuffer.h"
-#include "BaseProfileJSONWriter.h"
+#ifdef MOZ_BASE_PROFILER
+
+#  include "ProfiledThreadData.h"
 
-#include "js/TraceLoggerAPI.h"
-#include "mozilla/dom/ContentChild.h"
+#  include "ProfileBuffer.h"
+#  include "BaseProfileJSONWriter.h"
 
-#if defined(GP_OS_darwin)
-#  include <pthread.h>
-#endif
+#  include "js/TraceLoggerAPI.h"
+#  include "mozilla/dom/ContentChild.h"
+
+#  if defined(GP_OS_darwin)
+#    include <pthread.h>
+#  endif
 
 ProfiledThreadData::ProfiledThreadData(ThreadInfo* aThreadInfo,
                                        nsIEventTarget* aEventTarget,
                                        bool aIncludeResponsiveness)
     : mThreadInfo(aThreadInfo) {
   MOZ_COUNT_CTOR(ProfiledThreadData);
   if (aIncludeResponsiveness) {
     mResponsiveness.emplace(aEventTarget, aThreadInfo->IsMainThread());
@@ -296,8 +300,10 @@ void ProfiledThreadData::NotifyAboutToLo
           : mozilla::MakeUnique<JITFrameInfo>();
 
   aBuffer.AddJITInfoForRange(*mBufferPositionWhenReceivedJSContext,
                              mThreadInfo->ThreadId(), aContext, *jitFrameInfo);
 
   mJITFrameInfoForPreviousJSContexts = std::move(jitFrameInfo);
   mBufferPositionWhenReceivedJSContext = mozilla::Nothing();
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/ProfilerBacktrace.cpp
+++ b/mozglue/baseprofiler/core/ProfilerBacktrace.cpp
@@ -1,20 +1,24 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "ProfilerBacktrace.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
 
-#include "ProfileBuffer.h"
-#include "ProfiledThreadData.h"
-#include "BaseProfileJSONWriter.h"
-#include "ThreadInfo.h"
+#  include "ProfilerBacktrace.h"
+
+#  include "ProfileBuffer.h"
+#  include "ProfiledThreadData.h"
+#  include "BaseProfileJSONWriter.h"
+#  include "ThreadInfo.h"
 
 ProfilerBacktrace::ProfilerBacktrace(const char* aName, int aThreadId,
                                      mozilla::UniquePtr<ProfileBuffer> aBuffer)
     : mName(strdup(aName)), mThreadId(aThreadId), mBuffer(std::move(aBuffer)) {
   MOZ_COUNT_CTOR(ProfilerBacktrace);
 }
 
 ProfilerBacktrace::~ProfilerBacktrace() { MOZ_COUNT_DTOR(ProfilerBacktrace); }
@@ -27,8 +31,10 @@ void ProfilerBacktrace::StreamJSON(Splic
   // JitReturnAddr entries. For synchronous samples, JIT frames get expanded
   // at sample time.
   StreamSamplesAndMarkers(mName.get(), mThreadId, *mBuffer.get(), aWriter,
                           NS_LITERAL_CSTRING(""), aProcessStartTime,
                           /* aRegisterTime */ mozilla::TimeStamp(),
                           /* aUnregisterTime */ mozilla::TimeStamp(),
                           /* aSinceTime */ 0, aUniqueStacks);
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/ProfilerMarkerPayload.cpp
+++ b/mozglue/baseprofiler/core/ProfilerMarkerPayload.cpp
@@ -1,27 +1,30 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "BaseProfilerMarkerPayload.h"
+#include "BaseProfiler.h"
 
-#include "BaseProfiler.h"
-#include "ProfileBufferEntry.h"
-#include "BaseProfileJSONWriter.h"
-#include "ProfilerBacktrace.h"
+#ifdef MOZ_BASE_PROFILER
+
+#  include "BaseProfilerMarkerPayload.h"
 
-#include "gfxASurface.h"
-#include "Layers.h"
-#include "mozilla/Maybe.h"
-#include "mozilla/net/HttpBaseChannel.h"
-#include "mozilla/Sprintf.h"
+#  include "ProfileBufferEntry.h"
+#  include "BaseProfileJSONWriter.h"
+#  include "ProfilerBacktrace.h"
 
-#include <inttypes.h>
+#  include "gfxASurface.h"
+#  include "Layers.h"
+#  include "mozilla/Maybe.h"
+#  include "mozilla/net/HttpBaseChannel.h"
+#  include "mozilla/Sprintf.h"
+
+#  include <inttypes.h>
 
 using namespace mozilla;
 
 static void MOZ_ALWAYS_INLINE WriteTime(SpliceableJSONWriter& aWriter,
                                         const TimeStamp& aProcessStartTime,
                                         const TimeStamp& aTime,
                                         const char* aName) {
   if (!aTime.IsNull()) {
@@ -291,8 +294,10 @@ void StyleMarkerPayload::StreamPayload(S
 
 void LongTaskMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
                                           const TimeStamp& aProcessStartTime,
                                           UniqueStacks& aUniqueStacks) {
   StreamCommonProps("MainThreadLongTask", aWriter, aProcessStartTime,
                     aUniqueStacks);
   aWriter.StringProperty("category", "LongTask");
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/ProfilingCategory.cpp
+++ b/mozglue/baseprofiler/core/ProfilingCategory.cpp
@@ -1,36 +1,40 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "vm/GeckoProfiler-inl.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include "vm/GeckoProfiler-inl.h"
 
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/Sprintf.h"
+#  include "mozilla/ArrayUtils.h"
+#  include "mozilla/DebugOnly.h"
+#  include "mozilla/Sprintf.h"
 
-#include "jsnum.h"
+#  include "jsnum.h"
 
-#include "gc/GC.h"
-#include "gc/PublicIterators.h"
-#include "jit/BaselineFrame.h"
-#include "jit/BaselineJIT.h"
-#include "jit/JitcodeMap.h"
-#include "jit/JitFrames.h"
-#include "jit/JitRealm.h"
-#include "jit/JSJitFrameIter.h"
-#include "js/TraceLoggerAPI.h"
-#include "util/StringBuffer.h"
-#include "vm/JSScript.h"
+#  include "gc/GC.h"
+#  include "gc/PublicIterators.h"
+#  include "jit/BaselineFrame.h"
+#  include "jit/BaselineJIT.h"
+#  include "jit/JitcodeMap.h"
+#  include "jit/JitFrames.h"
+#  include "jit/JitRealm.h"
+#  include "jit/JSJitFrameIter.h"
+#  include "js/TraceLoggerAPI.h"
+#  include "util/StringBuffer.h"
+#  include "vm/JSScript.h"
 
-#include "gc/Marking-inl.h"
-#include "vm/JSScript-inl.h"
+#  include "gc/Marking-inl.h"
+#  include "vm/JSScript-inl.h"
 
 using namespace js;
 
 using mozilla::DebugOnly;
 
 GeckoProfilerThread::GeckoProfilerThread()
     : profilingStack_(nullptr), profilingStackIfEnabled_(nullptr) {}
 
@@ -147,24 +151,24 @@ void GeckoProfilerRuntime::enable(bool e
 
   // WebAssembly code does not need to be released, but profiling string
   // labels have to be generated so that they are available during async
   // profiling stack iteration.
   for (RealmsIter r(rt); !r.done(); r.next()) {
     r->wasm.ensureProfilingLabels(enabled);
   }
 
-#ifdef JS_STRUCTURED_SPEW
+#  ifdef JS_STRUCTURED_SPEW
   // Enable the structured spewer if the environment variable is set.
   if (enabled) {
     cx->spewer().enableSpewing();
   } else {
     cx->spewer().disableSpewing();
   }
-#endif
+#  endif
 }
 
 /* Lookup the string for the function/script, creating one if necessary */
 const char* GeckoProfilerRuntime::profileString(JSContext* cx,
                                                 JSScript* script) {
   ProfileStringMap::AddPtr s = strings().lookupForAdd(script);
 
   if (!s) {
@@ -204,38 +208,38 @@ void GeckoProfilerRuntime::markEvent(con
 
 bool GeckoProfilerThread::enter(JSContext* cx, JSScript* script) {
   const char* dynamicString =
       cx->runtime()->geckoProfiler().profileString(cx, script);
   if (dynamicString == nullptr) {
     return false;
   }
 
-#ifdef DEBUG
+#  ifdef DEBUG
   // In debug builds, assert the JS profiling stack frames already on the
   // stack have a non-null pc. Only look at the top frames to avoid quadratic
   // behavior.
   uint32_t sp = profilingStack_->stackPointer;
   if (sp > 0 && sp - 1 < profilingStack_->stackCapacity()) {
     size_t start = (sp > 4) ? sp - 4 : 0;
     for (size_t i = start; i < sp - 1; i++) {
       MOZ_ASSERT_IF(profilingStack_->frames[i].isJsFrame(),
                     profilingStack_->frames[i].pc());
     }
   }
-#endif
+#  endif
 
   profilingStack_->pushJsFrame("", dynamicString, script, script->code());
   return true;
 }
 
 void GeckoProfilerThread::exit(JSContext* cx, JSScript* script) {
   profilingStack_->pop();
 
-#ifdef DEBUG
+#  ifdef DEBUG
   /* Sanity check to make sure push/pop balanced */
   uint32_t sp = profilingStack_->stackPointer;
   if (sp < profilingStack_->stackCapacity()) {
     JSRuntime* rt = script->runtimeFromMainThread();
     const char* dynamicString = rt->geckoProfiler().profileString(cx, script);
     /* Can't fail lookup because we should already be in the set */
     MOZ_ASSERT(dynamicString);
 
@@ -255,17 +259,17 @@ void GeckoProfilerThread::exit(JSContext
       }
     }
 
     ProfilingStackFrame& frame = profilingStack_->frames[sp];
     MOZ_ASSERT(frame.isJsFrame());
     MOZ_ASSERT(frame.script() == script);
     MOZ_ASSERT(strcmp((const char*)frame.dynamicString(), dynamicString) == 0);
   }
-#endif
+#  endif
 }
 
 /*
  * Serializes the script/function pair into a "descriptive string" which is
  * allowed to fail. This function cannot trigger a GC because it could finalize
  * some scripts, resize the hash table of profile strings, and invalidate the
  * AddPtr held while invoking allocProfileString.
  */
@@ -374,26 +378,26 @@ void GeckoProfilerRuntime::fixupStringsM
     JSScript* script = e.front().key();
     if (IsForwarded(script)) {
       script = Forwarded(script);
       e.rekeyFront(script);
     }
   }
 }
 
-#ifdef JSGC_HASH_TABLE_CHECKS
+#  ifdef JSGC_HASH_TABLE_CHECKS
 void GeckoProfilerRuntime::checkStringsMapAfterMovingGC() {
   for (auto r = strings().all(); !r.empty(); r.popFront()) {
     JSScript* script = r.front().key();
     CheckGCThingAfterMovingGC(script);
     auto ptr = strings().lookup(script);
     MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
   }
 }
-#endif
+#  endif
 
 void ProfilingStackFrame::trace(JSTracer* trc) {
   if (isJsFrame()) {
     JSScript* s = rawScript();
     TraceNullableRoot(trc, &s, "ProfilingStackFrame script");
     spOrScript = s;
   }
 }
@@ -566,8 +570,10 @@ JS_FRIEND_API const ProfilingCategoryPai
 
   uint32_t categoryPairIndex = uint32_t(aCategoryPair);
   MOZ_RELEASE_ASSERT(categoryPairIndex <=
                      uint32_t(ProfilingCategoryPair::LAST));
   return sProfilingCategoryPairInfo[categoryPairIndex];
 }
 
 }  // namespace JS
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/ProfilingStack.cpp
+++ b/mozglue/baseprofiler/core/ProfilingStack.cpp
@@ -1,21 +1,25 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "js/ProfilingStack.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include "js/ProfilingStack.h"
 
-#include "mozilla/IntegerRange.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/UniquePtrExtensions.h"
+#  include "mozilla/IntegerRange.h"
+#  include "mozilla/UniquePtr.h"
+#  include "mozilla/UniquePtrExtensions.h"
 
-#include <algorithm>
+#  include <algorithm>
 
 using namespace js;
 
 ProfilingStack::~ProfilingStack() {
   // The label macros keep a reference to the ProfilingStack to avoid a TLS
   // access. If these are somehow not all cleared we will get a
   // use-after-free so better to crash now.
   MOZ_RELEASE_ASSERT(stackPointer == 0);
@@ -39,8 +43,10 @@ void ProfilingStack::ensureCapacitySlow(
     newFrames[i] = frames[i];
   }
 
   js::ProfilingStackFrame* oldFrames = frames;
   frames = newFrames;
   capacity = newCapacity;
   delete[] oldFrames;
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/RegisteredThread.cpp
+++ b/mozglue/baseprofiler/core/RegisteredThread.cpp
@@ -1,33 +1,37 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "RegisteredThread.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include "RegisteredThread.h"
 
 RegisteredThread::RegisteredThread(ThreadInfo* aInfo, nsIEventTarget* aThread,
                                    void* aStackTop)
     : mRacyRegisteredThread(aInfo->ThreadId()),
       mPlatformData(AllocPlatformData(aInfo->ThreadId())),
       mStackTop(aStackTop),
       mThreadInfo(aInfo),
       mThread(aThread),
       mContext(nullptr),
       mJSSampling(INACTIVE),
       mJSFlags(0) {
   MOZ_COUNT_CTOR(RegisteredThread);
 
   // We don't have to guess on mac
-#if defined(GP_OS_darwin)
+#  if defined(GP_OS_darwin)
   pthread_t self = pthread_self();
   mStackTop = pthread_get_stackaddr_np(self);
-#endif
+#  endif
 }
 
 RegisteredThread::~RegisteredThread() { MOZ_COUNT_DTOR(RegisteredThread); }
 
 size_t RegisteredThread::SizeOfIncludingThis(
     mozilla::MallocSizeOf aMallocSizeOf) const {
   size_t n = aMallocSizeOf(this);
 
@@ -36,8 +40,10 @@ size_t RegisteredThread::SizeOfIncluding
   // - mPlatformData
   // - mRacyRegisteredThread.mPendingMarkers
   //
   // The following members are not measured:
   // - mThreadInfo: because it is non-owning
 
   return n;
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/VTuneProfiler.cpp
+++ b/mozglue/baseprofiler/core/VTuneProfiler.cpp
@@ -1,22 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifdef XP_WIN
-#  undef UNICODE
-#  undef _UNICODE
-#endif
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
 
-#include "VTuneProfiler.h"
-#include "mozilla/Bootstrap.h"
-#include <memory>
+#  ifdef XP_WIN
+#    undef UNICODE
+#    undef _UNICODE
+#  endif
+
+#  include "VTuneProfiler.h"
+#  include "mozilla/Bootstrap.h"
+#  include <memory>
 
 using namespace std;
 
 VTuneProfiler* VTuneProfiler::mInstance = nullptr;
 
 void VTuneProfiler::Initialize() {
   // This is just a 'dirty trick' to find out if the ittnotify DLL was found.
   // If it wasn't this function always returns 0, otherwise it returns
@@ -74,9 +78,11 @@ void VTuneProfiler::RegisterThreadIntern
         __itt_thread_set_name("GPU Process");
         break;
       default:
         __itt_thread_set_name("Unknown Process");
     }
     return;
   }
   __itt_thread_set_name(aName);
-}
\ No newline at end of file
+}
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/platform.cpp
+++ b/mozglue/baseprofiler/core/platform.cpp
@@ -21,204 +21,207 @@
 //   register values.
 //
 // - A "backtrace" sample is the simplest kind. It is done in response to an
 //   API call (profiler_suspend_and_sample_thread()). It involves getting a
 //   stack trace via a ProfilerStackCollector; it does not write to a
 //   ProfileBuffer. The sampling is done from off-thread, and so uses
 //   SuspendAndSampleAndResumeThread() to get the register values.
 
-#include "platform.h"
-
 #include "BaseProfiler.h"
-#include "GeckoProfilerReporter.h"
-#include "PageInformation.h"
-#include "ProfiledThreadData.h"
-#include "ProfilerBacktrace.h"
-#include "ProfileBuffer.h"
-#include "ProfilerIOInterposeObserver.h"
-#include "BaseProfilerMarkerPayload.h"
-#include "ProfilerParent.h"
-#include "RegisteredThread.h"
-#include "BaseProfilerSharedLibraries.h"
-#include "ThreadInfo.h"
-#include "VTuneProfiler.h"
-
-#include "js/TraceLoggerAPI.h"
-#include "memory_hooks.h"
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/Atomics.h"
-#include "mozilla/AutoProfilerLabel.h"
-#include "mozilla/ExtensionPolicyService.h"
-#include "mozilla/extensions/WebExtensionPolicy.h"
-#include "mozilla/Printf.h"
-#include "mozilla/Services.h"
-#include "mozilla/StackWalk.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/SystemGroup.h"
-#include "mozilla/ThreadLocal.h"
-#include "mozilla/TimeStamp.h"
-#include "mozilla/Tuple.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/Vector.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsDirectoryServiceUtils.h"
-#include "nsIHttpProtocolHandler.h"
-#include "nsIObserverService.h"
-#include "nsIPropertyBag2.h"
-#include "nsIXULAppInfo.h"
-#include "nsIXULRuntime.h"
-#include "nsJSPrincipals.h"
-#include "nsMemoryReporterManager.h"
-#include "nsProfilerStartParams.h"
-#include "nsScriptSecurityManager.h"
-#include "nsThreadUtils.h"
-#include "nsXULAppAPI.h"
-#include "prdtoa.h"
-#include "prtime.h"
-
-#include <algorithm>
-#include <errno.h>
-#include <fstream>
-#include <ostream>
-#include <sstream>
-
-#ifdef MOZ_TASK_TRACER
-#  include "GeckoTaskTracer.h"
-#endif
-
-#if defined(GP_OS_android)
-#  include "FennecJNINatives.h"
-#  include "FennecJNIWrappers.h"
-#endif
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include "platform.h"
+
+#  include "GeckoProfilerReporter.h"
+#  include "PageInformation.h"
+#  include "ProfiledThreadData.h"
+#  include "ProfilerBacktrace.h"
+#  include "ProfileBuffer.h"
+#  include "ProfilerIOInterposeObserver.h"
+#  include "BaseProfilerMarkerPayload.h"
+#  include "ProfilerParent.h"
+#  include "RegisteredThread.h"
+#  include "BaseProfilerSharedLibraries.h"
+#  include "ThreadInfo.h"
+#  include "VTuneProfiler.h"
+
+#  include "js/TraceLoggerAPI.h"
+#  include "memory_hooks.h"
+#  include "mozilla/ArrayUtils.h"
+#  include "mozilla/Atomics.h"
+#  include "mozilla/AutoProfilerLabel.h"
+#  include "mozilla/ExtensionPolicyService.h"
+#  include "mozilla/extensions/WebExtensionPolicy.h"
+#  include "mozilla/Printf.h"
+#  include "mozilla/Services.h"
+#  include "mozilla/StackWalk.h"
+#  include "mozilla/StaticPtr.h"
+#  include "mozilla/SystemGroup.h"
+#  include "mozilla/ThreadLocal.h"
+#  include "mozilla/TimeStamp.h"
+#  include "mozilla/Tuple.h"
+#  include "mozilla/UniquePtr.h"
+#  include "mozilla/Vector.h"
+#  include "nsDirectoryServiceDefs.h"
+#  include "nsDirectoryServiceUtils.h"
+#  include "nsIHttpProtocolHandler.h"
+#  include "nsIObserverService.h"
+#  include "nsIPropertyBag2.h"
+#  include "nsIXULAppInfo.h"
+#  include "nsIXULRuntime.h"
+#  include "nsJSPrincipals.h"
+#  include "nsMemoryReporterManager.h"
+#  include "nsProfilerStartParams.h"
+#  include "nsScriptSecurityManager.h"
+#  include "nsThreadUtils.h"
+#  include "nsXULAppAPI.h"
+#  include "prdtoa.h"
+#  include "prtime.h"
+
+#  include <algorithm>
+#  include <errno.h>
+#  include <fstream>
+#  include <ostream>
+#  include <sstream>
+
+#  ifdef MOZ_TASK_TRACER
+#    include "GeckoTaskTracer.h"
+#  endif
+
+#  if defined(GP_OS_android)
+#    include "FennecJNINatives.h"
+#    include "FennecJNIWrappers.h"
+#  endif
 
 // Win32 builds always have frame pointers, so FramePointerStackWalk() always
 // works.
-#if defined(GP_PLAT_x86_windows)
-#  define HAVE_NATIVE_UNWIND
-#  define USE_FRAME_POINTER_STACK_WALK
-#endif
+#  if defined(GP_PLAT_x86_windows)
+#    define HAVE_NATIVE_UNWIND
+#    define USE_FRAME_POINTER_STACK_WALK
+#  endif
 
 // Win64 builds always omit frame pointers, so we use the slower
 // MozStackWalk(), which works in that case.
-#if defined(GP_PLAT_amd64_windows)
-#  define HAVE_NATIVE_UNWIND
-#  define USE_MOZ_STACK_WALK
-#endif
+#  if defined(GP_PLAT_amd64_windows)
+#    define HAVE_NATIVE_UNWIND
+#    define USE_MOZ_STACK_WALK
+#  endif
 
 // AArch64 Win64 doesn't seem to use frame pointers, so we use the slower
 // MozStackWalk().
-#if defined(GP_PLAT_arm64_windows)
-#  define HAVE_NATIVE_UNWIND
-#  define USE_MOZ_STACK_WALK
-#endif
+#  if defined(GP_PLAT_arm64_windows)
+#    define HAVE_NATIVE_UNWIND
+#    define USE_MOZ_STACK_WALK
+#  endif
 
 // Mac builds only have frame pointers when MOZ_PROFILING is specified, so
 // FramePointerStackWalk() only works in that case. We don't use MozStackWalk()
 // on Mac.
-#if defined(GP_OS_darwin) && defined(MOZ_PROFILING)
-#  define HAVE_NATIVE_UNWIND
-#  define USE_FRAME_POINTER_STACK_WALK
-#endif
+#  if defined(GP_OS_darwin) && defined(MOZ_PROFILING)
+#    define HAVE_NATIVE_UNWIND
+#    define USE_FRAME_POINTER_STACK_WALK
+#  endif
 
 // Android builds use the ARM Exception Handling ABI to unwind.
-#if defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
-#  define HAVE_NATIVE_UNWIND
-#  define USE_EHABI_STACKWALK
-#  include "EHABIStackWalk.h"
-#endif
+#  if defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
+#    define HAVE_NATIVE_UNWIND
+#    define USE_EHABI_STACKWALK
+#    include "EHABIStackWalk.h"
+#  endif
 
 // Linux builds use LUL, which uses DWARF info to unwind stacks.
-#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) ||     \
-    defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) || \
-    defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_arm64_linux) ||  \
-    defined(GP_PLAT_arm64_android)
-#  define HAVE_NATIVE_UNWIND
-#  define USE_LUL_STACKWALK
-#  include "lul/LulMain.h"
-#  include "lul/platform-linux-lul.h"
+#  if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) ||     \
+      defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) || \
+      defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_arm64_linux) ||  \
+      defined(GP_PLAT_arm64_android)
+#    define HAVE_NATIVE_UNWIND
+#    define USE_LUL_STACKWALK
+#    include "lul/LulMain.h"
+#    include "lul/platform-linux-lul.h"
 
 // On linux we use LUL for periodic samples and synchronous samples, but we use
 // FramePointerStackWalk for backtrace samples when MOZ_PROFILING is enabled.
 // (See the comment at the top of the file for a definition of
 // periodic/synchronous/backtrace.).
 //
 // FramePointerStackWalk can produce incomplete stacks when the current entry is
 // in a shared library without framepointers, however LUL can take a long time
 // to initialize, which is undesirable for consumers of
 // profiler_suspend_and_sample_thread like the Background Hang Reporter.
-#  if defined(MOZ_PROFILING)
-#    define USE_FRAME_POINTER_STACK_WALK
+#    if defined(MOZ_PROFILING)
+#      define USE_FRAME_POINTER_STACK_WALK
+#    endif
 #  endif
-#endif
 
 // We can only stackwalk without expensive initialization on platforms which
 // support FramePointerStackWalk or MozStackWalk. LUL Stackwalking requires
 // initializing LUL, and EHABIStackWalk requires initializing EHABI, both of
 // which can be expensive.
-#if defined(USE_FRAME_POINTER_STACK_WALK) || defined(USE_MOZ_STACK_WALK)
-#  define HAVE_FASTINIT_NATIVE_UNWIND
-#endif
-
-#ifdef MOZ_VALGRIND
-#  include <valgrind/memcheck.h>
-#else
-#  define VALGRIND_MAKE_MEM_DEFINED(_addr, _len) ((void)0)
-#endif
-
-#if defined(GP_OS_linux) || defined(GP_OS_android)
-#  include <ucontext.h>
-#endif
+#  if defined(USE_FRAME_POINTER_STACK_WALK) || defined(USE_MOZ_STACK_WALK)
+#    define HAVE_FASTINIT_NATIVE_UNWIND
+#  endif
+
+#  ifdef MOZ_VALGRIND
+#    include <valgrind/memcheck.h>
+#  else
+#    define VALGRIND_MAKE_MEM_DEFINED(_addr, _len) ((void)0)
+#  endif
+
+#  if defined(GP_OS_linux) || defined(GP_OS_android)
+#    include <ucontext.h>
+#  endif
 
 using namespace mozilla;
 using mozilla::profiler::detail::RacyFeatures;
 
 LazyLogModule gProfilerLog("prof");
 
-#if defined(GP_OS_android)
+#  if defined(GP_OS_android)
 class GeckoJavaSampler
     : public java::GeckoJavaSampler::Natives<GeckoJavaSampler> {
  private:
   GeckoJavaSampler();
 
  public:
   static double GetProfilerTime() {
     if (!profiler_is_active()) {
       return 0.0;
     }
     return profiler_time();
   };
 };
-#endif
+#  endif
 
 // Return all features that are available on this platform.
 static uint32_t AvailableFeatures() {
   uint32_t features = 0;
 
-#define ADD_FEATURE(n_, str_, Name_, desc_) \
-  ProfilerFeature::Set##Name_(features);
+#  define ADD_FEATURE(n_, str_, Name_, desc_) \
+    ProfilerFeature::Set##Name_(features);
 
   // Add all the possible features.
   PROFILER_FOR_EACH_FEATURE(ADD_FEATURE)
 
-#undef ADD_FEATURE
+#  undef ADD_FEATURE
 
   // Now remove features not supported on this platform/configuration.
-#if !defined(GP_OS_android)
+#  if !defined(GP_OS_android)
   ProfilerFeature::ClearJava(features);
-#endif
-#if !defined(HAVE_NATIVE_UNWIND)
+#  endif
+#  if !defined(HAVE_NATIVE_UNWIND)
   ProfilerFeature::ClearStackWalk(features);
-#endif
-#if !defined(MOZ_TASK_TRACER)
+#  endif
+#  if !defined(MOZ_TASK_TRACER)
   ProfilerFeature::ClearTaskTracer(features);
-#endif
-#if !(defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY))
+#  endif
+#  if !(defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY))
   ProfilerFeature::ClearMemory(features);
-#endif
+#  endif
   if (!JS::TraceLoggerSupported()) {
     ProfilerFeature::ClearJSTracer(features);
   }
 
   return features;
 }
 
 // Default features common to all contexts (even if not available).
@@ -239,27 +242,27 @@ static uint32_t StartupExtraDefaultFeatu
 class PSMutex : public StaticMutex {};
 
 typedef BaseAutoLock<PSMutex&> PSAutoLock;
 
 // Only functions that take a PSLockRef arg can access CorePS's and ActivePS's
 // fields.
 typedef const PSAutoLock& PSLockRef;
 
-#define PS_GET(type_, name_) \
-  static type_ name_(PSLockRef) { return sInstance->m##name_; }
-
-#define PS_GET_LOCKLESS(type_, name_) \
-  static type_ name_() { return sInstance->m##name_; }
-
-#define PS_GET_AND_SET(type_, name_)                  \
-  PS_GET(type_, name_)                                \
-  static void Set##name_(PSLockRef, type_ a##name_) { \
-    sInstance->m##name_ = a##name_;                   \
-  }
+#  define PS_GET(type_, name_) \
+    static type_ name_(PSLockRef) { return sInstance->m##name_; }
+
+#  define PS_GET_LOCKLESS(type_, name_) \
+    static type_ name_() { return sInstance->m##name_; }
+
+#  define PS_GET_AND_SET(type_, name_)                  \
+    PS_GET(type_, name_)                                \
+    static void Set##name_(PSLockRef, type_ a##name_) { \
+      sInstance->m##name_ = a##name_;                   \
+    }
 
 // All functions in this file can run on multiple threads unless they have an
 // NS_IsMainThread() assertion.
 
 // This class contains the profiler's core global state, i.e. that which is
 // valid even when the profiler is not active. Most profile operations can't do
 // anything useful when this class is not instantiated, so we release-assert
 // its non-nullness in all such operations.
@@ -276,20 +279,20 @@ typedef const PSAutoLock& PSLockRef;
 // - mProcessStartTime, because it's immutable;
 //
 // - each thread's RacyRegisteredThread object is accessible without locking via
 //   TLSRegisteredThread::RacyRegisteredThread().
 class CorePS {
  private:
   CorePS()
       : mProcessStartTime(TimeStamp::ProcessCreation())
-#ifdef USE_LUL_STACKWALK
+#  ifdef USE_LUL_STACKWALK
         ,
         mLul(nullptr)
-#endif
+#  endif
   {
   }
 
   ~CorePS() {}
 
  public:
   static void Create(PSLockRef aLock) { sInstance = new CorePS(); }
 
@@ -318,21 +321,21 @@ class CorePS {
     // Measurement of the following things may be added later if DMD finds it
     // is worthwhile:
     // - CorePS::mRegisteredThreads itself (its elements' children are
     // measured above)
     // - CorePS::mRegisteredPages itself (its elements' children are
     // measured above)
     // - CorePS::mInterposeObserver
 
-#if defined(USE_LUL_STACKWALK)
+#  if defined(USE_LUL_STACKWALK)
     if (sInstance->mLul) {
       aLulSize += sInstance->mLul->SizeOfIncludingThis(aMallocSizeOf);
     }
-#endif
+#  endif
   }
 
   // No PSLockRef is needed for this field because it's immutable.
   PS_GET_LOCKLESS(TimeStamp, ProcessStartTime)
 
   PS_GET(const Vector<UniquePtr<RegisteredThread>>&, RegisteredThreads)
 
   static void AppendRegisteredThread(
@@ -353,25 +356,25 @@ class CorePS {
   }
 
   PS_GET(Vector<RefPtr<PageInformation>>&, RegisteredPages)
 
   static void AppendRegisteredPage(PSLockRef,
                                    RefPtr<PageInformation>&& aRegisteredPage) {
     // Disabling this assertion for now until we fix the same page registration
     // issue. See Bug 1542918.
-#if 0
+#  if 0
     struct RegisteredPageComparator {
       PageInformation* aA;
       bool operator()(PageInformation* aB) const { return aA->Equals(aB); }
     };
     MOZ_RELEASE_ASSERT(std::none_of(
         sInstance->mRegisteredPages.begin(), sInstance->mRegisteredPages.end(),
         RegisteredPageComparator{aRegisteredPage.get()}));
-#endif
+#  endif
     MOZ_RELEASE_ASSERT(
         sInstance->mRegisteredPages.append(std::move(aRegisteredPage)));
   }
 
   static void RemoveRegisteredPages(PSLockRef,
                                     const nsID& aRegisteredDocShellId) {
     // Remove RegisteredPage from mRegisteredPages by given DocShell Id.
     sInstance->mRegisteredPages.eraseIf([&](const RefPtr<PageInformation>& rd) {
@@ -396,22 +399,22 @@ class CorePS {
     if (sInstance) {
       auto* counter = std::find(sInstance->mCounters.begin(),
                                 sInstance->mCounters.end(), aCounter);
       MOZ_RELEASE_ASSERT(counter != sInstance->mCounters.end());
       sInstance->mCounters.erase(counter);
     }
   }
 
-#ifdef USE_LUL_STACKWALK
+#  ifdef USE_LUL_STACKWALK
   static lul::LUL* Lul(PSLockRef) { return sInstance->mLul.get(); }
   static void SetLul(PSLockRef, UniquePtr<lul::LUL> aLul) {
     sInstance->mLul = std::move(aLul);
   }
-#endif
+#  endif
 
   PS_GET_AND_SET(const nsACString&, ProcessName)
 
  private:
   // The singleton instance
   static CorePS* sInstance;
 
   // The time that the process started.
@@ -423,20 +426,20 @@ class CorePS {
 
   // Info on all the registered pages.
   // DocShellId and DocShellHistoryId pairs in mRegisteredPages are unique.
   Vector<RefPtr<PageInformation>> mRegisteredPages;
 
   // Non-owning pointers to all active counters
   Vector<BaseProfilerCount*> mCounters;
 
-#ifdef USE_LUL_STACKWALK
+#  ifdef USE_LUL_STACKWALK
   // LUL's state. Null prior to the first activation, non-null thereafter.
   UniquePtr<lul::LUL> mLul;
-#endif
+#  endif
 
   // Process name, provided by child process initialization code.
   nsAutoCString mProcessName;
 };
 
 CorePS* CorePS::sInstance = nullptr;
 
 class SamplerThread;
@@ -456,21 +459,21 @@ struct LiveProfiledThreadData {
 // CorePS.
 //
 class ActivePS {
  private:
   static uint32_t AdjustFeatures(uint32_t aFeatures, uint32_t aFilterCount) {
     // Filter out any features unavailable in this platform/configuration.
     aFeatures &= AvailableFeatures();
 
-#if defined(GP_OS_android)
+#  if defined(GP_OS_android)
     if (!jni::IsFennec()) {
       aFeatures &= ~ProfilerFeature::Java;
     }
-#endif
+#  endif
 
     // Always enable ProfilerFeature::Threads if we have a filter, because
     // users sometimes ask to filter by a list of threads but forget to
     // explicitly specify ProfilerFeature::Threads.
     if (aFilterCount > 0) {
       aFeatures |= ProfilerFeature::Threads;
     }
 
@@ -489,31 +492,31 @@ class ActivePS {
         // The new sampler thread doesn't start sampling immediately because the
         // main loop within Run() is blocked until this function's caller
         // unlocks gPSMutex.
         ,
         mSamplerThread(NewSamplerThread(aLock, mGeneration, aInterval)),
         mInterposeObserver(ProfilerFeature::HasMainThreadIO(aFeatures)
                                ? new ProfilerIOInterposeObserver()
                                : nullptr)
-#undef HAS_FEATURE
+#  undef HAS_FEATURE
         ,
         mIsPaused(false)
-#if defined(GP_OS_linux)
+#  if defined(GP_OS_linux)
         ,
         mWasPaused(false)
-#endif
+#  endif
   {
     // Deep copy aFilters.
     MOZ_ALWAYS_TRUE(mFilters.resize(aFilterCount));
     for (uint32_t i = 0; i < aFilterCount; ++i) {
       mFilters[i] = aFilters[i];
     }
 
-#if !defined(RELEASE_OR_BETA)
+#  if !defined(RELEASE_OR_BETA)
     if (mInterposeObserver) {
       // We need to register the observer on the main thread, because we want
       // to observe IO that happens on the main thread.
       // IOInterposer needs to be initialized before calling
       // IOInterposer::Register or our observer will be silently dropped.
       if (NS_IsMainThread()) {
         IOInterposer::Init();
         IOInterposer::Register(IOInterposeObserver::OpAll, mInterposeObserver);
@@ -521,36 +524,36 @@ class ActivePS {
         RefPtr<ProfilerIOInterposeObserver> observer = mInterposeObserver;
         NS_DispatchToMainThread(
             NS_NewRunnableFunction("ActivePS::ActivePS", [=]() {
               IOInterposer::Init();
               IOInterposer::Register(IOInterposeObserver::OpAll, observer);
             }));
       }
     }
-#endif
+#  endif
   }
 
   ~ActivePS() {
-#if !defined(RELEASE_OR_BETA)
+#  if !defined(RELEASE_OR_BETA)
     if (mInterposeObserver) {
       // We need to unregister the observer on the main thread, because that's
       // where we've registered it.
       if (NS_IsMainThread()) {
         IOInterposer::Unregister(IOInterposeObserver::OpAll,
                                  mInterposeObserver);
       } else {
         RefPtr<ProfilerIOInterposeObserver> observer = mInterposeObserver;
         NS_DispatchToMainThread(
             NS_NewRunnableFunction("ActivePS::~ActivePS", [=]() {
               IOInterposer::Unregister(IOInterposeObserver::OpAll, observer);
             }));
       }
     }
-#endif
+#  endif
   }
 
   bool ThreadSelected(const char* aThreadName) {
     MOZ_RELEASE_ASSERT(sInstance);
 
     if (mFilters.empty()) {
       return true;
     }
@@ -643,24 +646,24 @@ class ActivePS {
   PS_GET(uint32_t, Capacity)
 
   PS_GET(Maybe<double>, Duration)
 
   PS_GET(double, Interval)
 
   PS_GET(uint32_t, Features)
 
-#define PS_GET_FEATURE(n_, str_, Name_, desc_)                \
-  static bool Feature##Name_(PSLockRef) {                     \
-    return ProfilerFeature::Has##Name_(sInstance->mFeatures); \
-  }
+#  define PS_GET_FEATURE(n_, str_, Name_, desc_)                \
+    static bool Feature##Name_(PSLockRef) {                     \
+      return ProfilerFeature::Has##Name_(sInstance->mFeatures); \
+    }
 
   PROFILER_FOR_EACH_FEATURE(PS_GET_FEATURE)
 
-#undef PS_GET_FEATURE
+#  undef PS_GET_FEATURE
 
   static uint32_t JSFlags(PSLockRef aLock) {
     uint32_t Flags = 0;
     Flags |= FeatureJS(aLock) ? uint32_t(JSSamplingFlags::StackSampling) : 0;
     Flags |= FeatureTrackOptimizations(aLock)
                  ? uint32_t(JSSamplingFlags::TrackOptimizations)
                  : 0;
     Flags |=
@@ -765,19 +768,19 @@ class ActivePS {
             &sInstance->mLiveProfiledThreads[i]);
         return;
       }
     }
   }
 
   PS_GET_AND_SET(bool, IsPaused)
 
-#if defined(GP_OS_linux)
+#  if defined(GP_OS_linux)
   PS_GET_AND_SET(bool, WasPaused)
-#endif
+#  endif
 
   static void DiscardExpiredDeadProfiledThreads(PSLockRef) {
     uint64_t bufferRangeStart = sInstance->mBuffer->mRangeStart;
     // Discard any dead threads that were unregistered before bufferRangeStart.
     sInstance->mDeadProfiledThreads.eraseIf(
         [bufferRangeStart](
             const UniquePtr<ProfiledThreadData>& aProfiledThreadData) {
           Maybe<uint64_t> bufferPosition =
@@ -815,17 +818,17 @@ class ActivePS {
           return *bufferPosition < bufferRangeStart;
         });
   }
 
   static void ClearUnregisteredPages(PSLockRef) {
     sInstance->mDeadProfiledPages.clear();
   }
 
-#if !defined(RELEASE_OR_BETA)
+#  if !defined(RELEASE_OR_BETA)
   static void UnregisterIOInterposer(PSLockRef) {
     if (!sInstance->mInterposeObserver) {
       return;
     }
 
     IOInterposer::Unregister(IOInterposeObserver::OpAll,
                              sInstance->mInterposeObserver);
 
@@ -844,17 +847,17 @@ class ActivePS {
   static void ResumeIOInterposer(PSLockRef) {
     if (!sInstance->mInterposeObserver) {
       return;
     }
 
     IOInterposer::Register(IOInterposeObserver::OpAll,
                            sInstance->mInterposeObserver);
   }
-#endif
+#  endif
 
   static void ClearExpiredExitProfiles(PSLockRef) {
     uint64_t bufferRangeStart = sInstance->mBuffer->mRangeStart;
     // Discard exit profiles that were gathered before our buffer RangeStart.
     sInstance->mExitProfiles.eraseIf(
         [bufferRangeStart](const ExitProfile& aExitProfile) {
           return aExitProfile.mBufferPositionAtGatherTime < bufferRangeStart;
         });
@@ -943,35 +946,35 @@ class ActivePS {
   SamplerThread* const mSamplerThread;
 
   // The interposer that records main thread I/O.
   RefPtr<ProfilerIOInterposeObserver> mInterposeObserver;
 
   // Is the profiler paused?
   bool mIsPaused;
 
-#if defined(GP_OS_linux)
+#  if defined(GP_OS_linux)
   // Used to record whether the profiler was paused just before forking. False
   // at all times except just before/after forking.
   bool mWasPaused;
-#endif
+#  endif
 
   struct ExitProfile {
     nsCString mJSON;
     uint64_t mBufferPositionAtGatherTime;
   };
   Vector<ExitProfile> mExitProfiles;
 };
 
 ActivePS* ActivePS::sInstance = nullptr;
 uint32_t ActivePS::sNextGeneration = 0;
 
-#undef PS_GET
-#undef PS_GET_LOCKLESS
-#undef PS_GET_AND_SET
+#  undef PS_GET
+#  undef PS_GET_LOCKLESS
+#  undef PS_GET_AND_SET
 
 // The mutex that guards accesses to CorePS and ActivePS.
 static PSMutex gPSMutex;
 
 Atomic<uint32_t, MemoryOrdering::Relaxed, recordreplay::Behavior::DontPreserve>
     RacyFeatures::sActiveAndFeatures(0);
 
 // Each live thread has a RegisteredThread, and we store a reference to it in
@@ -1046,35 +1049,35 @@ static const char* const kMainThreadName
 // BEGIN sampling/unwinding code
 
 // The registers used for stack unwinding and a few other sampling purposes.
 // The ctor does nothing; users are responsible for filling in the fields.
 class Registers {
  public:
   Registers() : mPC{nullptr}, mSP{nullptr}, mFP{nullptr}, mLR{nullptr} {}
 
-#if defined(HAVE_NATIVE_UNWIND)
+#  if defined(HAVE_NATIVE_UNWIND)
   // Fills in mPC, mSP, mFP, mLR, and mContext for a synchronous sample.
   void SyncPopulate();
-#endif
+#  endif
 
   void Clear() { memset(this, 0, sizeof(*this)); }
 
   // These fields are filled in by
   // SamplerThread::SuspendAndSampleAndResumeThread() for periodic and
   // backtrace samples, and by SyncPopulate() for synchronous samples.
   Address mPC;  // Instruction pointer.
   Address mSP;  // Stack pointer.
   Address mFP;  // Frame pointer.
   Address mLR;  // ARM link register.
-#if defined(GP_OS_linux) || defined(GP_OS_android)
+#  if defined(GP_OS_linux) || defined(GP_OS_android)
   // This contains all the registers, which means it duplicates the four fields
   // above. This is ok.
   ucontext_t* mContext;  // The context from the signal handler.
-#endif
+#  endif
 };
 
 // Setting MAX_NATIVE_FRAMES too high risks the unwinder wasting a lot of time
 // looping on corrupted stacks.
 static const size_t MAX_NATIVE_FRAMES = 1024;
 static const size_t MAX_JS_FRAMES = 1024;
 
 struct NativeStack {
@@ -1322,32 +1325,32 @@ static void MergeStacks(uint32_t aFeatur
   // profiler_suspend_and_sample_thread() from the background hang reporter -
   // in that case, aCollector.BufferRangeStart() will return Nothing().
   if (!aIsSynchronous && context && aCollector.BufferRangeStart()) {
     uint64_t bufferRangeStart = *aCollector.BufferRangeStart();
     JS::SetJSContextProfilerSampleBufferRangeStart(context, bufferRangeStart);
   }
 }
 
-#if defined(GP_OS_windows) && defined(USE_MOZ_STACK_WALK)
+#  if defined(GP_OS_windows) && defined(USE_MOZ_STACK_WALK)
 static HANDLE GetThreadHandle(PlatformData* aData);
-#endif
-
-#if defined(USE_FRAME_POINTER_STACK_WALK) || defined(USE_MOZ_STACK_WALK)
+#  endif
+
+#  if defined(USE_FRAME_POINTER_STACK_WALK) || defined(USE_MOZ_STACK_WALK)
 static void StackWalkCallback(uint32_t aFrameNumber, void* aPC, void* aSP,
                               void* aClosure) {
   NativeStack* nativeStack = static_cast<NativeStack*>(aClosure);
   MOZ_ASSERT(nativeStack->mCount < MAX_NATIVE_FRAMES);
   nativeStack->mSPs[nativeStack->mCount] = aSP;
   nativeStack->mPCs[nativeStack->mCount] = aPC;
   nativeStack->mCount++;
 }
-#endif
-
-#if defined(USE_FRAME_POINTER_STACK_WALK)
+#  endif
+
+#  if defined(USE_FRAME_POINTER_STACK_WALK)
 static void DoFramePointerBacktrace(PSLockRef aLock,
                                     const RegisteredThread& aRegisteredThread,
                                     const Registers& aRegs,
                                     NativeStack& aNativeStack) {
   // WARNING: this function runs within the profiler's "critical section".
   // WARNING: this function might be called while the profiler is inactive, and
   //          cannot rely on ActivePS.
 
@@ -1361,19 +1364,19 @@ static void DoFramePointerBacktrace(PSLo
 
   const void* stackEnd = aRegisteredThread.StackTop();
   if (aRegs.mFP >= aRegs.mSP && aRegs.mFP <= stackEnd) {
     FramePointerStackWalk(StackWalkCallback, /* skipFrames */ 0, maxFrames,
                           &aNativeStack, reinterpret_cast<void**>(aRegs.mFP),
                           const_cast<void*>(stackEnd));
   }
 }
-#endif
-
-#if defined(USE_MOZ_STACK_WALK)
+#  endif
+
+#  if defined(USE_MOZ_STACK_WALK)
 static void DoMozStackWalkBacktrace(PSLockRef aLock,
                                     const RegisteredThread& aRegisteredThread,
                                     const Registers& aRegs,
                                     NativeStack& aNativeStack) {
   // WARNING: this function runs within the profiler's "critical section".
   // WARNING: this function might be called while the profiler is inactive, and
   //          cannot rely on ActivePS.
 
@@ -1385,19 +1388,19 @@ static void DoMozStackWalkBacktrace(PSLo
 
   uint32_t maxFrames = uint32_t(MAX_NATIVE_FRAMES - aNativeStack.mCount);
 
   HANDLE thread = GetThreadHandle(aRegisteredThread.GetPlatformData());
   MOZ_ASSERT(thread);
   MozStackWalkThread(StackWalkCallback, /* skipFrames */ 0, maxFrames,
                      &aNativeStack, thread, /* context */ nullptr);
 }
-#endif
-
-#ifdef USE_EHABI_STACKWALK
+#  endif
+
+#  ifdef USE_EHABI_STACKWALK
 static void DoEHABIBacktrace(PSLockRef aLock,
                              const RegisteredThread& aRegisteredThread,
                              const Registers& aRegs,
                              NativeStack& aNativeStack) {
   // WARNING: this function runs within the profiler's "critical section".
   // WARNING: this function might be called while the profiler is inactive, and
   //          cannot rely on ActivePS.
 
@@ -1448,76 +1451,76 @@ static void DoEHABIBacktrace(PSLockRef a
   // Now unwind whatever's left (starting from either the last EnterJIT frame
   // or, if no EnterJIT was found, the original registers).
   aNativeStack.mCount +=
       EHABIStackWalk(*mcontext, const_cast<void*>(aRegisteredThread.StackTop()),
                      aNativeStack.mSPs + aNativeStack.mCount,
                      aNativeStack.mPCs + aNativeStack.mCount,
                      MAX_NATIVE_FRAMES - aNativeStack.mCount);
 }
-#endif
-
-#ifdef USE_LUL_STACKWALK
+#  endif
+
+#  ifdef USE_LUL_STACKWALK
 
 // See the comment at the callsite for why this function is necessary.
-#  if defined(MOZ_HAVE_ASAN_BLACKLIST)
+#    if defined(MOZ_HAVE_ASAN_BLACKLIST)
 MOZ_ASAN_BLACKLIST static void ASAN_memcpy(void* aDst, const void* aSrc,
                                            size_t aLen) {
   // The obvious thing to do here is call memcpy(). However, although
   // ASAN_memcpy() is not instrumented by ASAN, memcpy() still is, and the
   // false positive still manifests! So we must implement memcpy() ourselves
   // within this function.
   char* dst = static_cast<char*>(aDst);
   const char* src = static_cast<const char*>(aSrc);
 
   for (size_t i = 0; i < aLen; i++) {
     dst[i] = src[i];
   }
 }
-#  endif
+#    endif
 
 static void DoLULBacktrace(PSLockRef aLock,
                            const RegisteredThread& aRegisteredThread,
                            const Registers& aRegs, NativeStack& aNativeStack) {
   // WARNING: this function runs within the profiler's "critical section".
   // WARNING: this function might be called while the profiler is inactive, and
   //          cannot rely on ActivePS.
 
   const mcontext_t* mc = &aRegs.mContext->uc_mcontext;
 
   lul::UnwindRegs startRegs;
   memset(&startRegs, 0, sizeof(startRegs));
 
-#  if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android)
+#    if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android)
   startRegs.xip = lul::TaggedUWord(mc->gregs[REG_RIP]);
   startRegs.xsp = lul::TaggedUWord(mc->gregs[REG_RSP]);
   startRegs.xbp = lul::TaggedUWord(mc->gregs[REG_RBP]);
-#  elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
+#    elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
   startRegs.r15 = lul::TaggedUWord(mc->arm_pc);
   startRegs.r14 = lul::TaggedUWord(mc->arm_lr);
   startRegs.r13 = lul::TaggedUWord(mc->arm_sp);
   startRegs.r12 = lul::TaggedUWord(mc->arm_ip);
   startRegs.r11 = lul::TaggedUWord(mc->arm_fp);
   startRegs.r7 = lul::TaggedUWord(mc->arm_r7);
-#  elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android)
+#    elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android)
   startRegs.pc = lul::TaggedUWord(mc->pc);
   startRegs.x29 = lul::TaggedUWord(mc->regs[29]);
   startRegs.x30 = lul::TaggedUWord(mc->regs[30]);
   startRegs.sp = lul::TaggedUWord(mc->sp);
-#  elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
+#    elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
   startRegs.xip = lul::TaggedUWord(mc->gregs[REG_EIP]);
   startRegs.xsp = lul::TaggedUWord(mc->gregs[REG_ESP]);
   startRegs.xbp = lul::TaggedUWord(mc->gregs[REG_EBP]);
-#  elif defined(GP_PLAT_mips64_linux)
+#    elif defined(GP_PLAT_mips64_linux)
   startRegs.pc = lul::TaggedUWord(mc->pc);
   startRegs.sp = lul::TaggedUWord(mc->gregs[29]);
   startRegs.fp = lul::TaggedUWord(mc->gregs[30]);
-#  else
-#    error "Unknown plat"
-#  endif
+#    else
+#      error "Unknown plat"
+#    endif
 
   // Copy up to N_STACK_BYTES from rsp-REDZONE upwards, but not going past the
   // stack's registered top point.  Do some basic sanity checks too.  This
   // assumes that the TaggedUWord holding the stack pointer value is valid, but
   // it should be, since it was constructed that way in the code just above.
 
   // We could construct |stackImg| so that LUL reads directly from the stack in
   // question, rather than from a copy of it.  That would reduce overhead and
@@ -1543,34 +1546,34 @@ static void DoLULBacktrace(PSLockRef aLo
   // allocation risks deadlock.  Allocating it as a global variable is not
   // thread safe, which would be a problem if we ever allow multiple sampler
   // threads.  Hence allocating it on the stack seems to be the least-worst
   // option.
 
   lul::StackImage stackImg;
 
   {
-#  if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android)
+#    if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android)
     uintptr_t rEDZONE_SIZE = 128;
     uintptr_t start = startRegs.xsp.Value() - rEDZONE_SIZE;
-#  elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
+#    elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
     uintptr_t rEDZONE_SIZE = 0;
     uintptr_t start = startRegs.r13.Value() - rEDZONE_SIZE;
-#  elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android)
+#    elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android)
     uintptr_t rEDZONE_SIZE = 0;
     uintptr_t start = startRegs.sp.Value() - rEDZONE_SIZE;
-#  elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
+#    elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
     uintptr_t rEDZONE_SIZE = 0;
     uintptr_t start = startRegs.xsp.Value() - rEDZONE_SIZE;
-#  elif defined(GP_PLAT_mips64_linux)
+#    elif defined(GP_PLAT_mips64_linux)
     uintptr_t rEDZONE_SIZE = 0;
     uintptr_t start = startRegs.sp.Value() - rEDZONE_SIZE;
-#  else
-#    error "Unknown plat"
-#  endif
+#    else
+#      error "Unknown plat"
+#    endif
     uintptr_t end = reinterpret_cast<uintptr_t>(aRegisteredThread.StackTop());
     uintptr_t ws = sizeof(void*);
     start &= ~(ws - 1);
     end &= ~(ws - 1);
     uintptr_t nToCopy = 0;
     if (start < end) {
       nToCopy = end - start;
       if (nToCopy > lul::N_STACK_BYTES) nToCopy = lul::N_STACK_BYTES;
@@ -1583,21 +1586,21 @@ static void DoLULBacktrace(PSLockRef aLo
       //
       //   ERROR: AddressSanitizer: stack-buffer-underflow ...
       //   ...
       //   HINT: this may be a false positive if your program uses some custom
       //   stack unwind mechanism or swapcontext
       //
       // This code is very much a custom stack unwind mechanism! So we use an
       // alternative memcpy() implementation that is ignored by ASAN.
-#  if defined(MOZ_HAVE_ASAN_BLACKLIST)
+#    if defined(MOZ_HAVE_ASAN_BLACKLIST)
       ASAN_memcpy(&stackImg.mContents[0], (void*)start, nToCopy);
-#  else
+#    else
       memcpy(&stackImg.mContents[0], (void*)start, nToCopy);
-#  endif
+#    endif
       (void)VALGRIND_MAKE_MEM_DEFINED(&stackImg.mContents[0], nToCopy);
     }
   }
 
   size_t framePointerFramesAcquired = 0;
   lul::LUL* lul = CorePS::Lul(aLock);
   lul->Unwind(reinterpret_cast<uintptr_t*>(aNativeStack.mPCs),
               reinterpret_cast<uintptr_t*>(aNativeStack.mSPs),
@@ -1606,41 +1609,41 @@ static void DoLULBacktrace(PSLockRef aLo
 
   // Update stats in the LUL stats object.  Unfortunately this requires
   // three global memory operations.
   lul->mStats.mContext += 1;
   lul->mStats.mCFI += aNativeStack.mCount - 1 - framePointerFramesAcquired;
   lul->mStats.mFP += framePointerFramesAcquired;
 }
 
-#endif
-
-#ifdef HAVE_NATIVE_UNWIND
+#  endif
+
+#  ifdef HAVE_NATIVE_UNWIND
 static void DoNativeBacktrace(PSLockRef aLock,
                               const RegisteredThread& aRegisteredThread,
                               const Registers& aRegs,
                               NativeStack& aNativeStack) {
   // This method determines which stackwalker is used for periodic and
   // synchronous samples. (Backtrace samples are treated differently, see
   // profiler_suspend_and_sample_thread() for details). The only part of the
   // ordering that matters is that LUL must precede FRAME_POINTER, because on
   // Linux they can both be present.
-#  if defined(USE_LUL_STACKWALK)
+#    if defined(USE_LUL_STACKWALK)
   DoLULBacktrace(aLock, aRegisteredThread, aRegs, aNativeStack);
-#  elif defined(USE_EHABI_STACKWALK)
+#    elif defined(USE_EHABI_STACKWALK)
   DoEHABIBacktrace(aLock, aRegisteredThread, aRegs, aNativeStack);
-#  elif defined(USE_FRAME_POINTER_STACK_WALK)
+#    elif defined(USE_FRAME_POINTER_STACK_WALK)
   DoFramePointerBacktrace(aLock, aRegisteredThread, aRegs, aNativeStack);
-#  elif defined(USE_MOZ_STACK_WALK)
+#    elif defined(USE_MOZ_STACK_WALK)
   DoMozStackWalkBacktrace(aLock, aRegisteredThread, aRegs, aNativeStack);
-#  else
-#    error "Invalid configuration"
+#    else
+#      error "Invalid configuration"
+#    endif
+}
 #  endif
-}
-#endif
 
 // Writes some components shared by periodic and synchronous profiles to
 // ActivePS's ProfileBuffer. (This should only be called from DoSyncSample()
 // and DoPeriodicSample().)
 //
 // The grammar for entry sequences is in a comment above
 // ProfileBuffer::StreamSamplesToJSON.
 static inline void DoSharedSample(PSLockRef aLock, bool aIsSynchronous,
@@ -1659,24 +1662,24 @@ static inline void DoSharedSample(PSLock
   }
 
   TimeDuration delta = aNow - CorePS::ProcessStartTime();
   aBuffer.AddEntry(ProfileBufferEntry::Time(delta.ToMilliseconds()));
 
   ProfileBufferCollector collector(aBuffer, ActivePS::Features(aLock),
                                    samplePos);
   NativeStack nativeStack;
-#if defined(HAVE_NATIVE_UNWIND)
+#  if defined(HAVE_NATIVE_UNWIND)
   if (ActivePS::FeatureStackWalk(aLock)) {
     DoNativeBacktrace(aLock, aRegisteredThread, aRegs, nativeStack);
 
     MergeStacks(ActivePS::Features(aLock), aIsSynchronous, aRegisteredThread,
                 aRegs, nativeStack, collector);
   } else
-#endif
+#  endif
   {
     MergeStacks(ActivePS::Features(aLock), aIsSynchronous, aRegisteredThread,
                 aRegs, nativeStack, collector);
 
     // We can't walk the whole native stack, but we can record the top frame.
     if (ActivePS::FeatureLeaf(aLock)) {
       aBuffer.AddEntry(ProfileBufferEntry::NativeLeafAddr((void*)aRegs.mPC));
     }
@@ -1755,35 +1758,35 @@ static void AddSharedLibraryInfoToStream
 void AppendSharedLibraries(JSONWriter& aWriter) {
   SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
   info.SortByAddress();
   for (size_t i = 0; i < info.GetSize(); i++) {
     AddSharedLibraryInfoToStream(aWriter, info.GetEntry(i));
   }
 }
 
-#ifdef MOZ_TASK_TRACER
+#  ifdef MOZ_TASK_TRACER
 static void StreamNameAndThreadId(JSONWriter& aWriter, const char* aName,
                                   int aThreadId) {
   aWriter.StartObjectElement();
   {
     if (XRE_GetProcessType() == GeckoProcessType_Plugin) {
       // TODO Add the proper plugin name
       aWriter.StringProperty("name", "Plugin");
     } else {
       aWriter.StringProperty("name", aName);
     }
     aWriter.IntProperty("tid", aThreadId);
   }
   aWriter.EndObject();
 }
-#endif
+#  endif
 
 static void StreamTaskTracer(PSLockRef aLock, SpliceableJSONWriter& aWriter) {
-#ifdef MOZ_TASK_TRACER
+#  ifdef MOZ_TASK_TRACER
   MOZ_RELEASE_ASSERT(CorePS::Exists() && ActivePS::Exists(aLock));
 
   aWriter.StartArrayProperty("data");
   {
     UniquePtr<Vector<nsCString>> data =
         tasktracer::GetLoggedData(CorePS::ProcessStartTime());
     for (const nsCString& dataString : *data) {
       aWriter.StringElement(dataString.get());
@@ -1800,35 +1803,35 @@ static void StreamTaskTracer(PSLockRef a
       RefPtr<ThreadInfo> info = thread.second()->Info();
       StreamNameAndThreadId(aWriter, info->Name(), info->ThreadId());
     }
   }
   aWriter.EndArray();
 
   aWriter.DoubleProperty("start",
                          static_cast<double>(tasktracer::GetStartTime()));
-#endif
+#  endif
 }
 
 static void StreamCategories(SpliceableJSONWriter& aWriter) {
   // Same order as ProfilingCategory.
 
-#define CATEGORY_JSON_BEGIN_CATEGORY(name, labelAsString, color) \
-  aWriter.Start();                                               \
-  aWriter.StringProperty("name", labelAsString);                 \
-  aWriter.StringProperty("color", color);
-#define CATEGORY_JSON_SUBCATEGORY(category, name, labelAsString)
-#define CATEGORY_JSON_END_CATEGORY aWriter.EndObject();
+#  define CATEGORY_JSON_BEGIN_CATEGORY(name, labelAsString, color) \
+    aWriter.Start();                                               \
+    aWriter.StringProperty("name", labelAsString);                 \
+    aWriter.StringProperty("color", color);
+#  define CATEGORY_JSON_SUBCATEGORY(category, name, labelAsString)
+#  define CATEGORY_JSON_END_CATEGORY aWriter.EndObject();
 
   PROFILING_CATEGORY_LIST(CATEGORY_JSON_BEGIN_CATEGORY,
                           CATEGORY_JSON_SUBCATEGORY, CATEGORY_JSON_END_CATEGORY)
 
-#undef CATEGORY_JSON_BEGIN_CATEGORY
-#undef CATEGORY_JSON_SUBCATEGORY
-#undef CATEGORY_JSON_END_CATEGORY
+#  undef CATEGORY_JSON_BEGIN_CATEGORY
+#  undef CATEGORY_JSON_SUBCATEGORY
+#  undef CATEGORY_JSON_END_CATEGORY
 }
 
 static void StreamMetaJSCustomObject(PSLockRef aLock,
                                      SpliceableJSONWriter& aWriter,
                                      bool aIsShuttingDown) {
   MOZ_RELEASE_ASSERT(CorePS::Exists() && ActivePS::Exists(aLock));
 
   aWriter.IntProperty("version", 15);
@@ -1862,21 +1865,21 @@ static void StreamMetaJSCustomObject(PSL
     // process profile's "meta" object already has the rest of the properties,
     // and the parent process profile is dumped on that process's main thread.
     return;
   }
 
   aWriter.DoubleProperty("interval", ActivePS::Interval(aLock));
   aWriter.IntProperty("stackwalk", ActivePS::FeatureStackWalk(aLock));
 
-#ifdef DEBUG
+#  ifdef DEBUG
   aWriter.IntProperty("debug", 1);
-#else
+#  else
   aWriter.IntProperty("debug", 0);
-#endif
+#  endif
 
   aWriter.IntProperty("gcpoison", JS::IsGCPoisoning() ? 1 : 0);
 
   bool asyncStacks = Preferences::GetBool("javascript.options.asyncstack");
   aWriter.IntProperty("asyncstack", asyncStacks);
 
   aWriter.IntProperty("processType", XRE_GetProcessType());
 
@@ -1988,17 +1991,17 @@ static void StreamMetaJSCustomObject(PSL
 static void StreamPages(PSLockRef aLock, SpliceableJSONWriter& aWriter) {
   MOZ_RELEASE_ASSERT(CorePS::Exists());
   ActivePS::DiscardExpiredPages(aLock);
   for (const auto& page : ActivePS::ProfiledPages(aLock)) {
     page->StreamJSON(aWriter);
   }
 }
 
-#if defined(GP_OS_android)
+#  if defined(GP_OS_android)
 static UniquePtr<ProfileBuffer> CollectJavaThreadProfileData() {
   // locked_profiler_start uses sample count is 1000 for Java thread.
   // This entry size is enough now, but we might have to estimate it
   // if we can customize it
   auto buffer = MakeUnique<ProfileBuffer>(1000 * 1000);
 
   int sampleId = 0;
   while (true) {
@@ -2035,17 +2038,17 @@ static UniquePtr<ProfileBuffer> CollectJ
 
       buffer->CollectCodeLocation("", frameNameString.get(), 0, Nothing(),
                                   Nothing(), categoryPair);
     }
     sampleId++;
   }
   return buffer;
 }
-#endif
+#  endif
 
 static void locked_profiler_stream_json_for_this_process(
     PSLockRef aLock, SpliceableJSONWriter& aWriter, double aSinceTime,
     bool aIsShuttingDown) {
   LOG("locked_profiler_stream_json_for_this_process");
 
   MOZ_RELEASE_ASSERT(CorePS::Exists() && ActivePS::Exists(aLock));
 
@@ -2092,17 +2095,17 @@ static void locked_profiler_stream_json_
           registeredThread ? registeredThread->GetJSContext() : nullptr;
       ProfiledThreadData* profiledThreadData = thread.second();
       profiledThreadData->StreamJSON(buffer, cx, aWriter,
                                      CorePS::ProcessName(aLock),
                                      CorePS::ProcessStartTime(), aSinceTime,
                                      ActivePS::FeatureJSTracer(aLock));
     }
 
-#if defined(GP_OS_android)
+#  if defined(GP_OS_android)
     if (ActivePS::FeatureJava(aLock)) {
       java::GeckoJavaSampler::Pause();
 
       UniquePtr<ProfileBuffer> javaBuffer = CollectJavaThreadProfileData();
 
       // Thread id of java Main thread is 0, if we support profiling of other
       // java thread, we have to get thread id and name via JNI.
       RefPtr<ThreadInfo> threadInfo = new ThreadInfo(
@@ -2111,17 +2114,17 @@ static void locked_profiler_stream_json_
           threadInfo, nullptr, ActivePS::FeatureResponsiveness(aLock));
       profiledThreadData.StreamJSON(*javaBuffer.get(), nullptr, aWriter,
                                     CorePS::ProcessName(aLock),
                                     CorePS::ProcessStartTime(), aSinceTime,
                                     ActivePS::FeatureJSTracer(aLock));
 
       java::GeckoJavaSampler::Unpause();
     }
-#endif
+#  endif
   }
   aWriter.EndArray();
 
   if (ActivePS::FeatureJSTracer(aLock)) {
     aWriter.StartArrayProperty("jsTracerDictionary");
     {
       JS::AutoTraceLoggerLockGuard lockGuard;
       // Collect Event Dictionary
@@ -2156,25 +2159,25 @@ bool profiler_stream_json_for_this_proce
   MOZ_RELEASE_ASSERT(CorePS::Exists());
 
   PSAutoLock lock(gPSMutex);
 
   if (!ActivePS::Exists(lock)) {
     return false;
   }
 
-#if !defined(RELEASE_OR_BETA)
+#  if !defined(RELEASE_OR_BETA)
   ActivePS::PauseIOInterposer(lock);
-#endif
+#  endif
 
   locked_profiler_stream_json_for_this_process(lock, aWriter, aSinceTime,
                                                aIsShuttingDown);
-#if !defined(RELEASE_OR_BETA)
+#  if !defined(RELEASE_OR_BETA)
   ActivePS::ResumeIOInterposer(lock);
-#endif
+#  endif
 
   return true;
 }
 
 // END saving/streaming code
 ////////////////////////////////////////////////////////////////////////
 
 static char FeatureCategory(uint32_t aFeature) {
@@ -2250,23 +2253,24 @@ static void PrintUsageThenExit(int aExit
       "\n"
       "    Features: (x=unavailable, D/d=default/unavailable,\n"
       "               S/s=MOZ_PROFILER_STARTUP extra default/unavailable)\n",
       unsigned(PROFILER_DEFAULT_ENTRIES),
       unsigned(PROFILER_DEFAULT_STARTUP_ENTRIES), sizeof(ProfileBufferEntry),
       sizeof(ProfileBufferEntry) * PROFILER_DEFAULT_ENTRIES,
       sizeof(ProfileBufferEntry) * PROFILER_DEFAULT_STARTUP_ENTRIES);
 
-#define PRINT_FEATURE(n_, str_, Name_, desc_)                                  \
-  printf("    %c %5u: \"%s\" (%s)\n", FeatureCategory(ProfilerFeature::Name_), \
-         ProfilerFeature::Name_, str_, desc_);
+#  define PRINT_FEATURE(n_, str_, Name_, desc_)                             \
+    printf("    %c %5u: \"%s\" (%s)\n",                                     \
+           FeatureCategory(ProfilerFeature::Name_), ProfilerFeature::Name_, \
+           str_, desc_);
 
   PROFILER_FOR_EACH_FEATURE(PRINT_FEATURE)
 
-#undef PRINT_FEATURE
+#  undef PRINT_FEATURE
 
   printf(
       "    -        \"default\" (All above D+S defaults)\n"
       "\n"
       "  MOZ_PROFILER_STARTUP_FILTERS=<Filters>\n"
       "  If MOZ_PROFILER_STARTUP is set, specifies the thread filters, as a\n"
       "  comma-separated list of strings. A given thread will be sampled if\n"
       "  any of the filters is a case-insensitive substring of the thread\n"
@@ -2280,32 +2284,32 @@ static void PrintUsageThenExit(int aExit
       "  *Note* This will add a significant pause when gathering data, and\n"
       "  is intended mainly for local development.\n"
       "\n"
       "  MOZ_PROFILER_LUL_TEST\n"
       "  If set to any value, runs LUL unit tests at startup.\n"
       "\n"
       "  This platform %s native unwinding.\n"
       "\n",
-#if defined(HAVE_NATIVE_UNWIND)
+#  if defined(HAVE_NATIVE_UNWIND)
       "supports"
-#else
+#  else
       "does not support"
-#endif
+#  endif
   );
 
   exit(aExitCode);
 }
 
 ////////////////////////////////////////////////////////////////////////
 // BEGIN Sampler
 
-#if defined(GP_OS_linux) || defined(GP_OS_android)
+#  if defined(GP_OS_linux) || defined(GP_OS_android)
 struct SigHandlerCoordinator;
-#endif
+#  endif
 
 // Sampler performs setup and teardown of the state required to sample with the
 // profiler. Sampler may exist when ActivePS is not present.
 //
 // SuspendAndSampleAndResumeThread must only be called from a single thread,
 // and must not sample the thread it is being called from. A separate Sampler
 // instance must be used for each thread which wants to capture samples.
 
@@ -2330,34 +2334,34 @@ class Sampler {
   //
   // Func must be a function-like object of type `void()`.
   template <typename Func>
   void SuspendAndSampleAndResumeThread(
       PSLockRef aLock, const RegisteredThread& aRegisteredThread,
       const Func& aProcessRegs);
 
  private:
-#if defined(GP_OS_linux) || defined(GP_OS_android)
+#  if defined(GP_OS_linux) || defined(GP_OS_android)
   // Used to restore the SIGPROF handler when ours is removed.
   struct sigaction mOldSigprofHandler;
 
   // This process' ID. Needed as an argument for tgkill in
   // SuspendAndSampleAndResumeThread.
   int mMyPid;
 
   // The sampler thread's ID.  Used to assert that it is not sampling itself,
   // which would lead to deadlock.
   int mSamplerTid;
 
  public:
   // This is the one-and-only variable used to communicate between the sampler
   // thread and the samplee thread's signal handler. It's static because the
   // samplee thread's signal handler is static.
   static struct SigHandlerCoordinator* sSigHandlerCoordinator;
-#endif
+#  endif
 };
 
 // END Sampler
 ////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////
 // BEGIN SamplerThread
 
@@ -2385,21 +2389,21 @@ class SamplerThread : public Sampler {
 
   // The activity generation, for detecting when the sampler thread must stop.
   const uint32_t mActivityGeneration;
 
   // The interval between samples, measured in microseconds.
   const int mIntervalMicroseconds;
 
   // The OS-specific handle for the sampler thread.
-#if defined(GP_OS_windows)
+#  if defined(GP_OS_windows)
   HANDLE mThread;
-#elif defined(GP_OS_darwin) || defined(GP_OS_linux) || defined(GP_OS_android)
+#  elif defined(GP_OS_darwin) || defined(GP_OS_linux) || defined(GP_OS_android)
   pthread_t mThread;
-#endif
+#  endif
 
   SamplerThread(const SamplerThread&) = delete;
   void operator=(const SamplerThread&) = delete;
 };
 
 // This function is required because we need to create a SamplerThread within
 // ActivePS's constructor, but SamplerThread is defined after ActivePS. It
 // could probably be removed by moving some code around.
@@ -2447,19 +2451,19 @@ void SamplerThread::Run() {
         TimeDuration delta = sampleStart - CorePS::ProcessStartTime();
         ProfileBuffer& buffer = ActivePS::Buffer(lock);
 
         // Report memory use
         int64_t rssMemory = 0;
         int64_t ussMemory = 0;
         if (ActivePS::FeatureMemory(lock)) {
           rssMemory = nsMemoryReporterManager::ResidentFast();
-#if defined(GP_OS_linux) || defined(GP_OS_android)
+#  if defined(GP_OS_linux) || defined(GP_OS_android)
           ussMemory = nsMemoryReporterManager::ResidentUnique();
-#endif
+#  endif
           if (rssMemory != 0) {
             buffer.AddEntry(ProfileBufferEntry::ResidentMemory(rssMemory));
             if (ussMemory != 0) {
               buffer.AddEntry(ProfileBufferEntry::UnsharedMemory(ussMemory));
             }
           }
           buffer.AddEntry(ProfileBufferEntry::Time(delta.ToMilliseconds()));
         }
@@ -2519,24 +2523,24 @@ void SamplerThread::Run() {
                 // only report these once per sample-time (if 0 we don't put
                 // them in the buffer, so for the rest of the threads we won't
                 // insert them)
                 rssMemory = 0;
                 ussMemory = 0;
               });
         }
 
-#if defined(USE_LUL_STACKWALK)
+#  if defined(USE_LUL_STACKWALK)
         // The LUL unwind object accumulates frame statistics. Periodically we
         // should poke it to give it a chance to print those statistics.  This
         // involves doing I/O (fprintf, __android_log_print, etc.) and so
         // can't safely be done from the critical section inside
         // SuspendAndSampleAndResumeThread, which is why it is done here.
         CorePS::Lul(lock)->MaybeShowStats();
-#endif
+#  endif
         TimeStamp threadsSampled = TimeStamp::Now();
 
         buffer.AddEntry(
             ProfileBufferEntry::ProfilerOverheadTime(delta.ToMilliseconds()));
         buffer.AddEntry(ProfileBufferEntry::ProfilerOverheadDuration(
             (lockAcquired - sampleStart).ToMilliseconds()));
         buffer.AddEntry(ProfileBufferEntry::ProfilerOverheadDuration(
             (expiredMarkersCleaned - lockAcquired).ToMilliseconds()));
@@ -2572,25 +2576,25 @@ void SamplerThread::Run() {
     lastSleepOvershoot =
         sampleStart - (beforeSleep + TimeDuration::FromMicroseconds(sleepTime));
   }
 }
 
 // We #include these files directly because it means those files can use
 // declarations from this file trivially.  These provide target-specific
 // implementations of all SamplerThread methods except Run().
-#if defined(GP_OS_windows)
-#  include "platform-win32.cpp"
-#elif defined(GP_OS_darwin)
-#  include "platform-macos.cpp"
-#elif defined(GP_OS_linux) || defined(GP_OS_android)
-#  include "platform-linux-android.cpp"
-#else
-#  error "bad platform"
-#endif
+#  if defined(GP_OS_windows)
+#    include "platform-win32.cpp"
+#  elif defined(GP_OS_darwin)
+#    include "platform-macos.cpp"
+#  elif defined(GP_OS_linux) || defined(GP_OS_android)
+#    include "platform-linux-android.cpp"
+#  else
+#    error "bad platform"
+#  endif
 
 UniquePlatformData AllocPlatformData(int aThreadId) {
   return UniquePlatformData(new PlatformData(aThreadId));
 }
 
 void PlatformDataDestructor::operator()(PlatformData* aData) { delete aData; }
 
 // END SamplerThread
@@ -2621,42 +2625,42 @@ GeckoProfilerReporter::CollectReports(ns
     }
   }
 
   MOZ_COLLECT_REPORT(
       "explicit/profiler/profiler-state", KIND_HEAP, UNITS_BYTES, profSize,
       "Memory used by the Gecko Profiler's global state (excluding memory used "
       "by LUL).");
 
-#if defined(USE_LUL_STACKWALK)
+#  if defined(USE_LUL_STACKWALK)
   MOZ_COLLECT_REPORT(
       "explicit/profiler/lul", KIND_HEAP, UNITS_BYTES, lulSize,
       "Memory used by LUL, a stack unwinder used by the Gecko Profiler.");
-#endif
+#  endif
 
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(GeckoProfilerReporter, nsIMemoryReporter)
 
 static uint32_t ParseFeature(const char* aFeature, bool aIsStartup) {
   if (strcmp(aFeature, "default") == 0) {
     return (aIsStartup ? (DefaultFeatures() | StartupExtraDefaultFeatures())
                        : DefaultFeatures()) &
            AvailableFeatures();
   }
 
-#define PARSE_FEATURE_BIT(n_, str_, Name_, desc_) \
-  if (strcmp(aFeature, str_) == 0) {              \
-    return ProfilerFeature::Name_;                \
-  }
+#  define PARSE_FEATURE_BIT(n_, str_, Name_, desc_) \
+    if (strcmp(aFeature, str_) == 0) {              \
+      return ProfilerFeature::Name_;                \
+    }
 
   PROFILER_FOR_EACH_FEATURE(PARSE_FEATURE_BIT)
 
-#undef PARSE_FEATURE_BIT
+#  undef PARSE_FEATURE_BIT
 
   printf("\nUnrecognized feature \"%s\".\n\n", aFeature);
   PrintUsageThenExit(1);
   return 0;
 }
 
 uint32_t ParseFeaturesFromStringArray(const char** aFeatures,
                                       uint32_t aFeatureCount,
@@ -2847,25 +2851,25 @@ void profiler_init(void* aStackTop) {
     // indicates that the profiler has initialized successfully.
     CorePS::Create(lock);
 
     locked_register_thread(lock, kMainThreadName, aStackTop);
 
     // Platform-specific initialization.
     PlatformInit(lock);
 
-#ifdef MOZ_TASK_TRACER
+#  ifdef MOZ_TASK_TRACER
     tasktracer::InitTaskTracer();
-#endif
-
-#if defined(GP_OS_android)
+#  endif
+
+#  if defined(GP_OS_android)
     if (jni::IsFennec()) {
       GeckoJavaSampler::Init();
     }
-#endif
+#  endif
 
     // Setup support for pushing/popping labels in mozglue.
     RegisterProfilerLabelEnterExit(MozGlueLabelEnter, MozGlueLabelExit);
 
     // (Linux-only) We could create CorePS::mLul and read unwind info into it
     // at this point. That would match the lifetime implied by destruction of
     // it in profiler_shutdown() just below. However, that gives a big delay on
     // startup, even if no profiling is actually to be done. So, instead, it is
@@ -2962,23 +2966,23 @@ void profiler_init(void* aStackTop) {
       filters = SplitAtCommas(startupFilters, filterStorage);
       LOG("- MOZ_PROFILER_STARTUP_FILTERS = %s", startupFilters);
     }
 
     locked_profiler_start(lock, capacity, interval, features, filters.begin(),
                           filters.length(), duration);
   }
 
-#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
+#  if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
   if (ProfilerFeature::HasMemory(features)) {
     // start counting memory allocations (outside of lock because this may call
     // profiler_add_sampled_counter which would attempt to take the lock.)
     mozilla::profiler::install_memory_counter(true);
   }
-#endif
+#  endif
 
   // We do this with gPSMutex unlocked. The comment in profiler_stop() explains
   // why.
   NotifyProfilerStarted(capacity, duration, interval, features, filters.begin(),
                         filters.length());
 }
 
 static void locked_profiler_save_profile_to_file(PSLockRef aLock,
@@ -3000,37 +3004,37 @@ void profiler_shutdown() {
   SamplerThread* samplerThread = nullptr;
   {
     PSAutoLock lock(gPSMutex);
 
     // Save the profile on shutdown if requested.
     if (ActivePS::Exists(lock)) {
       const char* filename = getenv("MOZ_PROFILER_SHUTDOWN");
       if (filename) {
-#if !defined(RELEASE_OR_BETA)
+#  if !defined(RELEASE_OR_BETA)
         // Attempting to record the I/O we are doing to the shutdown profile
         // file while we are locked will deadlock.
         ActivePS::UnregisterIOInterposer(lock);
-#endif
+#  endif
         locked_profiler_save_profile_to_file(lock, filename,
                                              /* aIsShuttingDown */ true);
       }
 
       samplerThread = locked_profiler_stop(lock);
     }
 
     CorePS::Destroy(lock);
 
     // We just destroyed CorePS and the ThreadInfos it contains, so we can
     // clear this thread's TLSRegisteredThread.
     TLSRegisteredThread::SetRegisteredThread(lock, nullptr);
 
-#ifdef MOZ_TASK_TRACER
+#  ifdef MOZ_TASK_TRACER
     tasktracer::ShutdownTaskTracer();
-#endif
+#  endif
   }
 
   // We do these operations with gPSMutex unlocked. The comments in
   // profiler_stop() explain why.
   if (samplerThread) {
     ProfilerParent::ProfilerStopped();
     NotifyObservers("profiler-stopped");
     delete samplerThread;
@@ -3288,35 +3292,35 @@ static void locked_profiler_start(PSLock
                                   const char** aFilters, uint32_t aFilterCount,
                                   const Maybe<double>& aDuration) {
   if (LOG_TEST) {
     LOG("locked_profiler_start");
     LOG("- capacity  = %d", aCapacity);
     LOG("- duration  = %.2f", aDuration ? *aDuration : -1);
     LOG("- interval = %.2f", aInterval);
 
-#define LOG_FEATURE(n_, str_, Name_, desc_)     \
-  if (ProfilerFeature::Has##Name_(aFeatures)) { \
-    LOG("- feature  = %s", str_);               \
-  }
+#  define LOG_FEATURE(n_, str_, Name_, desc_)     \
+    if (ProfilerFeature::Has##Name_(aFeatures)) { \
+      LOG("- feature  = %s", str_);               \
+    }
 
     PROFILER_FOR_EACH_FEATURE(LOG_FEATURE)
 
-#undef LOG_FEATURE
+#  undef LOG_FEATURE
 
     for (uint32_t i = 0; i < aFilterCount; i++) {
       LOG("- threads  = %s", aFilters[i]);
     }
   }
 
   MOZ_RELEASE_ASSERT(CorePS::Exists() && !ActivePS::Exists(aLock));
 
-#if defined(GP_PLAT_amd64_windows)
+#  if defined(GP_PLAT_amd64_windows)
   InitializeWin64ProfilerHooks();
-#endif
+#  endif
 
   // Fall back to the default values if the passed-in values are unreasonable.
   uint32_t capacity = aCapacity > 0 ? aCapacity : PROFILER_DEFAULT_ENTRIES;
   Maybe<double> duration = aDuration;
 
   if (aDuration && *aDuration <= 0) {
     duration = Nothing();
   }
@@ -3354,32 +3358,32 @@ static void locked_profiler_start(PSLock
       }
       registeredThread->RacyRegisteredThread().ReinitializeOnResume();
       if (registeredThread->GetJSContext()) {
         profiledThreadData->NotifyReceivedJSContext(0);
       }
     }
   }
 
-#ifdef MOZ_TASK_TRACER
+#  ifdef MOZ_TASK_TRACER
   if (ActivePS::FeatureTaskTracer(aLock)) {
     tasktracer::StartLogging();
   }
-#endif
-
-#if defined(GP_OS_android)
+#  endif
+
+#  if defined(GP_OS_android)
   if (ActivePS::FeatureJava(aLock)) {
     int javaInterval = interval;
     // Java sampling doesn't accurately keep up with 1ms sampling.
     if (javaInterval < 10) {
       javaInterval = 10;
     }
     java::GeckoJavaSampler::Start(javaInterval, 1000);
   }
-#endif
+#  endif
 
   // At the very end, set up RacyFeatures.
   RacyFeatures::SetActive(ActivePS::Features(aLock));
 }
 
 void profiler_start(uint32_t aCapacity, double aInterval, uint32_t aFeatures,
                     const char** aFilters, uint32_t aFilterCount,
                     const Maybe<double>& aDuration) {
@@ -3398,23 +3402,23 @@ void profiler_start(uint32_t aCapacity, 
     if (ActivePS::Exists(lock)) {
       samplerThread = locked_profiler_stop(lock);
     }
 
     locked_profiler_start(lock, aCapacity, aInterval, aFeatures, aFilters,
                           aFilterCount, aDuration);
   }
 
-#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
+#  if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
   if (ProfilerFeature::HasMemory(aFeatures)) {
     // start counting memory allocations (outside of lock because this may call
     // profiler_add_sampled_counter which would attempt to take the lock.)
     mozilla::profiler::install_memory_counter(true);
   }
-#endif
+#  endif
 
   // We do these operations with gPSMutex unlocked. The comments in
   // profiler_stop() explain why.
   if (samplerThread) {
     ProfilerParent::ProfilerStopped();
     NotifyObservers("profiler-stopped");
     delete samplerThread;
   }
@@ -3439,42 +3443,42 @@ void profiler_ensure_started(uint32_t aC
     }
 
     if (ActivePS::Exists(lock)) {
       // The profiler is active.
       if (!ActivePS::Equals(lock, aCapacity, aDuration, aInterval, aFeatures,
                             aFilters, aFilterCount)) {
         // Stop and restart with different settings.
         samplerThread = locked_profiler_stop(lock);
-#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
+#  if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
         if (!ProfilerFeature::HasMemory(aFeatures)) {
           // Ensure we don't record memory measurements anymore (if we were).
           mozilla::profiler::install_memory_counter(false);
         }
-#endif
+#  endif
         locked_profiler_start(lock, aCapacity, aInterval, aFeatures, aFilters,
                               aFilterCount, aDuration);
         startedProfiler = true;
       }
     } else {
       // The profiler is stopped.
       locked_profiler_start(lock, aCapacity, aInterval, aFeatures, aFilters,
                             aFilterCount, aDuration);
       startedProfiler = true;
     }
   }
 
-#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
+#  if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
   if (startedProfiler && ProfilerFeature::HasMemory(aFeatures)) {
     // start counting memory allocations (outside of lock because this may
     // call profiler_add_sampled_counter which would attempt to take the
     // lock.)
     mozilla::profiler::install_memory_counter(true);
   }
-#endif
+#  endif
 
   // We do these operations with gPSMutex unlocked. The comments in
   // profiler_stop() explain why.
   if (samplerThread) {
     ProfilerParent::ProfilerStopped();
     NotifyObservers("profiler-stopped");
     delete samplerThread;
   }
@@ -3488,31 +3492,31 @@ void profiler_ensure_started(uint32_t aC
 static MOZ_MUST_USE SamplerThread* locked_profiler_stop(PSLockRef aLock) {
   LOG("locked_profiler_stop");
 
   MOZ_RELEASE_ASSERT(CorePS::Exists() && ActivePS::Exists(aLock));
 
   // At the very start, clear RacyFeatures.
   RacyFeatures::SetInactive();
 
-#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
+#  if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
   mozilla::profiler::install_memory_counter(false);
-#endif
-
-#if defined(GP_OS_android)
+#  endif
+
+#  if defined(GP_OS_android)
   if (ActivePS::FeatureJava(aLock)) {
     java::GeckoJavaSampler::Stop();
   }
-#endif
-
-#ifdef MOZ_TASK_TRACER
+#  endif
+
+#  ifdef MOZ_TASK_TRACER
   if (ActivePS::FeatureTaskTracer(aLock)) {
     tasktracer::StopLogging();
   }
-#endif
+#  endif
 
   // Stop sampling live threads.
   int tid = profiler_current_thread_id();
   const Vector<LiveProfiledThreadData>& liveProfiledThreads =
       ActivePS::LiveProfiledThreads(aLock);
   for (auto& thread : liveProfiledThreads) {
     RegisteredThread* registeredThread = thread.mRegisteredThread;
     registeredThread->RacyRegisteredThread().SetIsBeingProfiled(false);
@@ -3855,21 +3859,21 @@ UniqueProfilerBacktrace profiler_get_bac
     return nullptr;
   }
 
   int tid = profiler_current_thread_id();
 
   TimeStamp now = TimeStamp::Now();
 
   Registers regs;
-#if defined(HAVE_NATIVE_UNWIND)
+#  if defined(HAVE_NATIVE_UNWIND)
   regs.SyncPopulate();
-#else
+#  else
   regs.Clear();
-#endif
+#  endif
 
   // 1000 should be plenty for a single backtrace.
   auto buffer = MakeUnique<ProfileBuffer>(1000);
 
   DoSyncSample(lock, *registeredThread, now, regs, *buffer.get());
 
   return UniqueProfilerBacktrace(
       new ProfilerBacktrace("SyncProfile", tid, std::move(buffer)));
@@ -3975,30 +3979,30 @@ void profiler_add_marker_for_thread(int 
   TimeStamp origin = (aPayload && !aPayload->GetStartTime().IsNull())
                          ? aPayload->GetStartTime()
                          : TimeStamp::Now();
   TimeDuration delta = origin - CorePS::ProcessStartTime();
   ProfilerMarker* marker =
       new ProfilerMarker(aMarkerName, aCategoryPair, aThreadId,
                          std::move(aPayload), delta.ToMilliseconds());
 
-#ifdef DEBUG
+#  ifdef DEBUG
   // Assert that our thread ID makes sense
   bool realThread = false;
   const Vector<UniquePtr<RegisteredThread>>& registeredThreads =
       CorePS::RegisteredThreads(lock);
   for (auto& thread : registeredThreads) {
     RefPtr<ThreadInfo> info = thread->Info();
     if (info->ThreadId() == aThreadId) {
       realThread = true;
       break;
     }
   }
   MOZ_ASSERT(realThread, "Invalid thread id");
-#endif
+#  endif
 
   // Insert the marker into the buffer
   ProfileBuffer& buffer = ActivePS::Buffer(lock);
   buffer.AddStoredMarker(marker);
   buffer.AddEntry(ProfileBufferEntry::Marker(marker));
 }
 
 void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
@@ -4145,34 +4149,34 @@ void profiler_suspend_and_sample_thread(
 
       // Suspend, sample, and then resume the target thread.
       Sampler sampler(lock);
       sampler.SuspendAndSampleAndResumeThread(
           lock, registeredThread, [&](const Registers& aRegs) {
             // The target thread is now suspended. Collect a native backtrace,
             // and call the callback.
             bool isSynchronous = false;
-#if defined(HAVE_FASTINIT_NATIVE_UNWIND)
+#  if defined(HAVE_FASTINIT_NATIVE_UNWIND)
             if (aSampleNative) {
           // We can only use FramePointerStackWalk or MozStackWalk from
           // suspend_and_sample_thread as other stackwalking methods may not be
           // initialized.
-#  if defined(USE_FRAME_POINTER_STACK_WALK)
+#    if defined(USE_FRAME_POINTER_STACK_WALK)
               DoFramePointerBacktrace(lock, registeredThread, aRegs,
                                       nativeStack);
-#  elif defined(USE_MOZ_STACK_WALK)
+#    elif defined(USE_MOZ_STACK_WALK)
           DoMozStackWalkBacktrace(lock, registeredThread, aRegs, nativeStack);
-#  else
-#    error "Invalid configuration"
-#  endif
+#    else
+#      error "Invalid configuration"
+#    endif
 
               MergeStacks(aFeatures, isSynchronous, registeredThread, aRegs,
                           nativeStack, aCollector);
             } else
-#endif
+#  endif
             {
               MergeStacks(aFeatures, isSynchronous, registeredThread, aRegs,
                           nativeStack, aCollector);
 
               if (ProfilerFeature::HasLeaf(aFeatures)) {
                 aCollector.CollectNativeLeafAddr((void*)aRegs.mPC);
               }
             }
@@ -4183,8 +4187,10 @@ void profiler_suspend_and_sample_thread(
       sampler.Disable(lock);
       break;
     }
   }
 }
 
 // END externally visible functions
 ////////////////////////////////////////////////////////////////////////
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/shared-libraries-linux.cc
+++ b/mozglue/baseprofiler/core/shared-libraries-linux.cc
@@ -1,67 +1,71 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "BaseProfilerSharedLibraries.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include "BaseProfilerSharedLibraries.h"
 
-#define PATH_MAX_TOSTRING(x) #x
-#define PATH_MAX_STRING(x) PATH_MAX_TOSTRING(x)
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <unistd.h>
-#include <fstream>
-#include "platform.h"
-#include "mozilla/Sprintf.h"
-#include "mozilla/Unused.h"
-#include "nsDebug.h"
-#include "nsNativeCharsetUtils.h"
-#include <nsTArray.h>
+#  define PATH_MAX_TOSTRING(x) #  x
+#  define PATH_MAX_STRING(x) PATH_MAX_TOSTRING(x)
+#  include <stdlib.h>
+#  include <stdio.h>
+#  include <string.h>
+#  include <limits.h>
+#  include <unistd.h>
+#  include <fstream>
+#  include "platform.h"
+#  include "mozilla/Sprintf.h"
+#  include "mozilla/Unused.h"
+#  include "nsDebug.h"
+#  include "nsNativeCharsetUtils.h"
+#  include <nsTArray.h>
 
-#include "common/linux/file_id.h"
-#include <algorithm>
-#include <dlfcn.h>
-#include <features.h>
-#include <sys/types.h>
+#  include "common/linux/file_id.h"
+#  include <algorithm>
+#  include <dlfcn.h>
+#  include <features.h>
+#  include <sys/types.h>
 
-#if defined(GP_OS_linux)
-#  include <link.h>  // dl_phdr_info
-#elif defined(GP_OS_android)
-#  include "AutoObjectMapper.h"
-#  include "ElfLoader.h"  // dl_phdr_info
+#  if defined(GP_OS_linux)
+#    include <link.h>  // dl_phdr_info
+#  elif defined(GP_OS_android)
+#    include "AutoObjectMapper.h"
+#    include "ElfLoader.h"  // dl_phdr_info
 extern "C" MOZ_EXPORT __attribute__((weak)) int dl_iterate_phdr(
     int (*callback)(struct dl_phdr_info* info, size_t size, void* data),
     void* data);
-#else
-#  error "Unexpected configuration"
-#endif
+#  else
+#    error "Unexpected configuration"
+#  endif
 
 struct LoadedLibraryInfo {
   LoadedLibraryInfo(const char* aName, unsigned long aBaseAddress,
                     unsigned long aFirstMappingStart,
                     unsigned long aLastMappingEnd)
       : mName(aName),
         mBaseAddress(aBaseAddress),
         mFirstMappingStart(aFirstMappingStart),
         mLastMappingEnd(aLastMappingEnd) {}
 
   nsCString mName;
   unsigned long mBaseAddress;
   unsigned long mFirstMappingStart;
   unsigned long mLastMappingEnd;
 };
 
-#if defined(GP_OS_android)
+#  if defined(GP_OS_android)
 static void outputMapperLog(const char* aBuf) { LOG("%s", aBuf); }
-#endif
+#  endif
 
 static nsCString IDtoUUIDString(
     const google_breakpad::wasteful_vector<uint8_t>& aIdentifier) {
   using namespace google_breakpad;
 
   nsCString uuid;
   const std::string str = FileID::ConvertIdentifierToUUIDString(aIdentifier);
   uuid.Append(str.c_str(), str.size());
@@ -72,28 +76,28 @@ static nsCString IDtoUUIDString(
 
 // Get the breakpad Id for the binary file pointed by bin_name
 static nsCString getId(const char* bin_name) {
   using namespace google_breakpad;
 
   PageAllocator allocator;
   auto_wasteful_vector<uint8_t, kDefaultBuildIdSize> identifier(&allocator);
 
-#if defined(GP_OS_android)
+#  if defined(GP_OS_android)
   if (nsDependentCString(bin_name).Find("!/") != kNotFound) {
     AutoObjectMapperFaultyLib mapper(outputMapperLog);
     void* image = nullptr;
     size_t size = 0;
     if (mapper.Map(&image, &size, bin_name) && image && size) {
       if (FileID::ElfFileIdentifierFromMappedFile(image, identifier)) {
         return IDtoUUIDString(identifier);
       }
     }
   }
-#endif
+#  endif
 
   FileID file_id(bin_name);
   if (file_id.ElfFileIdentifier(identifier)) {
     return IDtoUUIDString(identifier);
   }
 
   return EmptyCString();
 }
@@ -144,17 +148,17 @@ static int dl_iterate_callback(struct dl
       dl_info->dlpi_name, baseAddress, firstMappingStart, lastMappingEnd));
 
   return 0;
 }
 
 SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
   SharedLibraryInfo info;
 
-#if defined(GP_OS_linux)
+#  if defined(GP_OS_linux)
   // We need to find the name of the executable (exeName, exeNameLen) and the
   // address of its executable section (exeExeAddr) in the running image.
   char exeName[PATH_MAX];
   memset(exeName, 0, sizeof(exeName));
 
   ssize_t exeNameLen = readlink("/proc/self/exe", exeName, sizeof(exeName) - 1);
   if (exeNameLen == -1) {
     // readlink failed for whatever reason.  Note this, but keep going.
@@ -163,28 +167,28 @@ SharedLibraryInfo SharedLibraryInfo::Get
     LOG("SharedLibraryInfo::GetInfoForSelf(): readlink failed");
   } else {
     // Assert no buffer overflow.
     MOZ_RELEASE_ASSERT(exeNameLen >= 0 &&
                        exeNameLen < static_cast<ssize_t>(sizeof(exeName)));
   }
 
   unsigned long exeExeAddr = 0;
-#endif
+#  endif
 
-#if defined(GP_OS_android)
+#  if defined(GP_OS_android)
   // If dl_iterate_phdr doesn't exist, we give up immediately.
   if (!dl_iterate_phdr) {
     // On ARM Android, dl_iterate_phdr is provided by the custom linker.
     // So if libxul was loaded by the system linker (e.g. as part of
     // xpcshell when running tests), it won't be available and we should
     // not call it.
     return info;
   }
-#endif
+#  endif
 
   // Read info from /proc/self/maps. We ignore most of it.
   pid_t pid = profiler_current_process_id();
   char path[PATH_MAX];
   SprintfLiteral(path, "/proc/%d/maps", pid);
   std::ifstream maps(path);
   std::string line;
   while (std::getline(maps, line)) {
@@ -202,62 +206,64 @@ SharedLibraryInfo SharedLibraryInfo::Get
       continue;
     }
     if (ret != 5 && ret != 4) {
       LOG("SharedLibraryInfo::GetInfoForSelf(): "
           "reading /proc/self/maps failed");
       continue;
     }
 
-#if defined(GP_OS_linux)
+#  if defined(GP_OS_linux)
     // Try to establish the main executable's load address.
     if (exeNameLen > 0 && strcmp(modulePath, exeName) == 0) {
       exeExeAddr = start;
     }
-#elif defined(GP_OS_android)
+#  elif defined(GP_OS_android)
     // Use /proc/pid/maps to get the dalvik-jit section since it has no
     // associated phdrs.
     if (0 == strcmp(modulePath, "/dev/ashmem/dalvik-jit-code-cache")) {
       info.AddSharedLibrary(
           SharedLibraryAtPath(modulePath, start, end, offset));
       if (info.GetSize() > 10000) {
         LOG("SharedLibraryInfo::GetInfoForSelf(): "
             "implausibly large number of mappings acquired");
         break;
       }
     }
-#endif
+#  endif
   }
 
   nsTArray<LoadedLibraryInfo> libInfoList;
 
   // We collect the bulk of the library info using dl_iterate_phdr.
   dl_iterate_phdr(dl_iterate_callback, &libInfoList);
 
   for (const auto& libInfo : libInfoList) {
     info.AddSharedLibrary(
         SharedLibraryAtPath(libInfo.mName.get(), libInfo.mFirstMappingStart,
                             libInfo.mLastMappingEnd,
                             libInfo.mFirstMappingStart - libInfo.mBaseAddress));
   }
 
-#if defined(GP_OS_linux)
+#  if defined(GP_OS_linux)
   // Make another pass over the information we just harvested from
   // dl_iterate_phdr.  If we see a nameless object mapped at what we earlier
   // established to be the main executable's load address, attach the
   // executable's name to that entry.
   for (size_t i = 0; i < info.GetSize(); i++) {
     SharedLibrary& lib = info.GetMutableEntry(i);
     if (lib.GetStart() == exeExeAddr && lib.GetNativeDebugPath().empty()) {
       lib = SharedLibraryAtPath(exeName, lib.GetStart(), lib.GetEnd(),
                                 lib.GetOffset());
 
       // We only expect to see one such entry.
       break;
     }
   }
-#endif
+#  endif
 
   return info;
 }
 
 void SharedLibraryInfo::Initialize() { /* do nothing */
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/shared-libraries-macos.cc
+++ b/mozglue/baseprofiler/core/shared-libraries-macos.cc
@@ -1,49 +1,53 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "BaseProfilerSharedLibraries.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include "BaseProfilerSharedLibraries.h"
 
-#include "ClearOnShutdown.h"
-#include "mozilla/StaticMutex.h"
-#include "mozilla/Unused.h"
-#include "nsNativeCharsetUtils.h"
-#include <AvailabilityMacros.h>
+#  include "ClearOnShutdown.h"
+#  include "mozilla/StaticMutex.h"
+#  include "mozilla/Unused.h"
+#  include "nsNativeCharsetUtils.h"
+#  include <AvailabilityMacros.h>
 
-#include <dlfcn.h>
-#include <mach-o/arch.h>
-#include <mach-o/dyld_images.h>
-#include <mach-o/dyld.h>
-#include <mach-o/loader.h>
-#include <mach/mach_init.h>
-#include <mach/mach_traps.h>
-#include <mach/task_info.h>
-#include <mach/task.h>
-#include <sstream>
-#include <stdlib.h>
-#include <string.h>
-#include <vector>
+#  include <dlfcn.h>
+#  include <mach-o/arch.h>
+#  include <mach-o/dyld_images.h>
+#  include <mach-o/dyld.h>
+#  include <mach-o/loader.h>
+#  include <mach/mach_init.h>
+#  include <mach/mach_traps.h>
+#  include <mach/task_info.h>
+#  include <mach/task.h>
+#  include <sstream>
+#  include <stdlib.h>
+#  include <string.h>
+#  include <vector>
 
 // Architecture specific abstraction.
-#if defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_x86)
 typedef mach_header platform_mach_header;
 typedef segment_command mach_segment_command_type;
-#  define MACHO_MAGIC_NUMBER MH_MAGIC
-#  define CMD_SEGMENT LC_SEGMENT
-#  define seg_size uint32_t
-#else
+#    define MACHO_MAGIC_NUMBER MH_MAGIC
+#    define CMD_SEGMENT LC_SEGMENT
+#    define seg_size uint32_t
+#  else
 typedef mach_header_64 platform_mach_header;
 typedef segment_command_64 mach_segment_command_type;
-#  define MACHO_MAGIC_NUMBER MH_MAGIC_64
-#  define CMD_SEGMENT LC_SEGMENT_64
-#  define seg_size uint64_t
-#endif
+#    define MACHO_MAGIC_NUMBER MH_MAGIC_64
+#    define CMD_SEGMENT LC_SEGMENT_64
+#    define seg_size uint64_t
+#  endif
 
 struct NativeSharedLibrary {
   const platform_mach_header* header;
   std::string path;
 };
 static std::vector<NativeSharedLibrary>* sSharedLibrariesList = nullptr;
 static mozilla::StaticMutex sSharedLibrariesMutex;
 
@@ -178,8 +182,10 @@ SharedLibraryInfo SharedLibraryInfo::Get
   SharedLibraryInfo sharedLibraryInfo;
 
   for (auto& info : *sSharedLibrariesList) {
     addSharedLibrary(info.header, info.path.c_str(), sharedLibraryInfo);
   }
 
   return sharedLibraryInfo;
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/core/shared-libraries-win32.cc
+++ b/mozglue/baseprofiler/core/shared-libraries-win32.cc
@@ -1,27 +1,31 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include <windows.h>
-#include <dbghelp.h>
-#include <sstream>
-#include <psapi.h>
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include <windows.h>
+#  include <dbghelp.h>
+#  include <sstream>
+#  include <psapi.h>
 
-#include "BaseProfilerSharedLibraries.h"
-#include "nsWindowsHelpers.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/Unused.h"
-#include "nsNativeCharsetUtils.h"
-#include "nsPrintfCString.h"
-#include "nsReadableUtils.h"
+#  include "BaseProfilerSharedLibraries.h"
+#  include "nsWindowsHelpers.h"
+#  include "mozilla/UniquePtr.h"
+#  include "mozilla/Unused.h"
+#  include "nsNativeCharsetUtils.h"
+#  include "nsPrintfCString.h"
+#  include "nsReadableUtils.h"
 
-#define CV_SIGNATURE 0x53445352  // 'SDSR'
+#  define CV_SIGNATURE 0x53445352  // 'SDSR'
 
 struct CodeViewRecord70 {
   uint32_t signature;
   GUID pdbSignature;
   uint32_t pdbAge;
   // A UTF-8 string, according to
   // https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/PDB/dbi/locator.cpp#L785
   char pdbFileName[1];
@@ -202,8 +206,10 @@ SharedLibraryInfo SharedLibraryInfo::Get
     FreeLibrary(handleLock);  // ok to free null handles
   }
 
   return sharedLibraryInfo;
 }
 
 void SharedLibraryInfo::Initialize() { /* do nothing */
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/lul/AutoObjectMapper.cpp
+++ b/mozglue/baseprofiler/lul/AutoObjectMapper.cpp
@@ -1,42 +1,46 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include <sys/mman.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include <sys/mman.h>
+#  include <unistd.h>
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#  include <fcntl.h>
 
-#include "mozilla/Assertions.h"
-#include "mozilla/Sprintf.h"
+#  include "mozilla/Assertions.h"
+#  include "mozilla/Sprintf.h"
 
-#include "PlatformMacros.h"
-#include "AutoObjectMapper.h"
+#  include "PlatformMacros.h"
+#  include "AutoObjectMapper.h"
 
-#if defined(GP_OS_android)
-#  include <dlfcn.h>
-#  include "mozilla/Types.h"
+#  if defined(GP_OS_android)
+#    include <dlfcn.h>
+#    include "mozilla/Types.h"
 // FIXME move these out of mozglue/linker/ElfLoader.h into their
 // own header, so as to avoid conflicts arising from two definitions
 // of Array
 extern "C" {
 MFBT_API size_t __dl_get_mappable_length(void* handle);
 MFBT_API void* __dl_mmap(void* handle, void* addr, size_t length, off_t offset);
 MFBT_API void __dl_munmap(void* handle, void* addr, size_t length);
 }
 // The following are for get_installation_lib_dir()
-#  include "nsString.h"
-#  include "nsDirectoryServiceUtils.h"
-#  include "nsDirectoryServiceDefs.h"
-#endif
+#    include "nsString.h"
+#    include "nsDirectoryServiceUtils.h"
+#    include "nsDirectoryServiceDefs.h"
+#  endif
 
 // A helper function for creating failure error messages in
 // AutoObjectMapper*::Map.
 static void failedToMessage(void (*aLog)(const char*), const char* aHowFailed,
                             std::string aFileName) {
   char buf[300];
   SprintfLiteral(buf, "AutoObjectMapper::Map: Failed to %s \'%s\'", aHowFailed,
                  aFileName.c_str());
@@ -90,17 +94,17 @@ bool AutoObjectMapperPOSIX::Map(/*OUT*/ 
 
   close(fd);
   mIsMapped = true;
   mImage = *start = image;
   mSize = *length = sz;
   return true;
 }
 
-#if defined(GP_OS_android)
+#  if defined(GP_OS_android)
 // A helper function for AutoObjectMapperFaultyLib::Map.  Finds out
 // where the installation's lib directory is, since we'll have to look
 // in there to get hold of libmozglue.so.  Returned C string is heap
 // allocated and the caller must deallocate it.
 static char* get_installation_lib_dir() {
   nsCOMPtr<nsIProperties> directoryService(
       do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   if (!directoryService) {
@@ -180,9 +184,11 @@ bool AutoObjectMapperFaultyLib::Map(/*OU
 
     mHdl = hdl;
     mImage = *start = image;
     mSize = *length = sz;
     return true;
   }
 }
 
-#endif  // defined(GP_OS_android)
+#  endif  // defined(GP_OS_android)
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/lul/LulCommon.cpp
+++ b/mozglue/baseprofiler/lul/LulCommon.cpp
@@ -32,25 +32,29 @@
 
 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
 
 // This file is derived from the following files in
 // toolkit/crashreporter/google-breakpad:
 //   src/common/module.cc
 //   src/common/unique_string.cc
 
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
 // There's no internal-only interface for LulCommon.  Hence include
 // the external interface directly.
-#include "LulCommonExt.h"
+#  include "LulCommonExt.h"
 
-#include <stdlib.h>
-#include <string.h>
+#  include <stdlib.h>
+#  include <string.h>
 
-#include <string>
-#include <map>
+#  include <string>
+#  include <map>
 
 namespace lul {
 
 using std::string;
 
 ////////////////////////////////////////////////////////////////
 // Module
 //
@@ -93,8 +97,10 @@ const UniqueString* UniqueStringUniverse
     map_[str] = ustr;
     return ustr;
   } else {
     return it->second;
   }
 }
 
 }  // namespace lul
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/lul/LulDwarf.cpp
+++ b/mozglue/baseprofiler/lul/LulDwarf.cpp
@@ -36,33 +36,37 @@
 // and dwarf2reader::CallFrameInfo. See dwarf2reader.h for details.
 
 // This file is derived from the following files in
 // toolkit/crashreporter/google-breakpad:
 //   src/common/dwarf/bytereader.cc
 //   src/common/dwarf/dwarf2reader.cc
 //   src/common/dwarf_cfi_to_module.cc
 
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include <stdint.h>
+#  include <stdio.h>
+#  include <string.h>
+#  include <stdlib.h>
 
-#include <map>
-#include <stack>
-#include <string>
+#  include <map>
+#  include <stack>
+#  include <string>
 
-#include "mozilla/Assertions.h"
-#include "mozilla/Sprintf.h"
+#  include "mozilla/Assertions.h"
+#  include "mozilla/Sprintf.h"
 
-#include "LulCommonExt.h"
-#include "LulDwarfInt.h"
+#  include "LulCommonExt.h"
+#  include "LulDwarfInt.h"
 
 // Set this to 1 for verbose logging
-#define DEBUG_DWARF 0
+#  define DEBUG_DWARF 0
 
 namespace lul {
 
 using std::string;
 
 ByteReader::ByteReader(enum Endianness endian)
     : offset_reader_(NULL),
       address_reader_(NULL),
@@ -2245,8 +2249,10 @@ void DwarfCFIToModule::Reporter::Express
   SprintfLiteral(buf,
                  "DwarfCFIToModule::Reporter::"
                  "ExpressionCouldNotBeSummarised(shown %llu times)\n",
                  (unsigned long long int)n_complaints);
   log_(buf);
 }
 
 }  // namespace lul
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/lul/LulDwarfSummariser.cpp
+++ b/mozglue/baseprofiler/lul/LulDwarfSummariser.cpp
@@ -1,23 +1,27 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "LulDwarfSummariser.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
 
-#include "LulDwarfExt.h"
+#  include "LulDwarfSummariser.h"
 
-#include "mozilla/Assertions.h"
-#include "mozilla/Sprintf.h"
+#  include "LulDwarfExt.h"
+
+#  include "mozilla/Assertions.h"
+#  include "mozilla/Sprintf.h"
 
 // Set this to 1 for verbose logging
-#define DEBUG_SUMMARISER 0
+#  define DEBUG_SUMMARISER 0
 
 namespace lul {
 
 // Do |s64|'s lowest 32 bits sign extend back to |s64| itself?
 static inline bool fitsIn32Bits(int64 s64) {
   return s64 == ((s64 & 0xffffffff) ^ 0x80000000) - 0x80000000;
 }
 
@@ -119,17 +123,17 @@ void Summariser::Rule(uintptr_t aAddress
   // any LExpr made here.  So we may as well check it right now.
   if (!fitsIn32Bits(offset)) {
     reason1 = "offset not in signed 32-bit range";
     goto cant_summarise;
   }
 
   // FIXME: factor out common parts of the arch-dependent summarisers.
 
-#if defined(GP_ARCH_arm)
+#  if defined(GP_ARCH_arm)
 
   // ----------------- arm ----------------- //
 
   // Now, can we add the rule to our summary?  This depends on whether
   // the registers and the overall expression are representable.  This
   // is the heart of the summarisation process.
   switch (aNewReg) {
     case DW_REG_CFA:
@@ -241,17 +245,17 @@ void Summariser::Rule(uintptr_t aAddress
   mCurrRules.mR13expr = LExpr(NODEREF, DW_REG_CFA, 0);
 
   // If there's no information about R15 (the return address), say
   // it's a copy of R14 (the link register).
   if (mCurrRules.mR15expr.mHow == UNKNOWN) {
     mCurrRules.mR15expr = LExpr(NODEREF, DW_REG_ARM_R14, 0);
   }
 
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
 
   // ----------------- arm64 ----------------- //
 
   switch (aNewReg) {
     case DW_REG_CFA:
       if (how != NODEREF) {
         reason1 = "rule for DW_REG_CFA: invalid |how|";
         goto cant_summarise;
@@ -322,17 +326,17 @@ void Summariser::Rule(uintptr_t aAddress
     mCurrRules.mX30expr = LExpr(NODEREF, DW_REG_AARCH64_X30, 0);
   }
   // On aarch64, it seems the old SP value before the call is always the
   // same as the CFA.  Therefore, in the absence of any other way to
   // recover the SP, specify that the CFA should be copied.
   if (mCurrRules.mSPexpr.mHow == UNKNOWN) {
     mCurrRules.mSPexpr = LExpr(NODEREF, DW_REG_CFA, 0);
   }
-#elif defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  elif defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
 
   // ---------------- x64/x86 ---------------- //
 
   // Now, can we add the rule to our summary?  This depends on whether
   // the registers and the overall expression are representable.  This
   // is the heart of the summarisation process.
   switch (aNewReg) {
     case DW_REG_CFA: {
@@ -422,17 +426,17 @@ void Summariser::Rule(uintptr_t aAddress
     mCurrRules.mXspExpr = LExpr(NODEREF, DW_REG_CFA, 0);
   }
 
   // Also, gcc says "Undef" for BP when it is unchanged.
   if (mCurrRules.mXbpExpr.mHow == UNKNOWN) {
     mCurrRules.mXbpExpr = LExpr(NODEREF, DW_REG_INTEL_XBP, 0);
   }
 
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
   // ---------------- mips ---------------- //
   //
   // Now, can we add the rule to our summary?  This depends on whether
   // the registers and the overall expression are representable.  This
   // is the heart of the summarisation process.
   switch (aNewReg) {
     case DW_REG_CFA:
       // This is a rule that defines the CFA.  The only forms we can
@@ -504,20 +508,20 @@ void Summariser::Rule(uintptr_t aAddress
     mCurrRules.mSPexpr = LExpr(NODEREF, DW_REG_CFA, 0);
   }
 
   // Also, gcc says "Undef" for FP when it is unchanged.
   if (mCurrRules.mFPexpr.mHow == UNKNOWN) {
     mCurrRules.mFPexpr = LExpr(NODEREF, DW_REG_MIPS_FP, 0);
   }
 
-#else
+#  else
 
-#  error "Unsupported arch"
-#endif
+#    error "Unsupported arch"
+#  endif
 
   return;
 
 cant_summarise:
   if (reason1 || reason2) {
     char buf[200];
     SprintfLiteral(buf,
                    "LUL  can't summarise: "
@@ -546,8 +550,10 @@ void Summariser::End() {
       mLog("LUL  ");
       mCurrRules.Print(mLog);
       mLog("\n");
     }
   }
 }
 
 }  // namespace lul
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/lul/LulElf.cpp
+++ b/mozglue/baseprofiler/lul/LulElf.cpp
@@ -40,47 +40,51 @@
 // it out as a Breakpad symbol file.
 
 // This file is derived from the following files in
 // toolkit/crashreporter/google-breakpad:
 //   src/common/linux/dump_symbols.cc
 //   src/common/linux/elfutils.cc
 //   src/common/linux/file_id.cc
 
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <arpa/inet.h>
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
 
-#include <set>
-#include <string>
-#include <vector>
+#  include <errno.h>
+#  include <fcntl.h>
+#  include <stdio.h>
+#  include <string.h>
+#  include <sys/mman.h>
+#  include <sys/stat.h>
+#  include <unistd.h>
+#  include <arpa/inet.h>
 
-#include "mozilla/Assertions.h"
-#include "mozilla/Sprintf.h"
+#  include <set>
+#  include <string>
+#  include <vector>
+
+#  include "mozilla/Assertions.h"
+#  include "mozilla/Sprintf.h"
 
-#include "PlatformMacros.h"
-#include "LulCommonExt.h"
-#include "LulDwarfExt.h"
-#include "LulElfInt.h"
-#include "LulMainInt.h"
+#  include "PlatformMacros.h"
+#  include "LulCommonExt.h"
+#  include "LulDwarfExt.h"
+#  include "LulElfInt.h"
+#  include "LulMainInt.h"
 
-#if defined(GP_PLAT_arm_android) && !defined(SHT_ARM_EXIDX)
+#  if defined(GP_PLAT_arm_android) && !defined(SHT_ARM_EXIDX)
 // bionic and older glibsc don't define it
-#  define SHT_ARM_EXIDX (SHT_LOPROC + 1)
-#endif
+#    define SHT_ARM_EXIDX (SHT_LOPROC + 1)
+#  endif
 
 // Old Linux header doesn't define EM_AARCH64
-#ifndef EM_AARCH64
-#  define EM_AARCH64 183
-#endif
+#  ifndef EM_AARCH64
+#    define EM_AARCH64 183
+#  endif
 
 // This namespace contains helper functions.
 namespace {
 
 using lul::DwarfCFIToModule;
 using lul::FindElfSectionByName;
 using lul::GetOffset;
 using lul::IsValidElf;
@@ -739,17 +743,17 @@ bool FindElfSegment(const void* elf_mapp
 
 // (derived from)
 // file_id.cc: Return a unique identifier for a file
 //
 // See file_id.h for documentation
 //
 
 // ELF note name and desc are 32-bits word padded.
-#define NOTE_PADDING(a) ((a + 3) & ~3)
+#  define NOTE_PADDING(a) ((a + 3) & ~3)
 
 // These functions are also used inside the crashed process, so be safe
 // and use the syscall/libc wrappers instead of direct syscalls or libc.
 
 template <typename ElfClass>
 static bool ElfClassBuildIDNoteIdentifier(const void* section, int length,
                                           uint8_t identifier[kMDGUIDSize]) {
   typedef typename ElfClass::Nhdr Nhdr;
@@ -864,8 +868,10 @@ void FileID::ConvertIdentifierToString(c
     buffer[buffer_idx++] = (lo >= 10) ? 'A' + lo - 10 : '0' + lo;
   }
 
   // NULL terminate
   buffer[(buffer_idx < buffer_length) ? buffer_idx : buffer_idx - 1] = 0;
 }
 
 }  // namespace lul
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/lul/LulMain.cpp
+++ b/mozglue/baseprofiler/lul/LulMain.cpp
@@ -1,43 +1,45 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "LulMain.h"
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
+
+#  include "LulMain.h"
 
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>  // write(), only for testing LUL
+#  include <string.h>
+#  include <stdlib.h>
+#  include <stdio.h>
+#  include <unistd.h>  // write(), only for testing LUL
 
-#include <algorithm>  // std::sort
-#include <string>
+#  include <algorithm>  // std::sort
+#  include <string>
 
-#include "mozilla/Assertions.h"
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/CheckedInt.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/MemoryChecking.h"
-#include "mozilla/Move.h"
-#include "mozilla/Sprintf.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/Unused.h"
+#  include "mozilla/Assertions.h"
+#  include "mozilla/ArrayUtils.h"
+#  include "mozilla/CheckedInt.h"
+#  include "mozilla/DebugOnly.h"
+#  include "mozilla/MemoryChecking.h"
+#  include "mozilla/Move.h"
+#  include "mozilla/Sprintf.h"
+#  include "mozilla/UniquePtr.h"
+#  include "mozilla/Unused.h"
 
-#include "LulCommonExt.h"
-#include "LulElfExt.h"
+#  include "LulCommonExt.h"
+#  include "LulElfExt.h"
 
-#include "LulMainInt.h"
-
-#include "BaseProfiler.h"  // for profiler_current_thread_id()
+#  include "LulMainInt.h"
 
 // Set this to 1 for verbose logging
-#define DEBUG_MAIN 0
+#  define DEBUG_MAIN 0
 
 namespace lul {
 
 using mozilla::CheckedInt;
 using mozilla::DebugOnly;
 using mozilla::MallocSizeOf;
 using mozilla::Unused;
 using std::pair;
@@ -57,53 +59,53 @@ using std::vector;
 ////////////////////////////////////////////////////////////////
 // RuleSet                                                    //
 ////////////////////////////////////////////////////////////////
 
 static const char* NameOf_DW_REG(int16_t aReg) {
   switch (aReg) {
     case DW_REG_CFA:
       return "cfa";
-#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
     case DW_REG_INTEL_XBP:
       return "xbp";
     case DW_REG_INTEL_XSP:
       return "xsp";
     case DW_REG_INTEL_XIP:
       return "xip";
-#elif defined(GP_ARCH_arm)
+#  elif defined(GP_ARCH_arm)
     case DW_REG_ARM_R7:
       return "r7";
     case DW_REG_ARM_R11:
       return "r11";
     case DW_REG_ARM_R12:
       return "r12";
     case DW_REG_ARM_R13:
       return "r13";
     case DW_REG_ARM_R14:
       return "r14";
     case DW_REG_ARM_R15:
       return "r15";
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
     case DW_REG_AARCH64_X29:
       return "x29";
     case DW_REG_AARCH64_X30:
       return "x30";
     case DW_REG_AARCH64_SP:
       return "sp";
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
     case DW_REG_MIPS_SP:
       return "sp";
     case DW_REG_MIPS_FP:
       return "fp";
     case DW_REG_MIPS_PC:
       return "pc";
-#else
-#  error "Unsupported arch"
-#endif
+#  else
+#    error "Unsupported arch"
+#  endif
     default:
       return "???";
   }
 }
 
 string LExpr::ShowRule(const char* aNewReg) const {
   char buf[64];
   string res = string(aNewReg) + "=";
@@ -133,82 +135,82 @@ string LExpr::ShowRule(const char* aNewR
 void RuleSet::Print(void (*aLog)(const char*)) const {
   char buf[96];
   SprintfLiteral(buf, "[%llx .. %llx]: let ", (unsigned long long int)mAddr,
                  (unsigned long long int)(mAddr + mLen - 1));
   string res = string(buf);
   res += mCfaExpr.ShowRule("cfa");
   res += " in";
   // For each reg we care about, print the recovery expression.
-#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
   res += mXipExpr.ShowRule(" RA");
   res += mXspExpr.ShowRule(" SP");
   res += mXbpExpr.ShowRule(" BP");
-#elif defined(GP_ARCH_arm)
+#  elif defined(GP_ARCH_arm)
   res += mR15expr.ShowRule(" R15");
   res += mR7expr.ShowRule(" R7");
   res += mR11expr.ShowRule(" R11");
   res += mR12expr.ShowRule(" R12");
   res += mR13expr.ShowRule(" R13");
   res += mR14expr.ShowRule(" R14");
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
   res += mX29expr.ShowRule(" X29");
   res += mX30expr.ShowRule(" X30");
   res += mSPexpr.ShowRule(" SP");
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
   res += mPCexpr.ShowRule(" PC");
   res += mSPexpr.ShowRule(" SP");
   res += mFPexpr.ShowRule(" FP");
-#else
-#  error "Unsupported arch"
-#endif
+#  else
+#    error "Unsupported arch"
+#  endif
   aLog(res.c_str());
 }
 
 LExpr* RuleSet::ExprForRegno(DW_REG_NUMBER aRegno) {
   switch (aRegno) {
     case DW_REG_CFA:
       return &mCfaExpr;
-#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
     case DW_REG_INTEL_XIP:
       return &mXipExpr;
     case DW_REG_INTEL_XSP:
       return &mXspExpr;
     case DW_REG_INTEL_XBP:
       return &mXbpExpr;
-#elif defined(GP_ARCH_arm)
+#  elif defined(GP_ARCH_arm)
     case DW_REG_ARM_R15:
       return &mR15expr;
     case DW_REG_ARM_R14:
       return &mR14expr;
     case DW_REG_ARM_R13:
       return &mR13expr;
     case DW_REG_ARM_R12:
       return &mR12expr;
     case DW_REG_ARM_R11:
       return &mR11expr;
     case DW_REG_ARM_R7:
       return &mR7expr;
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
     case DW_REG_AARCH64_X29:
       return &mX29expr;
     case DW_REG_AARCH64_X30:
       return &mX30expr;
     case DW_REG_AARCH64_SP:
       return &mSPexpr;
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
     case DW_REG_MIPS_SP:
       return &mSPexpr;
     case DW_REG_MIPS_FP:
       return &mFPexpr;
     case DW_REG_MIPS_PC:
       return &mPCexpr;
-#else
-#  error "Unknown arch"
-#endif
+#  else
+#    error "Unknown arch"
+#  endif
     default:
       return nullptr;
   }
 }
 
 RuleSet::RuleSet() {
   mAddr = 0;
   mLen = 0;
@@ -359,30 +361,30 @@ void SecMap::PrepareRuleSets(uintptr_t a
       nZeroLen--;
     }
 
     MOZ_ASSERT(mRuleSets.size() == j);
   }
 
   size_t n = mRuleSets.size();
 
-#ifdef DEBUG
+#  ifdef DEBUG
   // Do a final check on the rules: their address ranges must be
   // ascending, non overlapping, non zero sized.
   if (n > 0) {
     MOZ_ASSERT(mRuleSets[0].mLen > 0);
     for (size_t i = 1; i < n; ++i) {
       RuleSet* prev = &mRuleSets[i - 1];
       RuleSet* here = &mRuleSets[i];
       MOZ_ASSERT(prev->mAddr < here->mAddr);
       MOZ_ASSERT(here->mLen > 0);
       MOZ_ASSERT(prev->mAddr + prev->mLen <= here->mAddr);
     }
   }
-#endif
+#  endif
 
   // Set the summary min and max address values.
   if (n == 0) {
     // Use the values defined in comments in the class declaration.
     mSummaryMinAddr = 1;
     mSummaryMaxAddr = 0;
   } else {
     mSummaryMinAddr = mRuleSets[0].mAddr;
@@ -393,24 +395,24 @@ void SecMap::PrepareRuleSets(uintptr_t a
                  (int)n, (unsigned long long int)mSummaryMinAddr,
                  (unsigned long long int)mSummaryMaxAddr);
   buf[sizeof(buf) - 1] = 0;
   mLog(buf);
 
   // Is now usable for binary search.
   mUsable = true;
 
-#if 0
+#  if 0
   mLog("\nRulesets after preening\n");
   for (size_t i = 0; i < mRuleSets.size(); ++i) {
     mRuleSets[i].Print(mLog);
     mLog("\n");
   }
   mLog("\n");
-#endif
+#  endif
 }
 
 bool SecMap::IsEmpty() { return mRuleSets.empty(); }
 
 size_t SecMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
   size_t n = aMallocSizeOf(this);
 
   // It's conceivable that these calls would be unsafe with some
@@ -679,25 +681,25 @@ class PriMap {
   // a logging sink, for debugging.
   void (*mLog)(const char*);
 };
 
 ////////////////////////////////////////////////////////////////
 // LUL                                                        //
 ////////////////////////////////////////////////////////////////
 
-#define LUL_LOG(_str)                                           \
-  do {                                                          \
-    char buf[200];                                              \
-    SprintfLiteral(buf, "LUL: pid %d tid %d lul-obj %p: %s",    \
-                   profiler_current_process_id(),               \
-                   profiler_current_thread_id(), this, (_str)); \
-    buf[sizeof(buf) - 1] = 0;                                   \
-    mLog(buf);                                                  \
-  } while (0)
+#  define LUL_LOG(_str)                                           \
+    do {                                                          \
+      char buf[200];                                              \
+      SprintfLiteral(buf, "LUL: pid %d tid %d lul-obj %p: %s",    \
+                     profiler_current_process_id(),               \
+                     profiler_current_thread_id(), this, (_str)); \
+      buf[sizeof(buf) - 1] = 0;                                   \
+      mLog(buf);                                                  \
+    } while (0)
 
 LUL::LUL(void (*aLog)(const char*))
     : mLog(aLog),
       mAdminMode(true),
       mAdminThreadId(profiler_current_thread_id()),
       mPriMap(new PriMap(aLog)),
       mSegArray(new SegArray()),
       mUSU(new UniqueStringUniverse()) {
@@ -891,53 +893,53 @@ static TaggedUWord DerefTUW(TaggedUWord 
 }
 
 // RUNS IN NO-MALLOC CONTEXT
 static TaggedUWord EvaluateReg(int16_t aReg, const UnwindRegs* aOldRegs,
                                TaggedUWord aCFA) {
   switch (aReg) {
     case DW_REG_CFA:
       return aCFA;
-#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
     case DW_REG_INTEL_XBP:
       return aOldRegs->xbp;
     case DW_REG_INTEL_XSP:
       return aOldRegs->xsp;
     case DW_REG_INTEL_XIP:
       return aOldRegs->xip;
-#elif defined(GP_ARCH_arm)
+#  elif defined(GP_ARCH_arm)
     case DW_REG_ARM_R7:
       return aOldRegs->r7;
     case DW_REG_ARM_R11:
       return aOldRegs->r11;
     case DW_REG_ARM_R12:
       return aOldRegs->r12;
     case DW_REG_ARM_R13:
       return aOldRegs->r13;
     case DW_REG_ARM_R14:
       return aOldRegs->r14;
     case DW_REG_ARM_R15:
       return aOldRegs->r15;
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
     case DW_REG_AARCH64_X29:
       return aOldRegs->x29;
     case DW_REG_AARCH64_X30:
       return aOldRegs->x30;
     case DW_REG_AARCH64_SP:
       return aOldRegs->sp;
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
     case DW_REG_MIPS_SP:
       return aOldRegs->sp;
     case DW_REG_MIPS_FP:
       return aOldRegs->fp;
     case DW_REG_MIPS_PC:
       return aOldRegs->pc;
-#else
-#  error "Unsupported arch"
-#endif
+#  else
+#    error "Unsupported arch"
+#  endif
     default:
       MOZ_ASSERT(0);
       return TaggedUWord();
   }
 }
 
 // RUNS IN NO-MALLOC CONTEXT
 // See prototype for comment.
@@ -946,27 +948,27 @@ TaggedUWord EvaluatePfxExpr(int32_t star
                             const vector<PfxInstr>& aPfxInstrs) {
   // A small evaluation stack, and a stack pointer, which points to
   // the highest numbered in-use element.
   const int N_STACK = 10;
   TaggedUWord stack[N_STACK];
   int stackPointer = -1;
   for (int i = 0; i < N_STACK; i++) stack[i] = TaggedUWord();
 
-#define PUSH(_tuw)                                             \
-  do {                                                         \
-    if (stackPointer >= N_STACK - 1) goto fail; /* overflow */ \
-    stack[++stackPointer] = (_tuw);                            \
-  } while (0)
+#  define PUSH(_tuw)                                             \
+    do {                                                         \
+      if (stackPointer >= N_STACK - 1) goto fail; /* overflow */ \
+      stack[++stackPointer] = (_tuw);                            \
+    } while (0)
 
-#define POP(_lval)                                   \
-  do {                                               \
-    if (stackPointer < 0) goto fail; /* underflow */ \
-    _lval = stack[stackPointer--];                   \
-  } while (0)
+#  define POP(_lval)                                   \
+    do {                                               \
+      if (stackPointer < 0) goto fail; /* underflow */ \
+      _lval = stack[stackPointer--];                   \
+    } while (0)
 
   // Cursor in the instruction sequence.
   size_t curr = start + 1;
 
   // Check the start point is sane.
   size_t nInstrs = aPfxInstrs.size();
   if (start < 0 || (size_t)start >= nInstrs) goto fail;
 
@@ -1062,18 +1064,18 @@ TaggedUWord EvaluatePfxExpr(int32_t star
   if (stackPointer >= 0) {
     return stack[stackPointer];
   }
   // Else fall through
 
 fail:
   return TaggedUWord();
 
-#undef PUSH
-#undef POP
+#  undef PUSH
+#  undef POP
 }
 
 // RUNS IN NO-MALLOC CONTEXT
 TaggedUWord LExpr::EvaluateExpr(const UnwindRegs* aOldRegs, TaggedUWord aCFA,
                                 const StackImage* aStackImg,
                                 const vector<PfxInstr>* aPfxInstrs) const {
   switch (mHow) {
     case UNKNOWN:
@@ -1108,84 +1110,84 @@ static void UseRuleSet(/*MOD*/ UnwindReg
   // whilst computing the new ones.
   UnwindRegs old_regs = *aRegs;
 
   // Mark all the current register values as invalid, so that the
   // caller can see, on our return, which ones have been computed
   // anew.  If we don't even manage to compute a new PC value, then
   // the caller will have to abandon the unwind.
   // FIXME: Create and use instead: aRegs->SetAllInvalid();
-#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
   aRegs->xbp = TaggedUWord();
   aRegs->xsp = TaggedUWord();
   aRegs->xip = TaggedUWord();
-#elif defined(GP_ARCH_arm)
+#  elif defined(GP_ARCH_arm)
   aRegs->r7 = TaggedUWord();
   aRegs->r11 = TaggedUWord();
   aRegs->r12 = TaggedUWord();
   aRegs->r13 = TaggedUWord();
   aRegs->r14 = TaggedUWord();
   aRegs->r15 = TaggedUWord();
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
   aRegs->x29 = TaggedUWord();
   aRegs->x30 = TaggedUWord();
   aRegs->sp = TaggedUWord();
   aRegs->pc = TaggedUWord();
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
   aRegs->sp = TaggedUWord();
   aRegs->fp = TaggedUWord();
   aRegs->pc = TaggedUWord();
-#else
-#  error "Unsupported arch"
-#endif
+#  else
+#    error "Unsupported arch"
+#  endif
 
   // This is generally useful.
   const TaggedUWord inval = TaggedUWord();
 
   // First, compute the CFA.
   TaggedUWord cfa = aRS->mCfaExpr.EvaluateExpr(&old_regs, inval /*old cfa*/,
                                                aStackImg, aPfxInstrs);
 
   // If we didn't manage to compute the CFA, well .. that's ungood,
   // but keep going anyway.  It'll be OK provided none of the register
   // value rules mention the CFA.  In any case, compute the new values
   // for each register that we're tracking.
 
-#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
   aRegs->xbp =
       aRS->mXbpExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->xsp =
       aRS->mXspExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->xip =
       aRS->mXipExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
-#elif defined(GP_ARCH_arm)
+#  elif defined(GP_ARCH_arm)
   aRegs->r7 = aRS->mR7expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->r11 =
       aRS->mR11expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->r12 =
       aRS->mR12expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->r13 =
       aRS->mR13expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->r14 =
       aRS->mR14expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->r15 =
       aRS->mR15expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
   aRegs->x29 =
       aRS->mX29expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->x30 =
       aRS->mX30expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->sp = aRS->mSPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
   aRegs->sp = aRS->mSPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->fp = aRS->mFPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
   aRegs->pc = aRS->mPCexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
-#else
-#  error "Unsupported arch"
-#endif
+#  else
+#    error "Unsupported arch"
+#  endif
 
   // We're done.  Any regs for which we didn't manage to compute a
   // new value will now be marked as invalid.
 }
 
 // RUNS IN NO-MALLOC CONTEXT
 void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
                  /*OUT*/ uintptr_t* aFrameSPs,
@@ -1202,76 +1204,76 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFra
 
   UnwindRegs regs = *aStartRegs;
   TaggedUWord last_valid_sp = TaggedUWord();
 
   while (true) {
     if (DEBUG_MAIN) {
       char buf[300];
       mLog("\n");
-#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
       SprintfLiteral(
           buf, "LoopTop: rip %d/%llx  rsp %d/%llx  rbp %d/%llx\n",
           (int)regs.xip.Valid(), (unsigned long long int)regs.xip.Value(),
           (int)regs.xsp.Valid(), (unsigned long long int)regs.xsp.Value(),
           (int)regs.xbp.Valid(), (unsigned long long int)regs.xbp.Value());
       buf[sizeof(buf) - 1] = 0;
       mLog(buf);
-#elif defined(GP_ARCH_arm)
+#  elif defined(GP_ARCH_arm)
       SprintfLiteral(
           buf,
           "LoopTop: r15 %d/%llx  r7 %d/%llx  r11 %d/%llx"
           "  r12 %d/%llx  r13 %d/%llx  r14 %d/%llx\n",
           (int)regs.r15.Valid(), (unsigned long long int)regs.r15.Value(),
           (int)regs.r7.Valid(), (unsigned long long int)regs.r7.Value(),
           (int)regs.r11.Valid(), (unsigned long long int)regs.r11.Value(),
           (int)regs.r12.Valid(), (unsigned long long int)regs.r12.Value(),
           (int)regs.r13.Valid(), (unsigned long long int)regs.r13.Value(),
           (int)regs.r14.Valid(), (unsigned long long int)regs.r14.Value());
       buf[sizeof(buf) - 1] = 0;
       mLog(buf);
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
       SprintfLiteral(
           buf,
           "LoopTop: pc %d/%llx  x29 %d/%llx  x30 %d/%llx"
           "  sp %d/%llx\n",
           (int)regs.pc.Valid(), (unsigned long long int)regs.pc.Value(),
           (int)regs.x29.Valid(), (unsigned long long int)regs.x29.Value(),
           (int)regs.x30.Valid(), (unsigned long long int)regs.x30.Value(),
           (int)regs.sp.Valid(), (unsigned long long int)regs.sp.Value());
       buf[sizeof(buf) - 1] = 0;
       mLog(buf);
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
       SprintfLiteral(
           buf, "LoopTop: pc %d/%llx  sp %d/%llx  fp %d/%llx\n",
           (int)regs.pc.Valid(), (unsigned long long int)regs.pc.Value(),
           (int)regs.sp.Valid(), (unsigned long long int)regs.sp.Value(),
           (int)regs.fp.Valid(), (unsigned long long int)regs.fp.Value());
       buf[sizeof(buf) - 1] = 0;
       mLog(buf);
-#else
-#  error "Unsupported arch"
-#endif
+#  else
+#    error "Unsupported arch"
+#  endif
     }
 
-#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
+#  if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
     TaggedUWord ia = regs.xip;
     TaggedUWord sp = regs.xsp;
-#elif defined(GP_ARCH_arm)
+#  elif defined(GP_ARCH_arm)
     TaggedUWord ia = (*aFramesUsed == 0 ? regs.r15 : regs.r14);
     TaggedUWord sp = regs.r13;
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
     TaggedUWord ia = (*aFramesUsed == 0 ? regs.pc : regs.x30);
     TaggedUWord sp = regs.sp;
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
     TaggedUWord ia = regs.pc;
     TaggedUWord sp = regs.sp;
-#else
-#  error "Unsupported arch"
-#endif
+#  else
+#    error "Unsupported arch"
+#  endif
 
     if (*aFramesUsed >= aFramesAvail) {
       break;
     }
 
     // If we don't have a valid value for the PC, give up.
     if (!ia.Valid()) {
       break;
@@ -1320,17 +1322,17 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFra
     if (DEBUG_MAIN) {
       char buf[100];
       SprintfLiteral(buf, "ruleset for 0x%llx = %p\n",
                      (unsigned long long int)ia.Value(), ruleset);
       buf[sizeof(buf) - 1] = 0;
       mLog(buf);
     }
 
-#if defined(GP_PLAT_x86_android) || defined(GP_PLAT_x86_linux)
+#  if defined(GP_PLAT_x86_android) || defined(GP_PLAT_x86_linux)
     /////////////////////////////////////////////
     ////
     // On 32 bit x86-linux, syscalls are often done via the VDSO
     // function __kernel_vsyscall, which doesn't have a corresponding
     // object that we can read debuginfo from.  That effectively kills
     // off all stack traces for threads blocked in syscalls.  Hence
     // special-case by looking at the code surrounding the program
     // counter.
@@ -1389,31 +1391,31 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFra
             regs.xsp = new_esp;
             continue;
           }
         }
       }
     }
     ////
     /////////////////////////////////////////////
-#endif  // defined(GP_PLAT_x86_android) || defined(GP_PLAT_x86_linux)
+#  endif  // defined(GP_PLAT_x86_android) || defined(GP_PLAT_x86_linux)
 
     // So, do we have a ruleset for this address?  If so, use it now.
     if (ruleset) {
       if (DEBUG_MAIN) {
         ruleset->Print(mLog);
         mLog("\n");
       }
       // Use the RuleSet to compute the registers for the previous
       // frame.  |regs| is modified in-place.
       UseRuleSet(&regs, aStackImg, ruleset, pfxinstrs);
       continue;
     }
 
-#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux)
+#  if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux)
     // There's no RuleSet for the specified address.  On amd64/x86_linux, see if
     // it's possible to recover the caller's frame by using the frame pointer.
 
     // We seek to compute (new_IP, new_SP, new_BP) from (old_BP, stack image),
     // and assume the following layout:
     //
     //                 <--- new_SP
     //   +----------+
@@ -1452,17 +1454,17 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFra
           regs.xbp = new_xbp;
           regs.xip = new_xip;
           regs.xsp = new_xsp;
           (*aFramePointerFramesAcquired)++;
           continue;
         }
       }
     }
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
     // Here is an example of generated code for prologue and epilogue..
     //
     // stp     x29, x30, [sp, #-16]!
     // mov     x29, sp
     // ...
     // ldp     x29, x30, [sp], #16
     // ret
     //
@@ -1513,17 +1515,17 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFra
           // register, and there is no regular rule to compute previous sp
           // register. So mark as invalid.
           regs.sp = TaggedUWord();
           (*aFramePointerFramesAcquired)++;
           continue;
         }
       }
     }
-#endif  // defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux)
+#  endif  // defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux)
 
     // We failed to recover a frame either using CFI or FP chasing, and we
     // have no other ways to recover the frame.  So we have to give up.
     break;
 
   }  // top level unwind loop
 
   // END UNWIND
@@ -1531,23 +1533,23 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFra
 }
 
 ////////////////////////////////////////////////////////////////
 // LUL Unit Testing                                           //
 ////////////////////////////////////////////////////////////////
 
 static const int LUL_UNIT_TEST_STACK_SIZE = 32768;
 
-#if defined(GP_ARCH_mips64)
+#  if defined(GP_ARCH_mips64)
 static __attribute__((noinline)) unsigned long __getpc(void) {
   unsigned long rtaddr;
   __asm__ volatile("move %0, $31" : "=r"(rtaddr));
   return rtaddr;
 }
-#endif
+#  endif
 
 // This function is innermost in the test call sequence.  It uses LUL
 // to unwind, and compares the result with the sequence specified in
 // the director string.  These need to agree in order for the test to
 // pass.  In order not to screw up the results, this function needs
 // to have a not-very big stack frame, since we're only presenting
 // the innermost LUL_UNIT_TEST_STACK_SIZE bytes of stack to LUL, and
 // that chunk unavoidably includes the frame for this function.
@@ -1556,17 +1558,17 @@ static __attribute__((noinline)) unsigne
 // cause the expected-vs-actual backtrace consistency checking to
 // fail.  Prints summary results to |aLUL|'s logging sink and also
 // returns a boolean indicating whether or not the test passed.
 static __attribute__((noinline)) bool GetAndCheckStackTrace(
     LUL* aLUL, const char* dstring) {
   // Get hold of the current unwind-start registers.
   UnwindRegs startRegs;
   memset(&startRegs, 0, sizeof(startRegs));
-#if defined(GP_ARCH_amd64)
+#  if defined(GP_ARCH_amd64)
   volatile uintptr_t block[3];
   MOZ_ASSERT(sizeof(block) == 24);
   __asm__ __volatile__(
       "leaq 0(%%rip), %%r15"
       "\n\t"
       "movq %%r15, 0(%0)"
       "\n\t"
       "movq %%rsp, 8(%0)"
@@ -1576,17 +1578,17 @@ static __attribute__((noinline)) bool Ge
       :
       : "r"(&block[0])
       : "memory", "r15");
   startRegs.xip = TaggedUWord(block[0]);
   startRegs.xsp = TaggedUWord(block[1]);
   startRegs.xbp = TaggedUWord(block[2]);
   const uintptr_t REDZONE_SIZE = 128;
   uintptr_t start = block[1] - REDZONE_SIZE;
-#elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
+#  elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
   volatile uintptr_t block[3];
   MOZ_ASSERT(sizeof(block) == 12);
   __asm__ __volatile__(
       ".byte 0xE8,0x00,0x00,0x00,0x00" /*call next insn*/
       "\n\t"
       "popl %%edi"
       "\n\t"
       "movl %%edi, 0(%0)"
@@ -1598,17 +1600,17 @@ static __attribute__((noinline)) bool Ge
       :
       : "r"(&block[0])
       : "memory", "edi");
   startRegs.xip = TaggedUWord(block[0]);
   startRegs.xsp = TaggedUWord(block[1]);
   startRegs.xbp = TaggedUWord(block[2]);
   const uintptr_t REDZONE_SIZE = 0;
   uintptr_t start = block[1] - REDZONE_SIZE;
-#elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
+#  elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
   volatile uintptr_t block[6];
   MOZ_ASSERT(sizeof(block) == 24);
   __asm__ __volatile__(
       "mov r0, r15"
       "\n\t"
       "str r0,  [%0, #0]"
       "\n\t"
       "str r14, [%0, #4]"
@@ -1627,17 +1629,17 @@ static __attribute__((noinline)) bool Ge
   startRegs.r15 = TaggedUWord(block[0]);
   startRegs.r14 = TaggedUWord(block[1]);
   startRegs.r13 = TaggedUWord(block[2]);
   startRegs.r12 = TaggedUWord(block[3]);
   startRegs.r11 = TaggedUWord(block[4]);
   startRegs.r7 = TaggedUWord(block[5]);
   const uintptr_t REDZONE_SIZE = 0;
   uintptr_t start = block[1] - REDZONE_SIZE;
-#elif defined(GP_ARCH_arm64)
+#  elif defined(GP_ARCH_arm64)
   volatile uintptr_t block[4];
   MOZ_ASSERT(sizeof(block) == 32);
   __asm__ __volatile__(
       "adr x0, . \n\t"
       "str x0, [%0, #0] \n\t"
       "str x29, [%0, #8] \n\t"
       "str x30, [%0, #16] \n\t"
       "mov x0, sp \n\t"
@@ -1646,34 +1648,34 @@ static __attribute__((noinline)) bool Ge
       : "r"(&block[0])
       : "memory", "x0");
   startRegs.pc = TaggedUWord(block[0]);
   startRegs.x29 = TaggedUWord(block[1]);
   startRegs.x30 = TaggedUWord(block[2]);
   startRegs.sp = TaggedUWord(block[3]);
   const uintptr_t REDZONE_SIZE = 0;
   uintptr_t start = block[1] - REDZONE_SIZE;
-#elif defined(GP_ARCH_mips64)
+#  elif defined(GP_ARCH_mips64)
   volatile uintptr_t block[3];
   MOZ_ASSERT(sizeof(block) == 24);
   __asm__ __volatile__(
       "sd $29, 8(%0)     \n"
       "sd $30, 16(%0)    \n"
       :
       : "r"(block)
       : "memory");
   block[0] = __getpc();
   startRegs.pc = TaggedUWord(block[0]);
   startRegs.sp = TaggedUWord(block[1]);
   startRegs.fp = TaggedUWord(block[2]);
   const uintptr_t REDZONE_SIZE = 0;
   uintptr_t start = block[1] - REDZONE_SIZE;
-#else
-#  error "Unsupported platform"
-#endif
+#  else
+#    error "Unsupported platform"
+#  endif
 
   // Get hold of the innermost LUL_UNIT_TEST_STACK_SIZE bytes of the
   // stack.
   uintptr_t end = start + LUL_UNIT_TEST_STACK_SIZE;
   uintptr_t ws = sizeof(void*);
   start &= ~(ws - 1);
   end &= ~(ws - 1);
   uintptr_t nToCopy = end - start;
@@ -1791,87 +1793,88 @@ static __attribute__((noinline)) bool Ge
 // Macro magic to create a set of 8 mutually recursive functions with
 // varying frame sizes.  These will recurse amongst themselves as
 // specified by |strP|, the directory string, and call
 // GetAndCheckStackTrace when the string becomes empty, passing it the
 // original value of the string.  This checks the result, printing
 // results on |aLUL|'s logging sink, and also returns a boolean
 // indicating whether or not the results are acceptable (correct).
 
-#define DECL_TEST_FN(NAME) \
-  bool NAME(LUL* aLUL, const char* strPorig, const char* strP);
+#  define DECL_TEST_FN(NAME) \
+    bool NAME(LUL* aLUL, const char* strPorig, const char* strP);
 
-#define GEN_TEST_FN(NAME, FRAMESIZE)                                          \
-  bool NAME(LUL* aLUL, const char* strPorig, const char* strP) {              \
-    /* Create a frame of size (at least) FRAMESIZE, so that the */            \
-    /* 8 functions created by this macro offer some variation in frame */     \
-    /* sizes.  This isn't as simple as it might seem, since a clever */       \
-    /* optimizing compiler (eg, clang-5) detects that the array is unused */  \
-    /* and removes it.  We try to defeat this by passing it to a function */  \
-    /* in a different compilation unit, and hoping that clang does not */     \
-    /* notice that the call is a no-op. */                                    \
-    char space[FRAMESIZE];                                                    \
-    Unused << write(1, space, 0); /* write zero bytes of |space| to stdout */ \
-                                                                              \
-    if (*strP == '\0') {                                                      \
-      /* We've come to the end of the director string. */                     \
-      /* Take a stack snapshot. */                                            \
-      return GetAndCheckStackTrace(aLUL, strPorig);                           \
-    } else {                                                                  \
-      /* Recurse onwards.  This is a bit subtle.  The obvious */              \
-      /* thing to do here is call onwards directly, from within the */        \
-      /* arms of the case statement.  That gives a problem in that */         \
-      /* there will be multiple return points inside each function when */    \
-      /* unwinding, so it will be difficult to check for consistency */       \
-      /* against the director string.  Instead, we make an indirect */        \
-      /* call, so as to guarantee that there is only one call site */         \
-      /* within each function.  This does assume that the compiler */         \
-      /* won't transform it back to the simple direct-call form. */           \
-      /* To discourage it from doing so, the call is bracketed with */        \
-      /* __asm__ __volatile__ sections so as to make it not-movable. */       \
-      bool (*nextFn)(LUL*, const char*, const char*) = NULL;                  \
-      switch (*strP) {                                                        \
-        case '1':                                                             \
-          nextFn = TestFn1;                                                   \
-          break;                                                              \
-        case '2':                                                             \
-          nextFn = TestFn2;                                                   \
-          break;                                                              \
-        case '3':                                                             \
-          nextFn = TestFn3;                                                   \
-          break;                                                              \
-        case '4':                                                             \
-          nextFn = TestFn4;                                                   \
-          break;                                                              \
-        case '5':                                                             \
-          nextFn = TestFn5;                                                   \
-          break;                                                              \
-        case '6':                                                             \
-          nextFn = TestFn6;                                                   \
-          break;                                                              \
-        case '7':                                                             \
-          nextFn = TestFn7;                                                   \
-          break;                                                              \
-        case '8':                                                             \
-          nextFn = TestFn8;                                                   \
-          break;                                                              \
-        default:                                                              \
-          nextFn = TestFn8;                                                   \
-          break;                                                              \
-      }                                                                       \
-      /* "use" |space| immediately after the recursive call, */               \
-      /* so as to dissuade clang from deallocating the space while */         \
-      /* the call is active, or otherwise messing with the stack frame. */    \
-      __asm__ __volatile__("" ::: "cc", "memory");                            \
-      bool passed = nextFn(aLUL, strPorig, strP + 1);                         \
-      Unused << write(1, space, 0);                                           \
-      __asm__ __volatile__("" ::: "cc", "memory");                            \
-      return passed;                                                          \
-    }                                                                         \
-  }
+#  define GEN_TEST_FN(NAME, FRAMESIZE)                                         \
+    bool NAME(LUL* aLUL, const char* strPorig, const char* strP) {             \
+      /* Create a frame of size (at least) FRAMESIZE, so that the */           \
+      /* 8 functions created by this macro offer some variation in frame */    \
+      /* sizes.  This isn't as simple as it might seem, since a clever */      \
+      /* optimizing compiler (eg, clang-5) detects that the array is unused */ \
+      /* and removes it.  We try to defeat this by passing it to a function */ \
+      /* in a different compilation unit, and hoping that clang does not */    \
+      /* notice that the call is a no-op. */                                   \
+      char space[FRAMESIZE];                                                   \
+      Unused << write(1, space,                                                \
+                      0); /* write zero bytes of |space| to stdout */          \
+                                                                               \
+      if (*strP == '\0') {                                                     \
+        /* We've come to the end of the director string. */                    \
+        /* Take a stack snapshot. */                                           \
+        return GetAndCheckStackTrace(aLUL, strPorig);                          \
+      } else {                                                                 \
+        /* Recurse onwards.  This is a bit subtle.  The obvious */             \
+        /* thing to do here is call onwards directly, from within the */       \
+        /* arms of the case statement.  That gives a problem in that */        \
+        /* there will be multiple return points inside each function when */   \
+        /* unwinding, so it will be difficult to check for consistency */      \
+        /* against the director string.  Instead, we make an indirect */       \
+        /* call, so as to guarantee that there is only one call site */        \
+        /* within each function.  This does assume that the compiler */        \
+        /* won't transform it back to the simple direct-call form. */          \
+        /* To discourage it from doing so, the call is bracketed with */       \
+        /* __asm__ __volatile__ sections so as to make it not-movable. */      \
+        bool (*nextFn)(LUL*, const char*, const char*) = NULL;                 \
+        switch (*strP) {                                                       \
+          case '1':                                                            \
+            nextFn = TestFn1;                                                  \
+            break;                                                             \
+          case '2':                                                            \
+            nextFn = TestFn2;                                                  \
+            break;                                                             \
+          case '3':                                                            \
+            nextFn = TestFn3;                                                  \
+            break;                                                             \
+          case '4':                                                            \
+            nextFn = TestFn4;                                                  \
+            break;                                                             \
+          case '5':                                                            \
+            nextFn = TestFn5;                                                  \
+            break;                                                             \
+          case '6':                                                            \
+            nextFn = TestFn6;                                                  \
+            break;                                                             \
+          case '7':                                                            \
+            nextFn = TestFn7;                                                  \
+            break;                                                             \
+          case '8':                                                            \
+            nextFn = TestFn8;                                                  \
+            break;                                                             \
+          default:                                                             \
+            nextFn = TestFn8;                                                  \
+            break;                                                             \
+        }                                                                      \
+        /* "use" |space| immediately after the recursive call, */              \
+        /* so as to dissuade clang from deallocating the space while */        \
+        /* the call is active, or otherwise messing with the stack frame. */   \
+        __asm__ __volatile__("" ::: "cc", "memory");                           \
+        bool passed = nextFn(aLUL, strPorig, strP + 1);                        \
+        Unused << write(1, space, 0);                                          \
+        __asm__ __volatile__("" ::: "cc", "memory");                           \
+        return passed;                                                         \
+      }                                                                        \
+    }
 
 // The test functions are mutually recursive, so it is necessary to
 // declare them before defining them.
 DECL_TEST_FN(TestFn1)
 DECL_TEST_FN(TestFn2)
 DECL_TEST_FN(TestFn3)
 DECL_TEST_FN(TestFn4)
 DECL_TEST_FN(TestFn5)
@@ -1945,8 +1948,10 @@ void RunLulUnitTests(/*OUT*/ int* aNTest
   TestUnw(aNTests, aNTestsPassed, aLUL, "31415827271828325332173258");
   TestUnw(aNTests, aNTestsPassed, aLUL,
           "123456781122334455667788777777777777777777777");
   aLUL->mLog("LULUnitTest: END\n");
   aLUL->mLog(":\n");
 }
 
 }  // namespace lul
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/lul/platform-linux-lul.cpp
+++ b/mozglue/baseprofiler/lul/platform-linux-lul.cpp
@@ -1,49 +1,53 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include <stdio.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
+#include "BaseProfiler.h"
+
+#ifdef MOZ_BASE_PROFILER
 
-#include "platform.h"
-#include "PlatformMacros.h"
-#include "LulMain.h"
-#include "BaseProfilerSharedLibraries.h"
-#include "AutoObjectMapper.h"
+#  include <stdio.h>
+#  include <signal.h>
+#  include <string.h>
+#  include <stdlib.h>
+#  include <time.h>
+
+#  include "platform.h"
+#  include "PlatformMacros.h"
+#  include "LulMain.h"
+#  include "BaseProfilerSharedLibraries.h"
+#  include "AutoObjectMapper.h"
 
 // Contains miscellaneous helpers that are used to connect the Gecko Profiler
 // and LUL.
 
 // Find out, in a platform-dependent way, where the code modules got
 // mapped in the process' virtual address space, and get |aLUL| to
 // load unwind info for them.
 void read_procmaps(lul::LUL* aLUL) {
   MOZ_ASSERT(aLUL->CountMappings() == 0);
 
-#if defined(GP_OS_linux) || defined(GP_OS_android)
+#  if defined(GP_OS_linux) || defined(GP_OS_android)
   SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
 
   for (size_t i = 0; i < info.GetSize(); i++) {
     const SharedLibrary& lib = info.GetEntry(i);
 
     std::string nativePath = lib.GetNativeDebugPath();
 
-#  if defined(GP_OS_android)
+#    if defined(GP_OS_android)
     // We're using faulty.lib.  Use a special-case object mapper.
     AutoObjectMapperFaultyLib mapper(aLUL->mLog);
-#  else
+#    else
     // We can use the standard POSIX-based mapper.
     AutoObjectMapperPOSIX mapper(aLUL->mLog);
-#  endif
+#    endif
 
     // Ask |mapper| to map the object.  Then hand its mapped address
     // to NotifyAfterMap().
     void* image = nullptr;
     size_t size = 0;
     bool ok = mapper.Map(&image, &size, nativePath);
     if (ok && image && size > 0) {
       aLUL->NotifyAfterMap(lib.GetStart(), lib.GetEnd() - lib.GetStart(),
@@ -57,22 +61,24 @@ void read_procmaps(lul::LUL* aLUL) {
       // mapping, even though it can't read any unwind information for the area.
       aLUL->NotifyExecutableArea(lib.GetStart(), lib.GetEnd() - lib.GetStart());
     }
 
     // |mapper| goes out of scope at this point and so its destructor
     // unmaps the object.
   }
 
-#else
-#  error "Unknown platform"
-#endif
+#  else
+#    error "Unknown platform"
+#  endif
 }
 
 // LUL needs a callback for its logging sink.
 void logging_sink_for_LUL(const char* str) {
   // These are only printed when Verbose logging is enabled (e.g. with
   // MOZ_LOG="prof:5"). This is because LUL's logging is much more verbose than
   // the rest of the profiler's logging, which occurs at the Info (3) and Debug
   // (4) levels.
   MOZ_LOG(gProfilerLog, mozilla::LogLevel::Verbose,
           ("[%d] %s", profiler_current_process_id(), str));
 }
+
+#endif  // MOZ_BASE_PROFILER
--- a/mozglue/baseprofiler/public/BaseProfileJSONWriter.h
+++ b/mozglue/baseprofiler/public/BaseProfileJSONWriter.h
@@ -1,16 +1,22 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef PROFILEJSONWRITER_H
 #define PROFILEJSONWRITER_H
 
+#include "BaseProfiler.h"
+
+#ifndef MOZ_BASE_PROFILER
+#  error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
+#endif
+
 #include "mozilla/JSONWriter.h"
 #include "mozilla/UniquePtr.h"
 
 #include <functional>
 #include <ostream>
 #include <string>
 
 class SpliceableChunkedJSONWriter;
--- a/mozglue/baseprofiler/public/BaseProfiler.h
+++ b/mozglue/baseprofiler/public/BaseProfiler.h
@@ -11,18 +11,36 @@
 //
 // Samples are collected to form a timeline with optional timeline event
 // (markers) used for filtering. The samples include both native stacks and
 // platform-independent "label stack" frames.
 
 #ifndef GeckoProfiler_h
 #define GeckoProfiler_h
 
-// everything in here is also safe to include unconditionally, and only defines
-// empty macros if MOZ_BASE_PROFILER is unset
+// Everything in here is also safe to include unconditionally, and only defines
+// empty macros if MOZ_GECKO_PROFILER or MOZ_BASE_PROFILER is unset.
+
+// MOZ_BASE_PROFILER is #defined (or not) in this header, so it should be
+// #included wherever Base Profiler may be used.
+
+#ifdef MOZ_GECKO_PROFILER
+// Disable Base Profiler for now; will be enabled on supported platforms in
+// later patches.
+#  if 0
+#    define MOZ_BASE_PROFILER
+#  else
+// Other platforms are currently not supported. But you may uncomment the
+// following line to enable Base Profiler in your build.
+//#  define MOZ_BASE_PROFILER
+#  endif
+#endif  // MOZ_GECKO_PROFILER
+
+// BaseProfilerCounts.h is also safe to include unconditionally, with empty
+// macros if MOZ_BASE_PROFILER is unset.
 #include "mozilla/BaseProfilerCounts.h"
 
 #ifndef MOZ_BASE_PROFILER
 
 // This file can be #included unconditionally. However, everything within this
 // file must be guarded by a #ifdef MOZ_BASE_PROFILER, *except* for the
 // following macros, which encapsulate the most common operations and thus
 // avoid the need for many #ifdefs.
--- a/mozglue/baseprofiler/public/BaseProfilerMarkerPayload.h
+++ b/mozglue/baseprofiler/public/BaseProfilerMarkerPayload.h
@@ -2,26 +2,31 @@
 /* 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 ProfilerMarkerPayload_h
 #define ProfilerMarkerPayload_h
 
+#include "BaseProfiler.h"
+
+#ifndef MOZ_BASE_PROFILER
+#  error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
+#endif
+
 #include "mozilla/Attributes.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/UniquePtrExtensions.h"
 #include "mozilla/net/TimingStruct.h"
 
 #include "nsString.h"
-#include "BaseProfiler.h"
 
 #include "js/Utility.h"
 #include "gfxASurface.h"
 #include "mozilla/ServoTraversalStatistics.h"
 
 namespace mozilla {
 namespace layers {
 class Layer;
--- a/mozglue/baseprofiler/public/BaseProfilerSharedLibraries.h
+++ b/mozglue/baseprofiler/public/BaseProfilerSharedLibraries.h
@@ -2,18 +2,20 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 BASE_PROFILER_SHARED_LIBRARIES_H_
 #define BASE_PROFILER_SHARED_LIBRARIES_H_
 
+#include "BaseProfiler.h"
+
 #ifndef MOZ_BASE_PROFILER
-#  error This header does not have a useful implementation on your platform!
+#  error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
 #endif
 
 #include "nsNativeCharsetUtils.h"
 #include "nsString.h"
 #include <nsID.h>
 
 #include <algorithm>
 #include <stdint.h>
--- a/mozglue/baseprofiler/public/BaseProfilingCategory.h
+++ b/mozglue/baseprofiler/public/BaseProfilingCategory.h
@@ -2,16 +2,22 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 js_ProfilingCategory_h
 #define js_ProfilingCategory_h
 
+#include "BaseProfiler.h"
+
+#ifndef MOZ_BASE_PROFILER
+#  error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
+#endif
+
 #include "jstypes.h"  // JS_FRIEND_API
 
 // clang-format off
 
 // This higher-order macro lists all categories with their subcategories.
 //
 // PROFILING_CATEGORY_LIST(BEGIN_CATEGORY, SUBCATEGORY, END_CATEGORY)
 //   BEGIN_CATEGORY(name, labelAsString, colorAsString)
--- a/mozglue/baseprofiler/public/BaseProfilingStack.h
+++ b/mozglue/baseprofiler/public/BaseProfilingStack.h
@@ -2,16 +2,22 @@
  * 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 js_ProfilingStack_h
 #define js_ProfilingStack_h
 
+#include "BaseProfiler.h"
+
+#ifndef MOZ_BASE_PROFILER
+#  error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
+#endif
+
 #include <algorithm>
 #include <stdint.h>
 
 #include "jstypes.h"
 
 #include "js/ProfilingCategory.h"
 #include "js/TypeDecls.h"
 #include "js/Utility.h"
--- a/mozglue/moz.build
+++ b/mozglue/moz.build
@@ -9,14 +9,15 @@ with Files("**"):
 
 if CONFIG['MOZ_LINKER']:
     DIRS += ['linker']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     DIRS += ['android']
 
 DIRS += [
+  'baseprofiler',
   'build',
   'misc',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT']:
     TEST_DIRS += ['tests']