зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1575448 - De/serialize ProfilerMarkerPayload derived objects - r=gregtatum
Payloads will serialize themselves into a `BlocksRingBuffer` entry when first captured. Later they will be deserialized, to stream JSON for the output profile. Differential Revision: https://phabricator.services.mozilla.com/D43428 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
64f0dcdf95
Коммит
5b86107991
|
@ -54,9 +54,32 @@ class VideoFrameMarkerPayload : public ProfilerMarkerPayload {
|
|||
mAudioPositionUs(aAudioPositionUs),
|
||||
mVideoFrameTimeUs(aVideoFrameTimeUs) {}
|
||||
|
||||
BlocksRingBuffer::Length TagAndSerializationBytes() const override {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mAudioPositionUs, mVideoFrameTimeUs);
|
||||
}
|
||||
|
||||
void SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const override {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mAudioPositionUs);
|
||||
aEntryWriter.WriteObject(mVideoFrameTimeUs);
|
||||
}
|
||||
|
||||
static UniquePtr<ProfilerMarkerPayload> Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
auto audioPositionUs = aEntryReader.ReadObject<int64_t>();
|
||||
auto videoFrameTimeUs = aEntryReader.ReadObject<int64_t>();
|
||||
return UniquePtr<ProfilerMarkerPayload>(new VideoFrameMarkerPayload(
|
||||
std::move(props), audioPositionUs, videoFrameTimeUs));
|
||||
}
|
||||
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const override {
|
||||
StreamCommonProps("UpdateRenderVideoFrames", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
aWriter.IntProperty("audio", mAudioPositionUs);
|
||||
|
@ -64,6 +87,12 @@ class VideoFrameMarkerPayload : public ProfilerMarkerPayload {
|
|||
}
|
||||
|
||||
private:
|
||||
VideoFrameMarkerPayload(CommonProps&& aCommonProps, int64_t aAudioPositionUs,
|
||||
int64_t aVideoFrameTimeUs)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mAudioPositionUs(aAudioPositionUs),
|
||||
mVideoFrameTimeUs(aVideoFrameTimeUs) {}
|
||||
|
||||
int64_t mAudioPositionUs;
|
||||
int64_t mVideoFrameTimeUs;
|
||||
};
|
||||
|
|
|
@ -2530,12 +2530,32 @@ int32_t RecordContentFrameTime(
|
|||
ContentFramePayload(const mozilla::TimeStamp& aStartTime,
|
||||
const mozilla::TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) override {
|
||||
mozilla::BlocksRingBuffer::Length TagAndSerializationBytes()
|
||||
const override {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
void SerializeTagAndPayload(
|
||||
mozilla::BlocksRingBuffer::EntryWriter& aEntryWriter) const override {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const override {
|
||||
StreamCommonProps("CONTENT_FRAME_TIME", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit ContentFramePayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
static mozilla::UniquePtr<ProfilerMarkerPayload> Deserialize(
|
||||
mozilla::BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new ContentFramePayload(std::move(props)));
|
||||
}
|
||||
};
|
||||
AUTO_PROFILER_STATS(add_marker_with_ContentFramePayload);
|
||||
profiler_add_marker_for_thread(
|
||||
|
|
|
@ -367,12 +367,32 @@ void ContentCompositorBridgeParent::ShadowLayersUpdated(
|
|||
ContentBuildPayload(const mozilla::TimeStamp& aStartTime,
|
||||
const mozilla::TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) override {
|
||||
mozilla::BlocksRingBuffer::Length TagAndSerializationBytes()
|
||||
const override {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
void SerializeTagAndPayload(
|
||||
mozilla::BlocksRingBuffer::EntryWriter& aEntryWriter) const override {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const override {
|
||||
StreamCommonProps("CONTENT_FULL_PAINT_TIME", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit ContentBuildPayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
static mozilla::UniquePtr<ProfilerMarkerPayload> Deserialize(
|
||||
mozilla::BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new ContentBuildPayload(std::move(props)));
|
||||
}
|
||||
};
|
||||
AUTO_PROFILER_STATS(add_marker_with_ContentBuildPayload);
|
||||
profiler_add_marker_for_thread(
|
||||
|
|
|
@ -211,12 +211,34 @@ class SceneBuiltNotification : public wr::NotificationHandler {
|
|||
ContentFullPaintPayload(const mozilla::TimeStamp& aStartTime,
|
||||
const mozilla::TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
mozilla::BlocksRingBuffer::Length TagAndSerializationBytes()
|
||||
const override {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
void SerializeTagAndPayload(
|
||||
mozilla::BlocksRingBuffer::EntryWriter& aEntryWriter)
|
||||
const override {
|
||||
static const DeserializerTag tag =
|
||||
TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) override {
|
||||
UniqueStacks& aUniqueStacks) const override {
|
||||
StreamCommonProps("CONTENT_FULL_PAINT_TIME", aWriter,
|
||||
aProcessStartTime, aUniqueStacks);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit ContentFullPaintPayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
static mozilla::UniquePtr<ProfilerMarkerPayload> Deserialize(
|
||||
mozilla::BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new ContentFullPaintPayload(std::move(props)));
|
||||
}
|
||||
};
|
||||
|
||||
AUTO_PROFILER_STATS(add_marker_with_ContentFullPaintPayload);
|
||||
|
|
|
@ -21,6 +21,77 @@
|
|||
namespace mozilla {
|
||||
namespace baseprofiler {
|
||||
|
||||
static UniquePtr<ProfilerMarkerPayload> DeserializeNothing(
|
||||
mozilla::BlocksRingBuffer::EntryReader&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Number of currently-registered deserializers.
|
||||
// Starting at 1 for the initial `DeserializeNothing`.
|
||||
// static
|
||||
Atomic<ProfilerMarkerPayload::DeserializerTagAtomic, ReleaseAcquire,
|
||||
recordreplay::Behavior::DontPreserve>
|
||||
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,
|
||||
|
@ -31,14 +102,47 @@ static void MOZ_ALWAYS_INLINE WriteTime(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
|
||||
void ProfilerMarkerPayload::StreamType(const char* aMarkerType,
|
||||
SpliceableJSONWriter& aWriter) {
|
||||
SpliceableJSONWriter& aWriter) const {
|
||||
MOZ_ASSERT(aMarkerType);
|
||||
aWriter.StringProperty("type", aMarkerType);
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length
|
||||
ProfilerMarkerPayload::CommonPropsTagAndSerializationBytes() const {
|
||||
return sizeof(DeserializerTag) +
|
||||
BlocksRingBuffer::SumBytes(mCommonProps.mStartTime,
|
||||
mCommonProps.mEndTime, mCommonProps.mStack,
|
||||
mCommonProps.mDocShellId,
|
||||
mCommonProps.mDocShellHistoryId);
|
||||
}
|
||||
|
||||
void ProfilerMarkerPayload::SerializeTagAndCommonProps(
|
||||
DeserializerTag aDeserializerTag,
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
aEntryWriter.WriteObject(aDeserializerTag);
|
||||
aEntryWriter.WriteObject(mCommonProps.mStartTime);
|
||||
aEntryWriter.WriteObject(mCommonProps.mEndTime);
|
||||
aEntryWriter.WriteObject(mCommonProps.mStack);
|
||||
aEntryWriter.WriteObject(mCommonProps.mDocShellId);
|
||||
aEntryWriter.WriteObject(mCommonProps.mDocShellHistoryId);
|
||||
}
|
||||
|
||||
// static
|
||||
ProfilerMarkerPayload::CommonProps
|
||||
ProfilerMarkerPayload::DeserializeCommonProps(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
CommonProps props;
|
||||
aEntryReader.ReadIntoObject(props.mStartTime);
|
||||
aEntryReader.ReadIntoObject(props.mEndTime);
|
||||
aEntryReader.ReadIntoObject(props.mStack);
|
||||
aEntryReader.ReadIntoObject(props.mDocShellId);
|
||||
aEntryReader.ReadIntoObject(props.mDocShellHistoryId);
|
||||
return props;
|
||||
}
|
||||
|
||||
void ProfilerMarkerPayload::StreamCommonProps(
|
||||
const char* aMarkerType, SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime, UniqueStacks& aUniqueStacks) {
|
||||
const TimeStamp& aProcessStartTime, UniqueStacks& aUniqueStacks) const {
|
||||
StreamType(aMarkerType, aWriter);
|
||||
WriteTime(aWriter, aProcessStartTime, mCommonProps.mStartTime, "startTime");
|
||||
WriteTime(aWriter, aProcessStartTime, mCommonProps.mEndTime, "endTime");
|
||||
|
@ -59,9 +163,52 @@ void ProfilerMarkerPayload::StreamCommonProps(
|
|||
}
|
||||
}
|
||||
|
||||
TracingMarkerPayload::TracingMarkerPayload(
|
||||
const char* aCategory, TracingKind aKind,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId, UniqueProfilerBacktrace aCause)
|
||||
: ProfilerMarkerPayload(aDocShellId, aDocShellHistoryId, std::move(aCause)),
|
||||
mCategory(aCategory),
|
||||
mKind(aKind) {}
|
||||
|
||||
TracingMarkerPayload::TracingMarkerPayload(CommonProps&& aCommonProps,
|
||||
const char* aCategory,
|
||||
TracingKind aKind)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mCategory(aCategory),
|
||||
mKind(aKind) {}
|
||||
|
||||
TracingMarkerPayload::~TracingMarkerPayload() = default;
|
||||
|
||||
BlocksRingBuffer::Length TracingMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(WrapBlocksRingBufferRawPointer(mCategory),
|
||||
mKind);
|
||||
}
|
||||
|
||||
void TracingMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(WrapBlocksRingBufferRawPointer(mCategory));
|
||||
aEntryWriter.WriteObject(mKind);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> TracingMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("tracing", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
|
||||
if (mCategory) {
|
||||
|
@ -75,20 +222,135 @@ void TracingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
FileIOMarkerPayload::FileIOMarkerPayload(const char* aOperation,
|
||||
const char* aSource,
|
||||
const char* aFilename,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
UniqueProfilerBacktrace aStack)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, Nothing(), Nothing(),
|
||||
std::move(aStack)),
|
||||
mSource(aSource),
|
||||
mOperation(aOperation ? strdup(aOperation) : nullptr),
|
||||
mFilename(aFilename ? strdup(aFilename) : nullptr) {
|
||||
MOZ_ASSERT(aSource);
|
||||
}
|
||||
|
||||
FileIOMarkerPayload::FileIOMarkerPayload(CommonProps&& aCommonProps,
|
||||
const char* aSource,
|
||||
UniqueFreePtr<char>&& aOperation,
|
||||
UniqueFreePtr<char>&& aFilename)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mSource(aSource),
|
||||
mOperation(std::move(aOperation)),
|
||||
mFilename(std::move(aFilename)) {}
|
||||
|
||||
FileIOMarkerPayload::~FileIOMarkerPayload() = default;
|
||||
|
||||
BlocksRingBuffer::Length FileIOMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(WrapBlocksRingBufferRawPointer(mSource),
|
||||
mOperation, mFilename);
|
||||
}
|
||||
|
||||
void FileIOMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(WrapBlocksRingBufferRawPointer(mSource));
|
||||
aEntryWriter.WriteObject(mOperation);
|
||||
aEntryWriter.WriteObject(mFilename);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> FileIOMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
auto source = aEntryReader.ReadObject<const char*>();
|
||||
auto operation = aEntryReader.ReadObject<UniqueFreePtr<char>>();
|
||||
auto filename = aEntryReader.ReadObject<UniqueFreePtr<char>>();
|
||||
return UniquePtr<ProfilerMarkerPayload>(new FileIOMarkerPayload(
|
||||
std::move(props), source, std::move(operation), std::move(filename)));
|
||||
}
|
||||
|
||||
void FileIOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("FileIO", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("operation", mOperation.get());
|
||||
aWriter.StringProperty("source", mSource);
|
||||
if (mFilename) {
|
||||
if (mFilename && *mFilename) {
|
||||
aWriter.StringProperty("filename", mFilename.get());
|
||||
}
|
||||
}
|
||||
|
||||
UserTimingMarkerPayload::UserTimingMarkerPayload(
|
||||
const std::string& aName, const TimeStamp& aStartTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime, aDocShellId,
|
||||
aDocShellHistoryId),
|
||||
mEntryType("mark"),
|
||||
mName(aName) {}
|
||||
|
||||
UserTimingMarkerPayload::UserTimingMarkerPayload(
|
||||
const std::string& aName, const Maybe<std::string>& aStartMark,
|
||||
const Maybe<std::string>& aEndMark, const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime, const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, aDocShellId,
|
||||
aDocShellHistoryId),
|
||||
mEntryType("measure"),
|
||||
mName(aName),
|
||||
mStartMark(aStartMark),
|
||||
mEndMark(aEndMark) {}
|
||||
|
||||
UserTimingMarkerPayload::UserTimingMarkerPayload(
|
||||
CommonProps&& aCommonProps, const char* aEntryType, std::string&& aName,
|
||||
Maybe<std::string>&& aStartMark, Maybe<std::string>&& aEndMark)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mEntryType(aEntryType),
|
||||
mName(std::move(aName)),
|
||||
mStartMark(std::move(aStartMark)),
|
||||
mEndMark(std::move(aEndMark)) {}
|
||||
|
||||
UserTimingMarkerPayload::~UserTimingMarkerPayload() = default;
|
||||
|
||||
BlocksRingBuffer::Length UserTimingMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(WrapBlocksRingBufferRawPointer(mEntryType),
|
||||
mName, mStartMark, mEndMark);
|
||||
}
|
||||
|
||||
void UserTimingMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(WrapBlocksRingBufferRawPointer(mEntryType));
|
||||
aEntryWriter.WriteObject(mName);
|
||||
aEntryWriter.WriteObject(mStartMark);
|
||||
aEntryWriter.WriteObject(mEndMark);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> UserTimingMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
auto entryType = aEntryReader.ReadObject<const char*>();
|
||||
auto name = aEntryReader.ReadObject<std::string>();
|
||||
auto startMark = aEntryReader.ReadObject<Maybe<std::string>>();
|
||||
auto endMark = aEntryReader.ReadObject<Maybe<std::string>>();
|
||||
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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("UserTiming", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("name", mName.c_str());
|
||||
aWriter.StringProperty("entryType", mEntryType);
|
||||
|
@ -105,31 +367,181 @@ void UserTimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
TextMarkerPayload::TextMarkerPayload(const std::string& aText,
|
||||
const TimeStamp& aStartTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime), mText(aText) {}
|
||||
|
||||
TextMarkerPayload::TextMarkerPayload(const std::string& aText,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime), mText(aText) {}
|
||||
|
||||
TextMarkerPayload::TextMarkerPayload(const std::string& aText,
|
||||
const TimeStamp& aStartTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime, aDocShellId,
|
||||
aDocShellHistoryId),
|
||||
mText(aText) {}
|
||||
|
||||
TextMarkerPayload::TextMarkerPayload(const std::string& aText,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId,
|
||||
UniqueProfilerBacktrace aCause)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, aDocShellId,
|
||||
aDocShellHistoryId, std::move(aCause)),
|
||||
mText(aText) {}
|
||||
|
||||
TextMarkerPayload::TextMarkerPayload(CommonProps&& aCommonProps,
|
||||
std::string&& aText)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)), mText(std::move(aText)) {}
|
||||
|
||||
TextMarkerPayload::~TextMarkerPayload() = default;
|
||||
|
||||
BlocksRingBuffer::Length TextMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mText);
|
||||
}
|
||||
|
||||
void TextMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mText);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> TextMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
auto text = aEntryReader.ReadObject<std::string>();
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new TextMarkerPayload(std::move(props), std::move(text)));
|
||||
}
|
||||
|
||||
void TextMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("Text", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("name", mText.c_str());
|
||||
}
|
||||
|
||||
LogMarkerPayload::LogMarkerPayload(const char* aModule, const char* aText,
|
||||
const TimeStamp& aStartTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime),
|
||||
mModule(aModule),
|
||||
mText(aText) {}
|
||||
|
||||
LogMarkerPayload::LogMarkerPayload(CommonProps&& aCommonProps,
|
||||
std::string&& aModule, std::string&& aText)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mModule(std::move(aModule)),
|
||||
mText(std::move(aText)) {}
|
||||
|
||||
LogMarkerPayload::~LogMarkerPayload() = default;
|
||||
|
||||
BlocksRingBuffer::Length LogMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mModule, mText);
|
||||
}
|
||||
|
||||
void LogMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mModule);
|
||||
aEntryWriter.WriteObject(mText);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> LogMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
auto module = aEntryReader.ReadObject<std::string>();
|
||||
auto text = aEntryReader.ReadObject<std::string>();
|
||||
return UniquePtr<ProfilerMarkerPayload>(new LogMarkerPayload(
|
||||
std::move(props), std::move(module), std::move(text)));
|
||||
}
|
||||
|
||||
void LogMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("Log", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("name", mText.c_str());
|
||||
aWriter.StringProperty("module", mModule.c_str());
|
||||
}
|
||||
|
||||
HangMarkerPayload::HangMarkerPayload(const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
|
||||
HangMarkerPayload::HangMarkerPayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
|
||||
HangMarkerPayload::~HangMarkerPayload() = default;
|
||||
|
||||
BlocksRingBuffer::Length HangMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
|
||||
void HangMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> HangMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new HangMarkerPayload(std::move(props)));
|
||||
}
|
||||
|
||||
void HangMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("BHR-detected hang", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
}
|
||||
|
||||
LongTaskMarkerPayload::LongTaskMarkerPayload(const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
|
||||
LongTaskMarkerPayload::LongTaskMarkerPayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
|
||||
LongTaskMarkerPayload::~LongTaskMarkerPayload() = default;
|
||||
|
||||
BlocksRingBuffer::Length LongTaskMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
|
||||
void LongTaskMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> LongTaskMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new LongTaskMarkerPayload(std::move(props)));
|
||||
}
|
||||
|
||||
void LongTaskMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("MainThreadLongTask", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
aWriter.StringProperty("category", "LongTask");
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
# error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
|
||||
#endif
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/BlocksRingBuffer.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
@ -49,13 +51,81 @@ class ProfilerMarkerPayload {
|
|||
|
||||
virtual ~ProfilerMarkerPayload() {}
|
||||
|
||||
// Compute the number of bytes needed to serialize the `DeserializerTag` and
|
||||
// payload, including in the no-payload (nullptr) case.
|
||||
static BlocksRingBuffer::Length TagAndSerializationBytes(
|
||||
const ProfilerMarkerPayload* aPayload) {
|
||||
if (!aPayload) {
|
||||
return sizeof(DeserializerTag);
|
||||
}
|
||||
return aPayload->TagAndSerializationBytes();
|
||||
}
|
||||
|
||||
// Serialize the payload into an EntryWriter, including in the no-payload
|
||||
// (nullptr) case. Must be of the exact size given by
|
||||
// `TagAndSerializationBytes(aPayload)`.
|
||||
static void TagAndSerialize(const ProfilerMarkerPayload* aPayload,
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) {
|
||||
if (!aPayload) {
|
||||
aEntryWriter.WriteObject(DeserializerTag(0));
|
||||
return;
|
||||
}
|
||||
aPayload->SerializeTagAndPayload(aEntryWriter);
|
||||
}
|
||||
|
||||
// Deserialize a payload from an EntryReader, including in the no-payload
|
||||
// (nullptr) case.
|
||||
static UniquePtr<ProfilerMarkerPayload> DeserializeTagAndPayload(
|
||||
mozilla::BlocksRingBuffer::EntryReader& aER) {
|
||||
const auto tag = aER.ReadObject<DeserializerTag>();
|
||||
Deserializer deserializer = DeserializerForTag(tag);
|
||||
return deserializer(aER);
|
||||
}
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) = 0;
|
||||
UniqueStacks& aUniqueStacks) const = 0;
|
||||
|
||||
TimeStamp GetStartTime() const { return mCommonProps.mStartTime; }
|
||||
|
||||
protected:
|
||||
// A `Deserializer` is a free function that can read a serialized payload from
|
||||
// an `EntryReader` and return a reconstructed `ProfilerMarkerPayload`
|
||||
// sub-object (may be null if there was no payload).
|
||||
typedef UniquePtr<ProfilerMarkerPayload> (*Deserializer)(
|
||||
BlocksRingBuffer::EntryReader&);
|
||||
|
||||
// A `DeserializerTag` will be added before the payload, to help select the
|
||||
// correct deserializer when reading back the payload.
|
||||
using DeserializerTag = unsigned char;
|
||||
|
||||
// This needs to be big enough to handle all possible sub-types of
|
||||
// ProfilerMarkerPayload.
|
||||
static constexpr DeserializerTag DeserializerMax = 32;
|
||||
|
||||
// We need an atomic type that can hold a `DeserializerTag`. (Atomic doesn't
|
||||
// work with too-small types.)
|
||||
using DeserializerTagAtomic = int;
|
||||
|
||||
// Number of currently-registered deserializers.
|
||||
static Atomic<DeserializerTagAtomic, ReleaseAcquire,
|
||||
recordreplay::Behavior::DontPreserve>
|
||||
sDeserializerCount;
|
||||
|
||||
// List of currently-registered deserializers.
|
||||
// sDeserializers[0] is a no-payload deserializer.
|
||||
static Deserializer sDeserializers[DeserializerMax];
|
||||
|
||||
// Get the `DeserializerTag` for a `Deserializer` (which gets registered on
|
||||
// the first call.) Tag 0 means no payload; a null `aDeserializer` gives that
|
||||
// 0 tag.
|
||||
MFBT_API static DeserializerTag TagForDeserializer(
|
||||
Deserializer aDeserializer);
|
||||
|
||||
// Get the `Deserializer` for a given `DeserializerTag`.
|
||||
// Tag 0 is reserved as no-payload deserializer (which returns nullptr).
|
||||
MFBT_API static Deserializer DeserializerForTag(DeserializerTag aTag);
|
||||
|
||||
struct CommonProps {
|
||||
TimeStamp mStartTime;
|
||||
TimeStamp mEndTime;
|
||||
|
@ -64,62 +134,89 @@ class ProfilerMarkerPayload {
|
|||
Maybe<uint32_t> mDocShellHistoryId;
|
||||
};
|
||||
|
||||
// Deserializers can use this base constructor.
|
||||
explicit ProfilerMarkerPayload(CommonProps&& aCommonProps)
|
||||
: mCommonProps(std::move(aCommonProps)) {}
|
||||
|
||||
// Serialization/deserialization of common props in ProfilerMarkerPayload.
|
||||
MFBT_API BlocksRingBuffer::Length CommonPropsTagAndSerializationBytes() const;
|
||||
MFBT_API void SerializeTagAndCommonProps(
|
||||
DeserializerTag aDeserializerTag,
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const;
|
||||
MFBT_API static CommonProps DeserializeCommonProps(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader);
|
||||
|
||||
MFBT_API void StreamType(const char* aMarkerType,
|
||||
SpliceableJSONWriter& aWriter);
|
||||
SpliceableJSONWriter& aWriter) const;
|
||||
|
||||
MFBT_API void StreamCommonProps(const char* aMarkerType,
|
||||
SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks);
|
||||
UniqueStacks& aUniqueStacks) const;
|
||||
|
||||
private:
|
||||
// Compute the number of bytes needed to serialize the `DeserializerTag` and
|
||||
// payload in `SerializeTagAndPayload` below.
|
||||
virtual BlocksRingBuffer::Length TagAndSerializationBytes() const = 0;
|
||||
|
||||
// Serialize the `DeserializerTag` and payload into an EntryWriter.
|
||||
// Must be of the exact size given by `TagAndSerializationBytes()`.
|
||||
virtual void SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const = 0;
|
||||
|
||||
CommonProps mCommonProps;
|
||||
};
|
||||
|
||||
#define DECL_BASE_STREAM_PAYLOAD \
|
||||
virtual void StreamPayload( \
|
||||
::mozilla::baseprofiler::SpliceableJSONWriter& aWriter, \
|
||||
const ::mozilla::TimeStamp& aProcessStartTime, \
|
||||
::mozilla::baseprofiler::UniqueStacks& aUniqueStacks) override;
|
||||
#define DECL_BASE_STREAM_PAYLOAD \
|
||||
MFBT_API void StreamPayload( \
|
||||
::mozilla::baseprofiler::SpliceableJSONWriter& aWriter, \
|
||||
const ::mozilla::TimeStamp& aProcessStartTime, \
|
||||
::mozilla::baseprofiler::UniqueStacks& aUniqueStacks) const override; \
|
||||
static UniquePtr<ProfilerMarkerPayload> Deserialize( \
|
||||
BlocksRingBuffer::EntryReader& aEntryReader); \
|
||||
MFBT_API BlocksRingBuffer::Length TagAndSerializationBytes() const override; \
|
||||
MFBT_API void SerializeTagAndPayload( \
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const override;
|
||||
|
||||
// TODO: Increase the coverage of tracing markers that include DocShell
|
||||
// information
|
||||
class TracingMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
TracingMarkerPayload(const char* aCategory, TracingKind aKind,
|
||||
const Maybe<std::string>& aDocShellId = Nothing(),
|
||||
const Maybe<uint32_t>& aDocShellHistoryId = Nothing(),
|
||||
UniqueProfilerBacktrace aCause = nullptr)
|
||||
: ProfilerMarkerPayload(aDocShellId, aDocShellHistoryId,
|
||||
std::move(aCause)),
|
||||
mCategory(aCategory),
|
||||
mKind(aKind) {}
|
||||
MFBT_API TracingMarkerPayload(
|
||||
const char* aCategory, TracingKind aKind,
|
||||
const Maybe<std::string>& aDocShellId = Nothing(),
|
||||
const Maybe<uint32_t>& aDocShellHistoryId = Nothing(),
|
||||
UniqueProfilerBacktrace aCause = nullptr);
|
||||
|
||||
MFBT_API ~TracingMarkerPayload() override;
|
||||
|
||||
DECL_BASE_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
MFBT_API TracingMarkerPayload(CommonProps&& aCommonProps,
|
||||
const char* aCategory, TracingKind aKind);
|
||||
|
||||
const char* mCategory;
|
||||
TracingKind mKind;
|
||||
};
|
||||
|
||||
class FileIOMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
FileIOMarkerPayload(const char* aOperation, const char* aSource,
|
||||
const char* aFilename, const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime, UniqueProfilerBacktrace aStack)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, Nothing(), Nothing(),
|
||||
std::move(aStack)),
|
||||
mSource(aSource),
|
||||
mOperation(aOperation ? strdup(aOperation) : nullptr),
|
||||
mFilename(aFilename ? strdup(aFilename) : nullptr) {
|
||||
MOZ_ASSERT(aSource);
|
||||
}
|
||||
MFBT_API FileIOMarkerPayload(const char* aOperation, const char* aSource,
|
||||
const char* aFilename,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
UniqueProfilerBacktrace aStack);
|
||||
|
||||
MFBT_API ~FileIOMarkerPayload() override;
|
||||
|
||||
DECL_BASE_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
MFBT_API FileIOMarkerPayload(CommonProps&& aCommonProps, const char* aSource,
|
||||
UniqueFreePtr<char>&& aOperation,
|
||||
UniqueFreePtr<char>&& aFilename);
|
||||
|
||||
const char* mSource;
|
||||
UniqueFreePtr<char> mOperation;
|
||||
UniqueFreePtr<char> mFilename;
|
||||
|
@ -127,31 +224,29 @@ class FileIOMarkerPayload : public ProfilerMarkerPayload {
|
|||
|
||||
class UserTimingMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
UserTimingMarkerPayload(const std::string& aName, const TimeStamp& aStartTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime, aDocShellId,
|
||||
aDocShellHistoryId),
|
||||
mEntryType("mark"),
|
||||
mName(aName) {}
|
||||
MFBT_API UserTimingMarkerPayload(const std::string& aName,
|
||||
const TimeStamp& aStartTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId);
|
||||
|
||||
UserTimingMarkerPayload(const std::string& aName,
|
||||
const Maybe<std::string>& aStartMark,
|
||||
const Maybe<std::string>& aEndMark,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, aDocShellId,
|
||||
aDocShellHistoryId),
|
||||
mEntryType("measure"),
|
||||
mName(aName),
|
||||
mStartMark(aStartMark),
|
||||
mEndMark(aEndMark) {}
|
||||
MFBT_API UserTimingMarkerPayload(const std::string& aName,
|
||||
const Maybe<std::string>& aStartMark,
|
||||
const Maybe<std::string>& aEndMark,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId);
|
||||
|
||||
MFBT_API ~UserTimingMarkerPayload() override;
|
||||
|
||||
DECL_BASE_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
MFBT_API UserTimingMarkerPayload(CommonProps&& aCommonProps,
|
||||
const char* aEntryType, std::string&& aName,
|
||||
Maybe<std::string>&& aStartMark,
|
||||
Maybe<std::string>&& aEndMark);
|
||||
|
||||
// Either "mark" or "measure".
|
||||
const char* mEntryType;
|
||||
std::string mName;
|
||||
|
@ -161,68 +256,114 @@ class UserTimingMarkerPayload : public ProfilerMarkerPayload {
|
|||
|
||||
class HangMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
HangMarkerPayload(const TimeStamp& aStartTime, const TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
MFBT_API HangMarkerPayload(const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime);
|
||||
|
||||
MFBT_API ~HangMarkerPayload() override;
|
||||
|
||||
DECL_BASE_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
MFBT_API explicit HangMarkerPayload(CommonProps&& aCommonProps);
|
||||
};
|
||||
|
||||
class LongTaskMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
LongTaskMarkerPayload(const TimeStamp& aStartTime, const TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
MFBT_API LongTaskMarkerPayload(const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime);
|
||||
|
||||
DECL_BASE_STREAM_PAYLOAD
|
||||
};
|
||||
|
||||
class TextMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
TextMarkerPayload(const std::string& aText, const TimeStamp& aStartTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime), mText(aText) {}
|
||||
|
||||
TextMarkerPayload(const std::string& aText, const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime), mText(aText) {}
|
||||
|
||||
TextMarkerPayload(const std::string& aText, const TimeStamp& aStartTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime, aDocShellId,
|
||||
aDocShellHistoryId),
|
||||
mText(aText) {}
|
||||
|
||||
TextMarkerPayload(const std::string& aText, const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId,
|
||||
UniqueProfilerBacktrace aCause = nullptr)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, aDocShellId,
|
||||
aDocShellHistoryId, std::move(aCause)),
|
||||
mText(aText) {}
|
||||
MFBT_API ~LongTaskMarkerPayload() override;
|
||||
|
||||
DECL_BASE_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
MFBT_API explicit LongTaskMarkerPayload(CommonProps&& aCommonProps);
|
||||
};
|
||||
|
||||
class TextMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
MFBT_API TextMarkerPayload(const std::string& aText,
|
||||
const TimeStamp& aStartTime);
|
||||
|
||||
MFBT_API TextMarkerPayload(const std::string& aText,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime);
|
||||
|
||||
MFBT_API TextMarkerPayload(const std::string& aText,
|
||||
const TimeStamp& aStartTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId);
|
||||
|
||||
MFBT_API TextMarkerPayload(const std::string& aText,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
const Maybe<std::string>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId,
|
||||
UniqueProfilerBacktrace aCause = nullptr);
|
||||
|
||||
MFBT_API ~TextMarkerPayload() override;
|
||||
|
||||
DECL_BASE_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
MFBT_API TextMarkerPayload(CommonProps&& aCommonProps, std::string&& aText);
|
||||
|
||||
std::string mText;
|
||||
};
|
||||
|
||||
class LogMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
LogMarkerPayload(const char* aModule, const char* aText,
|
||||
const TimeStamp& aStartTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime),
|
||||
mModule(aModule),
|
||||
mText(aText) {}
|
||||
MFBT_API LogMarkerPayload(const char* aModule, const char* aText,
|
||||
const TimeStamp& aStartTime);
|
||||
|
||||
MFBT_API ~LogMarkerPayload() override;
|
||||
|
||||
DECL_BASE_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
MFBT_API LogMarkerPayload(CommonProps&& aCommonProps, std::string&& aModule,
|
||||
std::string&& aText);
|
||||
|
||||
std::string mModule; // longest known LazyLogModule name is ~24
|
||||
std::string mText;
|
||||
};
|
||||
|
||||
} // namespace baseprofiler
|
||||
|
||||
// Serialize a pointed-at ProfilerMarkerPayload, may be null when there are no
|
||||
// payloads.
|
||||
template <>
|
||||
struct BlocksRingBuffer::Serializer<
|
||||
UniquePtr<baseprofiler::ProfilerMarkerPayload>> {
|
||||
static Length Bytes(
|
||||
const UniquePtr<baseprofiler::ProfilerMarkerPayload>& aPayload) {
|
||||
return baseprofiler::ProfilerMarkerPayload::TagAndSerializationBytes(
|
||||
aPayload.get());
|
||||
}
|
||||
|
||||
static void Write(
|
||||
EntryWriter& aEW,
|
||||
const UniquePtr<baseprofiler::ProfilerMarkerPayload>& aPayload) {
|
||||
baseprofiler::ProfilerMarkerPayload::TagAndSerialize(aPayload.get(), aEW);
|
||||
}
|
||||
};
|
||||
|
||||
// Deserialize a ProfilerMarkerPayload into a UniquePtr, may be null if there
|
||||
// are no payloads.
|
||||
template <>
|
||||
struct BlocksRingBuffer::Deserializer<
|
||||
UniquePtr<baseprofiler::ProfilerMarkerPayload>> {
|
||||
static void ReadInto(
|
||||
EntryReader& aER,
|
||||
UniquePtr<baseprofiler::ProfilerMarkerPayload>& aPayload) {
|
||||
aPayload = Read(aER);
|
||||
}
|
||||
|
||||
static UniquePtr<baseprofiler::ProfilerMarkerPayload> Read(EntryReader& aER) {
|
||||
return baseprofiler::ProfilerMarkerPayload::DeserializeTagAndPayload(aER);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // BaseProfilerMarkerPayload_h
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#ifdef MOZ_BASE_PROFILER
|
||||
|
||||
# include "BaseProfileJSONWriter.h"
|
||||
# include "BaseProfilerMarkerPayload.h"
|
||||
# include "mozilla/BlocksRingBuffer.h"
|
||||
# include "mozilla/leb128iterator.h"
|
||||
# include "mozilla/ModuloBuffer.h"
|
||||
|
@ -1364,6 +1366,102 @@ void TestBlocksRingBufferSerialization() {
|
|||
printf("TestBlocksRingBufferSerialization done\n");
|
||||
}
|
||||
|
||||
class BaseTestMarkerPayload : public baseprofiler::ProfilerMarkerPayload {
|
||||
public:
|
||||
explicit BaseTestMarkerPayload(int aData) : mData(aData) {}
|
||||
|
||||
int GetData() const { return mData; }
|
||||
|
||||
// Exploded DECL_BASE_STREAM_PAYLOAD, but without `MFBT_API`s.
|
||||
static UniquePtr<ProfilerMarkerPayload> Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader);
|
||||
BlocksRingBuffer::Length TagAndSerializationBytes() const override;
|
||||
void SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const override;
|
||||
void StreamPayload(
|
||||
::mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const ::mozilla::TimeStamp& aProcessStartTime,
|
||||
::mozilla::baseprofiler::UniqueStacks& aUniqueStacks) const override;
|
||||
|
||||
private:
|
||||
BaseTestMarkerPayload(CommonProps&& aProps, int aData)
|
||||
: baseprofiler::ProfilerMarkerPayload(std::move(aProps)), mData(aData) {}
|
||||
|
||||
int mData;
|
||||
};
|
||||
|
||||
// static
|
||||
UniquePtr<baseprofiler::ProfilerMarkerPayload>
|
||||
BaseTestMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
CommonProps props = DeserializeCommonProps(aEntryReader);
|
||||
int data = aEntryReader.ReadObject<int>();
|
||||
return UniquePtr<baseprofiler::ProfilerMarkerPayload>(
|
||||
new BaseTestMarkerPayload(std::move(props), data));
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length BaseTestMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() + sizeof(int);
|
||||
}
|
||||
|
||||
void BaseTestMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mData);
|
||||
}
|
||||
|
||||
void BaseTestMarkerPayload::StreamPayload(
|
||||
baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
baseprofiler::UniqueStacks& aUniqueStacks) const {
|
||||
aWriter.IntProperty("data", mData);
|
||||
}
|
||||
|
||||
void TestProfilerMarkerSerialization() {
|
||||
printf("TestProfilerMarkerSerialization...\n");
|
||||
|
||||
constexpr uint32_t MBSize = 256;
|
||||
uint8_t buffer[MBSize * 3];
|
||||
for (size_t i = 0; i < MBSize * 3; ++i) {
|
||||
buffer[i] = uint8_t('A' + i);
|
||||
}
|
||||
BlocksRingBuffer rb(BlocksRingBuffer::ThreadSafety::WithMutex,
|
||||
&buffer[MBSize], MakePowerOfTwo32<MBSize>());
|
||||
|
||||
constexpr int data = 42;
|
||||
{
|
||||
UniquePtr<baseprofiler::ProfilerMarkerPayload> testPayload{
|
||||
new BaseTestMarkerPayload(data)};
|
||||
|
||||
rb.PutObject(testPayload);
|
||||
}
|
||||
|
||||
int read = 0;
|
||||
rb.ReadEach([&](BlocksRingBuffer::EntryReader& aER) {
|
||||
UniquePtr<baseprofiler::ProfilerMarkerPayload> payload =
|
||||
aER.ReadObject<UniquePtr<baseprofiler::ProfilerMarkerPayload>>();
|
||||
MOZ_RELEASE_ASSERT(!!payload);
|
||||
++read;
|
||||
BaseTestMarkerPayload* testPayload =
|
||||
static_cast<BaseTestMarkerPayload*>(payload.get());
|
||||
MOZ_RELEASE_ASSERT(testPayload);
|
||||
MOZ_RELEASE_ASSERT(testPayload->GetData() == data);
|
||||
});
|
||||
MOZ_RELEASE_ASSERT(read == 1);
|
||||
|
||||
// Everything around the sub-buffer should be unchanged.
|
||||
for (size_t i = 0; i < MBSize; ++i) {
|
||||
MOZ_RELEASE_ASSERT(buffer[i] == uint8_t('A' + i));
|
||||
}
|
||||
for (size_t i = MBSize * 2; i < MBSize * 3; ++i) {
|
||||
MOZ_RELEASE_ASSERT(buffer[i] == uint8_t('A' + i));
|
||||
}
|
||||
|
||||
printf("TestProfilerMarkerSerialization done\n");
|
||||
}
|
||||
|
||||
// Increase the depth, to a maximum (to avoid too-deep recursion).
|
||||
static constexpr size_t NextDepth(size_t aDepth) {
|
||||
constexpr size_t MAX_DEPTH = 128;
|
||||
|
@ -1419,6 +1517,7 @@ void TestProfiler() {
|
|||
TestBlocksRingBufferUnderlyingBufferChanges();
|
||||
TestBlocksRingBufferThreading();
|
||||
TestBlocksRingBufferSerialization();
|
||||
TestProfilerMarkerSerialization();
|
||||
|
||||
{
|
||||
printf("profiler_init()...\n");
|
||||
|
@ -1499,6 +1598,53 @@ void TestProfiler() {
|
|||
threadCancelFib.join();
|
||||
}
|
||||
|
||||
// Just making sure all payloads know how to (de)serialize and stream.
|
||||
baseprofiler::profiler_add_marker(
|
||||
"TracingMarkerPayload", baseprofiler::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<baseprofiler::TracingMarkerPayload>(
|
||||
"category", baseprofiler::TRACING_EVENT));
|
||||
|
||||
auto cause =
|
||||
# if defined(__linux__) || defined(__ANDROID__)
|
||||
// Currently disabled on these platforms, so just return a null.
|
||||
decltype(baseprofiler::profiler_get_backtrace()){};
|
||||
# else
|
||||
baseprofiler::profiler_get_backtrace();
|
||||
# endif
|
||||
baseprofiler::profiler_add_marker(
|
||||
"FileIOMarkerPayload", baseprofiler::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<baseprofiler::FileIOMarkerPayload>(
|
||||
"operation", "source", "filename", TimeStamp::NowUnfuzzed(),
|
||||
TimeStamp::NowUnfuzzed(), std::move(cause)));
|
||||
|
||||
baseprofiler::profiler_add_marker(
|
||||
"UserTimingMarkerPayload", baseprofiler::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<baseprofiler::UserTimingMarkerPayload>(
|
||||
"name", TimeStamp::NowUnfuzzed(), Nothing{}, Nothing{}));
|
||||
|
||||
baseprofiler::profiler_add_marker(
|
||||
"HangMarkerPayload", baseprofiler::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<baseprofiler::HangMarkerPayload>(TimeStamp::NowUnfuzzed(),
|
||||
TimeStamp::NowUnfuzzed()));
|
||||
|
||||
baseprofiler::profiler_add_marker(
|
||||
"LongTaskMarkerPayload", baseprofiler::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<baseprofiler::LongTaskMarkerPayload>(
|
||||
TimeStamp::NowUnfuzzed(), TimeStamp::NowUnfuzzed()));
|
||||
|
||||
{
|
||||
std::string s = "text payload";
|
||||
baseprofiler::profiler_add_marker(
|
||||
"TextMarkerPayload", baseprofiler::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<baseprofiler::TextMarkerPayload>(
|
||||
s, TimeStamp::NowUnfuzzed(), TimeStamp::NowUnfuzzed()));
|
||||
}
|
||||
|
||||
baseprofiler::profiler_add_marker(
|
||||
"LogMarkerPayload", baseprofiler::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<baseprofiler::LogMarkerPayload>("module", "text",
|
||||
TimeStamp::NowUnfuzzed()));
|
||||
|
||||
printf("Sleep 1s...\n");
|
||||
{
|
||||
AUTO_BASE_PROFILER_THREAD_SLEEP;
|
||||
|
|
|
@ -61,11 +61,11 @@ template <>
|
|||
struct BlocksRingBuffer::Serializer<ProfilerBacktrace> {
|
||||
static Length Bytes(const ProfilerBacktrace& aBacktrace) {
|
||||
if (!aBacktrace.mProfileBuffer) {
|
||||
return 1;
|
||||
return ULEB128Size<Length>(0);
|
||||
}
|
||||
auto bufferBytes = SumBytes(*aBacktrace.mBlocksRingBuffer);
|
||||
if (bufferBytes == 0) {
|
||||
return 1;
|
||||
return ULEB128Size<Length>(0);
|
||||
}
|
||||
return bufferBytes +
|
||||
SumBytes(aBacktrace.mThreadId,
|
||||
|
@ -88,7 +88,7 @@ struct BlocksRingBuffer::Serializer<UniquePtr<ProfilerBacktrace, Destructor>> {
|
|||
static Length Bytes(
|
||||
const UniquePtr<ProfilerBacktrace, Destructor>& aBacktrace) {
|
||||
if (!aBacktrace) {
|
||||
return 1;
|
||||
return ULEB128Size<Length>(0);
|
||||
}
|
||||
return SumBytes(*aBacktrace);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "gfxASurface.h"
|
||||
#include "Layers.h"
|
||||
#include "mozilla/BlocksRingBufferGeckoExtensions.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/net/HttpBaseChannel.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -21,6 +22,76 @@
|
|||
|
||||
using namespace mozilla;
|
||||
|
||||
static UniquePtr<ProfilerMarkerPayload> DeserializeNothing(
|
||||
BlocksRingBuffer::EntryReader&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Starting at 1 for the initial `DeserializeNothing`.
|
||||
// static
|
||||
Atomic<ProfilerMarkerPayload::DeserializerTagAtomic, ReleaseAcquire,
|
||||
recordreplay::Behavior::DontPreserve>
|
||||
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,
|
||||
|
@ -31,14 +102,47 @@ static void MOZ_ALWAYS_INLINE WriteTime(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
|
||||
void ProfilerMarkerPayload::StreamType(const char* aMarkerType,
|
||||
SpliceableJSONWriter& aWriter) {
|
||||
SpliceableJSONWriter& aWriter) const {
|
||||
MOZ_ASSERT(aMarkerType);
|
||||
aWriter.StringProperty("type", aMarkerType);
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length
|
||||
ProfilerMarkerPayload::CommonPropsTagAndSerializationBytes() const {
|
||||
return sizeof(DeserializerTag) +
|
||||
BlocksRingBuffer::SumBytes(mCommonProps.mStartTime,
|
||||
mCommonProps.mEndTime, mCommonProps.mStack,
|
||||
mCommonProps.mDocShellId,
|
||||
mCommonProps.mDocShellHistoryId);
|
||||
}
|
||||
|
||||
void ProfilerMarkerPayload::SerializeTagAndCommonProps(
|
||||
DeserializerTag aDeserializerTag,
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
aEntryWriter.WriteObject(aDeserializerTag);
|
||||
aEntryWriter.WriteObject(mCommonProps.mStartTime);
|
||||
aEntryWriter.WriteObject(mCommonProps.mEndTime);
|
||||
aEntryWriter.WriteObject(mCommonProps.mStack);
|
||||
aEntryWriter.WriteObject(mCommonProps.mDocShellId);
|
||||
aEntryWriter.WriteObject(mCommonProps.mDocShellHistoryId);
|
||||
}
|
||||
|
||||
// static
|
||||
ProfilerMarkerPayload::CommonProps
|
||||
ProfilerMarkerPayload::DeserializeCommonProps(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
CommonProps props;
|
||||
aEntryReader.ReadIntoObject(props.mStartTime);
|
||||
aEntryReader.ReadIntoObject(props.mEndTime);
|
||||
aEntryReader.ReadIntoObject(props.mStack);
|
||||
aEntryReader.ReadIntoObject(props.mDocShellId);
|
||||
aEntryReader.ReadIntoObject(props.mDocShellHistoryId);
|
||||
return props;
|
||||
}
|
||||
|
||||
void ProfilerMarkerPayload::StreamCommonProps(
|
||||
const char* aMarkerType, SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime, UniqueStacks& aUniqueStacks) {
|
||||
const TimeStamp& aProcessStartTime, UniqueStacks& aUniqueStacks) const {
|
||||
StreamType(aMarkerType, aWriter);
|
||||
WriteTime(aWriter, aProcessStartTime, mCommonProps.mStartTime, "startTime");
|
||||
WriteTime(aWriter, aProcessStartTime, mCommonProps.mEndTime, "endTime");
|
||||
|
@ -60,9 +164,41 @@ void ProfilerMarkerPayload::StreamCommonProps(
|
|||
}
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length TracingMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(WrapBlocksRingBufferRawPointer(mCategory),
|
||||
mKind);
|
||||
}
|
||||
|
||||
void TracingMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndPayload(tag, aEntryWriter);
|
||||
}
|
||||
|
||||
void TracingMarkerPayload::SerializeTagAndPayload(
|
||||
DeserializerTag aDeserializerTag,
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
SerializeTagAndCommonProps(aDeserializerTag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(WrapBlocksRingBufferRawPointer(mCategory));
|
||||
aEntryWriter.WriteObject(mKind);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> TracingMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("tracing", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
|
||||
if (mCategory) {
|
||||
|
@ -76,9 +212,36 @@ void TracingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length FileIOMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(WrapBlocksRingBufferRawPointer(mSource),
|
||||
mOperation, mFilename);
|
||||
}
|
||||
|
||||
void FileIOMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(WrapBlocksRingBufferRawPointer(mSource));
|
||||
aEntryWriter.WriteObject(mOperation);
|
||||
aEntryWriter.WriteObject(mFilename);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> FileIOMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
auto source = aEntryReader.ReadObject<const char*>();
|
||||
auto operation = aEntryReader.ReadObject<UniqueFreePtr<char>>();
|
||||
auto filename = aEntryReader.ReadObject<UniqueFreePtr<char>>();
|
||||
return UniquePtr<ProfilerMarkerPayload>(new FileIOMarkerPayload(
|
||||
std::move(props), source, std::move(operation), std::move(filename)));
|
||||
}
|
||||
|
||||
void FileIOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("FileIO", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("operation", mOperation.get());
|
||||
aWriter.StringProperty("source", mSource);
|
||||
|
@ -87,9 +250,40 @@ void FileIOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length UserTimingMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(WrapBlocksRingBufferRawPointer(mEntryType),
|
||||
mName, mStartMark, mEndMark);
|
||||
}
|
||||
|
||||
void UserTimingMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(WrapBlocksRingBufferRawPointer(mEntryType));
|
||||
aEntryWriter.WriteObject(mName);
|
||||
aEntryWriter.WriteObject(mStartMark);
|
||||
aEntryWriter.WriteObject(mEndMark);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> UserTimingMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("UserTiming", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("name", NS_ConvertUTF16toUTF8(mName).get());
|
||||
aWriter.StringProperty("entryType", mEntryType);
|
||||
|
@ -108,24 +302,99 @@ void UserTimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length TextMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mText);
|
||||
}
|
||||
|
||||
void TextMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mText);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> TextMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("Text", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("name", mText.get());
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length LogMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mModule, mText);
|
||||
}
|
||||
|
||||
void LogMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mModule);
|
||||
aEntryWriter.WriteObject(mText);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> LogMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("Log", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("name", mText.get());
|
||||
aWriter.StringProperty("module", mModule.get());
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length DOMEventMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return TracingMarkerPayload::TagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mTimeStamp, mEventType);
|
||||
}
|
||||
|
||||
void DOMEventMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
// Let our parent class serialize our tag with its payload.
|
||||
TracingMarkerPayload::SerializeTagAndPayload(tag, aEntryWriter);
|
||||
// Then write our extra data.
|
||||
aEntryWriter.WriteObject(mTimeStamp);
|
||||
aEntryWriter.WriteObject(mEventType);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> DOMEventMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
const char* category = aEntryReader.ReadObject<const char*>();
|
||||
TracingKind kind = aEntryReader.ReadObject<TracingKind>();
|
||||
auto timeStamp = aEntryReader.ReadObject<TimeStamp>();
|
||||
auto eventType = aEntryReader.ReadObject<nsString>();
|
||||
return UniquePtr<ProfilerMarkerPayload>(new DOMEventMarkerPayload(
|
||||
std::move(props), category, kind, timeStamp, std::move(eventType)));
|
||||
}
|
||||
|
||||
void DOMEventMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
TracingMarkerPayload::StreamPayload(aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
|
||||
|
@ -133,15 +402,46 @@ void DOMEventMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
aWriter.StringProperty("eventType", NS_ConvertUTF16toUTF8(mEventType).get());
|
||||
}
|
||||
|
||||
static const char* PrefValueKindToString(
|
||||
const mozilla::Maybe<PrefValueKind>& aKind) {
|
||||
BlocksRingBuffer::Length PrefMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mPrefAccessTime, mPrefName, mPrefKind,
|
||||
mPrefType, mPrefValue);
|
||||
}
|
||||
|
||||
void PrefMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& 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(
|
||||
BlocksRingBuffer::EntryReader& 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 const char* PrefValueKindToString(const Maybe<PrefValueKind>& aKind) {
|
||||
if (aKind) {
|
||||
return *aKind == PrefValueKind::Default ? "Default" : "User";
|
||||
}
|
||||
return "Shared";
|
||||
}
|
||||
|
||||
static const char* PrefTypeToString(const mozilla::Maybe<PrefType>& type) {
|
||||
static const char* PrefTypeToString(const Maybe<PrefType>& type) {
|
||||
if (type) {
|
||||
switch (*type) {
|
||||
case PrefType::None:
|
||||
|
@ -161,7 +461,7 @@ static const char* PrefTypeToString(const mozilla::Maybe<PrefType>& type) {
|
|||
|
||||
void PrefMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("PreferenceRead", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
WriteTime(aWriter, aProcessStartTime, mPrefAccessTime, "prefAccessTime");
|
||||
|
@ -171,9 +471,35 @@ void PrefMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
aWriter.StringProperty("prefValue", mPrefValue.get());
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length
|
||||
LayerTranslationMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(WrapBlocksRingBufferRawPointer(mLayer),
|
||||
mPoint);
|
||||
}
|
||||
|
||||
void LayerTranslationMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(WrapBlocksRingBufferRawPointer(mLayer));
|
||||
aEntryWriter.WriteObject(mPoint);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> LayerTranslationMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamType("LayerTranslation", aWriter);
|
||||
const size_t bufferSize = 32;
|
||||
char buffer[bufferSize];
|
||||
|
@ -184,12 +510,70 @@ void LayerTranslationMarkerPayload::StreamPayload(
|
|||
aWriter.IntProperty("y", mPoint.y);
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length VsyncMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
|
||||
void VsyncMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> VsyncMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new VsyncMarkerPayload(std::move(props)));
|
||||
}
|
||||
|
||||
void VsyncMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamType("VsyncTimestamp", aWriter);
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length NetworkMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mID, mURI, mRedirectURI, mType, mPri,
|
||||
mCount, mTimings, mCacheDisposition);
|
||||
}
|
||||
|
||||
void NetworkMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mID);
|
||||
aEntryWriter.WriteObject(mURI);
|
||||
aEntryWriter.WriteObject(mRedirectURI);
|
||||
aEntryWriter.WriteObject(mType);
|
||||
aEntryWriter.WriteObject(mPri);
|
||||
aEntryWriter.WriteObject(mCount);
|
||||
aEntryWriter.WriteObject(mTimings);
|
||||
aEntryWriter.WriteObject(mCacheDisposition);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> NetworkMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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 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>();
|
||||
return UniquePtr<ProfilerMarkerPayload>(new NetworkMarkerPayload(
|
||||
std::move(props), id, std::move(uri), std::move(redirectURI), type, pri,
|
||||
count, timings, cacheDisposition));
|
||||
}
|
||||
|
||||
static const char* GetNetworkState(NetworkLoadType aType) {
|
||||
switch (aType) {
|
||||
case NetworkLoadType::LOAD_START:
|
||||
|
@ -202,20 +586,19 @@ static const char* GetNetworkState(NetworkLoadType aType) {
|
|||
return "";
|
||||
}
|
||||
|
||||
static const char* GetCacheState(
|
||||
mozilla::net::CacheDisposition aCacheDisposition) {
|
||||
static const char* GetCacheState(net::CacheDisposition aCacheDisposition) {
|
||||
switch (aCacheDisposition) {
|
||||
case mozilla::net::kCacheUnresolved:
|
||||
case net::kCacheUnresolved:
|
||||
return "Unresolved";
|
||||
case mozilla::net::kCacheHit:
|
||||
case net::kCacheHit:
|
||||
return "Hit";
|
||||
case mozilla::net::kCacheHitViaReval:
|
||||
case net::kCacheHitViaReval:
|
||||
return "HitViaReval";
|
||||
case mozilla::net::kCacheMissedViaReval:
|
||||
case net::kCacheMissedViaReval:
|
||||
return "MissedViaReval";
|
||||
case mozilla::net::kCacheMissed:
|
||||
case net::kCacheMissed:
|
||||
return "Missed";
|
||||
case mozilla::net::kCacheUnknown:
|
||||
case net::kCacheUnknown:
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -223,7 +606,7 @@ static const char* GetCacheState(
|
|||
|
||||
void NetworkMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("Network", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.IntProperty("id", mID);
|
||||
const char* typeString = GetNetworkState(mType);
|
||||
|
@ -264,9 +647,37 @@ void NetworkMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length ScreenshotPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mScreenshotDataURL, mWindowSize,
|
||||
mWindowIdentifier);
|
||||
}
|
||||
|
||||
void ScreenshotPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& 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(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamType("CompositorScreenshot", aWriter);
|
||||
aUniqueStacks.mUniqueStrings->WriteProperty(aWriter, "url",
|
||||
mScreenshotDataURL.get());
|
||||
|
@ -278,9 +689,32 @@ void ScreenshotPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
aWriter.DoubleProperty("windowHeight", mWindowSize.height);
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length GCSliceMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mTimingJSON);
|
||||
}
|
||||
|
||||
void GCSliceMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mTimingJSON);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> GCSliceMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
MOZ_ASSERT(mTimingJSON);
|
||||
StreamCommonProps("GCSlice", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
if (mTimingJSON) {
|
||||
|
@ -290,9 +724,32 @@ void GCSliceMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length GCMajorMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mTimingJSON);
|
||||
}
|
||||
|
||||
void GCMajorMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mTimingJSON);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> GCMajorMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
MOZ_ASSERT(mTimingJSON);
|
||||
StreamCommonProps("GCMajor", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
if (mTimingJSON) {
|
||||
|
@ -302,9 +759,32 @@ void GCMajorMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length GCMinorMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mTimingData);
|
||||
}
|
||||
|
||||
void GCMinorMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mTimingData);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> GCMinorMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
MOZ_ASSERT(mTimingData);
|
||||
StreamCommonProps("GCMinor", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
if (mTimingData) {
|
||||
|
@ -314,16 +794,57 @@ void GCMinorMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length HangMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
|
||||
void HangMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> HangMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new HangMarkerPayload(std::move(props)));
|
||||
}
|
||||
|
||||
void HangMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("BHR-detected hang", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length StyleMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mStats);
|
||||
}
|
||||
|
||||
void StyleMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mStats);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> StyleMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("Styles", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("category", "Paint");
|
||||
aWriter.IntProperty("elementsTraversed", mStats.mElementsTraversed);
|
||||
|
@ -333,17 +854,80 @@ void StyleMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
aWriter.IntProperty("stylesReused", mStats.mStylesReused);
|
||||
}
|
||||
|
||||
BlocksRingBuffer::Length LongTaskMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
|
||||
void LongTaskMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> LongTaskMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new LongTaskMarkerPayload(std::move(props)));
|
||||
}
|
||||
|
||||
void LongTaskMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("MainThreadLongTask", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
aWriter.StringProperty("category", "LongTask");
|
||||
}
|
||||
|
||||
UniqueFreePtr<const char16_t> mTypeName;
|
||||
UniqueFreePtr<const char> mClassName;
|
||||
UniqueFreePtr<const char16_t> mDescriptiveTypeName;
|
||||
const char* mCoarseType;
|
||||
uint64_t mSize;
|
||||
bool mInNursery;
|
||||
|
||||
BlocksRingBuffer::Length JsAllocationMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
BlocksRingBuffer::SumBytes(mTypeName, mClassName, mDescriptiveTypeName,
|
||||
mCoarseType, mSize, mInNursery);
|
||||
}
|
||||
|
||||
void JsAllocationMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mTypeName);
|
||||
aEntryWriter.WriteObject(mClassName);
|
||||
aEntryWriter.WriteObject(mDescriptiveTypeName);
|
||||
aEntryWriter.WriteObject(WrapBlocksRingBufferRawPointer(mCoarseType));
|
||||
aEntryWriter.WriteObject(mSize);
|
||||
aEntryWriter.WriteObject(mInNursery);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> JsAllocationMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& 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) {
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("JS allocation", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
|
||||
if (mClassName) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef ProfilerMarkerPayload_h
|
||||
#define ProfilerMarkerPayload_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/BlocksRingBuffer.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
@ -61,13 +62,81 @@ class ProfilerMarkerPayload {
|
|||
|
||||
virtual ~ProfilerMarkerPayload() {}
|
||||
|
||||
// Compute the number of bytes needed to serialize the `DeserializerTag` and
|
||||
// payload, including in the no-payload (nullptr) case.
|
||||
static mozilla::BlocksRingBuffer::Length TagAndSerializationBytes(
|
||||
const ProfilerMarkerPayload* aPayload) {
|
||||
if (!aPayload) {
|
||||
return sizeof(DeserializerTag);
|
||||
}
|
||||
return aPayload->TagAndSerializationBytes();
|
||||
}
|
||||
|
||||
// Serialize the payload into an EntryWriter, including in the no-payload
|
||||
// (nullptr) case. Must be of the exact size given by
|
||||
// `TagAndSerializationBytes(aPayload)`.
|
||||
static void TagAndSerialize(
|
||||
const ProfilerMarkerPayload* aPayload,
|
||||
mozilla::BlocksRingBuffer::EntryWriter& aEntryWriter) {
|
||||
if (!aPayload) {
|
||||
aEntryWriter.WriteObject(DeserializerTag(0));
|
||||
return;
|
||||
}
|
||||
aPayload->SerializeTagAndPayload(aEntryWriter);
|
||||
}
|
||||
|
||||
// Deserialize a payload from an EntryReader, including in the no-payload
|
||||
// (nullptr) case.
|
||||
static mozilla::UniquePtr<ProfilerMarkerPayload> DeserializeTagAndPayload(
|
||||
mozilla::BlocksRingBuffer::EntryReader& aER) {
|
||||
const auto tag = aER.ReadObject<DeserializerTag>();
|
||||
Deserializer deserializer = DeserializerForTag(tag);
|
||||
return deserializer(aER);
|
||||
}
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) = 0;
|
||||
UniqueStacks& aUniqueStacks) const = 0;
|
||||
|
||||
mozilla::TimeStamp GetStartTime() const { return mCommonProps.mStartTime; }
|
||||
|
||||
protected:
|
||||
// A `Deserializer` is a free function that can read a serialized payload from
|
||||
// an `EntryReader` and return a reconstructed `ProfilerMarkerPayload`
|
||||
// sub-object (may be null if there was no payload).
|
||||
typedef mozilla::UniquePtr<ProfilerMarkerPayload> (*Deserializer)(
|
||||
mozilla::BlocksRingBuffer::EntryReader&);
|
||||
|
||||
// A `DeserializerTag` will be added before the payload, to help select the
|
||||
// correct deserializer when reading back the payload.
|
||||
using DeserializerTag = unsigned char;
|
||||
|
||||
// This needs to be big enough to handle all possible sub-types of
|
||||
// ProfilerMarkerPayload.
|
||||
static constexpr DeserializerTag DeserializerMax = 32;
|
||||
|
||||
// We need an atomic type that can hold a `DeserializerTag`. (Atomic doesn't
|
||||
// work with too-small types.)
|
||||
using DeserializerTagAtomic = int;
|
||||
|
||||
// Number of currently-registered deserializers.
|
||||
static mozilla::Atomic<DeserializerTagAtomic, mozilla::ReleaseAcquire,
|
||||
mozilla::recordreplay::Behavior::DontPreserve>
|
||||
sDeserializerCount;
|
||||
|
||||
// List of currently-registered deserializers.
|
||||
// sDeserializers[0] is a no-payload deserializer.
|
||||
static Deserializer sDeserializers[DeserializerMax];
|
||||
|
||||
// Get the `DeserializerTag` for a `Deserializer` (which gets registered on
|
||||
// the first call.) Tag 0 means no payload; a null `aDeserializer` gives that
|
||||
// 0 tag.
|
||||
static DeserializerTag TagForDeserializer(Deserializer aDeserializer);
|
||||
|
||||
// Get the `Deserializer` for a given `DeserializerTag`.
|
||||
// Tag 0 is reserved as no-payload deserializer (which returns nullptr).
|
||||
static Deserializer DeserializerForTag(DeserializerTag aTag);
|
||||
|
||||
struct CommonProps {
|
||||
mozilla::TimeStamp mStartTime;
|
||||
mozilla::TimeStamp mEndTime;
|
||||
|
@ -76,22 +145,47 @@ class ProfilerMarkerPayload {
|
|||
mozilla::Maybe<uint32_t> mDocShellHistoryId;
|
||||
};
|
||||
|
||||
// Deserializers can use this base constructor.
|
||||
explicit ProfilerMarkerPayload(CommonProps&& aCommonProps)
|
||||
: mCommonProps(std::move(aCommonProps)) {}
|
||||
|
||||
void StreamType(const char* aMarkerType, SpliceableJSONWriter& aWriter);
|
||||
// Serialization/deserialization of common props in ProfilerMarkerPayload.
|
||||
mozilla::BlocksRingBuffer::Length CommonPropsTagAndSerializationBytes() const;
|
||||
void SerializeTagAndCommonProps(
|
||||
DeserializerTag aDeserializerTag,
|
||||
mozilla::BlocksRingBuffer::EntryWriter& aEntryWriter) const;
|
||||
static CommonProps DeserializeCommonProps(
|
||||
mozilla::BlocksRingBuffer::EntryReader& aEntryReader);
|
||||
|
||||
void StreamType(const char* aMarkerType, SpliceableJSONWriter& aWriter) const;
|
||||
|
||||
void StreamCommonProps(const char* aMarkerType, SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks);
|
||||
UniqueStacks& aUniqueStacks) const;
|
||||
|
||||
private:
|
||||
// Compute the number of bytes needed to serialize payload in
|
||||
// `SerializeTagAndPayload` below.
|
||||
virtual mozilla::BlocksRingBuffer::Length TagAndSerializationBytes()
|
||||
const = 0;
|
||||
|
||||
// Serialize the payload into an EntryWriter.
|
||||
// Must be of the exact size given by `TagAndSerializationBytes()`.
|
||||
virtual void SerializeTagAndPayload(
|
||||
mozilla::BlocksRingBuffer::EntryWriter& aEntryWriter) const = 0;
|
||||
|
||||
CommonProps mCommonProps;
|
||||
};
|
||||
|
||||
#define DECL_STREAM_PAYLOAD \
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter, \
|
||||
const mozilla::TimeStamp& aProcessStartTime, \
|
||||
UniqueStacks& aUniqueStacks) override;
|
||||
#define DECL_STREAM_PAYLOAD \
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter, \
|
||||
const mozilla::TimeStamp& aProcessStartTime, \
|
||||
UniqueStacks& aUniqueStacks) const override; \
|
||||
static mozilla::UniquePtr<ProfilerMarkerPayload> Deserialize( \
|
||||
mozilla::BlocksRingBuffer::EntryReader& aEntryReader); \
|
||||
mozilla::BlocksRingBuffer::Length TagAndSerializationBytes() const override; \
|
||||
void SerializeTagAndPayload( \
|
||||
mozilla::BlocksRingBuffer::EntryWriter& aEntryWriter) const override;
|
||||
|
||||
// TODO: Increase the coverage of tracing markers that include DocShell
|
||||
// information
|
||||
|
@ -109,6 +203,18 @@ class TracingMarkerPayload : public ProfilerMarkerPayload {
|
|||
|
||||
DECL_STREAM_PAYLOAD
|
||||
|
||||
protected:
|
||||
TracingMarkerPayload(CommonProps&& aCommonProps, const char* aCategory,
|
||||
TracingKind aKind)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mCategory(aCategory),
|
||||
mKind(aKind) {}
|
||||
|
||||
// May be used by derived classes.
|
||||
void SerializeTagAndPayload(
|
||||
DeserializerTag aDeserializerTag,
|
||||
mozilla::BlocksRingBuffer::EntryWriter& aEntryWriter) const;
|
||||
|
||||
private:
|
||||
const char* mCategory;
|
||||
TracingKind mKind;
|
||||
|
@ -132,6 +238,14 @@ class FileIOMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
FileIOMarkerPayload(CommonProps&& aCommonProps, const char* aSource,
|
||||
mozilla::UniqueFreePtr<char>&& aOperation,
|
||||
mozilla::UniqueFreePtr<char>&& aFilename)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mSource(aSource),
|
||||
mOperation(std::move(aOperation)),
|
||||
mFilename(std::move(aFilename)) {}
|
||||
|
||||
const char* mSource;
|
||||
mozilla::UniqueFreePtr<char> mOperation;
|
||||
mozilla::UniqueFreePtr<char> mFilename;
|
||||
|
@ -151,6 +265,13 @@ class DOMEventMarkerPayload : public TracingMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
DOMEventMarkerPayload(CommonProps&& aCommonProps, const char* aCategory,
|
||||
TracingKind aKind, mozilla::TimeStamp aTimeStamp,
|
||||
nsString aEventType)
|
||||
: TracingMarkerPayload(std::move(aCommonProps), aCategory, aKind),
|
||||
mTimeStamp(aTimeStamp),
|
||||
mEventType(aEventType) {}
|
||||
|
||||
mozilla::TimeStamp mTimeStamp;
|
||||
nsString mEventType;
|
||||
};
|
||||
|
@ -172,6 +293,18 @@ class PrefMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
PrefMarkerPayload(CommonProps&& aCommonProps,
|
||||
mozilla::TimeStamp aPrefAccessTime, nsCString&& aPrefName,
|
||||
mozilla::Maybe<mozilla::PrefValueKind>&& aPrefKind,
|
||||
mozilla::Maybe<mozilla::PrefType>&& aPrefType,
|
||||
nsCString&& aPrefValue)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mPrefAccessTime(aPrefAccessTime),
|
||||
mPrefName(aPrefName),
|
||||
mPrefKind(aPrefKind),
|
||||
mPrefType(aPrefType),
|
||||
mPrefValue(aPrefValue) {}
|
||||
|
||||
mozilla::TimeStamp mPrefAccessTime;
|
||||
nsCString mPrefName;
|
||||
// Nothing means this is a shared preference. Something, on the other hand,
|
||||
|
@ -212,6 +345,16 @@ class UserTimingMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
UserTimingMarkerPayload(CommonProps&& aCommonProps, const char* aEntryType,
|
||||
nsString&& aName,
|
||||
mozilla::Maybe<nsString>&& aStartMark,
|
||||
mozilla::Maybe<nsString>&& aEndMark)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mEntryType(aEntryType),
|
||||
mName(std::move(aName)),
|
||||
mStartMark(std::move(aStartMark)),
|
||||
mEndMark(std::move(aEndMark)) {}
|
||||
|
||||
// Either "mark" or "measure".
|
||||
const char* mEntryType;
|
||||
nsString mName;
|
||||
|
@ -233,6 +376,13 @@ class LayerTranslationMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
LayerTranslationMarkerPayload(CommonProps&& aCommonProps,
|
||||
mozilla::layers::Layer* aLayer,
|
||||
mozilla::gfx::Point aPoint)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mLayer(aLayer),
|
||||
mPoint(aPoint) {}
|
||||
|
||||
mozilla::layers::Layer* mLayer;
|
||||
mozilla::gfx::Point mPoint;
|
||||
};
|
||||
|
@ -246,6 +396,10 @@ class VsyncMarkerPayload : public ProfilerMarkerPayload {
|
|||
: ProfilerMarkerPayload(aVsyncTimestamp, aVsyncTimestamp) {}
|
||||
|
||||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
explicit VsyncMarkerPayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
};
|
||||
|
||||
class NetworkMarkerPayload : public ProfilerMarkerPayload {
|
||||
|
@ -277,6 +431,22 @@ class NetworkMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
NetworkMarkerPayload(CommonProps&& aCommonProps, int64_t aID,
|
||||
mozilla::UniqueFreePtr<char>&& aURI,
|
||||
mozilla::UniqueFreePtr<char>&& aRedirectURI,
|
||||
NetworkLoadType aType, int32_t aPri, int64_t aCount,
|
||||
mozilla::net::TimingStruct aTimings,
|
||||
mozilla::net::CacheDisposition aCacheDisposition)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mID(aID),
|
||||
mURI(std::move(aURI)),
|
||||
mRedirectURI(std::move(aRedirectURI)),
|
||||
mType(aType),
|
||||
mPri(aPri),
|
||||
mCount(aCount),
|
||||
mTimings(aTimings),
|
||||
mCacheDisposition(aCacheDisposition) {}
|
||||
|
||||
int64_t mID;
|
||||
mozilla::UniqueFreePtr<char> mURI;
|
||||
mozilla::UniqueFreePtr<char> mRedirectURI;
|
||||
|
@ -301,6 +471,14 @@ class ScreenshotPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
ScreenshotPayload(CommonProps&& aCommonProps, nsCString&& aScreenshotDataURL,
|
||||
mozilla::gfx::IntSize aWindowSize,
|
||||
uintptr_t aWindowIdentifier)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mScreenshotDataURL(std::move(aScreenshotDataURL)),
|
||||
mWindowSize(aWindowSize),
|
||||
mWindowIdentifier(aWindowIdentifier) {}
|
||||
|
||||
nsCString mScreenshotDataURL;
|
||||
mozilla::gfx::IntSize mWindowSize;
|
||||
uintptr_t mWindowIdentifier;
|
||||
|
@ -317,6 +495,11 @@ class GCSliceMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
GCSliceMarkerPayload(CommonProps&& aCommonProps,
|
||||
JS::UniqueChars&& aTimingJSON)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mTimingJSON(std::move(aTimingJSON)) {}
|
||||
|
||||
JS::UniqueChars mTimingJSON;
|
||||
};
|
||||
|
||||
|
@ -331,6 +514,11 @@ class GCMajorMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
GCMajorMarkerPayload(CommonProps&& aCommonProps,
|
||||
JS::UniqueChars&& aTimingJSON)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mTimingJSON(std::move(aTimingJSON)) {}
|
||||
|
||||
JS::UniqueChars mTimingJSON;
|
||||
};
|
||||
|
||||
|
@ -345,6 +533,11 @@ class GCMinorMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
GCMinorMarkerPayload(CommonProps&& aCommonProps,
|
||||
JS::UniqueChars&& aTimingData)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mTimingData(std::move(aTimingData)) {}
|
||||
|
||||
JS::UniqueChars mTimingData;
|
||||
};
|
||||
|
||||
|
@ -356,6 +549,8 @@ class HangMarkerPayload : public ProfilerMarkerPayload {
|
|||
|
||||
DECL_STREAM_PAYLOAD
|
||||
private:
|
||||
explicit HangMarkerPayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
};
|
||||
|
||||
class StyleMarkerPayload : public ProfilerMarkerPayload {
|
||||
|
@ -373,6 +568,10 @@ class StyleMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
StyleMarkerPayload(CommonProps&& aCommonProps,
|
||||
mozilla::ServoTraversalStatistics aStats)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)), mStats(aStats) {}
|
||||
|
||||
mozilla::ServoTraversalStatistics mStats;
|
||||
};
|
||||
|
||||
|
@ -383,6 +582,10 @@ class LongTaskMarkerPayload : public ProfilerMarkerPayload {
|
|||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
|
||||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
explicit LongTaskMarkerPayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
};
|
||||
|
||||
class TextMarkerPayload : public ProfilerMarkerPayload {
|
||||
|
@ -417,6 +620,10 @@ class TextMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
TextMarkerPayload(CommonProps&& aCommonProps, nsCString&& aText)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mText(std::move(aText)) {}
|
||||
|
||||
nsCString mText;
|
||||
};
|
||||
|
||||
|
@ -431,6 +638,12 @@ class LogMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
LogMarkerPayload(CommonProps&& aCommonProps, nsAutoCStringN<32>&& aModule,
|
||||
nsCString&& aText)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mModule(std::move(aModule)),
|
||||
mText(std::move(aText)) {}
|
||||
|
||||
nsAutoCStringN<32> mModule; // longest known LazyLogModule name is ~24
|
||||
nsCString mText;
|
||||
};
|
||||
|
@ -457,6 +670,20 @@ class JsAllocationMarkerPayload : public ProfilerMarkerPayload {
|
|||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
JsAllocationMarkerPayload(
|
||||
CommonProps&& aCommonProps,
|
||||
mozilla::UniqueFreePtr<const char16_t>&& aTypeName,
|
||||
mozilla::UniqueFreePtr<const char>&& aClassName,
|
||||
mozilla::UniqueFreePtr<const char16_t>&& aDescriptiveTypeName,
|
||||
const char* aCoarseType, uint64_t aSize, bool aInNursery)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)),
|
||||
mTypeName(std::move(aTypeName)),
|
||||
mClassName(std::move(aClassName)),
|
||||
mDescriptiveTypeName(std::move(aDescriptiveTypeName)),
|
||||
mCoarseType(aCoarseType),
|
||||
mSize(aSize),
|
||||
mInNursery(aInNursery) {}
|
||||
|
||||
mozilla::UniqueFreePtr<const char16_t> mTypeName;
|
||||
mozilla::UniqueFreePtr<const char> mClassName;
|
||||
mozilla::UniqueFreePtr<const char16_t> mDescriptiveTypeName;
|
||||
|
@ -470,4 +697,36 @@ class JsAllocationMarkerPayload : public ProfilerMarkerPayload {
|
|||
bool mInNursery;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Serialize a pointed-at ProfilerMarkerPayload, may be null when there are no
|
||||
// payloads.
|
||||
template <>
|
||||
struct BlocksRingBuffer::Serializer<UniquePtr<ProfilerMarkerPayload>> {
|
||||
static Length Bytes(const UniquePtr<ProfilerMarkerPayload>& aPayload) {
|
||||
return ProfilerMarkerPayload::TagAndSerializationBytes(aPayload.get());
|
||||
}
|
||||
|
||||
static void Write(EntryWriter& aEW,
|
||||
const UniquePtr<ProfilerMarkerPayload>& aPayload) {
|
||||
ProfilerMarkerPayload::TagAndSerialize(aPayload.get(), aEW);
|
||||
}
|
||||
};
|
||||
|
||||
// Deserialize a ProfilerMarkerPayload into a UniquePtr, may be null if there
|
||||
// are no payloads.
|
||||
template <>
|
||||
struct BlocksRingBuffer::Deserializer<UniquePtr<ProfilerMarkerPayload>> {
|
||||
static void ReadInto(EntryReader& aER,
|
||||
UniquePtr<ProfilerMarkerPayload>& aPayload) {
|
||||
aPayload = Read(aER);
|
||||
}
|
||||
|
||||
static UniquePtr<ProfilerMarkerPayload> Read(EntryReader& aER) {
|
||||
return ProfilerMarkerPayload::DeserializeTagAndPayload(aER);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // ProfilerMarkerPayload_h
|
||||
|
|
|
@ -493,35 +493,68 @@ TEST(GeckoProfiler, Pause)
|
|||
// and destroyed.
|
||||
class GTestMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
explicit GTestMarkerPayload(int aN) : mN(aN) { sNumCreated++; }
|
||||
explicit GTestMarkerPayload(int aN) : mN(aN) { ++sNumCreated; }
|
||||
|
||||
virtual ~GTestMarkerPayload() { sNumDestroyed++; }
|
||||
virtual ~GTestMarkerPayload() { ++sNumDestroyed; }
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aStartTime,
|
||||
UniqueStacks& aUniqueStacks) override {
|
||||
StreamCommonProps("gtest", aWriter, aStartTime, aUniqueStacks);
|
||||
char buf[64];
|
||||
SprintfLiteral(buf, "gtest-%d", mN);
|
||||
aWriter.IntProperty(buf, mN);
|
||||
sNumStreamed++;
|
||||
}
|
||||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
GTestMarkerPayload(CommonProps&& aCommonProps, int aN)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)), mN(aN) {
|
||||
++sNumDeserialized;
|
||||
}
|
||||
|
||||
int mN;
|
||||
|
||||
public:
|
||||
// The number of GTestMarkerPayload instances that have been created,
|
||||
// streamed, and destroyed.
|
||||
static int sNumCreated;
|
||||
static int sNumSerialized;
|
||||
static int sNumDeserialized;
|
||||
static int sNumStreamed;
|
||||
static int sNumDestroyed;
|
||||
};
|
||||
|
||||
int GTestMarkerPayload::sNumCreated = 0;
|
||||
int GTestMarkerPayload::sNumSerialized = 0;
|
||||
int GTestMarkerPayload::sNumDeserialized = 0;
|
||||
int GTestMarkerPayload::sNumStreamed = 0;
|
||||
int GTestMarkerPayload::sNumDestroyed = 0;
|
||||
|
||||
BlocksRingBuffer::Length GTestMarkerPayload::TagAndSerializationBytes() const {
|
||||
return CommonPropsTagAndSerializationBytes() + BlocksRingBuffer::SumBytes(mN);
|
||||
}
|
||||
|
||||
void GTestMarkerPayload::SerializeTagAndPayload(
|
||||
BlocksRingBuffer::EntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
aEntryWriter.WriteObject(mN);
|
||||
++sNumSerialized;
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> GTestMarkerPayload::Deserialize(
|
||||
BlocksRingBuffer::EntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
auto n = aEntryReader.ReadObject<int>();
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new GTestMarkerPayload(std::move(props), n));
|
||||
}
|
||||
|
||||
void GTestMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aStartTime,
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("gtest", aWriter, aStartTime, aUniqueStacks);
|
||||
char buf[64];
|
||||
SprintfLiteral(buf, "gtest-%d", mN);
|
||||
aWriter.IntProperty(buf, mN);
|
||||
++sNumStreamed;
|
||||
}
|
||||
|
||||
TEST(GeckoProfiler, Markers)
|
||||
{
|
||||
uint32_t features = ProfilerFeature::StackWalk;
|
||||
|
@ -552,6 +585,12 @@ TEST(GeckoProfiler, Markers)
|
|||
for (int i = 0; i < 10; i++) {
|
||||
PROFILER_ADD_MARKER_WITH_PAYLOAD("M5", OTHER, GTestMarkerPayload, (i));
|
||||
}
|
||||
// The GTestMarkerPayloads should have only been created.
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumCreated, 10);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumSerialized, 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDeserialized, 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumStreamed, 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDestroyed, 0);
|
||||
|
||||
// Create two strings: one that is the maximum allowed length, and one that
|
||||
// is one char longer.
|
||||
|
@ -580,11 +619,12 @@ TEST(GeckoProfiler, Markers)
|
|||
|
||||
UniquePtr<char[]> profile = w.WriteFunc()->CopyData();
|
||||
|
||||
// The GTestMarkerPayloads should have been created and streamed, but not yet
|
||||
// destroyed.
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumCreated == 10);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumStreamed == 10);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 0);
|
||||
// The GTestMarkerPayloads should have been streamed.
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumCreated, 10 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumSerialized, 0 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDeserialized, 0 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumStreamed, 0 + 10);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDestroyed, 0 + 0);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
char buf[64];
|
||||
SprintfLiteral(buf, "\"gtest-%d\"", i);
|
||||
|
@ -634,7 +674,11 @@ TEST(GeckoProfiler, Markers)
|
|||
profiler_stop();
|
||||
|
||||
// The GTestMarkerPayloads should have been destroyed.
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 10);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumCreated, 10 + 0 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumSerialized, 0 + 0 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDeserialized, 0 + 0 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumStreamed, 0 + 10 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDestroyed, 0 + 0 + 10);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PROFILER_ADD_MARKER_WITH_PAYLOAD("M5", OTHER, GTestMarkerPayload, (i));
|
||||
|
@ -648,10 +692,13 @@ TEST(GeckoProfiler, Markers)
|
|||
|
||||
profiler_stop();
|
||||
|
||||
// The second set of GTestMarkerPayloads should not have been streamed.
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumCreated == 20);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumStreamed == 10);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 20);
|
||||
// The second set of GTestMarkerPayloads should not have been serialized or
|
||||
// streamed.
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumCreated, 10 + 0 + 0 + 10);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumSerialized, 0 + 0 + 0 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDeserialized, 0 + 0 + 0 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumStreamed, 0 + 10 + 0 + 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDestroyed, 0 + 0 + 10 + 10);
|
||||
}
|
||||
|
||||
TEST(GeckoProfiler, DurationLimit)
|
||||
|
@ -664,6 +711,8 @@ TEST(GeckoProfiler, DurationLimit)
|
|||
|
||||
// Clear up the counters after the last test.
|
||||
GTestMarkerPayload::sNumCreated = 0;
|
||||
GTestMarkerPayload::sNumSerialized = 0;
|
||||
GTestMarkerPayload::sNumDeserialized = 0;
|
||||
GTestMarkerPayload::sNumStreamed = 0;
|
||||
GTestMarkerPayload::sNumDestroyed = 0;
|
||||
|
||||
|
@ -675,10 +724,12 @@ TEST(GeckoProfiler, DurationLimit)
|
|||
SpliceableChunkedJSONWriter w;
|
||||
ASSERT_TRUE(profiler_stream_json_for_this_process(w));
|
||||
|
||||
// The first marker should be destroyed.
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumCreated == 2);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumStreamed == 1);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 1);
|
||||
// Only the first marker should have been streamed and destroyed.
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumCreated, 2);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumSerialized, 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDeserialized, 0);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumStreamed, 1);
|
||||
ASSERT_EQ(GTestMarkerPayload::sNumDestroyed, 1);
|
||||
}
|
||||
|
||||
#define COUNTER_NAME "TestCounter"
|
||||
|
|
Загрузка…
Ссылка в новой задаче