Bug 1646266 - MarkerOptions - r=gregtatum

A `MarkerOptions` must be constructed from a MarkerCategory, e.g.: `mozilla::baseprofiler::category::OTHER`. This will be required for all markers.
`MarkerOptions` also contains defaulted `MarkerThreadId`, `MarkerTiming`, `MarkerStack`, and `MarkerInnerWindowId`. They may be set by calling `WithOptions()` on the MarkerCategory, e.g.:
`PROFILER_MARKER<...>("name", OTHER.WithOptions(MarkerThreadId(otherThread), MarkerStack::Capture()), ...);`

Differential Revision: https://phabricator.services.mozilla.com/D87249
This commit is contained in:
Gerald Squelart 2020-09-01 03:58:01 +00:00
parent ecbd9b7fdd
commit 7aa5fd002d
2 changed files with 110 additions and 0 deletions

View File

@ -310,6 +310,41 @@ struct ProfileBufferEntryReader::Deserializer<MarkerStack> {
}
};
// ----------------------------------------------------------------------------
// Serializer, Deserializer: MarkerOptions
// The serialization contains all members (either trivially-copyable, or they
// provide their specialization above).
template <>
struct ProfileBufferEntryWriter::Serializer<MarkerOptions> {
static Length Bytes(const MarkerOptions& aOptions) {
return SumBytes(aOptions.Category(), aOptions.ThreadId(), aOptions.Timing(),
aOptions.Stack(), aOptions.InnerWindowId());
}
static void Write(ProfileBufferEntryWriter& aEW,
const MarkerOptions& aOptions) {
aEW.WriteObjects(aOptions.Category(), aOptions.ThreadId(),
aOptions.Timing(), aOptions.Stack(),
aOptions.InnerWindowId());
}
};
template <>
struct ProfileBufferEntryReader::Deserializer<MarkerOptions> {
static void ReadInto(ProfileBufferEntryReader& aER, MarkerOptions& aOptions) {
aER.ReadIntoObjects(aOptions.mCategory, aOptions.mThreadId,
aOptions.mTiming, aOptions.mStack,
aOptions.mInnerWindowId);
}
static MarkerOptions Read(ProfileBufferEntryReader& aER) {
MarkerOptions options;
ReadInto(aER, options);
return options;
}
};
} // namespace mozilla
#endif // MOZ_GECKO_PROFILER

View File

@ -15,6 +15,7 @@
#ifdef MOZ_GECKO_PROFILER
# include "BaseProfilingCategory.h"
# include "mozilla/ProfileChunkedBuffer.h"
# include "mozilla/TimeStamp.h"
# include "mozilla/UniquePtr.h"
@ -225,6 +226,11 @@ class MarkerCategory {
return mCategory;
}
// Create a MarkerOptions object from this category and options.
// Definition under MarkerOptions below.
template <typename... Options>
MarkerOptions WithOptions(Options&&... aOptions) const;
private:
// The default constructor is only used during deserialization of
// MarkerOptions.
@ -363,6 +369,7 @@ class MarkerTiming {
private:
friend ProfileBufferEntryWriter::Serializer<MarkerTiming>;
friend ProfileBufferEntryReader::Deserializer<MarkerTiming>;
friend MarkerOptions;
// Default timing leaves it internally "unspecified", serialization getters
// and add-marker functions will default to `InstantNow()`.
@ -556,6 +563,74 @@ class MarkerInnerWindowId {
uint64_t mInnerWindowId = scNoId;
};
// This class combines a compulsory category with the above marker options.
// To provide options to add-marker functions, first pick a MarkerCategory
// object, then options may be added with WithOptions(), e.g.:
// `mozilla::baseprofiler::category::OTHER_profiling`
// `mozilla::baseprofiler::category::DOM.WithOptions(
// MarkerThreadId(1), MarkerTiming::IntervalStart())`
class MarkerOptions {
public:
// Implicit constructor from category.
constexpr MOZ_IMPLICIT MarkerOptions(const MarkerCategory& aCategory)
: mCategory(aCategory) {}
// Constructor from category and other options.
template <typename... Options>
explicit MarkerOptions(const MarkerCategory& aCategory, Options&&... aOptions)
: mCategory(aCategory) {
(Set(std::forward<Options>(aOptions)), ...);
}
// Disallow copy.
MarkerOptions(const MarkerOptions&) = delete;
MarkerOptions& operator=(const MarkerOptions&) = delete;
// Allow move.
MarkerOptions(MarkerOptions&&) = default;
MarkerOptions& operator=(MarkerOptions&&) = default;
// The embedded `MarkerTiming` hasn't been specified yet.
[[nodiscard]] bool IsTimingUnspecified() const {
return mTiming.IsUnspecified();
}
// Each options may be added in a chain by e.g.: `Set(MarkerThreadId(123))`.
// Read them with the option name (without "Marker"), e.g.: `ThreadId()`.
# define FUNCTION_ON_MEMBER(NAME) \
MarkerOptions&& Set(Marker##NAME&& a##NAME) { \
m##NAME = std::move(a##NAME); \
return std::move(*this); \
} \
\
const Marker##NAME& NAME() const { return m##NAME; } \
Marker##NAME& NAME() { return m##NAME; }
FUNCTION_ON_MEMBER(Category);
FUNCTION_ON_MEMBER(ThreadId);
FUNCTION_ON_MEMBER(Timing);
FUNCTION_ON_MEMBER(Stack);
FUNCTION_ON_MEMBER(InnerWindowId);
# undef FUNCTION_ON_MEMBER
private:
friend ProfileBufferEntryReader::Deserializer<MarkerOptions>;
// The default constructor is only used during deserialization.
constexpr MarkerOptions() = default;
MarkerCategory mCategory;
MarkerThreadId mThreadId;
MarkerTiming mTiming;
MarkerStack mStack;
MarkerInnerWindowId mInnerWindowId;
};
template <typename... Options>
MarkerOptions MarkerCategory::WithOptions(Options&&... aOptions) const {
return MarkerOptions(*this, std::forward<Options>(aOptions)...);
}
} // namespace mozilla
#endif // MOZ_GECKO_PROFILER