Line data Source code
1 : //===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // Define types and operations on these types that represent the different kinds
11 : // of records we encounter in XRay flight data recorder mode traces.
12 : //
13 : //===----------------------------------------------------------------------===//
14 : #ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
15 : #define LLVM_LIB_XRAY_FDRRECORDS_H_
16 :
17 : #include "llvm/Support/DataExtractor.h"
18 : #include "llvm/Support/Error.h"
19 : #include "llvm/XRay/XRayRecord.h"
20 : #include <cstdint>
21 :
22 : namespace llvm {
23 : namespace xray {
24 :
25 : class RecordVisitor;
26 : class RecordInitializer;
27 :
28 : class Record {
29 : protected:
30 : enum class Type {
31 : Unknown,
32 : Function,
33 : Metadata,
34 : };
35 :
36 : public:
37 : Record(const Record &) = delete;
38 : Record(Record &&) = delete;
39 : Record &operator=(const Record &) = delete;
40 : Record &operator=(Record &&) = delete;
41 : Record() = default;
42 :
43 : virtual Type type() const = 0;
44 :
45 : // Each Record should be able to apply an abstract visitor, and choose the
46 : // appropriate function in the visitor to invoke, given its own type.
47 : virtual Error apply(RecordVisitor &V) = 0;
48 :
49 0 : virtual ~Record() = default;
50 : };
51 :
52 : class MetadataRecord : public Record {
53 : protected:
54 : static constexpr int kMetadataBodySize = 15;
55 : friend class RecordInitializer;
56 :
57 : public:
58 : enum class MetadataType : unsigned {
59 : Unknown,
60 : BufferExtents,
61 : WallClockTime,
62 : NewCPUId,
63 : TSCWrap,
64 : CustomEvent,
65 : CallArg,
66 : PIDEntry,
67 : NewBuffer,
68 : EndOfBuffer,
69 : };
70 :
71 18 : Type type() const override { return Type::Metadata; }
72 :
73 : // All metadata records must know to provide the type of their open
74 : // metadata record.
75 : virtual MetadataType metadataType() const = 0;
76 :
77 0 : virtual ~MetadataRecord() = default;
78 : };
79 :
80 : // What follows are specific Metadata record types which encapsulate the
81 : // information associated with specific metadata record types in an FDR mode
82 : // log.
83 : class BufferExtents : public MetadataRecord {
84 : uint64_t Size = 0;
85 : friend class RecordInitializer;
86 :
87 : public:
88 7 : BufferExtents() = default;
89 4 : explicit BufferExtents(uint64_t S) : MetadataRecord(), Size(S) {}
90 :
91 0 : MetadataType metadataType() const override {
92 0 : return MetadataType::BufferExtents;
93 : }
94 :
95 0 : uint64_t size() const { return Size; }
96 :
97 : Error apply(RecordVisitor &V) override;
98 : };
99 :
100 : class WallclockRecord : public MetadataRecord {
101 : uint64_t Seconds = 0;
102 : uint32_t Nanos = 0;
103 : friend class RecordInitializer;
104 :
105 : public:
106 10 : WallclockRecord() = default;
107 : explicit WallclockRecord(uint64_t S, uint32_t N)
108 2 : : MetadataRecord(), Seconds(S), Nanos(N) {}
109 :
110 0 : MetadataType metadataType() const override {
111 0 : return MetadataType::WallClockTime;
112 : }
113 :
114 0 : uint64_t seconds() const { return Seconds; }
115 0 : uint32_t nanos() const { return Nanos; }
116 :
117 : Error apply(RecordVisitor &V) override;
118 : };
119 :
120 : class NewCPUIDRecord : public MetadataRecord {
121 : uint16_t CPUId = 0;
122 : uint64_t TSC = 0;
123 : friend class RecordInitializer;
124 :
125 : public:
126 14 : NewCPUIDRecord() = default;
127 2 : NewCPUIDRecord(uint16_t C, uint64_t T) : MetadataRecord(), CPUId(C), TSC(T) {}
128 :
129 0 : MetadataType metadataType() const override { return MetadataType::NewCPUId; }
130 :
131 0 : uint16_t cpuid() const { return CPUId; }
132 :
133 0 : uint64_t tsc() const { return TSC; }
134 :
135 : Error apply(RecordVisitor &V) override;
136 : };
137 :
138 : class TSCWrapRecord : public MetadataRecord {
139 : uint64_t BaseTSC = 0;
140 : friend class RecordInitializer;
141 :
142 : public:
143 9 : TSCWrapRecord() = default;
144 2 : explicit TSCWrapRecord(uint64_t B) : MetadataRecord(), BaseTSC(B) {}
145 :
146 0 : MetadataType metadataType() const override { return MetadataType::TSCWrap; }
147 :
148 0 : uint64_t tsc() const { return BaseTSC; }
149 :
150 : Error apply(RecordVisitor &V) override;
151 : };
152 :
153 : class CustomEventRecord : public MetadataRecord {
154 : int32_t Size = 0;
155 : uint64_t TSC = 0;
156 : std::string Data{};
157 : friend class RecordInitializer;
158 :
159 : public:
160 1 : CustomEventRecord() = default;
161 : explicit CustomEventRecord(uint64_t S, uint64_t T, std::string D)
162 0 : : MetadataRecord(), Size(S), TSC(T), Data(std::move(D)) {}
163 :
164 0 : MetadataType metadataType() const override {
165 0 : return MetadataType::CustomEvent;
166 : }
167 :
168 0 : int32_t size() const { return Size; }
169 0 : uint64_t tsc() const { return TSC; }
170 : StringRef data() const { return Data; }
171 :
172 : Error apply(RecordVisitor &V) override;
173 : };
174 :
175 : class CallArgRecord : public MetadataRecord {
176 : uint64_t Arg;
177 : friend class RecordInitializer;
178 :
179 : public:
180 5 : CallArgRecord() = default;
181 2 : explicit CallArgRecord(uint64_t A) : MetadataRecord(), Arg(A) {}
182 :
183 0 : MetadataType metadataType() const override { return MetadataType::CallArg; }
184 :
185 0 : uint64_t arg() const { return Arg; }
186 :
187 : Error apply(RecordVisitor &V) override;
188 : };
189 :
190 : class PIDRecord : public MetadataRecord {
191 : int32_t PID = 0;
192 : friend class RecordInitializer;
193 :
194 : public:
195 5 : PIDRecord() = default;
196 2 : explicit PIDRecord(int32_t P) : MetadataRecord(), PID(P) {}
197 :
198 0 : MetadataType metadataType() const override { return MetadataType::PIDEntry; }
199 :
200 0 : int32_t pid() const { return PID; }
201 :
202 : Error apply(RecordVisitor &V) override;
203 : };
204 :
205 : class NewBufferRecord : public MetadataRecord {
206 : int32_t TID = 0;
207 : friend class RecordInitializer;
208 :
209 : public:
210 10 : NewBufferRecord() = default;
211 2 : explicit NewBufferRecord(int32_t T) : MetadataRecord(), TID(T) {}
212 :
213 0 : MetadataType metadataType() const override { return MetadataType::NewBuffer; }
214 :
215 0 : int32_t tid() const { return TID; }
216 :
217 : Error apply(RecordVisitor &V) override;
218 : };
219 :
220 : class EndBufferRecord : public MetadataRecord {
221 : public:
222 7 : EndBufferRecord() = default;
223 :
224 0 : MetadataType metadataType() const override {
225 0 : return MetadataType::EndOfBuffer;
226 : }
227 :
228 : Error apply(RecordVisitor &V) override;
229 : };
230 :
231 4 : class FunctionRecord : public Record {
232 : RecordTypes Kind;
233 : int32_t FuncId;
234 : uint32_t Delta;
235 : friend class RecordInitializer;
236 :
237 : static constexpr unsigned kFunctionRecordSize = 8;
238 :
239 : public:
240 580 : FunctionRecord() = default;
241 : explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
242 5 : : Record(), Kind(K), FuncId(F), Delta(D) {}
243 :
244 2 : Type type() const override { return Type::Function; }
245 :
246 : // A function record is a concrete record type which has a number of common
247 : // properties.
248 0 : RecordTypes recordType() const { return Kind; }
249 0 : int32_t functionId() const { return FuncId; }
250 0 : uint32_t delta() const { return Delta; }
251 :
252 : Error apply(RecordVisitor &V) override;
253 : };
254 :
255 : class RecordVisitor {
256 : public:
257 0 : virtual ~RecordVisitor() = default;
258 :
259 : // Support all specific kinds of records:
260 : virtual Error visit(BufferExtents &) = 0;
261 : virtual Error visit(WallclockRecord &) = 0;
262 : virtual Error visit(NewCPUIDRecord &) = 0;
263 : virtual Error visit(TSCWrapRecord &) = 0;
264 : virtual Error visit(CustomEventRecord &) = 0;
265 : virtual Error visit(CallArgRecord &) = 0;
266 : virtual Error visit(PIDRecord &) = 0;
267 : virtual Error visit(NewBufferRecord &) = 0;
268 : virtual Error visit(EndBufferRecord &) = 0;
269 : virtual Error visit(FunctionRecord &) = 0;
270 : };
271 :
272 645 : class RecordInitializer : public RecordVisitor {
273 : DataExtractor &E;
274 : uint32_t &OffsetPtr;
275 :
276 : public:
277 : explicit RecordInitializer(DataExtractor &DE, uint32_t &OP)
278 645 : : RecordVisitor(), E(DE), OffsetPtr(OP) {}
279 :
280 : Error visit(BufferExtents &) override;
281 : Error visit(WallclockRecord &) override;
282 : Error visit(NewCPUIDRecord &) override;
283 : Error visit(TSCWrapRecord &) override;
284 : Error visit(CustomEventRecord &) override;
285 : Error visit(CallArgRecord &) override;
286 : Error visit(PIDRecord &) override;
287 : Error visit(NewBufferRecord &) override;
288 : Error visit(EndBufferRecord &) override;
289 : Error visit(FunctionRecord &) override;
290 : };
291 :
292 : } // namespace xray
293 : } // namespace llvm
294 :
295 : #endif // LLVM_LIB_XRAY_FDRRECORDS_H_
|