зеркало из https://github.com/mozilla/gecko-dev.git
1173 строки
46 KiB
C++
1173 строки
46 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* 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/. */
|
|
|
|
#include "ProfilerMarkerPayload.h"
|
|
|
|
#include "GeckoProfiler.h"
|
|
#include "ProfileBufferEntry.h"
|
|
#include "ProfilerBacktrace.h"
|
|
|
|
#include "gfxASurface.h"
|
|
#include "Layers.h"
|
|
#include "mozilla/Maybe.h"
|
|
#include "mozilla/net/HttpBaseChannel.h"
|
|
#include "mozilla/Preferences.h"
|
|
#include "mozilla/ProfileBufferEntrySerializationGeckoExtensions.h"
|
|
#include "mozilla/ProfileJSONWriter.h"
|
|
#include "mozilla/Sprintf.h"
|
|
|
|
#include <inttypes.h>
|
|
|
|
using namespace mozilla;
|
|
|
|
static UniquePtr<ProfilerMarkerPayload> DeserializeNothing(
|
|
ProfileBufferEntryReader&) {
|
|
return nullptr;
|
|
}
|
|
|
|
// Starting at 1 for the initial `DeserializeNothing`.
|
|
// static
|
|
Atomic<ProfilerMarkerPayload::DeserializerTagAtomic, ReleaseAcquire>
|
|
ProfilerMarkerPayload::sDeserializerCount{1};
|
|
|
|
// Initialize `sDeserializers` with `DeserializeNothing` at index 0, all others
|
|
// are nullptrs.
|
|
// static
|
|
ProfilerMarkerPayload::Deserializer
|
|
ProfilerMarkerPayload::sDeserializers[DeserializerMax] = {
|
|
DeserializeNothing};
|
|
|
|
// static
|
|
ProfilerMarkerPayload::DeserializerTag
|
|
ProfilerMarkerPayload::TagForDeserializer(
|
|
ProfilerMarkerPayload::Deserializer aDeserializer) {
|
|
if (!aDeserializer) {
|
|
return 0;
|
|
}
|
|
// Start first search at index 0.
|
|
DeserializerTagAtomic start = 0;
|
|
for (;;) {
|
|
// Read the current count of deserializers.
|
|
const DeserializerTagAtomic tagCount = sDeserializerCount;
|
|
if (tagCount == 0) {
|
|
// Someone else is currently writing into the array, loop around until we
|
|
// get a valid count.
|
|
continue;
|
|
}
|
|
for (DeserializerTagAtomic i = start; i < tagCount; ++i) {
|
|
if (sDeserializers[i] == aDeserializer) {
|
|
// Deserializer already registered, return its tag.
|
|
return static_cast<ProfilerMarkerPayload::DeserializerTag>(i);
|
|
}
|
|
}
|
|
// Not found yet, let's register this new deserializer.
|
|
// Make sure we haven't reached the limit yet.
|
|
MOZ_RELEASE_ASSERT(tagCount < DeserializerMax);
|
|
// Reserve `tagCount` as an index, if not already claimed:
|
|
// If `sDeserializerCount` is still at our previously-read `tagCount`,
|
|
// replace it with a special 0 value to indicate a write.
|
|
if (sDeserializerCount.compareExchange(tagCount, 0)) {
|
|
// Here we own the `tagCount` index, write the deserializer there.
|
|
sDeserializers[tagCount] = aDeserializer;
|
|
// And publish by writing the real new count (1 past our index).
|
|
sDeserializerCount = tagCount + 1;
|
|
return static_cast<ProfilerMarkerPayload::DeserializerTag>(tagCount);
|
|
}
|
|
// Someone else beat us to grab an index, and it could be for the same
|
|
// deserializer! So let's just try searching starting from our recorded
|
|
// `tagCount` (and maybe attempting again to register). It should be rare
|
|
// enough and quick enough that it won't impact performances.
|
|
start = tagCount;
|
|
}
|
|
}
|
|
|
|
// static
|
|
ProfilerMarkerPayload::Deserializer ProfilerMarkerPayload::DeserializerForTag(
|
|
ProfilerMarkerPayload::DeserializerTag aTag) {
|
|
MOZ_RELEASE_ASSERT(aTag < DeserializerMax);
|
|
MOZ_RELEASE_ASSERT(aTag < sDeserializerCount);
|
|
return sDeserializers[aTag];
|
|
}
|
|
|
|
static void MOZ_ALWAYS_INLINE WriteTime(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
const TimeStamp& aTime,
|
|
const char* aName) {
|
|
if (!aTime.IsNull()) {
|
|
aWriter.DoubleProperty(MakeStringSpan(aName),
|
|
(aTime - aProcessStartTime).ToMilliseconds());
|
|
}
|
|
}
|
|
|
|
void ProfilerMarkerPayload::StreamType(const char* aMarkerType,
|
|
SpliceableJSONWriter& aWriter) const {
|
|
MOZ_ASSERT(aMarkerType);
|
|
aWriter.StringProperty("type", MakeStringSpan(aMarkerType));
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
ProfilerMarkerPayload::CommonPropsTagAndSerializationBytes() const {
|
|
return sizeof(DeserializerTag) +
|
|
ProfileBufferEntryWriter::SumBytes(
|
|
mCommonProps.mStartTime, mCommonProps.mEndTime,
|
|
mCommonProps.mStack, mCommonProps.mInnerWindowID);
|
|
}
|
|
|
|
void ProfilerMarkerPayload::SerializeTagAndCommonProps(
|
|
DeserializerTag aDeserializerTag,
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
aEntryWriter.WriteObject(aDeserializerTag);
|
|
aEntryWriter.WriteObject(mCommonProps.mStartTime);
|
|
aEntryWriter.WriteObject(mCommonProps.mEndTime);
|
|
aEntryWriter.WriteObject(mCommonProps.mStack);
|
|
aEntryWriter.WriteObject(mCommonProps.mInnerWindowID);
|
|
}
|
|
|
|
// static
|
|
ProfilerMarkerPayload::CommonProps
|
|
ProfilerMarkerPayload::DeserializeCommonProps(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
CommonProps props;
|
|
aEntryReader.ReadIntoObject(props.mStartTime);
|
|
aEntryReader.ReadIntoObject(props.mEndTime);
|
|
aEntryReader.ReadIntoObject(props.mStack);
|
|
aEntryReader.ReadIntoObject(props.mInnerWindowID);
|
|
return props;
|
|
}
|
|
|
|
// Deprecated: This function is providing a way for a few payloads to use the
|
|
// start time and end time in their payloads, which is currently deprecated.
|
|
// The startTime and endTime were removed from most payloads, in favor of
|
|
// the MarkerTiming::Phase idea. However, IPC and Network markers still have
|
|
// them as it was harder to upgrade the front-end without them.
|
|
void ProfilerMarkerPayload::StreamStartEndTime(
|
|
SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime) const {
|
|
WriteTime(aWriter, aProcessStartTime, mCommonProps.mStartTime, "startTime");
|
|
WriteTime(aWriter, aProcessStartTime, mCommonProps.mEndTime, "endTime");
|
|
}
|
|
|
|
void ProfilerMarkerPayload::StreamCommonProps(
|
|
const char* aMarkerType, SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime, UniqueStacks& aUniqueStacks) const {
|
|
StreamType(aMarkerType, aWriter);
|
|
if (mCommonProps.mInnerWindowID) {
|
|
// Here, we are converting uint64_t to double. Both Browsing Context and
|
|
// Inner Window IDs are creating using
|
|
// `nsContentUtils::GenerateProcessSpecificId`, which is specifically
|
|
// designed to only use 53 of the 64 bits to be lossless when passed into
|
|
// and out of JS as a double.
|
|
aWriter.DoubleProperty("innerWindowID", mCommonProps.mInnerWindowID.ref());
|
|
}
|
|
if (mCommonProps.mStack) {
|
|
aWriter.StartObjectProperty("stack");
|
|
{
|
|
mCommonProps.mStack->StreamJSON(aWriter, aProcessStartTime,
|
|
aUniqueStacks);
|
|
}
|
|
aWriter.EndObject();
|
|
}
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
TracingMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(
|
|
WrapProfileBufferRawPointer(mCategory), mKind);
|
|
}
|
|
|
|
void TracingMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndPayload(tag, aEntryWriter);
|
|
}
|
|
|
|
void TracingMarkerPayload::SerializeTagAndPayload(
|
|
DeserializerTag aDeserializerTag,
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
SerializeTagAndCommonProps(aDeserializerTag, aEntryWriter);
|
|
aEntryWriter.WriteObject(WrapProfileBufferRawPointer(mCategory));
|
|
aEntryWriter.WriteObject(mKind);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> TracingMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
const char* category = aEntryReader.ReadObject<const char*>();
|
|
TracingKind kind = aEntryReader.ReadObject<TracingKind>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new TracingMarkerPayload(std::move(props), category, kind));
|
|
}
|
|
|
|
void TracingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("tracing", aWriter, aProcessStartTime, aUniqueStacks);
|
|
|
|
if (mCategory) {
|
|
aWriter.StringProperty("category", MakeStringSpan(mCategory));
|
|
}
|
|
|
|
if (mKind == TRACING_INTERVAL_START) {
|
|
aWriter.StringProperty("interval", "start");
|
|
} else if (mKind == TRACING_INTERVAL_END) {
|
|
aWriter.StringProperty("interval", "end");
|
|
}
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length FileIOMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(
|
|
WrapProfileBufferRawPointer(mSource), mOperation, mFilename,
|
|
mIOThreadId);
|
|
}
|
|
|
|
void FileIOMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(WrapProfileBufferRawPointer(mSource));
|
|
aEntryWriter.WriteObject(mOperation);
|
|
aEntryWriter.WriteObject(mFilename);
|
|
aEntryWriter.WriteObject(mIOThreadId);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> FileIOMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto source = aEntryReader.ReadObject<const char*>();
|
|
auto operation = aEntryReader.ReadObject<UniqueFreePtr<char>>();
|
|
auto filename = aEntryReader.ReadObject<UniqueFreePtr<char>>();
|
|
auto ioThreadId = aEntryReader.ReadObject<Maybe<int>>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new FileIOMarkerPayload(std::move(props), source, std::move(operation),
|
|
std::move(filename), ioThreadId));
|
|
}
|
|
|
|
void FileIOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("FileIO", aWriter, aProcessStartTime, aUniqueStacks);
|
|
aWriter.StringProperty("operation", MakeStringSpan(mOperation.get()));
|
|
aWriter.StringProperty("source", MakeStringSpan(mSource));
|
|
if (mFilename) {
|
|
aWriter.StringProperty("filename", MakeStringSpan(mFilename.get()));
|
|
}
|
|
if (mIOThreadId.isSome()) {
|
|
aWriter.IntProperty("threadId", *mIOThreadId);
|
|
}
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
UserTimingMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(
|
|
WrapProfileBufferRawPointer(mEntryType), mName, mStartMark,
|
|
mEndMark);
|
|
}
|
|
|
|
void UserTimingMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(WrapProfileBufferRawPointer(mEntryType));
|
|
aEntryWriter.WriteObject(mName);
|
|
aEntryWriter.WriteObject(mStartMark);
|
|
aEntryWriter.WriteObject(mEndMark);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> UserTimingMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto entryType = aEntryReader.ReadObject<const char*>();
|
|
auto name = aEntryReader.ReadObject<nsString>();
|
|
auto startMark = aEntryReader.ReadObject<Maybe<nsString>>();
|
|
auto endMark = aEntryReader.ReadObject<Maybe<nsString>>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new UserTimingMarkerPayload(std::move(props), entryType, std::move(name),
|
|
std::move(startMark), std::move(endMark)));
|
|
}
|
|
|
|
void UserTimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("UserTiming", aWriter, aProcessStartTime, aUniqueStacks);
|
|
aWriter.StringProperty("name", NS_ConvertUTF16toUTF8(mName));
|
|
aWriter.StringProperty("entryType", MakeStringSpan(mEntryType));
|
|
|
|
if (mStartMark.isSome()) {
|
|
aWriter.StringProperty("startMark",
|
|
NS_ConvertUTF16toUTF8(mStartMark.value()));
|
|
} else {
|
|
aWriter.NullProperty("startMark");
|
|
}
|
|
if (mEndMark.isSome()) {
|
|
aWriter.StringProperty("endMark", NS_ConvertUTF16toUTF8(mEndMark.value()));
|
|
} else {
|
|
aWriter.NullProperty("endMark");
|
|
}
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length TimingMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes();
|
|
}
|
|
|
|
void TimingMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> TimingMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new TimingMarkerPayload(std::move(props)));
|
|
}
|
|
|
|
void TimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("Timing", aWriter, aProcessStartTime, aUniqueStacks);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length TextMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mText);
|
|
}
|
|
|
|
void TextMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mText);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> TextMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto text = aEntryReader.ReadObject<nsCString>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new TextMarkerPayload(std::move(props), std::move(text)));
|
|
}
|
|
|
|
void TextMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("Text", aWriter, aProcessStartTime, aUniqueStacks);
|
|
aWriter.StringProperty("name", mText);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length LogMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mModule, mText);
|
|
}
|
|
|
|
void LogMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mModule);
|
|
aEntryWriter.WriteObject(mText);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> LogMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto module = aEntryReader.ReadObject<nsAutoCStringN<32>>();
|
|
auto text = aEntryReader.ReadObject<nsCString>();
|
|
return UniquePtr<ProfilerMarkerPayload>(new LogMarkerPayload(
|
|
std::move(props), std::move(module), std::move(text)));
|
|
}
|
|
|
|
void LogMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("Log", aWriter, aProcessStartTime, aUniqueStacks);
|
|
aWriter.StringProperty("name", mText);
|
|
aWriter.StringProperty("module", mModule);
|
|
}
|
|
|
|
MediaSampleMarkerPayload::MediaSampleMarkerPayload(
|
|
const int64_t aSampleStartTimeUs, const int64_t aSampleEndTimeUs)
|
|
: mSampleStartTimeUs(aSampleStartTimeUs),
|
|
mSampleEndTimeUs(aSampleEndTimeUs) {}
|
|
|
|
MediaSampleMarkerPayload::MediaSampleMarkerPayload(
|
|
CommonProps&& aCommonProps, const int64_t aSampleStartTimeUs,
|
|
const int64_t aSampleEndTimeUs)
|
|
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
|
mSampleStartTimeUs(aSampleStartTimeUs),
|
|
mSampleEndTimeUs(aSampleEndTimeUs) {}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
MediaSampleMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mSampleStartTimeUs,
|
|
mSampleEndTimeUs);
|
|
}
|
|
|
|
void MediaSampleMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mSampleStartTimeUs);
|
|
aEntryWriter.WriteObject(mSampleEndTimeUs);
|
|
}
|
|
|
|
/* static */
|
|
UniquePtr<ProfilerMarkerPayload> MediaSampleMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto sampleStartTimeUs = aEntryReader.ReadObject<int64_t>();
|
|
auto sampleEndTimeUs = aEntryReader.ReadObject<int64_t>();
|
|
return UniquePtr<ProfilerMarkerPayload>(new MediaSampleMarkerPayload(
|
|
std::move(props), sampleStartTimeUs, sampleEndTimeUs));
|
|
}
|
|
|
|
void MediaSampleMarkerPayload::StreamPayload(
|
|
SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("MediaSample", aWriter, aProcessStartTime, aUniqueStacks);
|
|
aWriter.IntProperty("sampleStartTimeUs", mSampleStartTimeUs);
|
|
aWriter.IntProperty("sampleEndTimeUs", mSampleEndTimeUs);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length PrefMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mPrefAccessTime, mPrefName,
|
|
mPrefKind, mPrefType, mPrefValue);
|
|
}
|
|
|
|
void PrefMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mPrefAccessTime);
|
|
aEntryWriter.WriteObject(mPrefName);
|
|
aEntryWriter.WriteObject(mPrefKind);
|
|
aEntryWriter.WriteObject(mPrefType);
|
|
aEntryWriter.WriteObject(mPrefValue);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> PrefMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto prefAccessTime = aEntryReader.ReadObject<TimeStamp>();
|
|
auto prefName = aEntryReader.ReadObject<nsCString>();
|
|
auto prefKind = aEntryReader.ReadObject<Maybe<PrefValueKind>>();
|
|
auto prefType = aEntryReader.ReadObject<Maybe<PrefType>>();
|
|
auto prefValue = aEntryReader.ReadObject<nsCString>();
|
|
return UniquePtr<ProfilerMarkerPayload>(new PrefMarkerPayload(
|
|
std::move(props), prefAccessTime, std::move(prefName),
|
|
std::move(prefKind), std::move(prefType), std::move(prefValue)));
|
|
}
|
|
|
|
static Span<const char> PrefValueKindToString(
|
|
const Maybe<PrefValueKind>& aKind) {
|
|
if (aKind) {
|
|
return *aKind == PrefValueKind::Default ? MakeStringSpan("Default")
|
|
: MakeStringSpan("User");
|
|
}
|
|
return MakeStringSpan("Shared");
|
|
}
|
|
|
|
static Span<const char> PrefTypeToString(const Maybe<PrefType>& type) {
|
|
if (type) {
|
|
switch (*type) {
|
|
case PrefType::None:
|
|
return MakeStringSpan("None");
|
|
case PrefType::Int:
|
|
return MakeStringSpan("Int");
|
|
case PrefType::Bool:
|
|
return MakeStringSpan("Bool");
|
|
case PrefType::String:
|
|
return MakeStringSpan("String");
|
|
default:
|
|
MOZ_ASSERT_UNREACHABLE("Unknown preference type.");
|
|
}
|
|
}
|
|
return MakeStringSpan("Preference not found");
|
|
}
|
|
|
|
void PrefMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("PreferenceRead", aWriter, aProcessStartTime,
|
|
aUniqueStacks);
|
|
WriteTime(aWriter, aProcessStartTime, mPrefAccessTime, "prefAccessTime");
|
|
aWriter.StringProperty("prefName", mPrefName);
|
|
aWriter.StringProperty("prefKind", PrefValueKindToString(mPrefKind));
|
|
aWriter.StringProperty("prefType", PrefTypeToString(mPrefType));
|
|
aWriter.StringProperty("prefValue", mPrefValue);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
LayerTranslationMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(WrapProfileBufferRawPointer(mLayer),
|
|
mPoint);
|
|
}
|
|
|
|
void LayerTranslationMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(WrapProfileBufferRawPointer(mLayer));
|
|
aEntryWriter.WriteObject(mPoint);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> LayerTranslationMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto layer = aEntryReader.ReadObject<layers::Layer*>();
|
|
auto point = aEntryReader.ReadObject<gfx::Point>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new LayerTranslationMarkerPayload(std::move(props), layer, point));
|
|
}
|
|
|
|
void LayerTranslationMarkerPayload::StreamPayload(
|
|
SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamType("LayerTranslation", aWriter);
|
|
const size_t bufferSize = 32;
|
|
char buffer[bufferSize];
|
|
const int written = SprintfLiteral(buffer, "%p", mLayer);
|
|
MOZ_RELEASE_ASSERT(written > 0);
|
|
|
|
aWriter.StringProperty("layer", Span<const char>(buffer, size_t(written)));
|
|
aWriter.IntProperty("x", mPoint.x);
|
|
aWriter.IntProperty("y", mPoint.y);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length VsyncMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes();
|
|
}
|
|
|
|
void VsyncMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> VsyncMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new VsyncMarkerPayload(std::move(props)));
|
|
}
|
|
|
|
void VsyncMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamType("VsyncTimestamp", aWriter);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
NetworkMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(
|
|
mID, mURI, mRedirectURI, mRequestMethod, mType, mPri, mCount,
|
|
mTimings, mCacheDisposition, mContentType);
|
|
}
|
|
|
|
void NetworkMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mID);
|
|
aEntryWriter.WriteObject(mURI);
|
|
aEntryWriter.WriteObject(mRedirectURI);
|
|
aEntryWriter.WriteObject(mRequestMethod);
|
|
aEntryWriter.WriteObject(mType);
|
|
aEntryWriter.WriteObject(mPri);
|
|
aEntryWriter.WriteObject(mCount);
|
|
aEntryWriter.WriteObject(mTimings);
|
|
aEntryWriter.WriteObject(mCacheDisposition);
|
|
aEntryWriter.WriteObject(mContentType);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> NetworkMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto id = aEntryReader.ReadObject<int64_t>();
|
|
auto uri = aEntryReader.ReadObject<UniqueFreePtr<char>>();
|
|
auto redirectURI = aEntryReader.ReadObject<UniqueFreePtr<char>>();
|
|
auto requestMethod = aEntryReader.ReadObject<nsCString>();
|
|
auto type = aEntryReader.ReadObject<NetworkLoadType>();
|
|
auto pri = aEntryReader.ReadObject<int32_t>();
|
|
auto count = aEntryReader.ReadObject<int64_t>();
|
|
auto timings = aEntryReader.ReadObject<net::TimingStruct>();
|
|
auto cacheDisposition = aEntryReader.ReadObject<net::CacheDisposition>();
|
|
auto contentType = aEntryReader.ReadObject<Maybe<nsAutoCString>>();
|
|
return UniquePtr<ProfilerMarkerPayload>(new NetworkMarkerPayload(
|
|
std::move(props), id, std::move(uri), std::move(redirectURI),
|
|
std::move(requestMethod), type, pri, count, timings, cacheDisposition,
|
|
std::move(contentType)));
|
|
}
|
|
|
|
static Span<const char> GetNetworkState(NetworkLoadType aType) {
|
|
switch (aType) {
|
|
case NetworkLoadType::LOAD_START:
|
|
return MakeStringSpan("STATUS_START");
|
|
case NetworkLoadType::LOAD_STOP:
|
|
return MakeStringSpan("STATUS_STOP");
|
|
case NetworkLoadType::LOAD_REDIRECT:
|
|
return MakeStringSpan("STATUS_REDIRECT");
|
|
}
|
|
return MakeStringSpan("");
|
|
}
|
|
|
|
static Span<const char> GetCacheState(net::CacheDisposition aCacheDisposition) {
|
|
switch (aCacheDisposition) {
|
|
case net::kCacheUnresolved:
|
|
return MakeStringSpan("Unresolved");
|
|
case net::kCacheHit:
|
|
return MakeStringSpan("Hit");
|
|
case net::kCacheHitViaReval:
|
|
return MakeStringSpan("HitViaReval");
|
|
case net::kCacheMissedViaReval:
|
|
return MakeStringSpan("MissedViaReval");
|
|
case net::kCacheMissed:
|
|
return MakeStringSpan("Missed");
|
|
case net::kCacheUnknown:
|
|
default:
|
|
return MakeStringSpan("");
|
|
}
|
|
}
|
|
|
|
void NetworkMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("Network", aWriter, aProcessStartTime, aUniqueStacks);
|
|
// This payload still streams a startTime and endTime property because it made
|
|
// the migration to MarkerTiming on the front-end easier.
|
|
StreamStartEndTime(aWriter, aProcessStartTime);
|
|
|
|
aWriter.IntProperty("id", mID);
|
|
// want to use aUniqueStacks.mUniqueStrings->WriteElement(aWriter,
|
|
// typeString);
|
|
aWriter.StringProperty("status", GetNetworkState(mType));
|
|
if (Span<const char> cacheString = GetCacheState(mCacheDisposition);
|
|
!cacheString.empty()) {
|
|
aWriter.StringProperty("cache", cacheString);
|
|
}
|
|
aWriter.IntProperty("pri", mPri);
|
|
if (mCount > 0) {
|
|
aWriter.IntProperty("count", mCount);
|
|
}
|
|
if (mURI) {
|
|
aWriter.StringProperty("URI", MakeStringSpan(mURI.get()));
|
|
}
|
|
if (mRedirectURI) {
|
|
aWriter.StringProperty("RedirectURI", MakeStringSpan(mRedirectURI.get()));
|
|
}
|
|
aWriter.StringProperty("requestMethod", mRequestMethod);
|
|
|
|
if (mContentType.isSome()) {
|
|
aWriter.StringProperty("contentType", mContentType.value());
|
|
} else {
|
|
aWriter.NullProperty("contentType");
|
|
}
|
|
|
|
if (mType != NetworkLoadType::LOAD_START) {
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.domainLookupStart,
|
|
"domainLookupStart");
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.domainLookupEnd,
|
|
"domainLookupEnd");
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.connectStart,
|
|
"connectStart");
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.tcpConnectEnd,
|
|
"tcpConnectEnd");
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.secureConnectionStart,
|
|
"secureConnectionStart");
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.connectEnd, "connectEnd");
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.requestStart,
|
|
"requestStart");
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.responseStart,
|
|
"responseStart");
|
|
WriteTime(aWriter, aProcessStartTime, mTimings.responseEnd, "responseEnd");
|
|
}
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length ScreenshotPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mScreenshotDataURL, mWindowSize,
|
|
mWindowIdentifier);
|
|
}
|
|
|
|
void ScreenshotPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mScreenshotDataURL);
|
|
aEntryWriter.WriteObject(mWindowSize);
|
|
aEntryWriter.WriteObject(mWindowIdentifier);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> ScreenshotPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto screenshotDataURL = aEntryReader.ReadObject<nsCString>();
|
|
auto windowSize = aEntryReader.ReadObject<gfx::IntSize>();
|
|
auto windowIdentifier = aEntryReader.ReadObject<uintptr_t>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new ScreenshotPayload(std::move(props), std::move(screenshotDataURL),
|
|
windowSize, windowIdentifier));
|
|
}
|
|
|
|
void ScreenshotPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamType("CompositorScreenshot", aWriter);
|
|
aUniqueStacks.mUniqueStrings->WriteProperty(aWriter, "url",
|
|
mScreenshotDataURL.get());
|
|
|
|
char hexWindowID[32];
|
|
const int written =
|
|
SprintfLiteral(hexWindowID, "0x%" PRIXPTR, mWindowIdentifier);
|
|
MOZ_RELEASE_ASSERT(written > 0);
|
|
aWriter.StringProperty("windowID",
|
|
Span<const char>(hexWindowID, size_t(written)));
|
|
aWriter.DoubleProperty("windowWidth", mWindowSize.width);
|
|
aWriter.DoubleProperty("windowHeight", mWindowSize.height);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
GCSliceMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mTimingJSON);
|
|
}
|
|
|
|
void GCSliceMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mTimingJSON);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> GCSliceMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto timingJSON = aEntryReader.ReadObject<JS::UniqueChars>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new GCSliceMarkerPayload(std::move(props), std::move(timingJSON)));
|
|
}
|
|
|
|
void GCSliceMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
MOZ_ASSERT(mTimingJSON);
|
|
StreamCommonProps("GCSlice", aWriter, aProcessStartTime, aUniqueStacks);
|
|
if (mTimingJSON) {
|
|
aWriter.SplicedJSONProperty(MakeStringSpan("timings"),
|
|
MakeStringSpan(mTimingJSON.get()));
|
|
} else {
|
|
aWriter.NullProperty("timings");
|
|
}
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length BudgetMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes();
|
|
}
|
|
|
|
void BudgetMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> BudgetMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new BudgetMarkerPayload(std::move(props)));
|
|
}
|
|
|
|
void BudgetMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("Budget", aWriter, aProcessStartTime, aUniqueStacks);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
GCMajorMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mTimingJSON);
|
|
}
|
|
|
|
void GCMajorMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mTimingJSON);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> GCMajorMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto timingJSON = aEntryReader.ReadObject<JS::UniqueChars>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new GCMajorMarkerPayload(std::move(props), std::move(timingJSON)));
|
|
}
|
|
|
|
void GCMajorMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
MOZ_ASSERT(mTimingJSON);
|
|
StreamCommonProps("GCMajor", aWriter, aProcessStartTime, aUniqueStacks);
|
|
if (mTimingJSON) {
|
|
aWriter.SplicedJSONProperty(MakeStringSpan("timings"),
|
|
MakeStringSpan(mTimingJSON.get()));
|
|
} else {
|
|
aWriter.NullProperty("timings");
|
|
}
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
GCMinorMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mTimingData);
|
|
}
|
|
|
|
void GCMinorMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mTimingData);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> GCMinorMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto timingData = aEntryReader.ReadObject<JS::UniqueChars>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new GCMinorMarkerPayload(std::move(props), std::move(timingData)));
|
|
}
|
|
|
|
void GCMinorMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
MOZ_ASSERT(mTimingData);
|
|
StreamCommonProps("GCMinor", aWriter, aProcessStartTime, aUniqueStacks);
|
|
if (mTimingData) {
|
|
aWriter.SplicedJSONProperty(MakeStringSpan("nursery"),
|
|
MakeStringSpan(mTimingData.get()));
|
|
} else {
|
|
aWriter.NullProperty("nursery");
|
|
}
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length HangMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes();
|
|
}
|
|
|
|
void HangMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> HangMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new HangMarkerPayload(std::move(props)));
|
|
}
|
|
|
|
void HangMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("BHR-detected hang", aWriter, aProcessStartTime,
|
|
aUniqueStacks);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length StyleMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mStats);
|
|
}
|
|
|
|
void StyleMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mStats);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> StyleMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto stats = aEntryReader.ReadObject<ServoTraversalStatistics>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new StyleMarkerPayload(std::move(props), stats));
|
|
}
|
|
|
|
void StyleMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("Styles", aWriter, aProcessStartTime, aUniqueStacks);
|
|
aWriter.StringProperty("category", "Paint");
|
|
aWriter.IntProperty("elementsTraversed", mStats.mElementsTraversed);
|
|
aWriter.IntProperty("elementsStyled", mStats.mElementsStyled);
|
|
aWriter.IntProperty("elementsMatched", mStats.mElementsMatched);
|
|
aWriter.IntProperty("stylesShared", mStats.mStylesShared);
|
|
aWriter.IntProperty("stylesReused", mStats.mStylesReused);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
LongTaskMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes();
|
|
}
|
|
|
|
void LongTaskMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> LongTaskMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new LongTaskMarkerPayload(std::move(props)));
|
|
}
|
|
|
|
void LongTaskMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("MainThreadLongTask", aWriter, aProcessStartTime,
|
|
aUniqueStacks);
|
|
aWriter.StringProperty("category", "LongTask");
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
JsAllocationMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mTypeName, mClassName,
|
|
mDescriptiveTypeName, mCoarseType,
|
|
mSize, mInNursery);
|
|
}
|
|
|
|
void JsAllocationMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mTypeName);
|
|
aEntryWriter.WriteObject(mClassName);
|
|
aEntryWriter.WriteObject(mDescriptiveTypeName);
|
|
aEntryWriter.WriteObject(WrapProfileBufferRawPointer(mCoarseType));
|
|
aEntryWriter.WriteObject(mSize);
|
|
aEntryWriter.WriteObject(mInNursery);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> JsAllocationMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto typeName = aEntryReader.ReadObject<UniqueFreePtr<const char16_t>>();
|
|
auto className = aEntryReader.ReadObject<UniqueFreePtr<const char>>();
|
|
auto descriptiveTypeName =
|
|
aEntryReader.ReadObject<UniqueFreePtr<const char16_t>>();
|
|
auto coarseType = aEntryReader.ReadObject<const char*>();
|
|
auto size = aEntryReader.ReadObject<uint64_t>();
|
|
auto inNursery = aEntryReader.ReadObject<bool>();
|
|
return UniquePtr<ProfilerMarkerPayload>(new JsAllocationMarkerPayload(
|
|
std::move(props), std::move(typeName), std::move(className),
|
|
std::move(descriptiveTypeName), coarseType, size, inNursery));
|
|
}
|
|
|
|
void JsAllocationMarkerPayload::StreamPayload(
|
|
SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("JS allocation", aWriter, aProcessStartTime, aUniqueStacks);
|
|
|
|
if (mClassName) {
|
|
aWriter.StringProperty("className", MakeStringSpan(mClassName.get()));
|
|
}
|
|
if (mTypeName) {
|
|
aWriter.StringProperty("typeName", NS_ConvertUTF16toUTF8(mTypeName.get()));
|
|
}
|
|
if (mDescriptiveTypeName) {
|
|
aWriter.StringProperty("descriptiveTypeName",
|
|
NS_ConvertUTF16toUTF8(mDescriptiveTypeName.get()));
|
|
}
|
|
aWriter.StringProperty("coarseType", MakeStringSpan(mCoarseType));
|
|
aWriter.IntProperty("size", mSize);
|
|
aWriter.BoolProperty("inNursery", mInNursery);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length
|
|
NativeAllocationMarkerPayload::TagAndSerializationBytes() const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mSize, mThreadId, mMemoryAddress);
|
|
}
|
|
|
|
void NativeAllocationMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mSize);
|
|
aEntryWriter.WriteObject(mMemoryAddress);
|
|
aEntryWriter.WriteObject(mThreadId);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> NativeAllocationMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto size = aEntryReader.ReadObject<int64_t>();
|
|
auto memoryAddress = aEntryReader.ReadObject<uintptr_t>();
|
|
auto threadId = aEntryReader.ReadObject<int>();
|
|
return UniquePtr<ProfilerMarkerPayload>(new NativeAllocationMarkerPayload(
|
|
std::move(props), size, memoryAddress, threadId));
|
|
}
|
|
|
|
void NativeAllocationMarkerPayload::StreamPayload(
|
|
SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
StreamCommonProps("Native allocation", aWriter, aProcessStartTime,
|
|
aUniqueStacks);
|
|
aWriter.IntProperty("size", mSize);
|
|
aWriter.IntProperty("memoryAddress", static_cast<int64_t>(mMemoryAddress));
|
|
aWriter.IntProperty("threadId", mThreadId);
|
|
}
|
|
|
|
ProfileBufferEntryWriter::Length IPCMarkerPayload::TagAndSerializationBytes()
|
|
const {
|
|
return CommonPropsTagAndSerializationBytes() +
|
|
ProfileBufferEntryWriter::SumBytes(mOtherPid, mMessageSeqno,
|
|
mMessageType, mSide, mDirection,
|
|
mPhase, mSync);
|
|
}
|
|
|
|
void IPCMarkerPayload::SerializeTagAndPayload(
|
|
ProfileBufferEntryWriter& aEntryWriter) const {
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
aEntryWriter.WriteObject(mOtherPid);
|
|
aEntryWriter.WriteObject(mMessageSeqno);
|
|
aEntryWriter.WriteObject(mMessageType);
|
|
aEntryWriter.WriteObject(mSide);
|
|
aEntryWriter.WriteObject(mDirection);
|
|
aEntryWriter.WriteObject(mPhase);
|
|
aEntryWriter.WriteObject(mSync);
|
|
}
|
|
|
|
// static
|
|
UniquePtr<ProfilerMarkerPayload> IPCMarkerPayload::Deserialize(
|
|
ProfileBufferEntryReader& aEntryReader) {
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
DeserializeCommonProps(aEntryReader);
|
|
auto otherPid = aEntryReader.ReadObject<int32_t>();
|
|
auto messageSeqno = aEntryReader.ReadObject<int32_t>();
|
|
auto messageType = aEntryReader.ReadObject<IPC::Message::msgid_t>();
|
|
auto side = aEntryReader.ReadObject<ipc::Side>();
|
|
auto direction = aEntryReader.ReadObject<ipc::MessageDirection>();
|
|
auto phase = aEntryReader.ReadObject<ipc::MessagePhase>();
|
|
auto sync = aEntryReader.ReadObject<bool>();
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
new IPCMarkerPayload(std::move(props), otherPid, messageSeqno,
|
|
messageType, side, direction, phase, sync));
|
|
}
|
|
|
|
static Span<const char> IPCSideToString(ipc::Side aSide) {
|
|
switch (aSide) {
|
|
case ipc::ParentSide:
|
|
return MakeStringSpan("parent");
|
|
case ipc::ChildSide:
|
|
return MakeStringSpan("child");
|
|
case ipc::UnknownSide:
|
|
return MakeStringSpan("unknown");
|
|
default:
|
|
MOZ_ASSERT_UNREACHABLE("Invalid IPC side");
|
|
return MakeStringSpan("<invalid IPC side>");
|
|
}
|
|
}
|
|
|
|
static Span<const char> IPCPhaseToString(ipc::MessagePhase aPhase) {
|
|
switch (aPhase) {
|
|
case ipc::MessagePhase::Endpoint:
|
|
return MakeStringSpan("endpoint");
|
|
case ipc::MessagePhase::TransferStart:
|
|
return MakeStringSpan("transferStart");
|
|
case ipc::MessagePhase::TransferEnd:
|
|
return MakeStringSpan("transferEnd");
|
|
default:
|
|
MOZ_ASSERT_UNREACHABLE("Invalid IPC phase");
|
|
return MakeStringSpan("<invalid IPC phase>");
|
|
}
|
|
}
|
|
|
|
void IPCMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|
const TimeStamp& aProcessStartTime,
|
|
UniqueStacks& aUniqueStacks) const {
|
|
using namespace mozilla::ipc;
|
|
StreamCommonProps("IPC", aWriter, aProcessStartTime, aUniqueStacks);
|
|
|
|
// This payload still streams a startTime and endTime property because it made
|
|
// the migration to MarkerTiming on the front-end easier.
|
|
StreamStartEndTime(aWriter, aProcessStartTime);
|
|
|
|
aWriter.IntProperty("otherPid", mOtherPid);
|
|
aWriter.IntProperty("messageSeqno", mMessageSeqno);
|
|
aWriter.StringProperty(
|
|
"messageType",
|
|
MakeStringSpan(IPC::StringFromIPCMessageType(mMessageType)));
|
|
aWriter.StringProperty("side", IPCSideToString(mSide));
|
|
aWriter.StringProperty("direction", mDirection == MessageDirection::eSending
|
|
? MakeStringSpan("sending")
|
|
: MakeStringSpan("receiving"));
|
|
aWriter.StringProperty("phase", IPCPhaseToString(mPhase));
|
|
aWriter.BoolProperty("sync", mSync);
|
|
}
|