Flutter Engine
The Flutter Engine
perfetto_utils.h
Go to the documentation of this file.
1// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_PERFETTO_UTILS_H_
6#define RUNTIME_VM_PERFETTO_UTILS_H_
7
8#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
9
10#include <memory>
11#include <tuple>
12#include <utility>
13
14#include "perfetto/ext/tracing/core/trace_packet.h"
15#include "perfetto/protozero/scattered_heap_buffer.h"
16#include "vm/json_stream.h"
17#include "vm/os.h"
23
24namespace dart {
25
26namespace perfetto_utils {
27
28inline void SetTrustedPacketSequenceId(
30 // trusted_packet_sequence_id uniquely identifies a trace producer + writer
31 // pair. We set the trusted_packet_sequence_id of all packets that we write to
32 // the arbitrary value of 1.
34}
35
36inline void SetTimestampAndMonotonicClockId(
38 int64_t timestamp_micros) {
39 ASSERT(packet != nullptr);
40 // TODO(derekx): We should be able to set the unit_multiplier_ns field in a
41 // ClockSnapshot to avoid manually converting from microseconds to
42 // nanoseconds, but I haven't been able to get it to work.
43 packet->set_timestamp(timestamp_micros * 1000);
46}
47
48inline void PopulateClockSnapshotPacket(
50 SetTrustedPacketSequenceId(packet);
51
53 *packet->set_clock_snapshot();
54 clock_snapshot.set_primary_trace_clock(
56
58 *clock_snapshot.add_clocks();
59 clock.set_clock_id(
62}
63
64inline void PopulateProcessDescriptorPacket(
66 perfetto_utils::SetTrustedPacketSequenceId(packet);
67
69 *packet->set_track_descriptor();
70 const int64_t pid = OS::ProcessId();
71 track_descriptor.set_uuid(pid);
72
74 *track_descriptor.set_process();
75 process_descriptor.set_pid(pid);
76 // TODO(derekx): Add the process name.
77}
78
79inline const std::tuple<std::unique_ptr<const uint8_t[]>, intptr_t>
80GetProtoPreamble(
81 protozero::HeapBuffered<perfetto::protos::pbzero::TracePacket>* packet) {
82 ASSERT(packet != nullptr);
83
84 intptr_t size = 0;
85 for (const protozero::ScatteredHeapBuffer::Slice& slice :
86 packet->GetSlices()) {
87 size += slice.size() - slice.unused_bytes();
88 }
89
90 std::unique_ptr<uint8_t[]> preamble =
91 std::make_unique<uint8_t[]>(perfetto::TracePacket::kMaxPreambleBytes);
92 uint8_t* ptr = &preamble[0];
93
94 const uint8_t tag = protozero::proto_utils::MakeTagLengthDelimited(
95 perfetto::TracePacket::kPacketFieldNumber);
96 static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
97 *(ptr++) = tag;
98
99 ptr = protozero::proto_utils::WriteVarInt(size, ptr);
100 intptr_t preamble_size = reinterpret_cast<intptr_t>(ptr) -
101 reinterpret_cast<intptr_t>(&preamble[0]);
102 return std::make_tuple(std::move(preamble), preamble_size);
103}
104
105inline void AppendPacketToJSONBase64String(
106 JSONBase64String* jsonBase64String,
107 protozero::HeapBuffered<perfetto::protos::pbzero::TracePacket>* packet) {
108 ASSERT(jsonBase64String != nullptr);
109 ASSERT(packet != nullptr);
110
111 const std::tuple<std::unique_ptr<const uint8_t[]>, intptr_t>& response =
112 perfetto_utils::GetProtoPreamble(packet);
113 const uint8_t* preamble = std::get<0>(response).get();
114 const intptr_t preamble_length = std::get<1>(response);
115 jsonBase64String->AppendBytes(preamble, preamble_length);
116 for (const protozero::ScatteredHeapBuffer::Slice& slice :
117 packet->GetSlices()) {
118 jsonBase64String->AppendBytes(slice.start(),
119 slice.size() - slice.unused_bytes());
120 }
121}
122
123} // namespace perfetto_utils
124
125} // namespace dart
126
127#endif // defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
128
129#endif // RUNTIME_VM_PERFETTO_UTILS_H_
static intptr_t ProcessId()
static int64_t GetCurrentMonotonicMicrosForTimeline()
void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value)
void set_trusted_packet_sequence_id(uint32_t value)
#define ASSERT(E)
Definition: dart_vm.cc:33
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
const myers::Point & get< 1 >(const myers::Segment &s)
Definition: Myers.h:81
const myers::Point & get< 0 >(const myers::Segment &s)
Definition: Myers.h:80