Backed out changeset 0a133d5fd155 (bug 1864534) for causing screenshot related failur...
[gecko.git] / mozglue / baseprofiler / public / BaseProfilerMarkers.h
blobd706cefd4ab4c6fd5616c149df6f33bdaeecf079
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/. */
7 // Markers are useful to delimit something important happening such as the first
8 // paint. Unlike labels, which are only recorded in the profile buffer if a
9 // sample is collected while the label is on the label stack, markers will
10 // always be recorded in the profile buffer.
12 // This header contains basic definitions necessary to create marker types, and
13 // to add markers to the profiler buffers.
15 // If basic marker types are needed, #include
16 // "mozilla/BaseProfilerMarkerTypes.h" instead.
18 // But if you want to create your own marker type locally, you can #include this
19 // header only; look at mozilla/BaseProfilerMarkerTypes.h for examples of how to
20 // define types, and mozilla/BaseProfilerMarkerPrerequisites.h for some
21 // supporting types.
23 // To then record markers:
24 // - Use `baseprofiler::AddMarker(...)` from mozglue or other libraries that
25 // are outside of xul, especially if they may happen outside of xpcom's
26 // lifetime (typically startup, shutdown, or tests).
27 // - Otherwise #include "ProfilerMarkers.h" instead, and use
28 // `profiler_add_marker(...)`.
29 // See these functions for more details.
31 #ifndef BaseProfilerMarkers_h
32 #define BaseProfilerMarkers_h
34 #include "mozilla/BaseProfilerMarkersDetail.h"
35 #include "mozilla/BaseProfilerLabels.h"
36 #include "mozilla/TimeStamp.h"
37 #include "mozilla/Unused.h"
39 #include <functional>
40 #include <string>
41 #include <utility>
43 namespace mozilla::baseprofiler {
45 #ifdef MOZ_GECKO_PROFILER
46 // Forward-declaration. TODO: Move to more common header, see bug 1681416.
47 MFBT_API bool profiler_capture_backtrace_into(
48 ProfileChunkedBuffer& aChunkedBuffer, StackCaptureOptions aCaptureOptions);
50 // Add a marker to a given buffer. `AddMarker()` and related macros should be
51 // used in most cases, see below for more information about them and the
52 // parameters; This function may be useful when markers need to be recorded in a
53 // local buffer outside of the main profiler buffer.
54 template <typename MarkerType, typename... PayloadArguments>
55 ProfileBufferBlockIndex AddMarkerToBuffer(
56 ProfileChunkedBuffer& aBuffer, const ProfilerString8View& aName,
57 const MarkerCategory& aCategory, MarkerOptions&& aOptions,
58 MarkerType aMarkerType, const PayloadArguments&... aPayloadArguments) {
59 Unused << aMarkerType; // Only the empty object type is useful.
60 AUTO_BASE_PROFILER_LABEL("baseprofiler::AddMarkerToBuffer", PROFILER);
61 return base_profiler_markers_detail::AddMarkerToBuffer<MarkerType>(
62 aBuffer, aName, aCategory, std::move(aOptions),
63 // Do not capture a stack if the NoMarkerStacks feature is set.
64 profiler_active_without_feature(ProfilerFeature::NoMarkerStacks)
65 ? ::mozilla::baseprofiler::profiler_capture_backtrace_into
66 : nullptr,
67 aPayloadArguments...);
70 // Add a marker (without payload) to a given buffer.
71 inline ProfileBufferBlockIndex AddMarkerToBuffer(
72 ProfileChunkedBuffer& aBuffer, const ProfilerString8View& aName,
73 const MarkerCategory& aCategory, MarkerOptions&& aOptions = {}) {
74 return AddMarkerToBuffer(aBuffer, aName, aCategory, std::move(aOptions),
75 markers::NoPayload{});
77 #endif // MOZ_GECKO_PROFILER
79 // Add a marker to the Base Profiler buffer.
80 // - aName: Main name of this marker.
81 // - aCategory: Category for this marker.
82 // - aOptions: Optional settings (such as timing, inner window id,
83 // backtrace...), see `MarkerOptions` for details.
84 // - aMarkerType: Empty object that specifies the type of marker.
85 // - aPayloadArguments: Arguments expected by this marker type's
86 // ` StreamJSONMarkerData` function.
87 template <typename MarkerType, typename... PayloadArguments>
88 ProfileBufferBlockIndex AddMarker(
89 const ProfilerString8View& aName, const MarkerCategory& aCategory,
90 MarkerOptions&& aOptions, MarkerType aMarkerType,
91 const PayloadArguments&... aPayloadArguments) {
92 #ifndef MOZ_GECKO_PROFILER
93 return {};
94 #else
95 // Record base markers whenever the core buffer is in session.
96 // TODO: When profiler_thread_is_being_profiled becomes available from
97 // mozglue, use it instead.
98 ProfileChunkedBuffer& coreBuffer =
99 ::mozilla::baseprofiler::profiler_get_core_buffer();
100 if (!coreBuffer.IsInSession()) {
101 return {};
103 return ::mozilla::baseprofiler::AddMarkerToBuffer(
104 coreBuffer, aName, aCategory, std::move(aOptions), aMarkerType,
105 aPayloadArguments...);
106 #endif
109 // Add a marker (without payload) to the Base Profiler buffer.
110 inline ProfileBufferBlockIndex AddMarker(const ProfilerString8View& aName,
111 const MarkerCategory& aCategory,
112 MarkerOptions&& aOptions = {}) {
113 return AddMarker(aName, aCategory, std::move(aOptions), markers::NoPayload{});
116 } // namespace mozilla::baseprofiler
118 // Same as `AddMarker()` (without payload). This macro is safe to use even if
119 // MOZ_GECKO_PROFILER is not #defined.
120 #define BASE_PROFILER_MARKER_UNTYPED(markerName, categoryName, ...) \
121 do { \
122 AUTO_PROFILER_STATS(BASE_PROFILER_MARKER_UNTYPED); \
123 ::mozilla::baseprofiler::AddMarker( \
124 markerName, ::mozilla::baseprofiler::category::categoryName, \
125 ##__VA_ARGS__); \
126 } while (false)
128 // Same as `AddMarker()` (with payload). This macro is safe to use even if
129 // MOZ_GECKO_PROFILER is not #defined.
130 #define BASE_PROFILER_MARKER(markerName, categoryName, options, MarkerType, \
131 ...) \
132 do { \
133 AUTO_PROFILER_STATS(BASE_PROFILER_MARKER_with_##MarkerType); \
134 ::mozilla::baseprofiler::AddMarker( \
135 markerName, ::mozilla::baseprofiler::category::categoryName, options, \
136 ::mozilla::baseprofiler::markers::MarkerType{}, ##__VA_ARGS__); \
137 } while (false)
139 namespace mozilla::baseprofiler::markers {
140 // Most common marker type. Others are in BaseProfilerMarkerTypes.h.
141 struct TextMarker {
142 static constexpr Span<const char> MarkerTypeName() {
143 return MakeStringSpan("Text");
145 static void StreamJSONMarkerData(baseprofiler::SpliceableJSONWriter& aWriter,
146 const ProfilerString8View& aText) {
147 aWriter.StringProperty("name", aText);
149 static MarkerSchema MarkerTypeDisplay() {
150 using MS = MarkerSchema;
151 MS schema{MS::Location::MarkerChart, MS::Location::MarkerTable};
152 schema.SetChartLabel("{marker.data.name}");
153 schema.SetTableLabel("{marker.name} - {marker.data.name}");
154 schema.AddKeyLabelFormatSearchable("name", "Details", MS::Format::String,
155 MS::Searchable::Searchable);
156 return schema;
160 // Keep this struct in sync with the `gecko_profiler::marker::Tracing` Rust
161 // counterpart.
162 struct Tracing {
163 static constexpr Span<const char> MarkerTypeName() {
164 return MakeStringSpan("tracing");
166 static void StreamJSONMarkerData(SpliceableJSONWriter& aWriter,
167 const ProfilerString8View& aCategory) {
168 if (aCategory.Length() != 0) {
169 aWriter.StringProperty("category", aCategory);
172 static MarkerSchema MarkerTypeDisplay() {
173 using MS = MarkerSchema;
174 MS schema{MS::Location::MarkerChart, MS::Location::MarkerTable,
175 MS::Location::TimelineOverview};
176 schema.AddKeyLabelFormatSearchable("category", "Type", MS::Format::String,
177 MS::Searchable::Searchable);
178 return schema;
181 } // namespace mozilla::baseprofiler::markers
183 // Add a text marker. This macro is safe to use even if MOZ_GECKO_PROFILER is
184 // not #defined.
185 #define BASE_PROFILER_MARKER_TEXT(markerName, categoryName, options, text) \
186 do { \
187 AUTO_PROFILER_STATS(BASE_PROFILER_MARKER_TEXT); \
188 ::mozilla::baseprofiler::AddMarker( \
189 markerName, ::mozilla::baseprofiler::category::categoryName, options, \
190 ::mozilla::baseprofiler::markers::TextMarker{}, text); \
191 } while (false)
193 namespace mozilla::baseprofiler {
195 // RAII object that adds a BASE_PROFILER_MARKER_TEXT when destroyed; the
196 // marker's timing will be the interval from construction (unless an instant or
197 // start time is already specified in the provided options) until destruction.
198 class MOZ_RAII AutoProfilerTextMarker {
199 public:
200 AutoProfilerTextMarker(const char* aMarkerName,
201 const MarkerCategory& aCategory,
202 MarkerOptions&& aOptions, const std::string& aText)
203 : mMarkerName(aMarkerName),
204 mCategory(aCategory),
205 mOptions(std::move(aOptions)),
206 mText(aText) {
207 MOZ_ASSERT(mOptions.Timing().EndTime().IsNull(),
208 "AutoProfilerTextMarker options shouldn't have an end time");
209 if (profiler_is_active_and_unpaused() &&
210 mOptions.Timing().StartTime().IsNull()) {
211 mOptions.Set(MarkerTiming::InstantNow());
215 ~AutoProfilerTextMarker() {
216 if (profiler_is_active_and_unpaused()) {
217 mOptions.TimingRef().SetIntervalEnd();
218 AUTO_PROFILER_STATS(AUTO_BASE_PROFILER_MARKER_TEXT);
219 AddMarker(ProfilerString8View::WrapNullTerminatedString(mMarkerName),
220 mCategory, std::move(mOptions), markers::TextMarker{}, mText);
224 protected:
225 const char* mMarkerName;
226 MarkerCategory mCategory;
227 MarkerOptions mOptions;
228 std::string mText;
231 #ifdef MOZ_GECKO_PROFILER
232 extern template MFBT_API ProfileBufferBlockIndex
233 AddMarker(const ProfilerString8View&, const MarkerCategory&, MarkerOptions&&,
234 markers::TextMarker, const std::string&);
236 extern template MFBT_API ProfileBufferBlockIndex
237 AddMarkerToBuffer(ProfileChunkedBuffer&, const ProfilerString8View&,
238 const MarkerCategory&, MarkerOptions&&, markers::NoPayload);
240 extern template MFBT_API ProfileBufferBlockIndex AddMarkerToBuffer(
241 ProfileChunkedBuffer&, const ProfilerString8View&, const MarkerCategory&,
242 MarkerOptions&&, markers::TextMarker, const std::string&);
243 #endif // MOZ_GECKO_PROFILER
245 } // namespace mozilla::baseprofiler
247 // Creates an AutoProfilerTextMarker RAII object. This macro is safe to use
248 // even if MOZ_GECKO_PROFILER is not #defined.
249 #define AUTO_BASE_PROFILER_MARKER_TEXT(markerName, categoryName, options, \
250 text) \
251 ::mozilla::baseprofiler::AutoProfilerTextMarker PROFILER_RAII( \
252 markerName, ::mozilla::baseprofiler::category::categoryName, options, \
253 text)
255 #endif // BaseProfilerMarkers_h