Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / tools / profiler / core / ProfilerBindings.cpp
blob833facba00d870f09da102d9deea23aee4488415
1 /* -*- Mode: C++; tab-width: 8; 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 /* FFI functions for Profiler Rust API to call into profiler */
9 #include "ProfilerBindings.h"
11 #include "GeckoProfiler.h"
13 #include <set>
14 #include <type_traits>
16 void gecko_profiler_register_thread(const char* aName) {
17 PROFILER_REGISTER_THREAD(aName);
20 void gecko_profiler_unregister_thread() { PROFILER_UNREGISTER_THREAD(); }
22 void gecko_profiler_construct_label(mozilla::AutoProfilerLabel* aAutoLabel,
23 JS::ProfilingCategoryPair aCategoryPair) {
24 #ifdef MOZ_GECKO_PROFILER
25 new (aAutoLabel) mozilla::AutoProfilerLabel(
26 "", nullptr, aCategoryPair,
27 uint32_t(
28 js::ProfilingStackFrame::Flags::LABEL_DETERMINED_BY_CATEGORY_PAIR));
29 #endif
32 void gecko_profiler_destruct_label(mozilla::AutoProfilerLabel* aAutoLabel) {
33 #ifdef MOZ_GECKO_PROFILER
34 aAutoLabel->~AutoProfilerLabel();
35 #endif
38 void gecko_profiler_construct_timestamp_now(mozilla::TimeStamp* aTimeStamp) {
39 new (aTimeStamp) mozilla::TimeStamp(mozilla::TimeStamp::Now());
42 void gecko_profiler_clone_timestamp(const mozilla::TimeStamp* aSrcTimeStamp,
43 mozilla::TimeStamp* aDestTimeStamp) {
44 new (aDestTimeStamp) mozilla::TimeStamp(*aSrcTimeStamp);
47 void gecko_profiler_destruct_timestamp(mozilla::TimeStamp* aTimeStamp) {
48 aTimeStamp->~TimeStamp();
51 void gecko_profiler_add_timestamp(const mozilla::TimeStamp* aTimeStamp,
52 mozilla::TimeStamp* aDestTimeStamp,
53 double aMicroseconds) {
54 new (aDestTimeStamp) mozilla::TimeStamp(
55 *aTimeStamp + mozilla::TimeDuration::FromMicroseconds(aMicroseconds));
58 void gecko_profiler_subtract_timestamp(const mozilla::TimeStamp* aTimeStamp,
59 mozilla::TimeStamp* aDestTimeStamp,
60 double aMicroseconds) {
61 new (aDestTimeStamp) mozilla::TimeStamp(
62 *aTimeStamp - mozilla::TimeDuration::FromMicroseconds(aMicroseconds));
65 void gecko_profiler_construct_marker_timing_instant_at(
66 mozilla::MarkerTiming* aMarkerTiming, const mozilla::TimeStamp* aTime) {
67 #ifdef MOZ_GECKO_PROFILER
68 static_assert(std::is_trivially_copyable_v<mozilla::MarkerTiming>);
69 mozilla::MarkerTiming::UnsafeConstruct(aMarkerTiming, *aTime,
70 mozilla::TimeStamp{},
71 mozilla::MarkerTiming::Phase::Instant);
72 #endif
75 void gecko_profiler_construct_marker_timing_instant_now(
76 mozilla::MarkerTiming* aMarkerTiming) {
77 #ifdef MOZ_GECKO_PROFILER
78 static_assert(std::is_trivially_copyable_v<mozilla::MarkerTiming>);
79 mozilla::MarkerTiming::UnsafeConstruct(
80 aMarkerTiming, mozilla::TimeStamp::Now(), mozilla::TimeStamp{},
81 mozilla::MarkerTiming::Phase::Instant);
82 #endif
85 void gecko_profiler_construct_marker_timing_interval(
86 mozilla::MarkerTiming* aMarkerTiming, const mozilla::TimeStamp* aStartTime,
87 const mozilla::TimeStamp* aEndTime) {
88 #ifdef MOZ_GECKO_PROFILER
89 static_assert(std::is_trivially_copyable_v<mozilla::MarkerTiming>);
90 mozilla::MarkerTiming::UnsafeConstruct(
91 aMarkerTiming, *aStartTime, *aEndTime,
92 mozilla::MarkerTiming::Phase::Interval);
93 #endif
96 void gecko_profiler_construct_marker_timing_interval_until_now_from(
97 mozilla::MarkerTiming* aMarkerTiming,
98 const mozilla::TimeStamp* aStartTime) {
99 #ifdef MOZ_GECKO_PROFILER
100 static_assert(std::is_trivially_copyable_v<mozilla::MarkerTiming>);
101 mozilla::MarkerTiming::UnsafeConstruct(
102 aMarkerTiming, *aStartTime, mozilla::TimeStamp::Now(),
103 mozilla::MarkerTiming::Phase::Interval);
104 #endif
107 void gecko_profiler_construct_marker_timing_interval_start(
108 mozilla::MarkerTiming* aMarkerTiming, const mozilla::TimeStamp* aTime) {
109 #ifdef MOZ_GECKO_PROFILER
110 static_assert(std::is_trivially_copyable_v<mozilla::MarkerTiming>);
111 mozilla::MarkerTiming::UnsafeConstruct(
112 aMarkerTiming, *aTime, mozilla::TimeStamp{},
113 mozilla::MarkerTiming::Phase::IntervalStart);
114 #endif
117 void gecko_profiler_construct_marker_timing_interval_end(
118 mozilla::MarkerTiming* aMarkerTiming, const mozilla::TimeStamp* aTime) {
119 #ifdef MOZ_GECKO_PROFILER
120 static_assert(std::is_trivially_copyable_v<mozilla::MarkerTiming>);
121 mozilla::MarkerTiming::UnsafeConstruct(
122 aMarkerTiming, mozilla::TimeStamp{}, *aTime,
123 mozilla::MarkerTiming::Phase::IntervalEnd);
124 #endif
127 void gecko_profiler_destruct_marker_timing(
128 mozilla::MarkerTiming* aMarkerTiming) {
129 #ifdef MOZ_GECKO_PROFILER
130 aMarkerTiming->~MarkerTiming();
131 #endif
134 mozilla::MarkerSchema* gecko_profiler_construct_marker_schema(
135 const mozilla::MarkerSchema::Location* aLocations, size_t aLength) {
136 #ifdef MOZ_GECKO_PROFILER
137 return new mozilla::MarkerSchema(aLocations, aLength);
138 #else
139 return nullptr;
140 #endif
143 mozilla::MarkerSchema*
144 gecko_profiler_construct_marker_schema_with_special_front_end_location() {
145 #ifdef MOZ_GECKO_PROFILER
146 return new mozilla::MarkerSchema(
147 mozilla::MarkerSchema::SpecialFrontendLocation{});
148 #else
149 return nullptr;
150 #endif
153 void gecko_profiler_destruct_marker_schema(
154 mozilla::MarkerSchema* aMarkerSchema) {
155 #ifdef MOZ_GECKO_PROFILER
156 delete aMarkerSchema;
157 #endif
160 void gecko_profiler_marker_schema_set_chart_label(
161 mozilla::MarkerSchema* aSchema, const char* aLabel, size_t aLabelLength) {
162 #ifdef MOZ_GECKO_PROFILER
163 aSchema->SetChartLabel(std::string(aLabel, aLabelLength));
164 #endif
167 void gecko_profiler_marker_schema_set_tooltip_label(
168 mozilla::MarkerSchema* aSchema, const char* aLabel, size_t aLabelLength) {
169 #ifdef MOZ_GECKO_PROFILER
170 aSchema->SetTooltipLabel(std::string(aLabel, aLabelLength));
171 #endif
174 void gecko_profiler_marker_schema_set_table_label(
175 mozilla::MarkerSchema* aSchema, const char* aLabel, size_t aLabelLength) {
176 #ifdef MOZ_GECKO_PROFILER
177 aSchema->SetTableLabel(std::string(aLabel, aLabelLength));
178 #endif
181 void gecko_profiler_marker_schema_set_all_labels(mozilla::MarkerSchema* aSchema,
182 const char* aLabel,
183 size_t aLabelLength) {
184 #ifdef MOZ_GECKO_PROFILER
185 aSchema->SetAllLabels(std::string(aLabel, aLabelLength));
186 #endif
189 void gecko_profiler_marker_schema_add_key_format(
190 mozilla::MarkerSchema* aSchema, const char* aKey, size_t aKeyLength,
191 mozilla::MarkerSchema::Format aFormat) {
192 #ifdef MOZ_GECKO_PROFILER
193 aSchema->AddKeyFormat(std::string(aKey, aKeyLength), aFormat);
194 #endif
197 void gecko_profiler_marker_schema_add_key_label_format(
198 mozilla::MarkerSchema* aSchema, const char* aKey, size_t aKeyLength,
199 const char* aLabel, size_t aLabelLength,
200 mozilla::MarkerSchema::Format aFormat) {
201 #ifdef MOZ_GECKO_PROFILER
202 aSchema->AddKeyLabelFormat(std::string(aKey, aKeyLength),
203 std::string(aLabel, aLabelLength), aFormat);
204 #endif
207 void gecko_profiler_marker_schema_add_key_format_searchable(
208 mozilla::MarkerSchema* aSchema, const char* aKey, size_t aKeyLength,
209 mozilla::MarkerSchema::Format aFormat,
210 mozilla::MarkerSchema::Searchable aSearchable) {
211 #ifdef MOZ_GECKO_PROFILER
212 aSchema->AddKeyFormatSearchable(std::string(aKey, aKeyLength), aFormat,
213 aSearchable);
214 #endif
217 void gecko_profiler_marker_schema_add_key_label_format_searchable(
218 mozilla::MarkerSchema* aSchema, const char* aKey, size_t aKeyLength,
219 const char* aLabel, size_t aLabelLength,
220 mozilla::MarkerSchema::Format aFormat,
221 mozilla::MarkerSchema::Searchable aSearchable) {
222 #ifdef MOZ_GECKO_PROFILER
223 aSchema->AddKeyLabelFormatSearchable(std::string(aKey, aKeyLength),
224 std::string(aLabel, aLabelLength),
225 aFormat, aSearchable);
226 #endif
229 void gecko_profiler_marker_schema_add_static_label_value(
230 mozilla::MarkerSchema* aSchema, const char* aLabel, size_t aLabelLength,
231 const char* aValue, size_t aValueLength) {
232 #ifdef MOZ_GECKO_PROFILER
233 aSchema->AddStaticLabelValue(std::string(aLabel, aLabelLength),
234 std::string(aValue, aValueLength));
235 #endif
238 void gecko_profiler_marker_schema_stream(
239 mozilla::baseprofiler::SpliceableJSONWriter* aWriter, const char* aName,
240 size_t aNameLength, mozilla::MarkerSchema* aMarkerSchema,
241 void* aStreamedNamesSet) {
242 #ifdef MOZ_GECKO_PROFILER
243 auto* streamedNames = static_cast<std::set<std::string>*>(aStreamedNamesSet);
244 // std::set.insert(T&&) returns a pair, its `second` is true if the element
245 // was actually inserted (i.e., it was not there yet.).
246 const bool didInsert =
247 streamedNames->insert(std::string(aName, aNameLength)).second;
248 if (didInsert) {
249 std::move(*aMarkerSchema)
250 .Stream(*aWriter, mozilla::Span(aName, aNameLength));
252 #endif
255 void gecko_profiler_json_writer_int_property(
256 mozilla::baseprofiler::SpliceableJSONWriter* aWriter, const char* aName,
257 size_t aNameLength, int64_t aValue) {
258 #ifdef MOZ_GECKO_PROFILER
259 aWriter->IntProperty(mozilla::Span(aName, aNameLength), aValue);
260 #endif
263 void gecko_profiler_json_writer_float_property(
264 mozilla::baseprofiler::SpliceableJSONWriter* aWriter, const char* aName,
265 size_t aNameLength, double aValue) {
266 #ifdef MOZ_GECKO_PROFILER
267 aWriter->DoubleProperty(mozilla::Span(aName, aNameLength), aValue);
268 #endif
271 void gecko_profiler_json_writer_bool_property(
272 mozilla::baseprofiler::SpliceableJSONWriter* aWriter, const char* aName,
273 size_t aNameLength, bool aValue) {
274 #ifdef MOZ_GECKO_PROFILER
275 aWriter->BoolProperty(mozilla::Span(aName, aNameLength), aValue);
276 #endif
278 void gecko_profiler_json_writer_string_property(
279 mozilla::baseprofiler::SpliceableJSONWriter* aWriter, const char* aName,
280 size_t aNameLength, const char* aValue, size_t aValueLength) {
281 #ifdef MOZ_GECKO_PROFILER
282 aWriter->StringProperty(mozilla::Span(aName, aNameLength),
283 mozilla::Span(aValue, aValueLength));
284 #endif
287 void gecko_profiler_json_writer_unique_string_property(
288 mozilla::baseprofiler::SpliceableJSONWriter* aWriter, const char* aName,
289 size_t aNameLength, const char* aValue, size_t aValueLength) {
290 #ifdef MOZ_GECKO_PROFILER
291 aWriter->UniqueStringProperty(mozilla::Span(aName, aNameLength),
292 mozilla::Span(aValue, aValueLength));
293 #endif
296 void gecko_profiler_json_writer_null_property(
297 mozilla::baseprofiler::SpliceableJSONWriter* aWriter, const char* aName,
298 size_t aNameLength) {
299 #ifdef MOZ_GECKO_PROFILER
300 aWriter->NullProperty(mozilla::Span(aName, aNameLength));
301 #endif
304 void gecko_profiler_add_marker_untyped(
305 const char* aName, size_t aNameLength,
306 mozilla::baseprofiler::ProfilingCategoryPair aCategoryPair,
307 mozilla::MarkerTiming* aMarkerTiming,
308 mozilla::StackCaptureOptions aStackCaptureOptions) {
309 #ifdef MOZ_GECKO_PROFILER
310 profiler_add_marker(
311 mozilla::ProfilerString8View(aName, aNameLength),
312 mozilla::MarkerCategory{aCategoryPair},
313 mozilla::MarkerOptions(
314 std::move(*aMarkerTiming),
315 mozilla::MarkerStack::WithCaptureOptions(aStackCaptureOptions)));
316 #endif
319 void gecko_profiler_add_marker_text(
320 const char* aName, size_t aNameLength,
321 mozilla::baseprofiler::ProfilingCategoryPair aCategoryPair,
322 mozilla::MarkerTiming* aMarkerTiming,
323 mozilla::StackCaptureOptions aStackCaptureOptions, const char* aText,
324 size_t aTextLength) {
325 #ifdef MOZ_GECKO_PROFILER
326 profiler_add_marker(
327 mozilla::ProfilerString8View(aName, aNameLength),
328 mozilla::MarkerCategory{aCategoryPair},
329 mozilla::MarkerOptions(
330 std::move(*aMarkerTiming),
331 mozilla::MarkerStack::WithCaptureOptions(aStackCaptureOptions)),
332 geckoprofiler::markers::TextMarker{},
333 mozilla::ProfilerString8View(aText, aTextLength));
334 #endif
337 void gecko_profiler_add_marker(
338 const char* aName, size_t aNameLength,
339 mozilla::baseprofiler::ProfilingCategoryPair aCategoryPair,
340 mozilla::MarkerTiming* aMarkerTiming,
341 mozilla::StackCaptureOptions aStackCaptureOptions, uint8_t aMarkerTag,
342 const uint8_t* aPayload, size_t aPayloadSize) {
343 #ifdef MOZ_GECKO_PROFILER
344 // Copy the marker timing and create the marker option.
345 mozilla::MarkerOptions markerOptions(
346 std::move(*aMarkerTiming),
347 mozilla::MarkerStack::WithCaptureOptions(aStackCaptureOptions));
349 // Currently it's not possible to add a threadId option, but we will
350 // have it soon.
351 if (markerOptions.ThreadId().IsUnspecified()) {
352 // If yet unspecified, set thread to this thread where the marker is added.
353 markerOptions.Set(mozilla::MarkerThreadId::CurrentThread());
356 auto& buffer = profiler_get_core_buffer();
357 mozilla::Span payload(aPayload, aPayloadSize);
359 mozilla::StackCaptureOptions captureOptions =
360 markerOptions.Stack().CaptureOptions();
361 if (captureOptions != mozilla::StackCaptureOptions::NoStack &&
362 // Do not capture a stack if the NoMarkerStacks feature is set.
363 profiler_active_without_feature(ProfilerFeature::NoMarkerStacks)) {
364 // A capture was requested, let's attempt to do it here&now. This avoids a
365 // lot of allocations that would be necessary if capturing a backtrace
366 // separately.
367 // TODO use a local on-stack byte buffer to remove last allocation.
368 // TODO reduce internal profiler stack levels, see bug 1659872.
369 mozilla::ProfileBufferChunkManagerSingle chunkManager(
370 mozilla::ProfileBufferChunkManager::scExpectedMaximumStackSize);
371 mozilla::ProfileChunkedBuffer chunkedBuffer(
372 mozilla::ProfileChunkedBuffer::ThreadSafety::WithoutMutex,
373 chunkManager);
374 markerOptions.StackRef().UseRequestedBacktrace(
375 profiler_capture_backtrace_into(chunkedBuffer, captureOptions)
376 ? &chunkedBuffer
377 : nullptr);
379 // This call must be made from here, while chunkedBuffer is in scope.
380 buffer.PutObjects(
381 mozilla::ProfileBufferEntryKind::Marker, markerOptions,
382 mozilla::ProfilerString8View(aName, aNameLength),
383 mozilla::MarkerCategory{aCategoryPair},
384 mozilla::base_profiler_markers_detail::Streaming::DeserializerTag(
385 aMarkerTag),
386 mozilla::MarkerPayloadType::Rust, payload);
387 return;
390 buffer.PutObjects(
391 mozilla::ProfileBufferEntryKind::Marker, markerOptions,
392 mozilla::ProfilerString8View(aName, aNameLength),
393 mozilla::MarkerCategory{aCategoryPair},
394 mozilla::base_profiler_markers_detail::Streaming::DeserializerTag(
395 aMarkerTag),
396 mozilla::MarkerPayloadType::Rust, payload);
397 #endif