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