[VM/Timeline] Create perfetto_utils namespace

TEST=CI

Change-Id: Id6f1df83f5d7e34b8ff1f2c5ab9891d0ab3326a4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/288022
Reviewed-by: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Derek Xu 2023-04-20 16:42:23 +00:00 committed by Commit Queue
parent 6fb71e7237
commit f62620d361

View file

@ -40,6 +40,68 @@
namespace dart {
#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
namespace perfetto_utils {
inline void SetTrustedPacketSequenceId(
perfetto::protos::pbzero::TracePacket* packet) {
// trusted_packet_sequence_id uniquely identifies a trace producer + writer
// pair. We set the trusted_packet_sequence_id of all packets written by the
// Perfetto file recorder to the arbitrary value of 1.
packet->set_trusted_packet_sequence_id(1);
}
inline void PopulateClockSnapshotPacket(
perfetto::protos::pbzero::TracePacket* packet) {
SetTrustedPacketSequenceId(packet);
perfetto::protos::pbzero::ClockSnapshot& clock_snapshot =
*packet->set_clock_snapshot();
clock_snapshot.set_primary_trace_clock(
perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC);
perfetto::protos::pbzero::ClockSnapshot_Clock& clock =
*clock_snapshot.add_clocks();
clock.set_clock_id(
perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC);
clock.set_timestamp(OS::GetCurrentMonotonicMicrosForTimeline() * 1000);
}
inline void PopulateProcessDescriptorPacket(
perfetto::protos::pbzero::TracePacket* packet) {
perfetto_utils::SetTrustedPacketSequenceId(packet);
perfetto::protos::pbzero::TrackDescriptor& track_descriptor =
*packet->set_track_descriptor();
const int64_t pid = OS::ProcessId();
track_descriptor.set_uuid(pid);
perfetto::protos::pbzero::ProcessDescriptor& process_descriptor =
*track_descriptor.set_process();
process_descriptor.set_pid(pid);
// TODO(derekx): Add the process name.
}
inline const std::tuple<std::unique_ptr<const uint8_t[]>, intptr_t>
GetProtoPreamble(const intptr_t size) {
std::unique_ptr<uint8_t[]> preamble =
std::make_unique<uint8_t[]>(perfetto::TracePacket::kMaxPreambleBytes);
uint8_t* ptr = &preamble[0];
const uint8_t tag = protozero::proto_utils::MakeTagLengthDelimited(
perfetto::TracePacket::kPacketFieldNumber);
static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
*(ptr++) = tag;
ptr = protozero::proto_utils::WriteVarInt(size, ptr);
intptr_t preamble_size = reinterpret_cast<intptr_t>(ptr) -
reinterpret_cast<intptr_t>(&preamble[0]);
return std::make_tuple(std::move(preamble), preamble_size);
}
} // namespace perfetto_utils
#endif // defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
#if defined(PRODUCT)
#define DEFAULT_TIMELINE_RECORDER "none"
#define SUPPORTED_TIMELINE_RECORDERS "systrace, file, callback"
@ -891,17 +953,9 @@ void TimelineTrackMetadata::PrintJSON(const JSONArray& jsarr_events) const {
}
#if defined(SUPPORT_PERFETTO)
inline void SetTrustedPacketSequenceId(
perfetto::protos::pbzero::TracePacket* packet) {
// trusted_packet_sequence_id uniquely identifies a trace producer + writer
// pair. We set the trusted_packet_sequence_id of all packets written by the
// Perfetto file recorder to the arbitrary value of 1.
packet->set_trusted_packet_sequence_id(1);
}
void TimelineTrackMetadata::PopulateTracePacket(
perfetto::protos::pbzero::TracePacket* track_descriptor_packet) const {
SetTrustedPacketSequenceId(track_descriptor_packet);
perfetto_utils::SetTrustedPacketSequenceId(track_descriptor_packet);
perfetto::protos::pbzero::TrackDescriptor& track_descriptor =
*track_descriptor_packet->set_track_descriptor();
@ -924,7 +978,7 @@ AsyncTimelineTrackMetadata::AsyncTimelineTrackMetadata(intptr_t pid,
#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
void AsyncTimelineTrackMetadata::PopulateTracePacket(
perfetto::protos::pbzero::TracePacket* track_descriptor_packet) const {
SetTrustedPacketSequenceId(track_descriptor_packet);
perfetto_utils::SetTrustedPacketSequenceId(track_descriptor_packet);
perfetto::protos::pbzero::TrackDescriptor& track_descriptor =
*track_descriptor_packet->set_track_descriptor();
track_descriptor.set_parent_uuid(pid());
@ -1791,34 +1845,11 @@ void TimelineEventFileRecorder::DrainImpl(const TimelineEvent& event) {
TimelineEventPerfettoFileRecorder::TimelineEventPerfettoFileRecorder(
const char* path)
: TimelineEventFileRecorderBase(path) {
SetTrustedPacketSequenceId(packet_.get());
perfetto::protos::pbzero::ClockSnapshot& clock_snapshot =
*packet_->set_clock_snapshot();
clock_snapshot.set_primary_trace_clock(
perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC);
perfetto::protos::pbzero::ClockSnapshot_Clock& clock =
*clock_snapshot.add_clocks();
clock.set_clock_id(
perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC);
clock.set_timestamp(OS::GetCurrentMonotonicMicrosForTimeline() * 1000);
perfetto_utils::PopulateClockSnapshotPacket(packet_.get());
WritePacket(&packet_);
packet_.Reset();
SetTrustedPacketSequenceId(packet_.get());
perfetto::protos::pbzero::TrackDescriptor& track_descriptor =
*packet_->set_track_descriptor();
const int64_t pid = OS::ProcessId();
track_descriptor.set_uuid(pid);
perfetto::protos::pbzero::ProcessDescriptor& process_descriptor =
*track_descriptor.set_process();
process_descriptor.set_pid(pid);
// TODO(derekx): Add the process name.
perfetto_utils::PopulateProcessDescriptorPacket(packet_.get());
WritePacket(&packet_);
packet_.Reset();
@ -1849,23 +1880,6 @@ TimelineEventPerfettoFileRecorder::~TimelineEventPerfettoFileRecorder() {
}
}
inline const std::tuple<std::unique_ptr<char[]>, intptr_t> GetProtoPreamble(
const intptr_t size) {
auto preamble =
std::make_unique<char[]>(perfetto::TracePacket::kMaxPreambleBytes);
uint8_t* ptr = reinterpret_cast<uint8_t*>(&preamble[0]);
const uint8_t tag = protozero::proto_utils::MakeTagLengthDelimited(
perfetto::TracePacket::kPacketFieldNumber);
static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
*(ptr++) = tag;
ptr = protozero::proto_utils::WriteVarInt(size, ptr);
intptr_t preamble_size = reinterpret_cast<intptr_t>(ptr) -
reinterpret_cast<intptr_t>(&preamble[0]);
return std::make_tuple(std::move(preamble), preamble_size);
}
void TimelineEventPerfettoFileRecorder::WritePacket(
protozero::HeapBuffered<perfetto::protos::pbzero::TracePacket>* packet)
const {
@ -1874,9 +1888,10 @@ void TimelineEventPerfettoFileRecorder::WritePacket(
packet->GetSlices()) {
size += slice.size() - slice.unused_bytes();
}
const std::tuple<std::unique_ptr<char[]>, intptr_t>& response =
GetProtoPreamble(size);
Write(std::get<0>(response).get(), std::get<1>(response));
const std::tuple<std::unique_ptr<const uint8_t[]>, intptr_t>& response =
perfetto_utils::GetProtoPreamble(size);
Write(reinterpret_cast<const char*>(std::get<0>(response).get()),
std::get<1>(response));
for (const protozero::ScatteredHeapBuffer::Slice& slice :
packet->GetSlices()) {
Write(reinterpret_cast<char*>(slice.start()),
@ -1932,7 +1947,7 @@ inline void AddEndEventFields(
}
void TimelineEventPerfettoFileRecorder::DrainImpl(const TimelineEvent& event) {
SetTrustedPacketSequenceId(packet_.get());
perfetto_utils::SetTrustedPacketSequenceId(packet_.get());
// TODO(derekx): We should be able to set the unit_multiplier_ns field in a
// ClockSnapshot to avoid manually converting from microseconds to
// nanoseconds, but I haven't been able to get it to work.