Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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 */
// This header contains all definitions related to Base Profiler labels (outside
// of XUL).
// It is safe to include unconditionally, and only defines empty macros if
// MOZ_GECKO_PROFILER is not set.
#ifndef BaseProfilerLabels_h
#define BaseProfilerLabels_h
# define AUTO_BASE_PROFILER_LABEL(label, categoryPair)
# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr)
# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(label, categoryPair, str)
# define AUTO_BASE_PROFILER_LABEL_FAST(label, categoryPair, ctx)
# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, \
categoryPair, ctx, flags)
# include "BaseProfilingStack.h"
# include "mozilla/Attributes.h"
# include "mozilla/Maybe.h"
# include "mozilla/BaseProfilerRAIIMacro.h"
# include "mozilla/BaseProfilerState.h"
# include "mozilla/ThreadLocal.h"
# include <stdint.h>
# include <string>
namespace mozilla::baseprofiler {
// Insert an RAII object in this scope to enter a label stack frame. Any
// samples collected in this scope will contain this label in their stack.
// The label argument must be a static C string. It is usually of the
// form "ClassName::FunctionName". (Ideally we'd use the compiler to provide
// that for us, but __func__ gives us the function name without the class
// name.) If the label applies to only part of a function, you can qualify it
// like this: "ClassName::FunctionName:PartName".
// Use AUTO_BASE_PROFILER_LABEL_DYNAMIC_* if you want to add additional /
// dynamic information to the label stack frame.
# define AUTO_BASE_PROFILER_LABEL(label, categoryPair) \
::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \
label, nullptr, \
// Similar to AUTO_BASE_PROFILER_LABEL, but with only one argument: the category
// pair. The label string is taken from the category pair. This is convenient
// for labels like
// otherwise just repeat the string.
::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \
"", nullptr, \
::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, \
uint32_t(::mozilla::baseprofiler::ProfilingStackFrame::Flags:: \
// Similar to AUTO_BASE_PROFILER_LABEL, but with an additional string. The
// inserted RAII object stores the cStr pointer in a field; it does not copy the
// string.
// WARNING: This means that the string you pass to this macro needs to live at
// least until the end of the current scope. Be careful using this macro with
// ns[C]String; the other AUTO_BASE_PROFILER_LABEL_DYNAMIC_* macros below are
// preferred because they avoid this problem.
// If the profiler samples the current thread and walks the label stack while
// this RAII object is on the stack, it will copy the supplied string into the
// profile buffer. So there's one string copy operation, and it happens at
// sample time.
// Compare this to the plain AUTO_BASE_PROFILER_LABEL macro, which only accepts
// literal strings: When the label stack frames generated by
// AUTO_BASE_PROFILER_LABEL are sampled, no string copy needs to be made because
// the profile buffer can just store the raw pointers to the literal strings.
// Consequently, AUTO_BASE_PROFILER_LABEL frames take up considerably less space
// in the profile buffer than AUTO_BASE_PROFILER_LABEL_DYNAMIC_* frames.
# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr) \
::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \
label, cStr, \
// Similar to AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR, but takes an std::string.
// Note: The use of the Maybe<>s ensures the scopes for the dynamic string and
// the AutoProfilerLabel are appropriate, while also not incurring the runtime
// cost of the string assignment unless the profiler is active. Therefore,
// this macro doesn't push/pop a label when the profiler is inactive.
# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(label, categoryPair, str) \
Maybe<std::string> autoStr; \
Maybe<::mozilla::baseprofiler::AutoProfilerLabel> raiiObjectString; \
if (::mozilla::baseprofiler::profiler_is_active()) { \
autoStr.emplace(str); \
raiiObjectString.emplace( \
label, autoStr->c_str(), \
::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair); \
// Similar to AUTO_BASE_PROFILER_LABEL, but accepting a JSContext* parameter,
// and a no-op if the profiler is disabled. Used to annotate functions for which
// overhead in the range of nanoseconds is noticeable. It avoids overhead from
// the TLS lookup because it can get the ProfilingStack from the JS context, and
// avoids almost all overhead in the case where the profiler is disabled.
# define AUTO_BASE_PROFILER_LABEL_FAST(label, categoryPair, ctx) \
::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \
ctx, label, nullptr, \
// Similar to AUTO_BASE_PROFILER_LABEL_FAST, but also takes an extra string and
// an additional set of flags. The flags parameter should carry values from the
// ProfilingStackFrame::Flags enum.
# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, \
categoryPair, ctx, flags) \
::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \
ctx, label, dynamicString, \
::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, flags)
// This class creates a non-owning ProfilingStack reference. Objects of this
// class are stack-allocated, and so exist within a thread, and are thus bounded
// by the lifetime of the thread, which ensures that the references held can't
// be used after the ProfilingStack is destroyed.
class MOZ_RAII AutoProfilerLabel {
// variant.
AutoProfilerLabel(const char* aLabel, const char* aDynamicString,
ProfilingCategoryPair aCategoryPair, uint32_t aFlags = 0) {
// Get the ProfilingStack from TLS.
Push(GetProfilingStack(), aLabel, aDynamicString, aCategoryPair, aFlags);
void Push(ProfilingStack* aProfilingStack, const char* aLabel,
const char* aDynamicString, ProfilingCategoryPair aCategoryPair,
uint32_t aFlags = 0) {
// This function runs both on and off the main thread.
mProfilingStack = aProfilingStack;
if (mProfilingStack) {
mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this,
aCategoryPair, aFlags);
~AutoProfilerLabel() {
// This function runs both on and off the main thread.
if (mProfilingStack) {
MFBT_API static ProfilingStack* GetProfilingStack();
// We save a ProfilingStack pointer in the ctor so we don't have to redo the
// TLS lookup in the dtor.
ProfilingStack* mProfilingStack;
// See the comment on the definition in platform.cpp for details about this.
static MOZ_THREAD_LOCAL(ProfilingStack*) sProfilingStack;
} // namespace mozilla::baseprofiler
#endif // BaseProfilerLabels_h