Source code

Revision control

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 http://mozilla.org/MPL/2.0/. */
// 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
#ifndef MOZ_GECKO_PROFILER
# define AUTO_BASE_PROFILER_LABEL(label, categoryPair)
# define AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(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)
#else // !MOZ_GECKO_PROFILER
# include "BaseProfilingStack.h"
# include "mozilla/Attributes.h"
# include "mozilla/Maybe.h"
# include "mozilla/BaseProfilerState.h"
# include "mozilla/ThreadLocal.h"
# include <stdint.h>
# include <string>
// Macros used by the AUTO_PROFILER_* macros.
# define BASE_PROFILER_RAII_PASTE(id, line) id##line
# define BASE_PROFILER_RAII_EXPAND(id, line) BASE_PROFILER_RAII_PASTE(id, line)
# define BASE_PROFILER_RAII BASE_PROFILER_RAII_EXPAND(raiiObject, __LINE__)
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 BASE_PROFILER_RAII( \
label, nullptr, \
::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair)
// 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
// AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_LayerBuilding) which would
// otherwise just repeat the string.
# define AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(categoryPair) \
::mozilla::baseprofiler::AutoProfilerLabel BASE_PROFILER_RAII( \
"", nullptr, \
::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, \
uint32_t(::mozilla::baseprofiler::ProfilingStackFrame::Flags:: \
LABEL_DETERMINED_BY_CATEGORY_PAIR))
// 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 BASE_PROFILER_RAII( \
label, cStr, \
::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair)
// 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,
// unlike AUTO_BASE_PROFILER_LABEL and AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR,
// 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 BASE_PROFILER_RAII( \
ctx, label, nullptr, \
::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair)
// 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 BASE_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 {
public:
// This is the AUTO_BASE_PROFILER_LABEL and AUTO_BASE_PROFILER_LABEL_DYNAMIC
// 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) {
mProfilingStack->pop();
}
}
MFBT_API static ProfilingStack* GetProfilingStack();
private:
// We save a ProfilingStack pointer in the ctor so we don't have to redo the
// TLS lookup in the dtor.
ProfilingStack* mProfilingStack;
public:
// See the comment on the definition in platform.cpp for details about this.
static MOZ_THREAD_LOCAL(ProfilingStack*) sProfilingStack;
};
} // namespace mozilla::baseprofiler
#endif // !MOZ_GECKO_PROFILER
#endif // BaseProfilerLabels_h