1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "BaseProfilerMarkerPayload.h"
7
8 #include <inttypes.h>
9
10 #include "mozilla/Maybe.h"
11 #include "mozilla/Sprintf.h"
12
13 #include "BaseProfiler.h"
14 #include "BaseProfileJSONWriter.h"
15 #include "ProfileBufferEntry.h"
16 #include "ProfilerBacktrace.h"
17
18 namespace mozilla {
19 namespace baseprofiler {
20
DeserializeNothing(mozilla::ProfileBufferEntryReader &)21 static UniquePtr<ProfilerMarkerPayload> DeserializeNothing(
22 mozilla::ProfileBufferEntryReader&) {
23 return nullptr;
24 }
25
26 // Number of currently-registered deserializers.
27 // Starting at 1 for the initial `DeserializeNothing`.
28 // static
29 Atomic<ProfilerMarkerPayload::DeserializerTagAtomic, ReleaseAcquire>
30 ProfilerMarkerPayload::sDeserializerCount{1};
31
32 // Initialize `sDeserializers` with `DeserializeNothing` at index 0, all others
33 // are nullptrs.
34 // static
35 ProfilerMarkerPayload::Deserializer
36 ProfilerMarkerPayload::sDeserializers[DeserializerMax] = {
37 DeserializeNothing};
38
39 // static
40 ProfilerMarkerPayload::DeserializerTag
TagForDeserializer(ProfilerMarkerPayload::Deserializer aDeserializer)41 ProfilerMarkerPayload::TagForDeserializer(
42 ProfilerMarkerPayload::Deserializer aDeserializer) {
43 if (!aDeserializer) {
44 return 0;
45 }
46 // Start first search at index 0.
47 DeserializerTagAtomic start = 0;
48 for (;;) {
49 // Read the current count of deserializers.
50 const DeserializerTagAtomic tagCount = sDeserializerCount;
51 if (tagCount == 0) {
52 // Someone else is currently writing into the array, loop around until we
53 // get a valid count.
54 continue;
55 }
56 for (DeserializerTagAtomic i = start; i < tagCount; ++i) {
57 if (sDeserializers[i] == aDeserializer) {
58 // Deserializer already registered, return its tag.
59 return static_cast<ProfilerMarkerPayload::DeserializerTag>(i);
60 }
61 }
62 // Not found yet, let's register this new deserializer.
63 // Make sure we haven't reached the limit yet.
64 MOZ_RELEASE_ASSERT(tagCount < DeserializerMax);
65 // Reserve `tagCount` as an index, if not already claimed:
66 // If `sDeserializerCount` is still at our previously-read `tagCount`,
67 // replace it with a special 0 value to indicate a write.
68 if (sDeserializerCount.compareExchange(tagCount, 0)) {
69 // Here we own the `tagCount` index, write the deserializer there.
70 sDeserializers[tagCount] = aDeserializer;
71 // And publish by writing the real new count (1 past our index).
72 sDeserializerCount = tagCount + 1;
73 return static_cast<ProfilerMarkerPayload::DeserializerTag>(tagCount);
74 }
75 // Someone else beat us to grab an index, and it could be for the same
76 // deserializer! So let's just try searching starting from our recorded
77 // `tagCount` (and maybe attempting again to register). It should be rare
78 // enough and quick enough that it won't impact performances.
79 start = tagCount;
80 }
81 }
82
83 // static
DeserializerForTag(ProfilerMarkerPayload::DeserializerTag aTag)84 ProfilerMarkerPayload::Deserializer ProfilerMarkerPayload::DeserializerForTag(
85 ProfilerMarkerPayload::DeserializerTag aTag) {
86 MOZ_RELEASE_ASSERT(aTag < DeserializerMax);
87 MOZ_RELEASE_ASSERT(aTag < sDeserializerCount);
88 return sDeserializers[aTag];
89 }
90
WriteTime(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,const TimeStamp & aTime,const char * aName)91 static void MOZ_ALWAYS_INLINE WriteTime(SpliceableJSONWriter& aWriter,
92 const TimeStamp& aProcessStartTime,
93 const TimeStamp& aTime,
94 const char* aName) {
95 if (!aTime.IsNull()) {
96 aWriter.DoubleProperty(aName, (aTime - aProcessStartTime).ToMilliseconds());
97 }
98 }
99
StreamType(const char * aMarkerType,SpliceableJSONWriter & aWriter) const100 void ProfilerMarkerPayload::StreamType(const char* aMarkerType,
101 SpliceableJSONWriter& aWriter) const {
102 MOZ_ASSERT(aMarkerType);
103 aWriter.StringProperty("type", aMarkerType);
104 }
105
106 ProfileBufferEntryWriter::Length
CommonPropsTagAndSerializationBytes() const107 ProfilerMarkerPayload::CommonPropsTagAndSerializationBytes() const {
108 return sizeof(DeserializerTag) +
109 ProfileBufferEntryWriter::SumBytes(
110 mCommonProps.mStartTime, mCommonProps.mEndTime,
111 mCommonProps.mStack, mCommonProps.mInnerWindowID);
112 }
113
SerializeTagAndCommonProps(DeserializerTag aDeserializerTag,ProfileBufferEntryWriter & aEntryWriter) const114 void ProfilerMarkerPayload::SerializeTagAndCommonProps(
115 DeserializerTag aDeserializerTag,
116 ProfileBufferEntryWriter& aEntryWriter) const {
117 aEntryWriter.WriteObject(aDeserializerTag);
118 aEntryWriter.WriteObject(mCommonProps.mStartTime);
119 aEntryWriter.WriteObject(mCommonProps.mEndTime);
120 aEntryWriter.WriteObject(mCommonProps.mStack);
121 aEntryWriter.WriteObject(mCommonProps.mInnerWindowID);
122 }
123
124 // static
125 ProfilerMarkerPayload::CommonProps
DeserializeCommonProps(ProfileBufferEntryReader & aEntryReader)126 ProfilerMarkerPayload::DeserializeCommonProps(
127 ProfileBufferEntryReader& aEntryReader) {
128 CommonProps props;
129 aEntryReader.ReadIntoObject(props.mStartTime);
130 aEntryReader.ReadIntoObject(props.mEndTime);
131 aEntryReader.ReadIntoObject(props.mStack);
132 aEntryReader.ReadIntoObject(props.mInnerWindowID);
133 return props;
134 }
135
StreamCommonProps(const char * aMarkerType,SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const136 void ProfilerMarkerPayload::StreamCommonProps(
137 const char* aMarkerType, SpliceableJSONWriter& aWriter,
138 const TimeStamp& aProcessStartTime, UniqueStacks& aUniqueStacks) const {
139 StreamType(aMarkerType, aWriter);
140 WriteTime(aWriter, aProcessStartTime, mCommonProps.mStartTime, "startTime");
141 WriteTime(aWriter, aProcessStartTime, mCommonProps.mEndTime, "endTime");
142 if (mCommonProps.mInnerWindowID) {
143 // Here, we are converting uint64_t to double. Both Browsing Context and
144 // Inner Window IDs are creating using
145 // `nsContentUtils::GenerateProcessSpecificId`, which is specifically
146 // designed to only use 53 of the 64 bits to be lossless when passed into
147 // and out of JS as a double.
148 aWriter.DoubleProperty("innerWindowID", mCommonProps.mInnerWindowID.ref());
149 }
150 if (mCommonProps.mStack) {
151 aWriter.StartObjectProperty("stack");
152 {
153 mCommonProps.mStack->StreamJSON(aWriter, aProcessStartTime,
154 aUniqueStacks);
155 }
156 aWriter.EndObject();
157 }
158 }
159
TracingMarkerPayload(const char * aCategory,TracingKind aKind,const Maybe<uint64_t> & aInnerWindowID,UniqueProfilerBacktrace aCause)160 TracingMarkerPayload::TracingMarkerPayload(
161 const char* aCategory, TracingKind aKind,
162 const Maybe<uint64_t>& aInnerWindowID, UniqueProfilerBacktrace aCause)
163 : ProfilerMarkerPayload(aInnerWindowID, std::move(aCause)),
164 mCategory(aCategory),
165 mKind(aKind) {}
166
TracingMarkerPayload(CommonProps && aCommonProps,const char * aCategory,TracingKind aKind)167 TracingMarkerPayload::TracingMarkerPayload(CommonProps&& aCommonProps,
168 const char* aCategory,
169 TracingKind aKind)
170 : ProfilerMarkerPayload(std::move(aCommonProps)),
171 mCategory(aCategory),
172 mKind(aKind) {}
173
174 TracingMarkerPayload::~TracingMarkerPayload() = default;
175
176 ProfileBufferEntryWriter::Length
TagAndSerializationBytes() const177 TracingMarkerPayload::TagAndSerializationBytes() const {
178 return CommonPropsTagAndSerializationBytes() +
179 ProfileBufferEntryWriter::SumBytes(
180 WrapProfileBufferRawPointer(mCategory), mKind);
181 }
182
SerializeTagAndPayload(ProfileBufferEntryWriter & aEntryWriter) const183 void TracingMarkerPayload::SerializeTagAndPayload(
184 ProfileBufferEntryWriter& aEntryWriter) const {
185 static const DeserializerTag tag = TagForDeserializer(Deserialize);
186 SerializeTagAndCommonProps(tag, aEntryWriter);
187 aEntryWriter.WriteObject(WrapProfileBufferRawPointer(mCategory));
188 aEntryWriter.WriteObject(mKind);
189 }
190
191 // static
Deserialize(ProfileBufferEntryReader & aEntryReader)192 UniquePtr<ProfilerMarkerPayload> TracingMarkerPayload::Deserialize(
193 ProfileBufferEntryReader& aEntryReader) {
194 ProfilerMarkerPayload::CommonProps props =
195 DeserializeCommonProps(aEntryReader);
196 const char* category = aEntryReader.ReadObject<const char*>();
197 TracingKind kind = aEntryReader.ReadObject<TracingKind>();
198 return UniquePtr<ProfilerMarkerPayload>(
199 new TracingMarkerPayload(std::move(props), category, kind));
200 }
201
StreamPayload(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const202 void TracingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
203 const TimeStamp& aProcessStartTime,
204 UniqueStacks& aUniqueStacks) const {
205 StreamCommonProps("tracing", aWriter, aProcessStartTime, aUniqueStacks);
206
207 if (mCategory) {
208 aWriter.StringProperty("category", mCategory);
209 }
210
211 if (mKind == TRACING_INTERVAL_START) {
212 aWriter.StringProperty("interval", "start");
213 } else if (mKind == TRACING_INTERVAL_END) {
214 aWriter.StringProperty("interval", "end");
215 }
216 }
217
FileIOMarkerPayload(const char * aOperation,const char * aSource,const char * aFilename,const TimeStamp & aStartTime,const TimeStamp & aEndTime,UniqueProfilerBacktrace aStack)218 FileIOMarkerPayload::FileIOMarkerPayload(const char* aOperation,
219 const char* aSource,
220 const char* aFilename,
221 const TimeStamp& aStartTime,
222 const TimeStamp& aEndTime,
223 UniqueProfilerBacktrace aStack)
224 : ProfilerMarkerPayload(aStartTime, aEndTime, Nothing(), std::move(aStack)),
225 mSource(aSource),
226 mOperation(aOperation ? strdup(aOperation) : nullptr),
227 mFilename(aFilename ? strdup(aFilename) : nullptr) {
228 MOZ_ASSERT(aSource);
229 }
230
FileIOMarkerPayload(CommonProps && aCommonProps,const char * aSource,UniqueFreePtr<char> && aOperation,UniqueFreePtr<char> && aFilename)231 FileIOMarkerPayload::FileIOMarkerPayload(CommonProps&& aCommonProps,
232 const char* aSource,
233 UniqueFreePtr<char>&& aOperation,
234 UniqueFreePtr<char>&& aFilename)
235 : ProfilerMarkerPayload(std::move(aCommonProps)),
236 mSource(aSource),
237 mOperation(std::move(aOperation)),
238 mFilename(std::move(aFilename)) {}
239
240 FileIOMarkerPayload::~FileIOMarkerPayload() = default;
241
TagAndSerializationBytes() const242 ProfileBufferEntryWriter::Length FileIOMarkerPayload::TagAndSerializationBytes()
243 const {
244 return CommonPropsTagAndSerializationBytes() +
245 ProfileBufferEntryWriter::SumBytes(
246 WrapProfileBufferRawPointer(mSource), mOperation, mFilename);
247 }
248
SerializeTagAndPayload(ProfileBufferEntryWriter & aEntryWriter) const249 void FileIOMarkerPayload::SerializeTagAndPayload(
250 ProfileBufferEntryWriter& aEntryWriter) const {
251 static const DeserializerTag tag = TagForDeserializer(Deserialize);
252 SerializeTagAndCommonProps(tag, aEntryWriter);
253 aEntryWriter.WriteObject(WrapProfileBufferRawPointer(mSource));
254 aEntryWriter.WriteObject(mOperation);
255 aEntryWriter.WriteObject(mFilename);
256 }
257
258 // static
Deserialize(ProfileBufferEntryReader & aEntryReader)259 UniquePtr<ProfilerMarkerPayload> FileIOMarkerPayload::Deserialize(
260 ProfileBufferEntryReader& aEntryReader) {
261 ProfilerMarkerPayload::CommonProps props =
262 DeserializeCommonProps(aEntryReader);
263 auto source = aEntryReader.ReadObject<const char*>();
264 auto operation = aEntryReader.ReadObject<UniqueFreePtr<char>>();
265 auto filename = aEntryReader.ReadObject<UniqueFreePtr<char>>();
266 return UniquePtr<ProfilerMarkerPayload>(new FileIOMarkerPayload(
267 std::move(props), source, std::move(operation), std::move(filename)));
268 }
269
StreamPayload(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const270 void FileIOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
271 const TimeStamp& aProcessStartTime,
272 UniqueStacks& aUniqueStacks) const {
273 StreamCommonProps("FileIO", aWriter, aProcessStartTime, aUniqueStacks);
274 aWriter.StringProperty("operation", mOperation.get());
275 aWriter.StringProperty("source", mSource);
276 if (mFilename && *mFilename) {
277 aWriter.StringProperty("filename", mFilename.get());
278 }
279 }
280
UserTimingMarkerPayload(const std::string & aName,const TimeStamp & aStartTime,const Maybe<uint64_t> & aInnerWindowID)281 UserTimingMarkerPayload::UserTimingMarkerPayload(
282 const std::string& aName, const TimeStamp& aStartTime,
283 const Maybe<uint64_t>& aInnerWindowID)
284 : ProfilerMarkerPayload(aStartTime, aStartTime, aInnerWindowID),
285 mEntryType("mark"),
286 mName(aName) {}
287
UserTimingMarkerPayload(const std::string & aName,const Maybe<std::string> & aStartMark,const Maybe<std::string> & aEndMark,const TimeStamp & aStartTime,const TimeStamp & aEndTime,const Maybe<uint64_t> & aInnerWindowID)288 UserTimingMarkerPayload::UserTimingMarkerPayload(
289 const std::string& aName, const Maybe<std::string>& aStartMark,
290 const Maybe<std::string>& aEndMark, const TimeStamp& aStartTime,
291 const TimeStamp& aEndTime, const Maybe<uint64_t>& aInnerWindowID)
292 : ProfilerMarkerPayload(aStartTime, aEndTime, aInnerWindowID),
293 mEntryType("measure"),
294 mName(aName),
295 mStartMark(aStartMark),
296 mEndMark(aEndMark) {}
297
UserTimingMarkerPayload(CommonProps && aCommonProps,const char * aEntryType,std::string && aName,Maybe<std::string> && aStartMark,Maybe<std::string> && aEndMark)298 UserTimingMarkerPayload::UserTimingMarkerPayload(
299 CommonProps&& aCommonProps, const char* aEntryType, std::string&& aName,
300 Maybe<std::string>&& aStartMark, Maybe<std::string>&& aEndMark)
301 : ProfilerMarkerPayload(std::move(aCommonProps)),
302 mEntryType(aEntryType),
303 mName(std::move(aName)),
304 mStartMark(std::move(aStartMark)),
305 mEndMark(std::move(aEndMark)) {}
306
307 UserTimingMarkerPayload::~UserTimingMarkerPayload() = default;
308
309 ProfileBufferEntryWriter::Length
TagAndSerializationBytes() const310 UserTimingMarkerPayload::TagAndSerializationBytes() const {
311 return CommonPropsTagAndSerializationBytes() +
312 ProfileBufferEntryWriter::SumBytes(
313 WrapProfileBufferRawPointer(mEntryType), mName, mStartMark,
314 mEndMark);
315 }
316
SerializeTagAndPayload(ProfileBufferEntryWriter & aEntryWriter) const317 void UserTimingMarkerPayload::SerializeTagAndPayload(
318 ProfileBufferEntryWriter& aEntryWriter) const {
319 static const DeserializerTag tag = TagForDeserializer(Deserialize);
320 SerializeTagAndCommonProps(tag, aEntryWriter);
321 aEntryWriter.WriteObject(WrapProfileBufferRawPointer(mEntryType));
322 aEntryWriter.WriteObject(mName);
323 aEntryWriter.WriteObject(mStartMark);
324 aEntryWriter.WriteObject(mEndMark);
325 }
326
327 // static
Deserialize(ProfileBufferEntryReader & aEntryReader)328 UniquePtr<ProfilerMarkerPayload> UserTimingMarkerPayload::Deserialize(
329 ProfileBufferEntryReader& aEntryReader) {
330 ProfilerMarkerPayload::CommonProps props =
331 DeserializeCommonProps(aEntryReader);
332 auto entryType = aEntryReader.ReadObject<const char*>();
333 auto name = aEntryReader.ReadObject<std::string>();
334 auto startMark = aEntryReader.ReadObject<Maybe<std::string>>();
335 auto endMark = aEntryReader.ReadObject<Maybe<std::string>>();
336 return UniquePtr<ProfilerMarkerPayload>(
337 new UserTimingMarkerPayload(std::move(props), entryType, std::move(name),
338 std::move(startMark), std::move(endMark)));
339 }
340
StreamPayload(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const341 void UserTimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
342 const TimeStamp& aProcessStartTime,
343 UniqueStacks& aUniqueStacks) const {
344 StreamCommonProps("UserTiming", aWriter, aProcessStartTime, aUniqueStacks);
345 aWriter.StringProperty("name", mName.c_str());
346 aWriter.StringProperty("entryType", mEntryType);
347
348 if (mStartMark.isSome()) {
349 aWriter.StringProperty("startMark", mStartMark.value().c_str());
350 } else {
351 aWriter.NullProperty("startMark");
352 }
353 if (mEndMark.isSome()) {
354 aWriter.StringProperty("endMark", mEndMark.value().c_str());
355 } else {
356 aWriter.NullProperty("endMark");
357 }
358 }
359
TextMarkerPayload(const std::string & aText,const TimeStamp & aStartTime)360 TextMarkerPayload::TextMarkerPayload(const std::string& aText,
361 const TimeStamp& aStartTime)
362 : ProfilerMarkerPayload(aStartTime, aStartTime), mText(aText) {}
363
TextMarkerPayload(const std::string & aText,const TimeStamp & aStartTime,const TimeStamp & aEndTime)364 TextMarkerPayload::TextMarkerPayload(const std::string& aText,
365 const TimeStamp& aStartTime,
366 const TimeStamp& aEndTime)
367 : ProfilerMarkerPayload(aStartTime, aEndTime), mText(aText) {}
368
TextMarkerPayload(const std::string & aText,const TimeStamp & aStartTime,const Maybe<uint64_t> & aInnerWindowID)369 TextMarkerPayload::TextMarkerPayload(const std::string& aText,
370 const TimeStamp& aStartTime,
371 const Maybe<uint64_t>& aInnerWindowID)
372 : ProfilerMarkerPayload(aStartTime, aStartTime, aInnerWindowID),
373 mText(aText) {}
374
TextMarkerPayload(const std::string & aText,const TimeStamp & aStartTime,const TimeStamp & aEndTime,const Maybe<uint64_t> & aInnerWindowID,UniqueProfilerBacktrace aCause)375 TextMarkerPayload::TextMarkerPayload(const std::string& aText,
376 const TimeStamp& aStartTime,
377 const TimeStamp& aEndTime,
378 const Maybe<uint64_t>& aInnerWindowID,
379 UniqueProfilerBacktrace aCause)
380 : ProfilerMarkerPayload(aStartTime, aEndTime, aInnerWindowID,
381 std::move(aCause)),
382 mText(aText) {}
383
TextMarkerPayload(CommonProps && aCommonProps,std::string && aText)384 TextMarkerPayload::TextMarkerPayload(CommonProps&& aCommonProps,
385 std::string&& aText)
386 : ProfilerMarkerPayload(std::move(aCommonProps)), mText(std::move(aText)) {}
387
388 TextMarkerPayload::~TextMarkerPayload() = default;
389
TagAndSerializationBytes() const390 ProfileBufferEntryWriter::Length TextMarkerPayload::TagAndSerializationBytes()
391 const {
392 return CommonPropsTagAndSerializationBytes() +
393 ProfileBufferEntryWriter::SumBytes(mText);
394 }
395
SerializeTagAndPayload(ProfileBufferEntryWriter & aEntryWriter) const396 void TextMarkerPayload::SerializeTagAndPayload(
397 ProfileBufferEntryWriter& aEntryWriter) const {
398 static const DeserializerTag tag = TagForDeserializer(Deserialize);
399 SerializeTagAndCommonProps(tag, aEntryWriter);
400 aEntryWriter.WriteObject(mText);
401 }
402
403 // static
Deserialize(ProfileBufferEntryReader & aEntryReader)404 UniquePtr<ProfilerMarkerPayload> TextMarkerPayload::Deserialize(
405 ProfileBufferEntryReader& aEntryReader) {
406 ProfilerMarkerPayload::CommonProps props =
407 DeserializeCommonProps(aEntryReader);
408 auto text = aEntryReader.ReadObject<std::string>();
409 return UniquePtr<ProfilerMarkerPayload>(
410 new TextMarkerPayload(std::move(props), std::move(text)));
411 }
412
StreamPayload(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const413 void TextMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
414 const TimeStamp& aProcessStartTime,
415 UniqueStacks& aUniqueStacks) const {
416 StreamCommonProps("Text", aWriter, aProcessStartTime, aUniqueStacks);
417 aWriter.StringProperty("name", mText.c_str());
418 }
419
LogMarkerPayload(const char * aModule,const char * aText,const TimeStamp & aStartTime)420 LogMarkerPayload::LogMarkerPayload(const char* aModule, const char* aText,
421 const TimeStamp& aStartTime)
422 : ProfilerMarkerPayload(aStartTime, aStartTime),
423 mModule(aModule),
424 mText(aText) {}
425
LogMarkerPayload(CommonProps && aCommonProps,std::string && aModule,std::string && aText)426 LogMarkerPayload::LogMarkerPayload(CommonProps&& aCommonProps,
427 std::string&& aModule, std::string&& aText)
428 : ProfilerMarkerPayload(std::move(aCommonProps)),
429 mModule(std::move(aModule)),
430 mText(std::move(aText)) {}
431
432 LogMarkerPayload::~LogMarkerPayload() = default;
433
TagAndSerializationBytes() const434 ProfileBufferEntryWriter::Length LogMarkerPayload::TagAndSerializationBytes()
435 const {
436 return CommonPropsTagAndSerializationBytes() +
437 ProfileBufferEntryWriter::SumBytes(mModule, mText);
438 }
439
SerializeTagAndPayload(ProfileBufferEntryWriter & aEntryWriter) const440 void LogMarkerPayload::SerializeTagAndPayload(
441 ProfileBufferEntryWriter& aEntryWriter) const {
442 static const DeserializerTag tag = TagForDeserializer(Deserialize);
443 SerializeTagAndCommonProps(tag, aEntryWriter);
444 aEntryWriter.WriteObject(mModule);
445 aEntryWriter.WriteObject(mText);
446 }
447
448 // static
Deserialize(ProfileBufferEntryReader & aEntryReader)449 UniquePtr<ProfilerMarkerPayload> LogMarkerPayload::Deserialize(
450 ProfileBufferEntryReader& aEntryReader) {
451 ProfilerMarkerPayload::CommonProps props =
452 DeserializeCommonProps(aEntryReader);
453 auto module = aEntryReader.ReadObject<std::string>();
454 auto text = aEntryReader.ReadObject<std::string>();
455 return UniquePtr<ProfilerMarkerPayload>(new LogMarkerPayload(
456 std::move(props), std::move(module), std::move(text)));
457 }
458
StreamPayload(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const459 void LogMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
460 const TimeStamp& aProcessStartTime,
461 UniqueStacks& aUniqueStacks) const {
462 StreamCommonProps("Log", aWriter, aProcessStartTime, aUniqueStacks);
463 aWriter.StringProperty("name", mText.c_str());
464 aWriter.StringProperty("module", mModule.c_str());
465 }
466
MediaSampleMarkerPayload(const int64_t aSampleStartTimeUs,const int64_t aSampleEndTimeUs)467 MediaSampleMarkerPayload::MediaSampleMarkerPayload(
468 const int64_t aSampleStartTimeUs, const int64_t aSampleEndTimeUs)
469 : mSampleStartTimeUs(aSampleStartTimeUs),
470 mSampleEndTimeUs(aSampleEndTimeUs) {}
471
MediaSampleMarkerPayload(CommonProps && aCommonProps,const int64_t aSampleStartTimeUs,const int64_t aSampleEndTimeUs)472 MediaSampleMarkerPayload::MediaSampleMarkerPayload(
473 CommonProps&& aCommonProps, const int64_t aSampleStartTimeUs,
474 const int64_t aSampleEndTimeUs)
475 : ProfilerMarkerPayload(std::move(aCommonProps)),
476 mSampleStartTimeUs(aSampleStartTimeUs),
477 mSampleEndTimeUs(aSampleEndTimeUs) {}
478
479 ProfileBufferEntryWriter::Length
TagAndSerializationBytes() const480 MediaSampleMarkerPayload::TagAndSerializationBytes() const {
481 return CommonPropsTagAndSerializationBytes() +
482 ProfileBufferEntryWriter::SumBytes(mSampleStartTimeUs,
483 mSampleEndTimeUs);
484 }
485
SerializeTagAndPayload(ProfileBufferEntryWriter & aEntryWriter) const486 void MediaSampleMarkerPayload::SerializeTagAndPayload(
487 ProfileBufferEntryWriter& aEntryWriter) const {
488 static const DeserializerTag tag = TagForDeserializer(Deserialize);
489 SerializeTagAndCommonProps(tag, aEntryWriter);
490 aEntryWriter.WriteObject(mSampleStartTimeUs);
491 aEntryWriter.WriteObject(mSampleEndTimeUs);
492 }
493
494 /* static */
Deserialize(ProfileBufferEntryReader & aEntryReader)495 UniquePtr<ProfilerMarkerPayload> MediaSampleMarkerPayload::Deserialize(
496 ProfileBufferEntryReader& aEntryReader) {
497 ProfilerMarkerPayload::CommonProps props =
498 DeserializeCommonProps(aEntryReader);
499 auto sampleStartTimeUs = aEntryReader.ReadObject<int64_t>();
500 auto sampleEndTimeUs = aEntryReader.ReadObject<int64_t>();
501 return UniquePtr<ProfilerMarkerPayload>(new MediaSampleMarkerPayload(
502 std::move(props), sampleStartTimeUs, sampleEndTimeUs));
503 }
504
StreamPayload(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const505 void MediaSampleMarkerPayload::StreamPayload(
506 SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime,
507 UniqueStacks& aUniqueStacks) const {
508 StreamCommonProps("MediaSample", aWriter, aProcessStartTime, aUniqueStacks);
509 aWriter.IntProperty("sampleStartTimeUs", mSampleStartTimeUs);
510 aWriter.IntProperty("sampleEndTimeUs", mSampleEndTimeUs);
511 }
512
HangMarkerPayload(const TimeStamp & aStartTime,const TimeStamp & aEndTime)513 HangMarkerPayload::HangMarkerPayload(const TimeStamp& aStartTime,
514 const TimeStamp& aEndTime)
515 : ProfilerMarkerPayload(aStartTime, aEndTime) {}
516
HangMarkerPayload(CommonProps && aCommonProps)517 HangMarkerPayload::HangMarkerPayload(CommonProps&& aCommonProps)
518 : ProfilerMarkerPayload(std::move(aCommonProps)) {}
519
520 HangMarkerPayload::~HangMarkerPayload() = default;
521
TagAndSerializationBytes() const522 ProfileBufferEntryWriter::Length HangMarkerPayload::TagAndSerializationBytes()
523 const {
524 return CommonPropsTagAndSerializationBytes();
525 }
526
SerializeTagAndPayload(ProfileBufferEntryWriter & aEntryWriter) const527 void HangMarkerPayload::SerializeTagAndPayload(
528 ProfileBufferEntryWriter& aEntryWriter) const {
529 static const DeserializerTag tag = TagForDeserializer(Deserialize);
530 SerializeTagAndCommonProps(tag, aEntryWriter);
531 }
532
533 // static
Deserialize(ProfileBufferEntryReader & aEntryReader)534 UniquePtr<ProfilerMarkerPayload> HangMarkerPayload::Deserialize(
535 ProfileBufferEntryReader& aEntryReader) {
536 ProfilerMarkerPayload::CommonProps props =
537 DeserializeCommonProps(aEntryReader);
538 return UniquePtr<ProfilerMarkerPayload>(
539 new HangMarkerPayload(std::move(props)));
540 }
541
StreamPayload(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const542 void HangMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
543 const TimeStamp& aProcessStartTime,
544 UniqueStacks& aUniqueStacks) const {
545 StreamCommonProps("BHR-detected hang", aWriter, aProcessStartTime,
546 aUniqueStacks);
547 }
548
LongTaskMarkerPayload(const TimeStamp & aStartTime,const TimeStamp & aEndTime)549 LongTaskMarkerPayload::LongTaskMarkerPayload(const TimeStamp& aStartTime,
550 const TimeStamp& aEndTime)
551 : ProfilerMarkerPayload(aStartTime, aEndTime) {}
552
LongTaskMarkerPayload(CommonProps && aCommonProps)553 LongTaskMarkerPayload::LongTaskMarkerPayload(CommonProps&& aCommonProps)
554 : ProfilerMarkerPayload(std::move(aCommonProps)) {}
555
556 LongTaskMarkerPayload::~LongTaskMarkerPayload() = default;
557
558 ProfileBufferEntryWriter::Length
TagAndSerializationBytes() const559 LongTaskMarkerPayload::TagAndSerializationBytes() const {
560 return CommonPropsTagAndSerializationBytes();
561 }
562
SerializeTagAndPayload(ProfileBufferEntryWriter & aEntryWriter) const563 void LongTaskMarkerPayload::SerializeTagAndPayload(
564 ProfileBufferEntryWriter& aEntryWriter) const {
565 static const DeserializerTag tag = TagForDeserializer(Deserialize);
566 SerializeTagAndCommonProps(tag, aEntryWriter);
567 }
568
569 // static
Deserialize(ProfileBufferEntryReader & aEntryReader)570 UniquePtr<ProfilerMarkerPayload> LongTaskMarkerPayload::Deserialize(
571 ProfileBufferEntryReader& aEntryReader) {
572 ProfilerMarkerPayload::CommonProps props =
573 DeserializeCommonProps(aEntryReader);
574 return UniquePtr<ProfilerMarkerPayload>(
575 new LongTaskMarkerPayload(std::move(props)));
576 }
577
StreamPayload(SpliceableJSONWriter & aWriter,const TimeStamp & aProcessStartTime,UniqueStacks & aUniqueStacks) const578 void LongTaskMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
579 const TimeStamp& aProcessStartTime,
580 UniqueStacks& aUniqueStacks) const {
581 StreamCommonProps("MainThreadLongTask", aWriter, aProcessStartTime,
582 aUniqueStacks);
583 aWriter.StringProperty("category", "LongTask");
584 }
585
586 } // namespace baseprofiler
587 } // namespace mozilla
588