/* -*- 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/BaseProfilerRAIIMacro.h" # include "mozilla/BaseProfilerState.h" # include "mozilla/ThreadLocal.h" # include # include 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, \ ::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 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 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 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, \ ::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 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