Bug 1573273: Add ProfilerLabelBegin and ProfilerLabelEnd to mozglue; r=gerald
authorAaron Klotz <aklotz@mozilla.com>
Wed, 14 Aug 2019 03:46:41 +0000
changeset 487915 02d5d29830cf35a3c467bc6fa21864230ea73475
parent 487914 f562fda29d7c0e097e27b631816e52d28d8d4278
child 487916 771185e8e4dc342f4343d81bf98d852f8a640328
push id36433
push userbtara@mozilla.com
push dateWed, 14 Aug 2019 21:57:52 +0000
treeherdermozilla-central@7d9a2196d313 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1573273
milestone70.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 1573273: Add ProfilerLabelBegin and ProfilerLabelEnd to mozglue; r=gerald While mozglue continues to be the correct location for calling the affected code in this patch, the calls requiring profiler labels will soon be originating from firefox.exe via the launcher process. mozglue will be supplying the launcher process with an interface that consists of what are effectively "OnBeginDllLoad" and "OnEndDllLoad" callback notifications; obviously an RAII class is not going to be useful for that case. We still want to keep the RAII stuff around, however, since we still need it for cases where we need to fall back to using the legacy DLL blocklist. Differential Revision: https://phabricator.services.mozilla.com/D41807
mozglue/misc/AutoProfilerLabel.cpp
mozglue/misc/AutoProfilerLabel.h
--- a/mozglue/misc/AutoProfilerLabel.cpp
+++ b/mozglue/misc/AutoProfilerLabel.cpp
@@ -25,16 +25,18 @@ class MOZ_RAII AutoProfilerLabelData {
   ProfilerLabelEnter& EnterRef() { return sEnter; }
 
   const ProfilerLabelExit& ExitCRef() const { return sExit; }
   ProfilerLabelExit& ExitRef() { return sExit; }
 
   const uint32_t& GenerationCRef() const { return sGeneration; }
   uint32_t& GenerationRef() { return sGeneration; }
 
+  static bool RacyIsProfilerPresent() { return !!sGeneration; }
+
  private:
   // Thin shell around mozglue PlatformMutex, for local internal use.
   // Does not preserve behavior in JS record/replay.
   class Mutex : private mozilla::detail::MutexImpl {
    public:
     Mutex()
         : mozilla::detail::MutexImpl(
               mozilla::recordreplay::Behavior::DontPreserve) {}
@@ -64,31 +66,48 @@ void RegisterProfilerLabelEnterExit(Prof
   AutoProfilerLabelData data;
   MOZ_ASSERT(!aEnter != !data.EnterRef(),
              "Must go from null to non-null, or from non-null to null");
   data.EnterRef() = aEnter;
   data.ExitRef() = aExit;
   ++data.GenerationRef();
 }
 
+bool IsProfilerPresent() {
+  return AutoProfilerLabelData::RacyIsProfilerPresent();
+}
+
+ProfilerLabel ProfilerLabelBegin(const char* aLabelName,
+                                 const char* aDynamicString, void* aSp) {
+  const AutoProfilerLabelData data;
+  void* entryContext = (data.EnterCRef())
+                           ? data.EnterCRef()(aLabelName, aDynamicString, aSp)
+                           : nullptr;
+  uint32_t generation = data.GenerationCRef();
+
+  return MakeTuple(entryContext, generation);
+}
+
+void ProfilerLabelEnd(const ProfilerLabel& aLabel) {
+  if (!IsValidProfilerLabel(aLabel)) {
+    return;
+  }
+
+  const AutoProfilerLabelData data;
+  if (data.ExitCRef() && (Get<1>(aLabel) == data.GenerationCRef())) {
+    data.ExitCRef()(Get<0>(aLabel));
+  }
+}
+
 AutoProfilerLabel::AutoProfilerLabel(
     const char* aLabel,
     const char* aDynamicString MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
-  const AutoProfilerLabelData data;
-  mEntryContext = (data.EnterCRef())
-                      ? data.EnterCRef()(aLabel, aDynamicString, this)
-                      : nullptr;
-  mGeneration = data.GenerationCRef();
+  Tie(mEntryContext, mGeneration) =
+      ProfilerLabelBegin(aLabel, aDynamicString, this);
 }
 
 AutoProfilerLabel::~AutoProfilerLabel() {
-  if (!mEntryContext) {
-    return;
-  }
-  const AutoProfilerLabelData data;
-  if (data.ExitCRef() && (mGeneration == data.GenerationCRef())) {
-    data.ExitCRef()(mEntryContext);
-  }
+  ProfilerLabelEnd(MakeTuple(mEntryContext, mGeneration));
 }
 
 }  // namespace mozilla
--- a/mozglue/misc/AutoProfilerLabel.h
+++ b/mozglue/misc/AutoProfilerLabel.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_AutoProfilerLabel_h
 #define mozilla_AutoProfilerLabel_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/GuardObjects.h"
+#include "mozilla/Tuple.h"
 #include "mozilla/Types.h"
 
 // The Gecko Profiler defines AutoProfilerLabel, an RAII class for
 // pushing/popping frames to/from the ProfilingStack.
 //
 // This file defines a class of the same name that does much the same thing,
 // but which can be used in (and only in) mozglue. A different class is
 // necessary because mozglue cannot directly access sProfilingStack.
@@ -49,13 +50,24 @@ class MOZ_RAII AutoProfilerLabel {
  private:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   void* mEntryContext;
   // Number of RegisterProfilerLabelEnterExit calls, to avoid giving an entry
   // context from one generation to the next.
   uint32_t mGeneration;
 };
 
+using ProfilerLabel = Tuple<void*, uint32_t>;
+
+bool IsProfilerPresent();
+ProfilerLabel ProfilerLabelBegin(const char* aLabelName,
+                                 const char* aDynamicString, void* aSp);
+void ProfilerLabelEnd(const ProfilerLabel& aLabel);
+
+inline bool IsValidProfilerLabel(const ProfilerLabel& aLabel) {
+  return !!Get<0>(aLabel);
+}
+
 #endif
 
 }  // namespace mozilla
 
 #endif  // mozilla_AutoProfilerLabel_h