tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BaseProfilerLabels.h (8589B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 // This header contains all definitions related to Base Profiler labels (outside
      8 // of XUL).
      9 // It is safe to include unconditionally, and only defines empty macros if
     10 // MOZ_GECKO_PROFILER is not set.
     11 
     12 #ifndef BaseProfilerLabels_h
     13 #define BaseProfilerLabels_h
     14 
     15 #ifndef MOZ_GECKO_PROFILER
     16 
     17 #  define AUTO_BASE_PROFILER_LABEL(label, categoryPair)
     18 #  define AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(categoryPair)
     19 #  define AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr)
     20 #  define AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(label, categoryPair, str)
     21 #  define AUTO_BASE_PROFILER_LABEL_FAST(label, categoryPair, ctx)
     22 #  define AUTO_BASE_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, \
     23                                                categoryPair, ctx, flags)
     24 
     25 #else  // !MOZ_GECKO_PROFILER
     26 
     27 #  include "BaseProfilingStack.h"
     28 
     29 #  include "mozilla/Attributes.h"
     30 #  include "mozilla/Maybe.h"
     31 #  include "mozilla/BaseProfilerRAIIMacro.h"
     32 #  include "mozilla/BaseProfilerState.h"
     33 #  include "mozilla/ThreadLocal.h"
     34 
     35 #  include <stdint.h>
     36 #  include <string>
     37 
     38 namespace mozilla::baseprofiler {
     39 
     40 // Insert an RAII object in this scope to enter a label stack frame. Any
     41 // samples collected in this scope will contain this label in their stack.
     42 // The label argument must be a static C string. It is usually of the
     43 // form "ClassName::FunctionName". (Ideally we'd use the compiler to provide
     44 // that for us, but __func__ gives us the function name without the class
     45 // name.) If the label applies to only part of a function, you can qualify it
     46 // like this: "ClassName::FunctionName:PartName".
     47 //
     48 // Use AUTO_BASE_PROFILER_LABEL_DYNAMIC_* if you want to add additional /
     49 // dynamic information to the label stack frame.
     50 #  define AUTO_BASE_PROFILER_LABEL(label, categoryPair)       \
     51    ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \
     52        label, nullptr,                                       \
     53        ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair)
     54 
     55 // Similar to AUTO_BASE_PROFILER_LABEL, but with only one argument: the category
     56 // pair. The label string is taken from the category pair. This is convenient
     57 // for labels like
     58 // AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_LayerBuilding) which would
     59 // otherwise just repeat the string.
     60 #  define AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(categoryPair)         \
     61    ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII(          \
     62        "", nullptr,                                                   \
     63        ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair,  \
     64        uint32_t(::mozilla::baseprofiler::ProfilingStackFrame::Flags:: \
     65                     LABEL_DETERMINED_BY_CATEGORY_PAIR))
     66 
     67 // Similar to AUTO_BASE_PROFILER_LABEL, but with an additional string. The
     68 // inserted RAII object stores the cStr pointer in a field; it does not copy the
     69 // string.
     70 //
     71 // WARNING: This means that the string you pass to this macro needs to live at
     72 // least until the end of the current scope. Be careful using this macro with
     73 // ns[C]String; the other AUTO_BASE_PROFILER_LABEL_DYNAMIC_* macros below are
     74 // preferred because they avoid this problem.
     75 //
     76 // If the profiler samples the current thread and walks the label stack while
     77 // this RAII object is on the stack, it will copy the supplied string into the
     78 // profile buffer. So there's one string copy operation, and it happens at
     79 // sample time.
     80 //
     81 // Compare this to the plain AUTO_BASE_PROFILER_LABEL macro, which only accepts
     82 // literal strings: When the label stack frames generated by
     83 // AUTO_BASE_PROFILER_LABEL are sampled, no string copy needs to be made because
     84 // the profile buffer can just store the raw pointers to the literal strings.
     85 // Consequently, AUTO_BASE_PROFILER_LABEL frames take up considerably less space
     86 // in the profile buffer than AUTO_BASE_PROFILER_LABEL_DYNAMIC_* frames.
     87 #  define AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr) \
     88    ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII(              \
     89        label, cStr,                                                       \
     90        ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair)
     91 
     92 // Similar to AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR, but takes an std::string.
     93 //
     94 // Note: The use of the Maybe<>s ensures the scopes for the dynamic string and
     95 // the AutoProfilerLabel are appropriate, while also not incurring the runtime
     96 // cost of the string assignment unless the profiler is active. Therefore,
     97 // unlike AUTO_BASE_PROFILER_LABEL and AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR,
     98 // this macro doesn't push/pop a label when the profiler is inactive.
     99 #  define AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(label, categoryPair, str) \
    100    Maybe<std::string> autoStr;                                             \
    101    Maybe<::mozilla::baseprofiler::AutoProfilerLabel> raiiObjectString;     \
    102    if (::mozilla::baseprofiler::profiler_is_active()) {                    \
    103      autoStr.emplace(str);                                                 \
    104      raiiObjectString.emplace(                                             \
    105          label, autoStr->c_str(),                                          \
    106          ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair);    \
    107    }
    108 
    109 // Similar to AUTO_BASE_PROFILER_LABEL, but accepting a JSContext* parameter,
    110 // and a no-op if the profiler is disabled. Used to annotate functions for which
    111 // overhead in the range of nanoseconds is noticeable. It avoids overhead from
    112 // the TLS lookup because it can get the ProfilingStack from the JS context, and
    113 // avoids almost all overhead in the case where the profiler is disabled.
    114 #  define AUTO_BASE_PROFILER_LABEL_FAST(label, categoryPair, ctx) \
    115    ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII(     \
    116        ctx, label, nullptr,                                      \
    117        ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair)
    118 
    119 // Similar to AUTO_BASE_PROFILER_LABEL_FAST, but also takes an extra string and
    120 // an additional set of flags. The flags parameter should carry values from the
    121 // ProfilingStackFrame::Flags enum.
    122 #  define AUTO_BASE_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString,     \
    123                                                categoryPair, ctx, flags) \
    124    ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII(             \
    125        ctx, label, dynamicString,                                        \
    126        ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, flags)
    127 
    128 // This class creates a non-owning ProfilingStack reference. Objects of this
    129 // class are stack-allocated, and so exist within a thread, and are thus bounded
    130 // by the lifetime of the thread, which ensures that the references held can't
    131 // be used after the ProfilingStack is destroyed.
    132 class MOZ_RAII AutoProfilerLabel {
    133 public:
    134  // This is the AUTO_BASE_PROFILER_LABEL and AUTO_BASE_PROFILER_LABEL_DYNAMIC
    135  // variant.
    136  AutoProfilerLabel(const char* aLabel, const char* aDynamicString,
    137                    ProfilingCategoryPair aCategoryPair, uint32_t aFlags = 0) {
    138    // Get the ProfilingStack from TLS.
    139    Push(GetProfilingStack(), aLabel, aDynamicString, aCategoryPair, aFlags);
    140  }
    141 
    142  void Push(ProfilingStack* aProfilingStack, const char* aLabel,
    143            const char* aDynamicString, ProfilingCategoryPair aCategoryPair,
    144            uint32_t aFlags = 0) {
    145    // This function runs both on and off the main thread.
    146 
    147    mProfilingStack = aProfilingStack;
    148    if (mProfilingStack) {
    149      mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this,
    150                                      aCategoryPair, aFlags);
    151    }
    152  }
    153 
    154  ~AutoProfilerLabel() {
    155    // This function runs both on and off the main thread.
    156 
    157    if (mProfilingStack) {
    158      mProfilingStack->pop();
    159    }
    160  }
    161 
    162  MFBT_API static ProfilingStack* GetProfilingStack();
    163 
    164 private:
    165  // We save a ProfilingStack pointer in the ctor so we don't have to redo the
    166  // TLS lookup in the dtor.
    167  ProfilingStack* mProfilingStack;
    168 
    169 public:
    170  // See the comment on the definition in platform.cpp for details about this.
    171  static MOZ_THREAD_LOCAL(ProfilingStack*) sProfilingStack;
    172 };
    173 
    174 }  // namespace mozilla::baseprofiler
    175 
    176 #endif  // !MOZ_GECKO_PROFILER
    177 
    178 #endif  // BaseProfilerLabels_h