gecko-dev/tools/profiler/public/ProfilerMarkerPayload.h

790 строки
29 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ProfilerMarkerPayload_h
#define ProfilerMarkerPayload_h
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/BlocksRingBuffer.h"
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Preferences.h"
#include "mozilla/UniquePtrExtensions.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/net/TimingStruct.h"
#include "nsString.h"
#include "nsCRTGlue.h"
#include "GeckoProfiler.h"
#include "js/Utility.h"
#include "js/AllocationRecording.h"
#include "js/ProfilingFrameIterator.h"
#include "gfxASurface.h"
#include "mozilla/ServoTraversalStatistics.h"
namespace mozilla {
namespace layers {
class Layer;
} // namespace layers
} // namespace mozilla
class SpliceableJSONWriter;
class UniqueStacks;
// This is an abstract class that can be implemented to supply data to be
// attached with a profiler marker.
//
// When subclassing this, note that the destructor can be called on any thread,
// i.e. not necessarily on the thread that created the object.
class ProfilerMarkerPayload {
public:
explicit ProfilerMarkerPayload(
const mozilla::Maybe<uint64_t>& aInnerWindowID = mozilla::Nothing(),
UniqueProfilerBacktrace aStack = nullptr)
: mCommonProps{mozilla::TimeStamp{}, mozilla::TimeStamp{},
std::move(aStack), aInnerWindowID} {}
ProfilerMarkerPayload(
const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime,
const mozilla::Maybe<uint64_t>& aInnerWindowID = mozilla::Nothing(),
UniqueProfilerBacktrace aStack = nullptr)
: mCommonProps{aStartTime, aEndTime, std::move(aStack), aInnerWindowID} {}
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) 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;
UniqueProfilerBacktrace mStack;
mozilla::Maybe<uint64_t> mInnerWindowID;
};
// Deserializers can use this base constructor.
explicit ProfilerMarkerPayload(CommonProps&& aCommonProps)
: mCommonProps(std::move(aCommonProps)) {}
// 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) 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 \
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 InnerWindowID
// information
class TracingMarkerPayload : public ProfilerMarkerPayload {
public:
TracingMarkerPayload(
const char* aCategory, TracingKind aKind,
const mozilla::Maybe<uint64_t>& aInnerWindowID = mozilla::Nothing(),
UniqueProfilerBacktrace aCause = nullptr)
: ProfilerMarkerPayload(aInnerWindowID, std::move(aCause)),
mCategory(aCategory),
mKind(aKind) {}
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;
};
class FileIOMarkerPayload : public ProfilerMarkerPayload {
public:
FileIOMarkerPayload(const char* aOperation, const char* aSource,
const char* aFilename,
const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime,
UniqueProfilerBacktrace aStack)
: ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing(),
std::move(aStack)),
mSource(aSource),
mOperation(aOperation ? strdup(aOperation) : nullptr),
mFilename(aFilename ? strdup(aFilename) : nullptr) {
MOZ_ASSERT(aSource);
}
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;
};
class DOMEventMarkerPayload : public TracingMarkerPayload {
public:
DOMEventMarkerPayload(const nsAString& aEventType,
const mozilla::TimeStamp& aTimeStamp,
const char* aCategory, TracingKind aKind,
const mozilla::Maybe<uint64_t>& aInnerWindowID)
: TracingMarkerPayload(aCategory, aKind, aInnerWindowID),
mTimeStamp(aTimeStamp),
mEventType(aEventType) {}
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;
};
class PrefMarkerPayload : public ProfilerMarkerPayload {
public:
PrefMarkerPayload(const char* aPrefName,
const mozilla::Maybe<mozilla::PrefValueKind>& aPrefKind,
const mozilla::Maybe<mozilla::PrefType>& aPrefType,
const nsCString& aPrefValue,
const mozilla::TimeStamp& aPrefAccessTime)
: ProfilerMarkerPayload(aPrefAccessTime, aPrefAccessTime),
mPrefAccessTime(aPrefAccessTime),
mPrefName(aPrefName),
mPrefKind(aPrefKind),
mPrefType(aPrefType),
mPrefValue(aPrefValue) {}
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,
// holds an actual PrefValueKind indicating either a Default or User
// preference.
mozilla::Maybe<mozilla::PrefValueKind> mPrefKind;
// Nothing means that the mPrefName preference was not found. Something
// contains the type of the preference.
mozilla::Maybe<mozilla::PrefType> mPrefType;
nsCString mPrefValue;
};
class UserTimingMarkerPayload : public ProfilerMarkerPayload {
public:
UserTimingMarkerPayload(const nsAString& aName,
const mozilla::TimeStamp& aStartTime,
const mozilla::Maybe<uint64_t>& aInnerWindowID)
: ProfilerMarkerPayload(aStartTime, aStartTime, aInnerWindowID),
mEntryType("mark"),
mName(aName) {}
UserTimingMarkerPayload(const nsAString& aName,
const mozilla::Maybe<nsString>& aStartMark,
const mozilla::Maybe<nsString>& aEndMark,
const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime,
const mozilla::Maybe<uint64_t>& aInnerWindowID)
: ProfilerMarkerPayload(aStartTime, aEndTime, aInnerWindowID),
mEntryType("measure"),
mName(aName),
mStartMark(aStartMark),
mEndMark(aEndMark) {}
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;
mozilla::Maybe<nsString> mStartMark;
mozilla::Maybe<nsString> mEndMark;
};
// Contains the translation applied to a 2d layer so we can track the layer
// position at each frame.
class LayerTranslationMarkerPayload : public ProfilerMarkerPayload {
public:
LayerTranslationMarkerPayload(mozilla::layers::Layer* aLayer,
mozilla::gfx::Point aPoint,
mozilla::TimeStamp aStartTime)
: ProfilerMarkerPayload(aStartTime, aStartTime),
mLayer(aLayer),
mPoint(aPoint) {}
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;
};
#include "Units.h" // For ScreenIntPoint
// Tracks when a vsync occurs according to the HardwareComposer.
class VsyncMarkerPayload : public ProfilerMarkerPayload {
public:
explicit VsyncMarkerPayload(mozilla::TimeStamp aVsyncTimestamp)
: ProfilerMarkerPayload(aVsyncTimestamp, aVsyncTimestamp) {}
DECL_STREAM_PAYLOAD
private:
explicit VsyncMarkerPayload(CommonProps&& aCommonProps)
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
};
class NetworkMarkerPayload : public ProfilerMarkerPayload {
public:
NetworkMarkerPayload(int64_t aID, const char* aURI, NetworkLoadType aType,
const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime, int32_t aPri,
int64_t aCount,
mozilla::net::CacheDisposition aCacheDisposition,
const mozilla::net::TimingStruct* aTimings = nullptr,
const char* aRedirectURI = nullptr,
UniqueProfilerBacktrace aSource = nullptr)
: ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing(),
std::move(aSource)),
mID(aID),
mURI(aURI ? strdup(aURI) : nullptr),
mRedirectURI(aRedirectURI && (strlen(aRedirectURI) > 0)
? strdup(aRedirectURI)
: nullptr),
mType(aType),
mPri(aPri),
mCount(aCount),
mCacheDisposition(aCacheDisposition) {
if (aTimings) {
mTimings = *aTimings;
}
}
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;
NetworkLoadType mType;
int32_t mPri;
int64_t mCount;
mozilla::net::TimingStruct mTimings;
mozilla::net::CacheDisposition mCacheDisposition;
};
class ScreenshotPayload : public ProfilerMarkerPayload {
public:
explicit ScreenshotPayload(mozilla::TimeStamp aTimeStamp,
nsCString&& aScreenshotDataURL,
const mozilla::gfx::IntSize& aWindowSize,
uintptr_t aWindowIdentifier)
: ProfilerMarkerPayload(aTimeStamp, mozilla::TimeStamp()),
mScreenshotDataURL(std::move(aScreenshotDataURL)),
mWindowSize(aWindowSize),
mWindowIdentifier(aWindowIdentifier) {}
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;
};
class GCSliceMarkerPayload : public ProfilerMarkerPayload {
public:
GCSliceMarkerPayload(const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime,
JS::UniqueChars&& aTimingJSON)
: ProfilerMarkerPayload(aStartTime, aEndTime),
mTimingJSON(std::move(aTimingJSON)) {}
DECL_STREAM_PAYLOAD
private:
GCSliceMarkerPayload(CommonProps&& aCommonProps,
JS::UniqueChars&& aTimingJSON)
: ProfilerMarkerPayload(std::move(aCommonProps)),
mTimingJSON(std::move(aTimingJSON)) {}
JS::UniqueChars mTimingJSON;
};
class GCMajorMarkerPayload : public ProfilerMarkerPayload {
public:
GCMajorMarkerPayload(const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime,
JS::UniqueChars&& aTimingJSON)
: ProfilerMarkerPayload(aStartTime, aEndTime),
mTimingJSON(std::move(aTimingJSON)) {}
DECL_STREAM_PAYLOAD
private:
GCMajorMarkerPayload(CommonProps&& aCommonProps,
JS::UniqueChars&& aTimingJSON)
: ProfilerMarkerPayload(std::move(aCommonProps)),
mTimingJSON(std::move(aTimingJSON)) {}
JS::UniqueChars mTimingJSON;
};
class GCMinorMarkerPayload : public ProfilerMarkerPayload {
public:
GCMinorMarkerPayload(const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime,
JS::UniqueChars&& aTimingData)
: ProfilerMarkerPayload(aStartTime, aEndTime),
mTimingData(std::move(aTimingData)) {}
DECL_STREAM_PAYLOAD
private:
GCMinorMarkerPayload(CommonProps&& aCommonProps,
JS::UniqueChars&& aTimingData)
: ProfilerMarkerPayload(std::move(aCommonProps)),
mTimingData(std::move(aTimingData)) {}
JS::UniqueChars mTimingData;
};
class HangMarkerPayload : public ProfilerMarkerPayload {
public:
HangMarkerPayload(const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime)
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
DECL_STREAM_PAYLOAD
private:
explicit HangMarkerPayload(CommonProps&& aCommonProps)
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
};
class StyleMarkerPayload : public ProfilerMarkerPayload {
public:
StyleMarkerPayload(const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime,
UniqueProfilerBacktrace aCause,
const mozilla::ServoTraversalStatistics& aStats,
const mozilla::Maybe<uint64_t>& aInnerWindowID)
: ProfilerMarkerPayload(aStartTime, aEndTime, aInnerWindowID,
std::move(aCause)),
mStats(aStats) {}
DECL_STREAM_PAYLOAD
private:
StyleMarkerPayload(CommonProps&& aCommonProps,
mozilla::ServoTraversalStatistics aStats)
: ProfilerMarkerPayload(std::move(aCommonProps)), mStats(aStats) {}
mozilla::ServoTraversalStatistics mStats;
};
class LongTaskMarkerPayload : public ProfilerMarkerPayload {
public:
LongTaskMarkerPayload(const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime)
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
DECL_STREAM_PAYLOAD
private:
explicit LongTaskMarkerPayload(CommonProps&& aCommonProps)
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
};
class TextMarkerPayload : public ProfilerMarkerPayload {
public:
TextMarkerPayload(const nsACString& aText,
const mozilla::TimeStamp& aStartTime)
: ProfilerMarkerPayload(aStartTime, aStartTime), mText(aText) {}
TextMarkerPayload(const nsACString& aText,
const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime)
: ProfilerMarkerPayload(aStartTime, aEndTime), mText(aText) {}
TextMarkerPayload(const nsACString& aText,
const mozilla::TimeStamp& aStartTime,
const mozilla::Maybe<uint64_t>& aInnerWindowID)
: ProfilerMarkerPayload(aStartTime, aStartTime, aInnerWindowID),
mText(aText) {}
TextMarkerPayload(const nsACString& aText,
const mozilla::TimeStamp& aStartTime,
const mozilla::TimeStamp& aEndTime,
const mozilla::Maybe<uint64_t>& aInnerWindowID,
UniqueProfilerBacktrace aCause = nullptr)
: ProfilerMarkerPayload(aStartTime, aEndTime, aInnerWindowID,
std::move(aCause)),
mText(aText) {}
DECL_STREAM_PAYLOAD
private:
TextMarkerPayload(CommonProps&& aCommonProps, nsCString&& aText)
: ProfilerMarkerPayload(std::move(aCommonProps)),
mText(std::move(aText)) {}
nsCString mText;
};
class LogMarkerPayload : public ProfilerMarkerPayload {
public:
LogMarkerPayload(const char* aModule, const char* aText,
const mozilla::TimeStamp& aStartTime)
: ProfilerMarkerPayload(aStartTime, aStartTime),
mModule(aModule),
mText(aText) {}
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;
};
class JsAllocationMarkerPayload : public ProfilerMarkerPayload {
public:
JsAllocationMarkerPayload(const mozilla::TimeStamp& aStartTime,
JS::RecordAllocationInfo&& aInfo,
UniqueProfilerBacktrace aStack)
: ProfilerMarkerPayload(aStartTime, aStartTime, mozilla::Nothing(),
std::move(aStack)),
// Copy the strings, and take ownership of them.
mTypeName(aInfo.typeName ? NS_xstrdup(aInfo.typeName) : nullptr),
mClassName(aInfo.className ? strdup(aInfo.className) : nullptr),
mDescriptiveTypeName(aInfo.descriptiveTypeName
? NS_xstrdup(aInfo.descriptiveTypeName)
: nullptr),
// The coarseType points to a string literal, so does not need to be
// duplicated.
mCoarseType(aInfo.coarseType),
mSize(aInfo.size),
mInNursery(aInfo.inNursery) {}
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;
// Points to a string literal, so does not need to be freed.
const char* mCoarseType;
// The size in bytes of the allocation.
uint64_t mSize;
// Whether or not the allocation is in the nursery or not.
bool mInNursery;
};
// This payload is for collecting information about native allocations. There is
// a memory hook into malloc and other memory functions that can sample a subset
// of the allocations. This information is then stored in this payload.
class NativeAllocationMarkerPayload : public ProfilerMarkerPayload {
public:
NativeAllocationMarkerPayload(const mozilla::TimeStamp& aStartTime,
const int64_t aSize,
UniqueProfilerBacktrace aStack)
: ProfilerMarkerPayload(aStartTime, aStartTime, mozilla::Nothing(),
std::move(aStack)),
mSize(aSize) {}
DECL_STREAM_PAYLOAD
private:
NativeAllocationMarkerPayload(CommonProps&& aCommonProps, int64_t aSize)
: ProfilerMarkerPayload(std::move(aCommonProps)), mSize(aSize) {}
// The size in bytes of the allocation or de-allocation.
int64_t mSize;
};
class IPCMarkerPayload : public ProfilerMarkerPayload {
public:
IPCMarkerPayload(int32_t aOtherPid, int32_t aMessageSeqno,
IPC::Message::msgid_t aMessageType, mozilla::ipc::Side aSide,
mozilla::ipc::MessageDirection aDirection, bool aSync,
const mozilla::TimeStamp& aStartTime)
: ProfilerMarkerPayload(aStartTime, aStartTime),
mOtherPid(aOtherPid),
mMessageSeqno(aMessageSeqno),
mMessageType(aMessageType),
mSide(aSide),
mDirection(aDirection),
mSync(aSync) {}
DECL_STREAM_PAYLOAD
private:
IPCMarkerPayload(CommonProps&& aCommonProps, int32_t aOtherPid,
int32_t aMessageSeqno, IPC::Message::msgid_t aMessageType,
mozilla::ipc::Side aSide,
mozilla::ipc::MessageDirection aDirection, bool aSync)
: ProfilerMarkerPayload(std::move(aCommonProps)),
mOtherPid(aOtherPid),
mMessageSeqno(aMessageSeqno),
mMessageType(aMessageType),
mSide(aSide),
mDirection(aDirection),
mSync(aSync) {}
int32_t mOtherPid;
int32_t mMessageSeqno;
IPC::Message::msgid_t mMessageType;
mozilla::ipc::Side mSide;
mozilla::ipc::MessageDirection mDirection;
bool mSync;
};
namespace mozilla {
// Serialize a pointed-at ProfilerMarkerPayload, may be null when there are no
// payloads.
template <>
struct BlocksRingBuffer::Serializer<const ProfilerMarkerPayload*> {
static Length Bytes(const ProfilerMarkerPayload* aPayload) {
return ProfilerMarkerPayload::TagAndSerializationBytes(aPayload);
}
static void Write(EntryWriter& aEW, const ProfilerMarkerPayload* aPayload) {
ProfilerMarkerPayload::TagAndSerialize(aPayload, aEW);
}
};
// 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